[rs-commit] r39 - in /redwax-tool/trunk: redwax_nss.c redwax_openssl.c redwax_p11kit.c

rs-commit at redwax.eu rs-commit at redwax.eu
Thu Nov 18 22:02:58 CET 2021


Author: minfrin at redwax.eu
Date: Thu Nov 18 22:02:58 2021
New Revision: 39

Log:
Add option to export a pkcs11 key.

Modified:
    redwax-tool/trunk/redwax_nss.c
    redwax-tool/trunk/redwax_openssl.c
    redwax-tool/trunk/redwax_p11kit.c

Modified: redwax-tool/trunk/redwax_nss.c
==============================================================================
--- redwax-tool/trunk/redwax_nss.c	(original)
+++ redwax-tool/trunk/redwax_nss.c	Thu Nov 18 22:02:58 2021
@@ -59,11 +59,11 @@
 static apr_status_t cleanup_nss(void *dummy)
 {
     if (dummy) {
-    	SECStatus rv = NSS_ShutdownContext(dummy);
+        SECStatus rv = NSS_ShutdownContext(dummy);
         if (rv != SECSuccess) {
             fprintf(stderr, "Could not shutdown NSS database: %s\n",
                     PR_ErrorToName(PR_GetError()));
-    	}
+        }
     }
 
     return APR_SUCCESS;
@@ -523,6 +523,12 @@
             SECItem nickname = { siBuffer, (unsigned char*) key->name,
                     key->name ? strlen(key->name) : 0 };
 
