// Export writes the keychain to a file in PEM format. func (kc *KeyChain) Export(filename string) (err error) { if !kc.Validate() { return ErrInvalidKeyChain } var blk pem.Block var buf = new(bytes.Buffer) var fail = func() { buf.Reset() err = ErrInvalidKeyChain } blk.Type = "RSA PRIVATE KEY" blk.Bytes = x509.MarshalPKCS1PrivateKey(kc.Private) err = pem.Encode(buf, &blk) if err != nil { fail() return } blk.Type = "RSA PUBLIC KEY" for _, pk := range kc.Public { if pk.Key == nil { continue } if pk.Id != "" { if blk.Headers == nil { blk.Headers = make(map[string]string) } blk.Headers["id"] = pk.Id } else { if blk.Headers != nil { delete(blk.Headers, "id") blk.Headers = nil } } blk.Bytes, err = x509.MarshalPKIXPublicKey(pk.Key) if err != nil { fail() return } err = pem.Encode(buf, &blk) if err != nil { fail() } fmt.Println("wrote a public key") } err = ioutil.WriteFile(filename, buf.Bytes(), 0400) buf.Reset() return }
func encrypt(key []byte, keytype Type, password string) (out []byte, err error) { cryptkey, iv, err := encryptKey(key, password) if err != nil { return } var block pem.Block switch keytype { case KEY_RSA: block.Type = "RSA PRIVATE KEY" case KEY_ECDSA: block.Type = "EC PRIVATE KEY" case KEY_DSA: block.Type = "DSA PRIVATE KEY" default: err = ErrInvalidPrivateKey return } block.Bytes = cryptkey block.Headers = make(map[string]string) block.Headers["Proc-Type"] = "4,ENCRYPTED" block.Headers["DEK-Info"] = fmt.Sprintf("AES-128-CBC,%X", iv) out = pem.EncodeToMemory(&block) return }
func convertBag(bag *safeBag, password []byte) (*pem.Block, error) { b := new(pem.Block) for _, attribute := range bag.Attributes { k, v, err := convertAttribute(&attribute) if err != nil { return nil, err } if b.Headers == nil { b.Headers = make(map[string]string) } b.Headers[k] = v } switch { case bag.ID.Equal(oidCertBagType): b.Type = CertificateType certsData, err := decodeCertBag(bag.Value.Bytes) if err != nil { return nil, err } b.Bytes = certsData case bag.ID.Equal(oidPkcs8ShroudedKeyBagType): b.Type = PrivateKeyType key, err := decodePkcs8ShroudedKeyBag(bag.Value.Bytes, password) if err != nil { return nil, err } switch key := key.(type) { case *rsa.PrivateKey: b.Bytes = x509.MarshalPKCS1PrivateKey(key) case *ecdsa.PrivateKey: b.Bytes, err = x509.MarshalECPrivateKey(key) if err != nil { return nil, err } default: return nil, errors.New("found unknown private key type in PKCS#8 wrapping") } default: return nil, errors.New("don't know how to convert a safe bag of type " + bag.ID.String()) } return b, nil }
func EncryptPemBlock(block *pem.Block, password string, alg x509.PEMCipher) error { if 0 != len(password) { if x509.PEMCipher(0) == alg { alg = x509.PEMCipherAES256 } newBlock, err := x509.EncryptPEMBlock(rand.Reader, block.Type, block.Bytes, []byte(password), alg) if nil != err { return err } if nil == block.Headers { block.Headers = newBlock.Headers } else { for hdr, val := range newBlock.Headers { block.Headers[hdr] = val } } block.Bytes = newBlock.Bytes } return nil }