@@ -18,6 +18,7 @@ package cosign
1818import (
1919 "crypto"
2020 "crypto/ecdsa"
21+ "crypto/ed25519"
2122 "crypto/elliptic"
2223 "crypto/rand"
2324 "crypto/rsa"
@@ -37,10 +38,14 @@ import (
3738)
3839
3940const (
40- PrivateKeyPemType = "ENCRYPTED COSIGN PRIVATE KEY"
41+ CosignPrivateKeyPemType = "ENCRYPTED COSIGN PRIVATE KEY"
42+ // PEM-encoded PKCS #1 RSA private key
4143 RSAPrivateKeyPemType = "RSA PRIVATE KEY"
42- ECPrivateKeyPemType = "EC PRIVATE KEY"
43- BundleKey = static .BundleAnnotationKey
44+ // PEM-encoded ECDSA private key
45+ ECPrivateKeyPemType = "EC PRIVATE KEY"
46+ // PEM-encoded PKCS #8 RSA, ECDSA or ED25519 private key
47+ PrivateKeyPemType = "PRIVATE KEY"
48+ BundleKey = static .BundleAnnotationKey
4449)
4550
4651type PassFunc func (bool ) ([]byte , error )
@@ -56,6 +61,35 @@ type KeysBytes struct {
5661 password []byte
5762}
5863
64+ // Enforce a minimum and maximum RSA key size.
65+ func validateRsaKey (pk * rsa.PrivateKey ) error {
66+ // Key size is the bit length of modulus
67+ keySize := pk .N .BitLen ()
68+ if keySize < 2048 {
69+ return fmt .Errorf ("rsa key size too small, expected >= 2048" )
70+ }
71+ if keySize > 4096 {
72+ return fmt .Errorf ("rsa key size too large, expected <= 4096" )
73+ }
74+ return nil
75+ }
76+
77+ // Enforce that the ECDSA key curve is one of:
78+ // * NIST P-256 (secp256r1, prime256v1)
79+ // * NIST P-384
80+ // * NIST P-521.
81+ // Other EC curves, like secp256k1, are not supported by Go.
82+ func validateEcdsaKey (pk * ecdsa.PrivateKey ) error {
83+ switch pk .Curve {
84+ case elliptic .P224 ():
85+ return fmt .Errorf ("unsupported ec curve, expected NIST P-256, P-384, or P-521" )
86+ case elliptic .P256 (), elliptic .P384 (), elliptic .P521 ():
87+ return nil
88+ default :
89+ return fmt .Errorf ("unexpected ec curve" )
90+ }
91+ }
92+
5993func GeneratePrivateKey () (* ecdsa.PrivateKey , error ) {
6094 return ecdsa .GenerateKey (elliptic .P256 (), rand .Reader )
6195}
@@ -75,15 +109,47 @@ func ImportKeyPair(keyPath string, pf PassFunc) (*KeysBytes, error) {
75109
76110 switch p .Type {
77111 case RSAPrivateKeyPemType :
78- pk , err = x509 .ParsePKCS1PrivateKey (p .Bytes )
112+ rsaPk , err : = x509 .ParsePKCS1PrivateKey (p .Bytes )
79113 if err != nil {
80- return nil , fmt .Errorf ("parsing error " )
114+ return nil , fmt .Errorf ("error parsing rsa private key " )
81115 }
82- default :
83- pk , err = x509 .ParseECPrivateKey (p .Bytes )
116+ if err = validateRsaKey (rsaPk ); err != nil {
117+ return nil , errors .Wrap (err , "error validating rsa key" )
118+ }
119+ pk = rsaPk
120+ case ECPrivateKeyPemType :
121+ ecdsaPk , err := x509 .ParseECPrivateKey (p .Bytes )
84122 if err != nil {
85- return nil , fmt .Errorf ("parsing error " )
123+ return nil , fmt .Errorf ("error parsing ecdsa private key " )
86124 }
125+ if err = validateEcdsaKey (ecdsaPk ); err != nil {
126+ return nil , errors .Wrap (err , "error validating ecdsa key" )
127+ }
128+ pk = ecdsaPk
129+ case PrivateKeyPemType :
130+ pkcs8Pk , err := x509 .ParsePKCS8PrivateKey (p .Bytes )
131+ if err != nil {
132+ return nil , fmt .Errorf ("error parsing pkcs #8 private key" )
133+ }
134+ switch k := pkcs8Pk .(type ) {
135+ case * rsa.PrivateKey :
136+ if err = validateRsaKey (k ); err != nil {
137+ return nil , errors .Wrap (err , "error validating rsa key" )
138+ }
139+ pk = k
140+ case * ecdsa.PrivateKey :
141+ if err = validateEcdsaKey (k ); err != nil {
142+ return nil , errors .Wrap (err , "error validating ecdsa key" )
143+ }
144+ pk = k
145+ case ed25519.PrivateKey :
146+ // Nothing to validate, since ED25519 supports only one key size.
147+ pk = k
148+ default :
149+ return nil , fmt .Errorf ("unexpected private key" )
150+ }
151+ default :
152+ return nil , fmt .Errorf ("unsupported private key" )
87153 }
88154 return marshalKeyPair (Keys {pk , pk .Public ()}, pf )
89155}
@@ -107,7 +173,7 @@ func marshalKeyPair(keypair Keys, pf PassFunc) (*KeysBytes, error) {
107173 // store in PEM format
108174 privBytes := pem .EncodeToMemory (& pem.Block {
109175 Bytes : encBytes ,
110- Type : PrivateKeyPemType ,
176+ Type : CosignPrivateKeyPemType ,
111177 })
112178
113179 // Now do the public key
@@ -154,7 +220,7 @@ func LoadPrivateKey(key []byte, pass []byte) (signature.SignerVerifier, error) {
154220 if p == nil {
155221 return nil , errors .New ("invalid pem block" )
156222 }
157- if p .Type != PrivateKeyPemType {
223+ if p .Type != CosignPrivateKeyPemType {
158224 return nil , fmt .Errorf ("unsupported pem type: %s" , p .Type )
159225 }
160226
0 commit comments