int pkcs11_init_tls_session(pkcs11h_certificate_t certificate, struct tls_root_ctx * const ssl_ctx) { int ret = 1; X509 *x509 = NULL; RSA *rsa = NULL; pkcs11h_openssl_session_t openssl_session = NULL; if ((openssl_session = pkcs11h_openssl_createSession (certificate)) == NULL) { msg (M_WARN, "PKCS#11: Cannot initialize openssl session"); goto cleanup; } /* * Will be released by openssl_session */ certificate = NULL; if ((rsa = pkcs11h_openssl_session_getRSA (openssl_session)) == NULL) { msg (M_WARN, "PKCS#11: Unable get rsa object"); goto cleanup; } if ((x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL) { msg (M_WARN, "PKCS#11: Unable get certificate object"); goto cleanup; } if (!SSL_CTX_use_RSAPrivateKey (ssl_ctx->ctx, rsa)) { msg (M_WARN, "PKCS#11: Cannot set private key for openssl"); goto cleanup; } if (!SSL_CTX_use_certificate (ssl_ctx->ctx, x509)) { msg (M_WARN, "PKCS#11: Cannot set certificate for openssl"); goto cleanup; } ret = 0; cleanup: /* * Certificate freeing is usually handled by openssl_session. * If something went wrong, creating the session we have to do it manually. */ if (certificate != NULL) { pkcs11h_certificate_freeCertificate (certificate); certificate = NULL; } /* * openssl objects have reference * count, so release them */ if (x509 != NULL) { X509_free (x509); x509 = NULL; } if (rsa != NULL) { RSA_free (rsa); rsa = NULL; } if (openssl_session != NULL) { pkcs11h_openssl_freeSession (openssl_session); openssl_session = NULL; } return ret; }
EVP_PKEY * pkcs11h_openssl_session_getEVP ( IN const pkcs11h_openssl_session_t openssl_session ) { X509 *x509 = NULL; EVP_PKEY *evp = NULL; EVP_PKEY *ret = NULL; _PKCS11H_ASSERT (openssl_session!=NULL); _PKCS11H_ASSERT (!openssl_session->initialized); _PKCS11H_ASSERT (openssl_session!=NULL); _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_openssl_session_getEVP - entry openssl_session=%p", (void *)openssl_session ); /* * Dup x509 so RSA will not hold session x509 */ if ((x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get certificate object"); goto cleanup; } if ((evp = X509_get_pubkey (x509)) == NULL) { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get public key"); goto cleanup; } if (0) { } #ifndef OPENSSL_NO_RSA else if (EVP_PKEY_id (evp) == EVP_PKEY_RSA) { if (!__pkcs11h_openssl_session_setRSA(openssl_session, evp)) { goto cleanup; } } #endif #ifndef OPENSSL_NO_RSA else if (EVP_PKEY_id (evp) == EVP_PKEY_DSA) { if (!__pkcs11h_openssl_session_setDSA(openssl_session, evp)) { goto cleanup; } } #endif #ifdef __ENABLE_EC else if (evp->type == EVP_PKEY_EC) { if (!__pkcs11h_openssl_session_setECDSA(openssl_session, evp)) { goto cleanup; } } #endif else { _PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Invalid public key algorithm %d", EVP_PKEY_id (evp)); goto cleanup; } #if defined(ENABLE_PKCS11H_THREADING) _pkcs11h_threading_mutexLock(&openssl_session->reference_count_lock); #endif openssl_session->reference_count++; #if defined(ENABLE_PKCS11H_THREADING) _pkcs11h_threading_mutexRelease(&openssl_session->reference_count_lock); #endif openssl_session->initialized = TRUE; ret = evp; evp = NULL; cleanup: /* * openssl objects have reference * count, so release them */ if (evp != NULL) { EVP_PKEY_free (evp); evp = NULL; } if (x509 != NULL) { X509_free (x509); x509 = NULL; } _PKCS11H_DEBUG ( PKCS11H_LOG_DEBUG2, "PKCS#11: pkcs11h_openssl_session_getEVP - return ret=%p", (void *)ret ); return ret; }