+            if (!key->der) {
+                redwax_print_error(r, "nss-out: non-extractable private key, skipping\n");
+
+                continue;
+            }
+
             redwax_print_error(r, "nss-out: private key\n");
 
             rv = PK11_ImportDERPrivateKeyInfo(slot, &pkcs8PrivKeyItem,

Modified: redwax-tool/trunk/redwax_openssl.c
==============================================================================
--- redwax-tool/trunk/redwax_openssl.c	(original)
+++ redwax-tool/trunk/redwax_openssl.c	Thu Nov 18 22:02:58 2021
@@ -1674,6 +1674,12 @@
             PKCS8_PRIV_KEY_INFO *p8inf;
             EVP_PKEY *pkey;
 
+            if (!key->der) {
+                redwax_print_error(r, "pem-out: non-extractable private key, skipping\n");
+
+                continue;
+            }
+
             if ((kbio = BIO_new_mem_buf(key->der, key->len)) == NULL) {
                 return APR_ENOMEM;
             }
@@ -1973,6 +1979,12 @@
 
             const unsigned char *der = key->der;
 
+            if (!key->der) {
+                redwax_print_error(r, "pkcs12-out: non-extractable private key, skipping\n");
+
+                return APR_ENOENT;
+            }
+
             pkey = d2i_AutoPrivateKey(NULL, &der, key->len);
 
             if (!pkey) {
@@ -2484,8 +2496,81 @@
     /*
      * RSA components are present, but the DER encoded key is not.
      */
-    else if (key->rsa && !key->der) {
-
+    else if (key->common.type == REDWAX_KEY_RSA && key->rsa && !key->der) {
+
+        BIO *kbio;
+        PKCS8_PRIV_KEY_INFO *p8inf;
+        EVP_PKEY *pkey = EVP_PKEY_new();
+        X509_PUBKEY *pub = NULL;
+        RSA *rsa = RSA_new();
+
+        RSA_set0_key(rsa,
+                BN_bin2bn(key->rsa->modulus, key->rsa->modulus_len,
+                        NULL),
+                BN_bin2bn(key->rsa->public_exponent,
+                        key->rsa->public_exponent_len, NULL),
+                BN_bin2bn(key->rsa->private_exponent,
+                        key->rsa->private_exponent_len, NULL));
+        RSA_set0_factors(rsa,
+                BN_bin2bn(key->rsa->prime_1, key->rsa->prime_1_len,
+                        NULL),
+                BN_bin2bn(key->rsa->prime_2, key->rsa->prime_2_len,
+                        NULL));
+        RSA_set0_crt_params(rsa,
+                BN_bin2bn(key->rsa->exponent_1, key->rsa->exponent_1_len,
+                        NULL),
+                BN_bin2bn(key->rsa->exponent_2, key->rsa->exponent_2_len,
+                        NULL),
+                BN_bin2bn(key->rsa->coefficient, key->rsa->coefficient_len,
+                        NULL));
+
+        EVP_PKEY_set1_RSA(pkey, rsa);
+        p8inf = EVP_PKEY2PKCS8(pkey);
+
+        /* handle public key */
+        if (X509_PUBKEY_set(&pub, pkey)) {
+
+            unsigned char *der;
+
+            // checkme - r->pool?
+
+            key->common.subjectpublickeyinfo_len = i2d_X509_PUBKEY(pub, NULL);
+            key->common.subjectpublickeyinfo_der = der = apr_palloc(r->pool,
+                    key->common.subjectpublickeyinfo_len);
+            i2d_X509_PUBKEY(pub, &der);
+
+            /* index the key */
+            if (index) {
+
+                if (!apr_hash_get(r->keys_index,
+                        key->common.subjectpublickeyinfo_der,
+                        key->common.subjectpublickeyinfo_len)) {
+                    apr_hash_set(r->keys_index,
+                            key->common.subjectpublickeyinfo_der,
+                            key->common.subjectpublickeyinfo_len, key);
+                }
+
+            }
+
+        }
+
+        /* handle private key */
+        if (key->rsa->private_exponent_len) {
+            if ((kbio = BIO_new(BIO_s_mem())) == NULL) {
+                return APR_ENOMEM;
+            }
+
+            apr_pool_cleanup_register(key->pool, kbio, cleanup_bio,
+                    apr_pool_cleanup_null);
+
+            i2d_PKCS8_PRIV_KEY_INFO_bio(kbio, p8inf);
+            key->len = BIO_get_mem_data(kbio, &key->der);
+
+            PKCS8_PRIV_KEY_INFO_free(p8inf);
+        }
+
+        EVP_PKEY_free(pkey);
+        RSA_free(rsa);
     }
 
     return APR_SUCCESS;

Modified: redwax-tool/trunk/redwax_p11kit.c
==============================================================================
--- redwax-tool/trunk/redwax_p11kit.c	(original)
+++ redwax-tool/trunk/redwax_p11kit.c	Thu Nov 18 22:02:58 2021
@@ -29,9 +29,10 @@
  */
 
 #include <apr_crypto.h>
+#include <apr_encode.h>
+#include <apr_escape.h>
 #include <apr_lib.h>
 #include <apr_strings.h>
-#include <apr_escape.h>
 
 #include "config.h"
 #include "redwax-tool.h"
@@ -736,6 +737,8 @@
 
     apr_ssize_t userPIN_len = 0;
 
+    // urlPIN = "";
+
     /* support a pinpad reader */
     if (tokenInfo->flags & CKF_PROTECTED_AUTHENTICATION_PATH) {
         /* userPIN is null */
@@ -1289,10 +1292,148 @@
 
         else if (CKO_PRIVATE_KEY == clazz) {
 
-            redwax_print_error(r,
-                    "pkcs11-in: Private key found on '%s', skipping\n",
-                    redwax_pstrntrim(pool, (const char*) tokenInfo->label,
-                            sizeof(tokenInfo->label)));
+            CK_KEY_TYPE type;
+
+            CK_ATTRIBUTE type_template[] = {
+              {CKA_KEY_TYPE, NULL_PTR, 0},
+              {CKA_ID, NULL_PTR, 0}
+            };
+
+            int type_template_len = 2;
+
+            ret = redwax_p11kit_read_attributes(pool, module, session, object,
+                    type_template, type_template_len);
+            if (ret != CKR_OK) {
+
+                /* ignore anything we cannot read */
+                continue;
+            }
+
+            type = *(CK_KEY_TYPE *)type_template[0].pValue;
+
+            /* 4.9.1 RSA private key objects */
+            if (CKK_RSA == type) {
+
+                redwax_key_t *key;
+
+                CK_ATTRIBUTE key_template[] =
+                    { { CKA_MODULUS, NULL_PTR, 0 },
+                      { CKA_PUBLIC_EXPONENT, NULL_PTR, 0 },
+                      { CKA_PRIVATE_EXPONENT, NULL_PTR, 0 },
+                      { CKA_PRIME_1, NULL_PTR, 0 },
+                      { CKA_PRIME_2, NULL_PTR, 0 },
+                      { CKA_EXPONENT_1, NULL_PTR, 0 },
+                      { CKA_EXPONENT_2, NULL_PTR, 0 },
+                      { CKA_COEFFICIENT, NULL_PTR, 0 }
+                    };
+                int key_template_len = 8;
+
+                key = apr_array_push(r->keys_in);
+
+                apr_pool_create(&key->pool, r->pool);
+
+                key->common.type = REDWAX_KEY_RSA;
+                key->common.id_der = type_template[1].pValue;
+                key->common.id_len = type_template[1].ulValueLen;
+
+                ret = redwax_p11kit_read_attributes(pool, module, session, object,
+                        key_template, key_template_len);
+                if (ret == CKR_OK || ret == CKR_ATTRIBUTE_SENSITIVE
+                        || ret == CKR_ATTRIBUTE_TYPE_INVALID) {
+
+                    key->rsa = apr_pcalloc(key->pool, sizeof(redwax_key_rsa_t));
+
+                    if (CK_UNAVAILABLE_INFORMATION
+                            != key_template[0].ulValueLen) {
+                        key->rsa->modulus_len = key_template[0].ulValueLen;
+                        key->rsa->modulus = key_template[0].pValue;
+#if HAVE_APR_CRYPTO_CLEAR
+                        apr_crypto_clear(key->pool, key->rsa->modulus, key->rsa->modulus_len);
+#endif
+                    }
+
+                    if (CK_UNAVAILABLE_INFORMATION
+                            != key_template[1].ulValueLen) {
+                        key->rsa->public_exponent_len =
+                                key_template[1].ulValueLen;
+                        key->rsa->public_exponent = key_template[1].pValue;
+#if HAVE_APR_CRYPTO_CLEAR
+                        apr_crypto_clear(key->pool, key->rsa->public_exponent, key->rsa->public_exponent_len);
+#endif
+                    }
+
+                    if (CK_UNAVAILABLE_INFORMATION
+                            != key_template[2].ulValueLen) {
+                        key->rsa->private_exponent_len =
+                                key_template[2].ulValueLen;
+                        key->rsa->private_exponent = key_template[2].pValue;
+#if HAVE_APR_CRYPTO_CLEAR
+                        apr_crypto_clear(key->pool, key->rsa->private_exponent, key->rsa->private_exponent_len);
+#endif
+                    }
+
+                    if (CK_UNAVAILABLE_INFORMATION
+                            != key_template[3].ulValueLen) {
+                        key->rsa->prime_1_len = key_template[3].ulValueLen;
+                        key->rsa->prime_1 = key_template[3].pValue;
+#if HAVE_APR_CRYPTO_CLEAR
+                        apr_crypto_clear(key->pool, key->rsa->prime_1, key->rsa->prime_1_len);
+#endif
+                    }
+
+                    if (CK_UNAVAILABLE_INFORMATION
+                            != key_template[4].ulValueLen) {
+                        key->rsa->prime_2_len = key_template[4].ulValueLen;
+                        key->rsa->prime_2 = key_template[4].pValue;
+#if HAVE_APR_CRYPTO_CLEAR
+                        apr_crypto_clear(key->pool, key->rsa->prime_2, key->rsa->prime_2_len);
+#endif
+                    }
+
+                    if (CK_UNAVAILABLE_INFORMATION
+                            != key_template[5].ulValueLen) {
+                        key->rsa->exponent_1_len = key_template[5].ulValueLen;
+                        key->rsa->exponent_1 = key_template[5].pValue;
+#if HAVE_APR_CRYPTO_CLEAR
+                        apr_crypto_clear(key->pool, key->rsa->exponent_1, key->rsa->exponent_1_len);
+#endif
+                    }
+
+                    if (CK_UNAVAILABLE_INFORMATION
+                            != key_template[6].ulValueLen) {
+                        key->rsa->exponent_2_len = key_template[6].ulValueLen;
+                        key->rsa->exponent_2 = key_template[6].pValue;
+#if HAVE_APR_CRYPTO_CLEAR
+                        apr_crypto_clear(key->pool, key->rsa->exponent_2, key->rsa->exponent_2_len);
+#endif
+                    }
+
+                    if (CK_UNAVAILABLE_INFORMATION
+                            != key_template[7].ulValueLen) {
+                        key->rsa->coefficient_len = key_template[7].ulValueLen;
+                        key->rsa->coefficient = key_template[7].pValue;
+#if HAVE_APR_CRYPTO_CLEAR
+                        apr_crypto_clear(key->pool, key->rsa->coefficient, key->rsa->coefficient_len);
+#endif
+                    }
+
+                    rt_run_normalise_key(r, key, 1);
+
+                    redwax_print_error(r, "pkcs11-in: private key: %s\n",
+                            apr_pencode_base16_binary(pool, key->common.id_der,
+                                    key->common.id_len, APR_ENCODE_LOWER, NULL));
+
+                }
+
+            }
+            else {
+
+                redwax_print_error(r,
+                        "pkcs11-in: Private key type %d on '%s' not understood, skipping\n",
+                        (int)type,
+                        redwax_pstrntrim(pool, (const char*) tokenInfo->label,
+                                sizeof(tokenInfo->label)));
+            }
 
         }
         else {



More information about the rs-commit mailing list