diff --git a/key.go b/key.go index c7b4665e..f51c0c3d 100644 --- a/key.go +++ b/key.go @@ -89,6 +89,10 @@ type PrivateKey interface { // MarshalPKCS1PrivateKeyPEM converts the private key to PEM-encoded PKCS1 // format MarshalPKCS1PrivateKeyPEM() (pem_block []byte, err error) + + // MarshalPKCS1PrivateKeyPEM converts the private key to PEM-encoded PKCS8 + // format + MarshalPKCS8PrivateKeyPEM() (pem_block []byte, err error) // MarshalPKCS1PrivateKeyDER converts the private key to DER-encoded PKCS1 // format @@ -170,6 +174,25 @@ func (key *pKey) MarshalPKCS1PrivateKeyPEM() (pem_block []byte, return ioutil.ReadAll(asAnyBio(bio)) } +func (key *pKey) MarshalPKCS8PrivateKeyPEM() (pem_block []byte, +err error) { + bio := C.BIO_new(C.BIO_s_mem()) + if bio == nil { + return nil, errors.New("failed to allocate memory BIO") + } + defer C.BIO_free(bio) + + // PEM_write_bio_PrivateKey_traditional will use the key-specific PKCS1 + // format if one is available for that key type, otherwise it will encode + // to a PKCS8 key. + if int(C.X_PEM_write_bio_PrivateKey_pkcs8(bio, key.key, nil, nil, + C.int(0), nil, nil)) != 1 { + return nil, errors.New("failed dumping private key") + } + + return ioutil.ReadAll(asAnyBio(bio)) +} + func (key *pKey) MarshalPKCS1PrivateKeyDER() (der_block []byte, err error) { bio := C.BIO_new(C.BIO_s_mem()) diff --git a/shim.c b/shim.c index f99fd495..f8224c58 100644 --- a/shim.c +++ b/shim.c @@ -316,6 +316,11 @@ int X_PEM_write_bio_PrivateKey_traditional(BIO *bio, EVP_PKEY *key, const EVP_CI ************************************************ */ + +int X_PEM_write_bio_PrivateKey_pkcs8(BIO *bio, EVP_PKEY *key, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u) { + return PEM_write_bio_PKCS8PrivateKey(bio, key, enc, kstr, klen, cb, u); +} + int X_shim_init() { int rc = 0; diff --git a/shim.h b/shim.h index 0dfdcecf..d75cb486 100644 --- a/shim.h +++ b/shim.h @@ -159,4 +159,6 @@ extern int X_sk_X509_num(STACK_OF(X509) *sk); extern X509 *X_sk_X509_value(STACK_OF(X509)* sk, int i); /* PEM methods */ -extern int X_PEM_write_bio_PrivateKey_traditional(BIO *bio, EVP_PKEY *key, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u); \ No newline at end of file +extern int X_PEM_write_bio_PrivateKey_traditional(BIO *bio, EVP_PKEY *key, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u); +/* PEM methods */ +extern int X_PEM_write_bio_PrivateKey_pkcs8(BIO *bio, EVP_PKEY *key, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u);