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