in sec/pkcs.go [79:132]
func parseEncryptedPrivateKey(der []byte) (key interface{}, err error) {
var wrapper pkcs5
if _, err = asn1.Unmarshal(der, &wrapper); err != nil {
return nil, err
}
if !wrapper.Algo.Algorithm.Equal(oidPbes2) {
return nil, fmt.Errorf("pkcs5: Unknown PKCS#5 wrapper algorithm: %v", wrapper.Algo.Algorithm)
}
var pbparm pbes2
if _, err = asn1.Unmarshal(wrapper.Algo.Parameters.FullBytes, &pbparm); err != nil {
return nil, err
}
if !pbparm.KeyDerivationFunc.Algorithm.Equal(oidPbkdf2) {
return nil, fmt.Errorf("pkcs5: Unknown KDF: %v", pbparm.KeyDerivationFunc.Algorithm)
}
var kdfParam pbkdf2Param
if _, err = asn1.Unmarshal(pbparm.KeyDerivationFunc.Parameters.FullBytes, &kdfParam); err != nil {
return nil, err
}
var hashNew hashFunc
switch {
case kdfParam.HashFunc.Algorithm.Equal(oidHmacWithSha1):
hashNew = sha1.New
case kdfParam.HashFunc.Algorithm.Equal(oidHmacWithSha224):
hashNew = sha256.New224
case kdfParam.HashFunc.Algorithm.Equal(oidHmacWithSha256):
hashNew = sha256.New
default:
return nil, fmt.Errorf("pkcs5: Unsupported hash: %v", pbparm.EncryptionScheme.Algorithm)
}
// Get the encryption used.
size := 0
var iv []byte
switch {
case pbparm.EncryptionScheme.Algorithm.Equal(oidAes256CBC):
size = 32
if _, err = asn1.Unmarshal(pbparm.EncryptionScheme.Parameters.FullBytes, &iv); err != nil {
return nil, err
}
case pbparm.EncryptionScheme.Algorithm.Equal(oidAes128CBC):
size = 16
if _, err = asn1.Unmarshal(pbparm.EncryptionScheme.Parameters.FullBytes, &iv); err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("pkcs5: Unsupported cipher: %v", pbparm.EncryptionScheme.Algorithm)
}
return unwrapPbes2Pbkdf2(&kdfParam, size, iv, hashNew, wrapper.Encrypted)
}