| // Copyright 2015 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package pkcs12 |
| |
| import ( |
| "crypto/x509" |
| "encoding/asn1" |
| "errors" |
| ) |
| |
| var ( |
| // see https://tools.ietf.org/html/rfc7292#appendix-D |
| oidCertTypeX509Certificate = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 9, 22, 1}) |
| oidPKCS8ShroundedKeyBag = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 10, 1, 2}) |
| oidCertBag = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 10, 1, 3}) |
| ) |
| |
| type certBag struct { |
| Id asn1.ObjectIdentifier |
| Data []byte `asn1:"tag:0,explicit"` |
| } |
| |
| func decodePkcs8ShroudedKeyBag(asn1Data, password []byte) (privateKey interface{}, err error) { |
| pkinfo := new(encryptedPrivateKeyInfo) |
| if err = unmarshal(asn1Data, pkinfo); err != nil { |
| return nil, errors.New("pkcs12: error decoding PKCS#8 shrouded key bag: " + err.Error()) |
| } |
| |
| pkData, err := pbDecrypt(pkinfo, password) |
| if err != nil { |
| return nil, errors.New("pkcs12: error decrypting PKCS#8 shrouded key bag: " + err.Error()) |
| } |
| |
| ret := new(asn1.RawValue) |
| if err = unmarshal(pkData, ret); err != nil { |
| return nil, errors.New("pkcs12: error unmarshaling decrypted private key: " + err.Error()) |
| } |
| |
| if privateKey, err = x509.ParsePKCS8PrivateKey(pkData); err != nil { |
| return nil, errors.New("pkcs12: error parsing PKCS#8 private key: " + err.Error()) |
| } |
| |
| return privateKey, nil |
| } |
| |
| func decodeCertBag(asn1Data []byte) (x509Certificates []byte, err error) { |
| bag := new(certBag) |
| if err := unmarshal(asn1Data, bag); err != nil { |
| return nil, errors.New("pkcs12: error decoding cert bag: " + err.Error()) |
| } |
| if !bag.Id.Equal(oidCertTypeX509Certificate) { |
| return nil, NotImplementedError("only X509 certificates are supported") |
| } |
| return bag.Data, nil |
| } |