Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 1 addition & 28 deletions ca/ca.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@ package ca
import (
"bytes"
"context"
"crypto"
"crypto/rand"
"crypto/sha256"
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/hex"
"errors"
"fmt"
Expand Down Expand Up @@ -251,7 +247,7 @@ func (ca *certificateAuthorityImpl) IssueCertificate(ctx context.Context, req *c
return nil, err
}

subjectKeyId, err := generateSKID(csr.PublicKey)
subjectKeyId, err := core.GenerateSKID(csr.PublicKey)
if err != nil {
return nil, fmt.Errorf("computing subject key ID: %w", err)
}
Expand Down Expand Up @@ -492,29 +488,6 @@ func (ca *certificateAuthorityImpl) generateSerialNumber() *big.Int {
return serialBigInt
}

// generateSKID computes the Subject Key Identifier using one of the methods in
// RFC 7093 Section 2 Additional Methods for Generating Key Identifiers:
// The keyIdentifier [may be] composed of the leftmost 160-bits of the
// SHA-256 hash of the value of the BIT STRING subjectPublicKey
// (excluding the tag, length, and number of unused bits).
func generateSKID(pk crypto.PublicKey) ([]byte, error) {
pkBytes, err := x509.MarshalPKIXPublicKey(pk)
if err != nil {
return nil, err
}

var pkixPublicKey struct {
Algo pkix.AlgorithmIdentifier
BitString asn1.BitString
}
if _, err := asn1.Unmarshal(pkBytes, &pkixPublicKey); err != nil {
return nil, err
}

skid := sha256.Sum256(pkixPublicKey.BitString.Bytes)
return skid[0:20:20], nil
}

// verifyTBSCertIsDeterministic verifies that x509.CreateCertificate signing
// operation is deterministic and produced identical DER bytes between the given
// lint certificate and leaf certificate. If the DER byte equality check fails
Expand Down
12 changes: 0 additions & 12 deletions ca/ca_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -941,18 +941,6 @@ func TestNoteSignError(t *testing.T) {
test.AssertMetricWithLabelsEquals(t, metrics.signErrorCount, prometheus.Labels{"type": "HSM"}, 1)
}

func TestGenerateSKID(t *testing.T) {
t.Parallel()
key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
test.AssertNotError(t, err, "Error generating key")

sha256skid, err := generateSKID(key.Public())
test.AssertNotError(t, err, "Error generating SKID")
test.AssertEquals(t, len(sha256skid), 20)
test.AssertEquals(t, cap(sha256skid), 20)
features.Reset()
}

func TestVerifyTBSCertIsDeterministic(t *testing.T) {
t.Parallel()

Expand Down
25 changes: 4 additions & 21 deletions cmd/ceremony/cert.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ package main

import (
"crypto"
"crypto/sha256"
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"errors"
"fmt"
"io"
"math/big"
"regexp"
"slices"
"time"

"github.com/letsencrypt/boulder/core"
)

type policyInfoConfig struct {
Expand Down Expand Up @@ -187,25 +187,8 @@ var stringToKeyUsage = map[string]x509.KeyUsage{
"Cert Sign": x509.KeyUsageCertSign,
}

func generateSKID(pk []byte) ([]byte, error) {
var pkixPublicKey struct {
Algo pkix.AlgorithmIdentifier
BitString asn1.BitString
}
if _, err := asn1.Unmarshal(pk, &pkixPublicKey); err != nil {
return nil, err
}

// RFC 7093 Section 2 Additional Methods for Generating Key Identifiers: The
// keyIdentifier [may be] composed of the leftmost 160-bits of the SHA-256
// hash of the value of the BIT STRING subjectPublicKey (excluding the tag,
// length, and number of unused bits).
skid := sha256.Sum256(pkixPublicKey.BitString.Bytes)
return skid[0:20:20], nil
}

// makeTemplate generates the certificate template for use in x509.CreateCertificate
func makeTemplate(randReader io.Reader, profile *certProfile, pubKey []byte, tbcs *x509.Certificate, ct certType) (*x509.Certificate, error) {
func makeTemplate(randReader io.Reader, profile *certProfile, pubKey crypto.PublicKey, tbcs *x509.Certificate, ct certType) (*x509.Certificate, error) {
// Handle "unrestricted" vs "restricted" subordinate CA profile specifics.
if ct == crossCert && tbcs == nil {
return nil, fmt.Errorf("toBeCrossSigned cert field was nil, but was required to gather EKUs for the lint cert")
Expand All @@ -220,7 +203,7 @@ func makeTemplate(randReader io.Reader, profile *certProfile, pubKey []byte, tbc
issuingCertificateURL = []string{profile.IssuerURL}
}

subjectKeyID, err := generateSKID(pubKey)
subjectKeyID, err := core.GenerateSKID(pubKey)
if err != nil {
return nil, err
}
Expand Down
Loading