github.com/hellobchain/third_party@v0.0.0-20230331131523-deb0478a2e52/hyperledger/fabric/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/elliptic" 11 "crypto/rand" 12 "encoding/asn1" 13 "encoding/pem" 14 "errors" 15 "fmt" 16 "github.com/hellobchain/newcryptosm/ecdsa" 17 "github.com/hellobchain/newcryptosm/sm2" 18 "github.com/hellobchain/newcryptosm/x509" 19 ) 20 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 oidNamedCurveSM2 = asn1.ObjectIdentifier{1, 2, 156, 10197, 1, 301} 40 ) 41 42 var oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1} 43 var oidPublicKeySM2 = asn1.ObjectIdentifier{1, 2, 156, 197, 1, 301} 44 45 func oidPublicKeyFromNamedCurve(curve elliptic.Curve) asn1.ObjectIdentifier { 46 switch curve { 47 case elliptic.P224(): 48 return oidPublicKeyECDSA 49 case elliptic.P384(): 50 return oidPublicKeyECDSA 51 case elliptic.P521(): 52 return oidPublicKeyECDSA 53 case elliptic.P256(): 54 return oidPublicKeyECDSA 55 case sm2.SM2(): 56 return oidPublicKeySM2 57 } 58 return nil 59 } 60 61 func oidFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, bool) { 62 switch curve { 63 case elliptic.P224(): 64 return oidNamedCurveP224, true 65 case elliptic.P256(): 66 return oidNamedCurveP256, true 67 case elliptic.P384(): 68 return oidNamedCurveP384, true 69 case elliptic.P521(): 70 return oidNamedCurveP521, true 71 case sm2.SM2(): 72 return oidNamedCurveSM2, true 73 } 74 return nil, false 75 } 76 77 func privateKeyToDER(privateKey *ecdsa.PrivateKey) ([]byte, error) { 78 if privateKey == nil { 79 return nil, errors.New("invalid ecdsa private key. It must be different from nil") 80 } 81 82 return x509.MarshalECPrivateKey(privateKey) 83 } 84 85 func privateKeyToPEM(privateKey interface{}, pwd []byte) ([]byte, error) { 86 // Validate inputs 87 if len(pwd) != 0 { 88 return privateKeyToEncryptedPEM(privateKey, pwd) 89 } 90 if privateKey == nil { 91 return nil, errors.New("invalid key. It must be different from nil") 92 } 93 94 switch k := privateKey.(type) { 95 case *ecdsa.PrivateKey: 96 if k == nil { 97 return nil, errors.New("invalid ecdsa private key. It must be different from nil") 98 } 99 100 // get the oid for the curve 101 oidNamedCurve, ok := oidFromNamedCurve(k.Curve) 102 if !ok { 103 return nil, errors.New("unknown elliptic curve") 104 } 105 106 // based on https://golang.org/src/crypto/x509/sec1.go 107 privateKeyBytes := k.D.Bytes() 108 paddedPrivateKey := make([]byte, (k.Curve.Params().N.BitLen()+7)/8) 109 copy(paddedPrivateKey[len(paddedPrivateKey)-len(privateKeyBytes):], privateKeyBytes) 110 // omit NamedCurveOID for compatibility as it's optional 111 asn1Bytes, err := asn1.Marshal(ecPrivateKey{ 112 Version: 1, 113 PrivateKey: paddedPrivateKey, 114 PublicKey: asn1.BitString{Bytes: elliptic.Marshal(k.Curve, k.X, k.Y)}, 115 }) 116 if err != nil { 117 return nil, fmt.Errorf("error marshaling EC key to asn1: [%s]", err) 118 } 119 120 var pkcs8Key pkcs8Info 121 pkcs8Key.Version = 0 122 pkcs8Key.PrivateKeyAlgorithm = make([]asn1.ObjectIdentifier, 2) 123 pkcs8Key.PrivateKeyAlgorithm[0] = oidPublicKeyFromNamedCurve(k.Curve) 124 pkcs8Key.PrivateKeyAlgorithm[1] = oidNamedCurve 125 pkcs8Key.PrivateKey = asn1Bytes 126 127 pkcs8Bytes, err := asn1.Marshal(pkcs8Key) 128 if err != nil { 129 return nil, fmt.Errorf("error marshaling EC key to asn1: [%s]", err) 130 } 131 return pem.EncodeToMemory( 132 &pem.Block{ 133 Type: "PRIVATE KEY", 134 Bytes: pkcs8Bytes, 135 }, 136 ), nil 137 138 default: 139 return nil, errors.New("invalid key type. It must be *ecdsa.PrivateKey") 140 } 141 } 142 143 func privateKeyToEncryptedPEM(privateKey interface{}, pwd []byte) ([]byte, error) { 144 if privateKey == nil { 145 return nil, errors.New("invalid private key. It must be different from nil") 146 } 147 148 switch k := privateKey.(type) { 149 case *ecdsa.PrivateKey: 150 if k == nil { 151 return nil, errors.New("invalid ecdsa private key. It must be different from nil") 152 } 153 raw, err := x509.MarshalECPrivateKey(k) 154 if err != nil { 155 return nil, err 156 } 157 158 block, err := x509.EncryptPEMBlock( 159 rand.Reader, 160 "PRIVATE KEY", 161 raw, 162 pwd, 163 x509.PEMCipherAES256) 164 if err != nil { 165 return nil, err 166 } 167 168 return pem.EncodeToMemory(block), nil 169 170 default: 171 return nil, errors.New("invalid key type. It must be *ecdsa.PrivateKey") 172 } 173 } 174 175 func derToPrivateKey(der []byte) (key interface{}, err error) { 176 if key, err = x509.ParsePKCS1PrivateKey(der); err == nil { 177 return key, nil 178 } 179 180 if key, err = x509.ParsePKCS8PrivateKey(der); err == nil { 181 switch key.(type) { 182 case *ecdsa.PrivateKey: 183 return 184 default: 185 return nil, errors.New("found unknown private key type in PKCS#8 wrapping") 186 } 187 } 188 189 if key, err = x509.ParseECPrivateKey(der); err == nil { 190 return 191 } 192 193 return nil, errors.New("invalid key type. The DER must contain an ecdsa.PrivateKey") 194 } 195 196 func pemToPrivateKey(raw []byte, pwd []byte) (interface{}, error) { 197 block, _ := pem.Decode(raw) 198 if block == nil { 199 return nil, fmt.Errorf("failed decoding PEM. Block must be different from nil [% x]", raw) 200 } 201 202 // TODO: derive from header the type of the key 203 204 if x509.IsEncryptedPEMBlock(block) { 205 if len(pwd) == 0 { 206 return nil, errors.New("encrypted Key. Need a password") 207 } 208 209 decrypted, err := x509.DecryptPEMBlock(block, pwd) 210 if err != nil { 211 return nil, fmt.Errorf("failed PEM decryption: [%s]", err) 212 } 213 214 key, err := derToPrivateKey(decrypted) 215 if err != nil { 216 return nil, err 217 } 218 return key, err 219 } 220 221 cert, err := derToPrivateKey(block.Bytes) 222 if err != nil { 223 return nil, err 224 } 225 return cert, err 226 } 227 228 func pemToAES(raw []byte, pwd []byte) ([]byte, error) { 229 if len(raw) == 0 { 230 return nil, errors.New("invalid PEM. It must be different from nil") 231 } 232 block, _ := pem.Decode(raw) 233 if block == nil { 234 return nil, fmt.Errorf("failed decoding PEM. Block must be different from nil [% x]", raw) 235 } 236 237 if x509.IsEncryptedPEMBlock(block) { 238 if len(pwd) == 0 { 239 return nil, errors.New("encrypted Key. Password must be different fom nil") 240 } 241 242 decrypted, err := x509.DecryptPEMBlock(block, pwd) 243 if err != nil { 244 return nil, fmt.Errorf("failed PEM decryption: [%s]", err) 245 } 246 return decrypted, nil 247 } 248 249 return block.Bytes, nil 250 } 251 252 func aesToPEM(raw []byte) []byte { 253 return pem.EncodeToMemory(&pem.Block{Type: "AES PRIVATE KEY", Bytes: raw}) 254 } 255 256 func aesToEncryptedPEM(raw []byte, pwd []byte) ([]byte, error) { 257 if len(raw) == 0 { 258 return nil, errors.New("invalid aes key. It must be different from nil") 259 } 260 if len(pwd) == 0 { 261 return aesToPEM(raw), nil 262 } 263 264 block, err := x509.EncryptPEMBlock( 265 rand.Reader, 266 "AES PRIVATE KEY", 267 raw, 268 pwd, 269 x509.PEMCipherAES256) 270 if err != nil { 271 return nil, err 272 } 273 274 return pem.EncodeToMemory(block), nil 275 } 276 277 func pemToSM4(raw []byte, pwd []byte) ([]byte, error) { 278 if len(raw) == 0 { 279 return nil, errors.New("invalid PEM. It must be different from nil") 280 } 281 block, _ := pem.Decode(raw) 282 if block == nil { 283 return nil, fmt.Errorf("failed decoding PEM. Block must be different from nil [% x]", raw) 284 } 285 286 if x509.IsEncryptedPEMBlock(block) { 287 if len(pwd) == 0 { 288 return nil, errors.New("encrypted Key. Password must be different fom nil") 289 } 290 291 decrypted, err := x509.DecryptPEMBlock(block, pwd) 292 if err != nil { 293 return nil, fmt.Errorf("failed PEM decryption: [%s]", err) 294 } 295 return decrypted, nil 296 } 297 298 return block.Bytes, nil 299 } 300 301 // sm4toPEM encapsulates an SM4 key in the PEM format 302 func sm4toPEM(raw []byte) []byte { 303 return pem.EncodeToMemory(&pem.Block{Type: "SM4 PRIVATE KEY", Bytes: raw}) 304 } 305 306 // sm4toEncryptedPEM encapsulates an SM4 key in the encrypted PEM format 307 func sm4toEncryptedPEM(raw []byte, pwd []byte) ([]byte, error) { 308 if len(raw) == 0 { 309 return nil, errors.New("Invalid sm4 key. It must be different from nil") 310 } 311 if len(pwd) == 0 { 312 return sm4toPEM(raw), nil 313 } 314 315 block, err := x509.EncryptPEMBlock( 316 rand.Reader, 317 "SM4 PRIVATE KEY", 318 raw, 319 pwd, 320 x509.PEMCipherSM4) 321 322 if err != nil { 323 return nil, err 324 } 325 326 return pem.EncodeToMemory(block), nil 327 } 328 329 func publicKeyToPEM(publicKey interface{}, pwd []byte) ([]byte, error) { 330 if len(pwd) != 0 { 331 return publicKeyToEncryptedPEM(publicKey, pwd) 332 } 333 334 if publicKey == nil { 335 return nil, errors.New("invalid public key. 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 PubASN1, err := x509.MarshalPKIXPublicKey(k) 344 if err != nil { 345 return nil, err 346 } 347 348 return pem.EncodeToMemory( 349 &pem.Block{ 350 Type: "PUBLIC KEY", 351 Bytes: PubASN1, 352 }, 353 ), nil 354 355 default: 356 return nil, errors.New("invalid key type. It must be *ecdsa.PublicKey") 357 } 358 } 359 360 func publicKeyToEncryptedPEM(publicKey interface{}, pwd []byte) ([]byte, error) { 361 switch k := publicKey.(type) { 362 case *ecdsa.PublicKey: 363 if k == nil { 364 return nil, errors.New("invalid ecdsa public key. It must be different from nil") 365 } 366 raw, err := x509.MarshalPKIXPublicKey(k) 367 if err != nil { 368 return nil, err 369 } 370 371 block, err := x509.EncryptPEMBlock( 372 rand.Reader, 373 "PUBLIC KEY", 374 raw, 375 pwd, 376 x509.PEMCipherAES256) 377 if err != nil { 378 return nil, err 379 } 380 381 return pem.EncodeToMemory(block), nil 382 default: 383 return nil, errors.New("invalid key type. It must be *ecdsa.PublicKey") 384 } 385 } 386 387 func pemToPublicKey(raw []byte, pwd []byte) (interface{}, error) { 388 if len(raw) == 0 { 389 return nil, errors.New("invalid PEM. It must be different from nil") 390 } 391 block, _ := pem.Decode(raw) 392 if block == nil { 393 return nil, fmt.Errorf("failed decoding. Block must be different from nil [% x]", raw) 394 } 395 396 // TODO: derive from header the type of the key 397 if x509.IsEncryptedPEMBlock(block) { 398 if len(pwd) == 0 { 399 return nil, errors.New("encrypted Key. Password must be different from nil") 400 } 401 402 decrypted, err := x509.DecryptPEMBlock(block, pwd) 403 if err != nil { 404 return nil, fmt.Errorf("failed PEM decryption: [%s]", err) 405 } 406 407 key, err := derToPublicKey(decrypted) 408 if err != nil { 409 return nil, err 410 } 411 return key, err 412 } 413 414 cert, err := derToPublicKey(block.Bytes) 415 if err != nil { 416 return nil, err 417 } 418 return cert, err 419 } 420 421 func derToPublicKey(raw []byte) (pub interface{}, err error) { 422 if len(raw) == 0 { 423 return nil, errors.New("invalid DER. It must be different from nil") 424 } 425 426 key, err := x509.ParsePKIXPublicKey(raw) 427 428 return key, err 429 }