Author: jfclere Date: Sun Nov 8 10:34:31 2015 New Revision: 1713220 URL: http://svn.apache.org/viewvc?rev=1713220&view=rev Log: Allow to use raw (well keystore) certificates and keys.
Modified: tomcat/native/trunk/native/src/sslcontext.c Modified: tomcat/native/trunk/native/src/sslcontext.c URL: http://svn.apache.org/viewvc/tomcat/native/trunk/native/src/sslcontext.c?rev=1713220&r1=1713219&r2=1713220&view=diff ============================================================================== --- tomcat/native/trunk/native/src/sslcontext.c (original) +++ tomcat/native/trunk/native/src/sslcontext.c Sun Nov 8 10:34:31 2015 @@ -974,6 +974,120 @@ cleanup: return rv; } +TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificateRaw)(TCN_STDARGS, jlong ctx, + jbyteArray javaCert, jbyteArray javaKey, jint idx) +{ +#ifdef HAVE_ECC +#if defined(SSL_CTX_set_ecdh_auto) + EC_KEY *eckey = NULL; +#endif +#endif + jsize lengthOfCert; + unsigned char* cert; + X509 * certs; + EVP_PKEY * evp; + const unsigned char *tmp; + BIO * bio; + + tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *); + jboolean rv = JNI_TRUE; + char err[256]; + + /* we get the key contents into a byte array */ + jbyte* bufferPtr = (*e)->GetByteArrayElements(e, javaKey, NULL); + jsize lengthOfKey = (*e)->GetArrayLength(e, javaKey); + unsigned char* key = malloc(lengthOfKey); + memcpy(key, bufferPtr, lengthOfKey); + (*e)->ReleaseByteArrayElements(e, javaKey, bufferPtr, 0); + + bufferPtr = (*e)->GetByteArrayElements(e, javaCert, NULL); + lengthOfCert = (*e)->GetArrayLength(e, javaCert); + cert = malloc(lengthOfCert); + memcpy(cert, bufferPtr, lengthOfCert); + (*e)->ReleaseByteArrayElements(e, javaCert, bufferPtr, 0); + + UNREFERENCED(o); + TCN_ASSERT(ctx != 0); + + if (idx < 0 || idx >= SSL_AIDX_MAX) { + tcn_Throw(e, "Invalid key type"); + rv = JNI_FALSE; + goto cleanup; + } + + tmp = (const unsigned char *)cert; + certs = d2i_X509(NULL, &tmp, lengthOfCert); + if (certs == NULL) { + ERR_error_string(ERR_get_error(), err); + tcn_Throw(e, "Error reading certificat (%s)", err); + rv = JNI_FALSE; + goto cleanup; + } + if(c->certs[idx] != NULL) { + free(c->certs[idx]); + } + c->certs[idx] = certs; + + bio = BIO_new(BIO_s_mem()); + BIO_write(bio, key, lengthOfKey); + + evp = PEM_read_bio_PrivateKey(bio, NULL, 0, NULL); + if (evp == NULL) { + BIO_free(bio); + ERR_error_string(ERR_get_error(), err); + tcn_Throw(e, "Error reading private key (%s)", err); + rv = JNI_FALSE; + goto cleanup; + } + BIO_free(bio); + if(c->keys[idx] != NULL) { + free(c->keys[idx]); + } + c->keys[idx] = evp; + + if (SSL_CTX_use_certificate(c->ctx, c->certs[idx]) <= 0) { + ERR_error_string(ERR_get_error(), err); + tcn_Throw(e, "Error setting certificate (%s)", err); + rv = JNI_FALSE; + goto cleanup; + } + if (SSL_CTX_use_PrivateKey(c->ctx, c->keys[idx]) <= 0) { + ERR_error_string(ERR_get_error(), err); + tcn_Throw(e, "Error setting private key (%s)", err); + rv = JNI_FALSE; + goto cleanup; + } + if (SSL_CTX_check_private_key(c->ctx) <= 0) { + ERR_error_string(ERR_get_error(), err); + tcn_Throw(e, "Private key does not match the certificate public key (%s)", + err); + rv = JNI_FALSE; + goto cleanup; + } + + /* + * TODO Try to read DH parameters from somewhere... + */ + +#ifdef HAVE_ECC + /* + * TODO try to read the ECDH curve name from somewhere... + */ +#if defined(SSL_CTX_set_ecdh_auto) + SSL_CTX_set_ecdh_auto(c->ctx, 1); +#else + eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + SSL_CTX_set_tmp_ecdh(c->ctx, eckey); + EC_KEY_free(eckey); +#endif +#endif + SSL_CTX_set_tmp_dh_callback(c->ctx, SSL_callback_tmp_DH); +cleanup: + free(key); + free(cert); + return rv; +} + static int ssl_array_index(apr_array_header_t *array, const char *s) { --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org