Example #1
0
// 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
}
Example #2
0
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
}
Example #3
0
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
}
Example #4
0
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
}