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