func parseEncryptedPrivateKey()

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)
}