in pkcs8.go [136:185]
func ParsePrivateKey(der []byte, password []byte) (interface{}, KDFParameters, error) {
// No password provided, assume the private key is unencrypted
if len(password) == 0 {
privateKey, err := x509.ParsePKCS8PrivateKey(der)
return privateKey, nil, err
}
// Use the password provided to decrypt the private key
var privKey encryptedPrivateKeyInfo
if _, err := asn1.Unmarshal(der, &privKey); err != nil {
return nil, nil, errors.New("pkcs8: only PKCS #5 v2.0 supported")
}
if !privKey.EncryptionAlgorithm.Algorithm.Equal(oidPBES2) {
return nil, nil, errors.New("pkcs8: only PBES2 supported")
}
var params pbes2Params
if _, err := asn1.Unmarshal(privKey.EncryptionAlgorithm.Parameters.FullBytes, ¶ms); err != nil {
return nil, nil, errors.New("pkcs8: invalid PBES2 parameters")
}
cipher, iv, err := parseEncryptionScheme(params.EncryptionScheme)
if err != nil {
return nil, nil, err
}
kdfParams, err := parseKeyDerivationFunc(params.KeyDerivationFunc)
if err != nil {
return nil, nil, err
}
keySize := cipher.KeySize()
symkey, err := kdfParams.DeriveKey(password, keySize)
if err != nil {
return nil, nil, err
}
encryptedKey := privKey.EncryptedData
decryptedKey, err := cipher.Decrypt(symkey, iv, encryptedKey)
if err != nil {
return nil, nil, err
}
key, err := x509.ParsePKCS8PrivateKey(decryptedKey)
if err != nil {
return nil, nil, errors.New("pkcs8: incorrect password")
}
return key, kdfParams, nil
}