Skip to content

Commit 086d2f5

Browse files
committed
Allow generating ML-DSA roots and intermediates
1 parent d5f9c75 commit 086d2f5

100 files changed

Lines changed: 16414 additions & 19 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

ca/ca.go

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"crypto/elliptic"
88
"crypto/rand"
99
"crypto/rsa"
10-
"crypto/sha1"
10+
"crypto/sha256"
1111
"crypto/x509"
1212
"crypto/x509/pkix"
1313
"encoding/asn1"
@@ -21,6 +21,8 @@ import (
2121
"strings"
2222
"time"
2323

24+
"github.com/cloudflare/circl/sign/mldsa/mldsa65"
25+
2426
"github.com/letsencrypt/pebble/v2/acme"
2527
"github.com/letsencrypt/pebble/v2/core"
2628
"github.com/letsencrypt/pebble/v2/db"
@@ -78,25 +80,37 @@ func makeSerial() *big.Int {
7880

7981
// Taken from https://github.com/cloudflare/cfssl/blob/b94e044bb51ec8f5a7232c71b1ed05dbe4da96ce/signer/signer.go#L221-L244
8082
func makeSubjectKeyID(key crypto.PublicKey) ([]byte, error) {
81-
// Marshal the public key as ASN.1
82-
pubAsDER, err := x509.MarshalPKIXPublicKey(key)
83-
if err != nil {
84-
return nil, err
85-
}
83+
var pubkeyBytes []byte
84+
var err error
85+
switch key := key.(type) {
86+
case *rsa.PublicKey, *ecdsa.PublicKey:
87+
// Marshal the public key as ASN.1
88+
pubAsDER, err := x509.MarshalPKIXPublicKey(key)
89+
if err != nil {
90+
return nil, err
91+
}
8692

87-
// Unmarshal it again so we can extract the key bitstring bytes
88-
var pubInfo struct {
89-
Algorithm pkix.AlgorithmIdentifier
90-
SubjectPublicKey asn1.BitString
91-
}
92-
_, err = asn1.Unmarshal(pubAsDER, &pubInfo)
93-
if err != nil {
94-
return nil, err
93+
// Unmarshal it again so we can extract the key bitstring bytes
94+
var pubInfo struct {
95+
Algorithm pkix.AlgorithmIdentifier
96+
SubjectPublicKey asn1.BitString
97+
}
98+
_, err = asn1.Unmarshal(pubAsDER, &pubInfo)
99+
if err != nil {
100+
return nil, err
101+
}
102+
103+
pubkeyBytes = pubInfo.SubjectPublicKey.Bytes
104+
case *mldsa65.PublicKey:
105+
pubkeyBytes, err = key.MarshalBinary()
106+
if err != nil {
107+
return nil, err
108+
}
95109
}
96110

97-
// Hash it according to https://tools.ietf.org/html/rfc5280#section-4.2.1.2 Method #1:
98-
ski := sha1.Sum(pubInfo.SubjectPublicKey.Bytes)
99-
return ski[:], nil
111+
// Hash it according to https://datatracker.ietf.org/doc/html/rfc7093#section-2 Method #1:
112+
skid := sha256.Sum256(pubkeyBytes)
113+
return skid[0:20:20], nil
100114
}
101115

102116
// makeKey and makeRootCert are adapted from MiniCA:
@@ -112,6 +126,8 @@ func makeKey(keyAlg string) (crypto.Signer, []byte, error) {
112126
key, err = rsa.GenerateKey(rand.Reader, 2048)
113127
case "ecdsa":
114128
key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
129+
case "mldsa":
130+
_, key, err = mldsa65.GenerateKey(rand.Reader)
115131
}
116132
if err != nil {
117133
return nil, nil, err

ca/ca_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ var (
2727
func makeCa() *CAImpl {
2828
logger := log.New(os.Stdout, "Pebble ", log.LstdFlags)
2929
db := db.NewMemoryStore()
30-
return New(logger, db, "", "ecdsa", 0, 1, map[string]Profile{"default": {}})
30+
return New(logger, db, "", "mldsa", 0, 1, map[string]Profile{"default": {}})
3131
}
3232

3333
func makeCertOrderWithExtensions(extensions []pkix.Extension) core.Order {

cmd/pebble/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ func main() {
109109
if keyAlg == "" {
110110
keyAlg = "rsa"
111111
}
112-
acceptableKeyAlgs := []string{"rsa", "ecdsa"}
112+
acceptableKeyAlgs := []string{"rsa", "ecdsa", "mldsa"}
113113
if !slices.Contains(acceptableKeyAlgs, keyAlg) {
114114
cmd.FailOnError(fmt.Errorf("%q is not one of %#v", keyAlg, acceptableKeyAlgs), "invalid key algorithm")
115115
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.24
55
toolchain go1.24.2
66

77
require (
8+
github.com/cloudflare/circl v1.6.1
89
github.com/go-jose/go-jose/v4 v4.1.2
910
github.com/letsencrypt/challtestsrv v1.3.2
1011
github.com/miekg/dns v1.1.62

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
2+
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
13
github.com/go-jose/go-jose/v4 v4.1.2 h1:TK/7NqRQZfgAh+Td8AlsrvtPoUyiHh0LqVvokh+1vHI=
24
github.com/go-jose/go-jose/v4 v4.1.2/go.mod h1:22cg9HWM1pOlnRiY+9cQYJ9XHmya1bYW8OeDM6Ku6Oo=
35
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=

vendor/github.com/cloudflare/circl/LICENSE

Lines changed: 57 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/cloudflare/circl/internal/sha3/doc.go

Lines changed: 62 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/cloudflare/circl/internal/sha3/hashes.go

Lines changed: 69 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)