aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schneider <asn@cryptomilk.org>2013-11-27 17:32:07 +0100
committerAndreas Schneider <asn@cryptomilk.org>2013-11-27 22:54:40 +0100
commit1fdc1025a87792c740fa8cdd8463801392fa918e (patch)
tree346e9a1ebae3a1945d475c59f845f354b254cc09
parenta375b6c996f20dbaa290fd61edb719f4e96c3363 (diff)
downloadlibssh-1fdc1025a87792c740fa8cdd8463801392fa918e.tar.gz
libssh-1fdc1025a87792c740fa8cdd8463801392fa918e.tar.xz
libssh-1fdc1025a87792c740fa8cdd8463801392fa918e.zip
pki_crypto: Add pki_private_key_to_pem().
-rw-r--r--src/pki_crypto.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/src/pki_crypto.c b/src/pki_crypto.c
index e87d7ace..dc61290f 100644
--- a/src/pki_crypto.c
+++ b/src/pki_crypto.c
@@ -528,6 +528,124 @@ int pki_key_compare(const ssh_key k1,
return 0;
}
+ssh_string pki_private_key_to_pem(const ssh_key key,
+ const char *passphrase,
+ ssh_auth_callback auth_fn,
+ void *auth_data)
+{
+ ssh_string blob;
+ BUF_MEM *buf;
+ BIO *mem;
+ int rc;
+
+ /* needed for openssl initialization */
+ if (ssh_init() < 0) {
+ return NULL;
+ }
+
+ mem = BIO_new(BIO_s_mem());
+ if (mem == NULL) {
+ return NULL;
+ }
+
+ switch (key->type) {
+ case SSH_KEYTYPE_DSS:
+ if (passphrase == NULL) {
+ struct pem_get_password_struct pgp = { auth_fn, auth_data };
+
+ rc = PEM_write_bio_DSAPrivateKey(mem,
+ key->dsa,
+ NULL, /* cipher */
+ NULL, /* kstr */
+ 0, /* klen */
+ pem_get_password,
+ &pgp);
+ } else {
+ rc = PEM_write_bio_DSAPrivateKey(mem,
+ key->dsa,
+ NULL, /* cipher */
+ NULL, /* kstr */
+ 0, /* klen */
+ NULL, /* auth_fn */
+ (void*) passphrase);
+ }
+ if (rc != 1) {
+ goto err;
+ }
+ break;
+ case SSH_KEYTYPE_RSA:
+ case SSH_KEYTYPE_RSA1:
+ if (passphrase == NULL) {
+ struct pem_get_password_struct pgp = { auth_fn, auth_data };
+
+ rc = PEM_write_bio_RSAPrivateKey(mem,
+ key->rsa,
+ NULL, /* cipher */
+ NULL, /* kstr */
+ 0, /* klen */
+ pem_get_password,
+ &pgp);
+ } else {
+ rc = PEM_write_bio_RSAPrivateKey(mem,
+ key->rsa,
+ NULL, /* cipher */
+ NULL, /* kstr */
+ 0, /* klen */
+ NULL, /* auth_fn */
+ (void*) passphrase);
+ }
+ if (rc != 1) {
+ goto err;
+ }
+ break;
+ case SSH_KEYTYPE_ECDSA:
+#ifdef HAVE_ECC
+ if (passphrase == NULL) {
+ struct pem_get_password_struct pgp = { auth_fn, auth_data };
+
+ rc = PEM_write_bio_ECPrivateKey(mem,
+ key->ecdsa,
+ NULL, /* cipher */
+ NULL, /* kstr */
+ 0, /* klen */
+ pem_get_password,
+ &pgp);
+ } else {
+ rc = PEM_write_bio_ECPrivateKey(mem,
+ key->ecdsa,
+ NULL, /* cipher */
+ NULL, /* kstr */
+ 0, /* klen */
+ NULL, /* auth_fn */
+ (void*) passphrase);
+ }
+ if (rc != 1) {
+ goto err;
+ }
+ break;
+#endif
+ case SSH_KEYTYPE_UNKNOWN:
+ BIO_free(mem);
+ ssh_pki_log("Unkown or invalid private key type %d", key->type);
+ return NULL;
+ }
+
+ BIO_get_mem_ptr(mem, &buf);
+
+ blob = ssh_string_new(buf->length);
+ if (blob == NULL) {
+ goto err;
+ }
+
+ ssh_string_fill(blob, buf->data, buf->length);
+ BIO_free(mem);
+
+ return blob;
+err:
+ BIO_free(mem);
+ return NULL;
+}
+
ssh_key pki_private_key_from_base64(const char *b64_key,
const char *passphrase,
ssh_auth_callback auth_fn,