github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/bccsp/sw/keys.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package sw 8 9 import ( 10 "crypto/ecdsa" 11 "crypto/elliptic" 12 "crypto/rand" 13 "crypto/x509" 14 "encoding/asn1" 15 "encoding/pem" 16 "errors" 17 "fmt" 18 ) 19 20 type pkcs8Info struct { 21 Version int 22 PrivateKeyAlgorithm []asn1.ObjectIdentifier 23 PrivateKey []byte 24 } 25 26 type ecPrivateKey struct { 27 Version int 28 PrivateKey []byte 29 NamedCurveOID asn1.ObjectIdentifier `asn1:"optional,explicit,tag:0"` 30 PublicKey asn1.BitString `asn1:"optional,explicit,tag:1"` 31 } 32 33 var ( 34 oidNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33} 35 oidNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7} 36 oidNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34} 37 oidNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35} 38 ) 39 40 var oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1} 41 42 func oidFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, bool) { 43 switch curve { 44 case elliptic.P224(): 45 return oidNamedCurveP224, true 46 case elliptic.P256(): 47 return oidNamedCurveP256, true 48 case elliptic.P384(): 49 return oidNamedCurveP384, true 50 case elliptic.P521(): 51 return oidNamedCurveP521, true 52 } 53 return nil, false 54 } 55 56 func privateKeyToDER(privateKey *ecdsa.PrivateKey) ([]byte, error) { 57 if privateKey == nil { 58 return nil, errors.New("invalid ecdsa private key. It must be different from nil") 59 } 60 61 return x509.MarshalECPrivateKey(privateKey) 62 } 63 64 func privateKeyToPEM(privateKey interface{}, pwd []byte) ([]byte, error) { 65 // Validate inputs 66 if len(pwd) != 0 { 67 return privateKeyToEncryptedPEM(privateKey, pwd) 68 } 69 if privateKey == nil { 70 return nil, errors.New("invalid key. It must be different from nil") 71 } 72 73 switch k := privateKey.(type) { 74 case *ecdsa.PrivateKey: 75 if k == nil { 76 return nil, errors.New("invalid ecdsa private key. It must be different from nil") 77 } 78 79 // get the oid for the curve 80 oidNamedCurve, ok := oidFromNamedCurve(k.Curve) 81 if !ok { 82 return nil, errors.New("unknown elliptic curve") 83 } 84 85 // based on https://golang.org/src/crypto/x509/sec1.go 86 privateKeyBytes := k.D.Bytes() 87 paddedPrivateKey := make([]byte, (k.Curve.Params().N.BitLen()+7)/8) 88 copy(paddedPrivateKey[len(paddedPrivateKey)-len(privateKeyBytes):], privateKeyBytes) 89 // omit NamedCurveOID for compatibility as it's optional 90 asn1Bytes, err := asn1.Marshal(ecPrivateKey{ 91 Version: 1, 92 PrivateKey: paddedPrivateKey, 93 PublicKey: asn1.BitString{Bytes: elliptic.Marshal(k.Curve, k.X, k.Y)}, 94 }) 95 96 if err != nil { 97 return nil, fmt.Errorf("error marshaling EC key to asn1: [%s]", err) 98 } 99 100 var pkcs8Key pkcs8Info 101 pkcs8Key.Version = 0 102 pkcs8Key.PrivateKeyAlgorithm = make([]asn1.ObjectIdentifier, 2) 103 pkcs8Key.PrivateKeyAlgorithm[0] = oidPublicKeyECDSA 104 pkcs8Key.PrivateKeyAlgorithm[1] = oidNamedCurve 105 pkcs8Key.PrivateKey = asn1Bytes 106 107 pkcs8Bytes, err := asn1.Marshal(pkcs8Key) 108 if err != nil { 109 return nil, fmt.Errorf("error marshaling EC key to asn1: [%s]", err) 110 } 111 return pem.EncodeToMemory( 112 &pem.Block{ 113 Type: "PRIVATE KEY", 114 Bytes: pkcs8Bytes, 115 }, 116 ), nil 117 118 default: 119 return nil, errors.New("invalid key type. It must be *ecdsa.PrivateKey") 120 } 121 } 122 123 func privateKeyToEncryptedPEM(privateKey interface{}, pwd []byte) ([]byte, error) { 124 if privateKey == nil { 125 return nil, errors.New("invalid private key. It must be different from nil") 126 } 127 128 switch k := privateKey.(type) { 129 case *ecdsa.PrivateKey: 130 if k == nil { 131 return nil, errors.New("invalid ecdsa private key. It must be different from nil") 132 } 133 raw, err := x509.MarshalECPrivateKey(k) 134 135 if err != nil { 136 return nil, err 137 } 138 139 block, err := x509.EncryptPEMBlock( 140 rand.Reader, 141 "PRIVATE KEY", 142 raw, 143 pwd, 144 x509.PEMCipherAES256) 145 146 if err != nil { 147 return nil, err 148 } 149 150 return pem.EncodeToMemory(block), nil 151 152 default: 153 return nil, errors.New("invalid key type. It must be *ecdsa.PrivateKey") 154 } 155 } 156 157 func derToPrivateKey(der []byte) (key interface{}, err error) { 158 159 if key, err = x509.ParsePKCS1PrivateKey(der); err == nil { 160 return key, nil 161 } 162 163 if key, err = x509.ParsePKCS8PrivateKey(der); err == nil { 164 switch key.(type) { 165 case *ecdsa.PrivateKey: 166 return 167 default: 168 return nil, errors.New("found unknown private key type in PKCS#8 wrapping") 169 } 170 } 171 172 if key, err = x509.ParseECPrivateKey(der); err == nil { 173 return 174 } 175 176 return nil, errors.New("invalid key type. The DER must contain an ecdsa.PrivateKey") 177 } 178 179 func pemToPrivateKey(raw []byte, pwd []byte) (interface{}, error) { 180 block, _ := pem.Decode(raw) 181 if block == nil { 182 return nil, fmt.Errorf("failed decoding PEM. Block must be different from nil [% x]", raw) 183 } 184 185 // TODO: derive from header the type of the key 186 187 if x509.IsEncryptedPEMBlock(block) { 188 if len(pwd) == 0 { 189 return nil, errors.New("encrypted Key. Need a password") 190 } 191 192 decrypted, err := x509.DecryptPEMBlock(block, pwd) 193 if err != nil { 194 return nil, fmt.Errorf("failed PEM decryption: [%s]", err) 195 } 196 197 key, err := derToPrivateKey(decrypted) 198 if err != nil { 199 return nil, err 200 } 201 return key, err 202 } 203 204 cert, err := derToPrivateKey(block.Bytes) 205 if err != nil { 206 return nil, err 207 } 208 return cert, err 209 } 210 211 func pemToAES(raw []byte, pwd []byte) ([]byte, error) { 212 if len(raw) == 0 { 213 return nil, errors.New("invalid PEM. It must be different from nil") 214 } 215 block, _ := pem.Decode(raw) 216 if block == nil { 217 return nil, fmt.Errorf("failed decoding PEM. Block must be different from nil [% x]", raw) 218 } 219 220 if x509.IsEncryptedPEMBlock(block) { 221 if len(pwd) == 0 { 222 return nil, errors.New("encrypted Key. Password must be different fom nil") 223 } 224 225 decrypted, err := x509.DecryptPEMBlock(block, pwd) 226 if err != nil { 227 return nil, fmt.Errorf("failed PEM decryption: [%s]", err) 228 } 229 return decrypted, nil 230 } 231 232 return block.Bytes, nil 233 } 234 235 func aesToPEM(raw []byte) []byte { 236 return pem.EncodeToMemory(&pem.Block{Type: "AES PRIVATE KEY", Bytes: raw}) 237 } 238 239 func aesToEncryptedPEM(raw []byte, pwd []byte) ([]byte, error) { 240 if len(raw) == 0 { 241 return nil, errors.New("invalid aes key. It must be different from nil") 242 } 243 if len(pwd) == 0 { 244 return aesToPEM(raw), nil 245 } 246 247 block, err := x509.EncryptPEMBlock( 248 rand.Reader, 249 "AES PRIVATE KEY", 250 raw, 251 pwd, 252 x509.PEMCipherAES256) 253 254 if err != nil { 255 return nil, err 256 } 257 258 return pem.EncodeToMemory(block), nil 259 } 260 261 func publicKeyToPEM(publicKey interface{}, pwd []byte) ([]byte, error) { 262 if len(pwd) != 0 { 263 return publicKeyToEncryptedPEM(publicKey, pwd) 264 } 265 266 if publicKey == nil { 267 return nil, errors.New("invalid public key. It must be different from nil") 268 } 269 270 switch k := publicKey.(type) { 271 case *ecdsa.PublicKey: 272 if k == nil { 273 return nil, errors.New("invalid ecdsa public key. It must be different from nil") 274 } 275 PubASN1, err := x509.MarshalPKIXPublicKey(k) 276 if err != nil { 277 return nil, err 278 } 279 280 return pem.EncodeToMemory( 281 &pem.Block{ 282 Type: "PUBLIC KEY", 283 Bytes: PubASN1, 284 }, 285 ), nil 286 287 default: 288 return nil, errors.New("invalid key type. It must be *ecdsa.PublicKey") 289 } 290 } 291 292 func publicKeyToEncryptedPEM(publicKey interface{}, pwd []byte) ([]byte, error) { 293 switch k := publicKey.(type) { 294 case *ecdsa.PublicKey: 295 if k == nil { 296 return nil, errors.New("invalid ecdsa public key. It must be different from nil") 297 } 298 raw, err := x509.MarshalPKIXPublicKey(k) 299 if err != nil { 300 return nil, err 301 } 302 303 block, err := x509.EncryptPEMBlock( 304 rand.Reader, 305 "PUBLIC KEY", 306 raw, 307 pwd, 308 x509.PEMCipherAES256) 309 310 if err != nil { 311 return nil, err 312 } 313 314 return pem.EncodeToMemory(block), nil 315 default: 316 return nil, errors.New("invalid key type. It must be *ecdsa.PublicKey") 317 } 318 } 319 320 func pemToPublicKey(raw []byte, pwd []byte) (interface{}, error) { 321 if len(raw) == 0 { 322 return nil, errors.New("invalid PEM. It must be different from nil") 323 } 324 block, _ := pem.Decode(raw) 325 if block == nil { 326 return nil, fmt.Errorf("failed decoding. Block must be different from nil [% x]", raw) 327 } 328 329 // TODO: derive from header the type of the key 330 if x509.IsEncryptedPEMBlock(block) { 331 if len(pwd) == 0 { 332 return nil, errors.New("encrypted Key. Password must be different from nil") 333 } 334 335 decrypted, err := x509.DecryptPEMBlock(block, pwd) 336 if err != nil { 337 return nil, fmt.Errorf("failed PEM decryption: [%s]", err) 338 } 339 340 key, err := derToPublicKey(decrypted) 341 if err != nil { 342 return nil, err 343 } 344 return key, err 345 } 346 347 cert, err := derToPublicKey(block.Bytes) 348 if err != nil { 349 return nil, err 350 } 351 return cert, err 352 } 353 354 func derToPublicKey(raw []byte) (pub interface{}, err error) { 355 if len(raw) == 0 { 356 return nil, errors.New("invalid DER. It must be different from nil") 357 } 358 359 key, err := x509.ParsePKIXPublicKey(raw) 360 361 return key, err 362 }