pki: calculate Subject Key Identifier according to RFC 5280 (#11218)

Calculate the Subject Key Identifier as suggested in RFC 5280, Section 4.2.1.2

> (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the
value of the BIT STRING subjectPublicKey (excluding the tag,
length, and number of unused bits).

fixes #11153
This commit is contained in:
Dominik Roos 2022-01-28 16:46:51 +01:00 committed by GitHub
parent 45875e2e9d
commit 7a6ae24e9f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 12 deletions

3
changelog/11218.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:improvement
secrets/pki: Calculate the Subject Key Identifier as suggested in [RFC 5280, Section 4.2.1.2](https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.2).
```

View File

@ -77,21 +77,42 @@ func ParseHexFormatted(in, sep string) []byte {
return ret.Bytes()
}
// GetSubjKeyID returns the subject key ID, e.g. the SHA1 sum
// of the marshaled public key
// GetSubjKeyID returns the subject key ID. The computed ID is the SHA-1 hash of
// the marshaled public key according to
// https://tools.ietf.org/html/rfc5280#section-4.2.1.2 (1)
func GetSubjKeyID(privateKey crypto.Signer) ([]byte, error) {
if privateKey == nil {
return nil, errutil.InternalError{Err: "passed-in private key is nil"}
}
return getSubjectKeyID(privateKey.Public())
}
marshaledKey, err := x509.MarshalPKIXPublicKey(privateKey.Public())
func getSubjectKeyID(pub interface{}) ([]byte, error) {
var publicKeyBytes []byte
switch pub := pub.(type) {
case *rsa.PublicKey:
type pkcs1PublicKey struct {
N *big.Int
E int
}
var err error
publicKeyBytes, err = asn1.Marshal(pkcs1PublicKey{
N: pub.N,
E: pub.E,
})
if err != nil {
return nil, errutil.InternalError{Err: fmt.Sprintf("error marshalling public key: %s", err)}
}
subjKeyID := sha1.Sum(marshaledKey)
return subjKeyID[:], nil
case *ecdsa.PublicKey:
publicKeyBytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y)
case ed25519.PublicKey:
publicKeyBytes = pub
default:
return nil, errutil.InternalError{Err: fmt.Sprintf("unsupported public key type: %T", pub)}
}
skid := sha1.Sum(publicKeyBytes)
return skid[:], nil
}
// ParsePKIMap takes a map (for instance, the Secret.Data
@ -986,11 +1007,10 @@ func signCertificate(data *CreationBundle, randReader io.Reader) (*ParsedCertBun
return nil, err
}
marshaledKey, err := x509.MarshalPKIXPublicKey(data.CSR.PublicKey)
subjKeyID, err := getSubjectKeyID(data.CSR.PublicKey)
if err != nil {
return nil, errutil.InternalError{Err: fmt.Sprintf("error marshalling public key: %s", err)}
return nil, err
}
subjKeyID := sha1.Sum(marshaledKey)
caCert := data.SigningBundle.Certificate