Author: brane Date: Mon Dec 5 13:46:54 2016 New Revision: 1772669 URL: http://svn.apache.org/viewvc?rev=1772669&view=rev Log: On the ocsp-verification branch: Add support for importing certificates from their exported form.
* serf_bucket_types.h (serf_ssl_cert_import): New prototype ... * buckets/ssl_buckets.c (serf_ssl_cert_import): ... implemented here. * test/test_ssl.c (load_cert_file_der): New; utility function for loading the Base64- -encoded certificate from a PEM-encoded file. (test_ssl_cert_export): Use load_cert_file_der. (test_ssl_cert_import): New test case, for serf_ssl_cert_import. (test_ssl): Add test_ssl_cert_import to the test suite. Modified: serf/branches/ocsp-verification/buckets/ssl_buckets.c serf/branches/ocsp-verification/serf_bucket_types.h serf/branches/ocsp-verification/test/test_ssl.c Modified: serf/branches/ocsp-verification/buckets/ssl_buckets.c URL: http://svn.apache.org/viewvc/serf/branches/ocsp-verification/buckets/ssl_buckets.c?rev=1772669&r1=1772668&r2=1772669&view=diff ============================================================================== --- serf/branches/ocsp-verification/buckets/ssl_buckets.c (original) +++ serf/branches/ocsp-verification/buckets/ssl_buckets.c Mon Dec 5 13:46:54 2016 @@ -2348,6 +2348,33 @@ const char *serf_ssl_cert_export( return encoded_cert; } + +serf_ssl_certificate_t *serf_ssl_cert_import( + const char *encoded_cert, + apr_pool_t *pool) +{ + char *binary_cert; + int binary_len; + const unsigned char *unused; + X509* ssl_cert; + serf_ssl_certificate_t *cert; + + binary_cert = apr_palloc(pool, apr_base64_decode_len(encoded_cert)); + binary_len = apr_base64_decode(binary_cert, encoded_cert); + + unused = (unsigned char*) binary_cert; /* unused is incremented */ + ssl_cert = d2i_X509(NULL, &unused, binary_len); + if (!ssl_cert) { + return NULL; + } + + /* TODO: Setup pool cleanup to free certificate */ + cert = apr_palloc(pool, sizeof(serf_ssl_certificate_t)); + cert->ssl_cert = ssl_cert; + return cert; +} + + /* Disables compression for all SSL sessions. */ static void disable_compression(serf_ssl_context_t *ssl_ctx) { Modified: serf/branches/ocsp-verification/serf_bucket_types.h URL: http://svn.apache.org/viewvc/serf/branches/ocsp-verification/serf_bucket_types.h?rev=1772669&r1=1772668&r2=1772669&view=diff ============================================================================== --- serf/branches/ocsp-verification/serf_bucket_types.h (original) +++ serf/branches/ocsp-verification/serf_bucket_types.h Mon Dec 5 13:46:54 2016 @@ -717,6 +717,14 @@ const char *serf_ssl_cert_export( apr_pool_t *pool); /** + * Import a certificate from a base64-encoded, zero-terminated string. + * The returned certificates is allocated in @a pool. Returns NULL on failure. + */ +serf_ssl_certificate_t *serf_ssl_cert_import( + const char *encoded_cert, + apr_pool_t *pool); + +/** * Load a CA certificate file from a path @a file_path. If the file was loaded * and parsed correctly, a certificate @a cert will be created and returned. * This certificate object will be alloced in @a pool. Modified: serf/branches/ocsp-verification/test/test_ssl.c URL: http://svn.apache.org/viewvc/serf/branches/ocsp-verification/test/test_ssl.c?rev=1772669&r1=1772668&r2=1772669&view=diff ============================================================================== --- serf/branches/ocsp-verification/test/test_ssl.c (original) +++ serf/branches/ocsp-verification/test/test_ssl.c Mon Dec 5 13:46:54 2016 @@ -252,17 +252,40 @@ static const char *extract_cert_from_pem return NULL; } -static void test_ssl_cert_export(CuTest *tc) +static const char* load_cert_file_der(CuTest *tc, + const char *path, + apr_pool_t *pool) { - test_baton_t *tb = tc->testBaton; - serf_ssl_certificate_t *cert = NULL; apr_file_t *fp; apr_finfo_t file_info; - const char *base64derbuf; char *pembuf; apr_size_t pemlen; apr_status_t status; + status = apr_file_open(&fp, path, + APR_FOPEN_READ | APR_FOPEN_BINARY, + APR_FPROT_OS_DEFAULT, pool); + CuAssertIntEquals(tc, APR_SUCCESS, status); + + status = apr_file_info_get(&file_info, APR_FINFO_SIZE, fp); + CuAssertIntEquals(tc, APR_SUCCESS, status); + pembuf = apr_palloc(pool, file_info.size + 1); + + status = apr_file_read_full(fp, pembuf, file_info.size, &pemlen); + CuAssertIntEquals(tc, APR_SUCCESS, status); + pembuf[file_info.size] = '\0'; + + return extract_cert_from_pem(pembuf, pool); +} + +static void test_ssl_cert_export(CuTest *tc) +{ + test_baton_t *tb = tc->testBaton; + serf_ssl_certificate_t *cert = NULL; + const char *extractedbuf; + const char *base64derbuf; + apr_status_t status; + status = serf_ssl_load_cert_file(&cert, get_srcdir_file(tb->pool, @@ -273,25 +296,43 @@ static void test_ssl_cert_export(CuTest /* A .pem file contains a Base64 encoded DER certificate, which is exactly what serf_ssl_cert_export is supposed to be returning. */ - status = apr_file_open(&fp, - get_srcdir_file(tb->pool, "test/serftestca.pem"), - APR_FOPEN_READ | APR_FOPEN_BINARY, - APR_FPROT_OS_DEFAULT, tb->pool); - CuAssertIntEquals(tc, APR_SUCCESS, status); + extractedbuf = load_cert_file_der(tc, + get_srcdir_file(tb->pool, + "test/serftestca.pem"), + tb->pool); + base64derbuf = serf_ssl_cert_export(cert, tb->pool); - status = apr_file_info_get(&file_info, APR_FINFO_SIZE, fp); - CuAssertIntEquals(tc, APR_SUCCESS, status); - pembuf = apr_palloc(tb->pool, file_info.size + 1); + CuAssertStrEquals(tc, extractedbuf, base64derbuf); +} - status = apr_file_read_full(fp, pembuf, file_info.size, &pemlen); +static void test_ssl_cert_import(CuTest *tc) +{ + test_baton_t *tb = tc->testBaton; + serf_ssl_certificate_t *cert = NULL; + serf_ssl_certificate_t *imported_cert = NULL; + const char *extractedbuf; + const char *base64derbuf; + apr_status_t status; + + status = serf_ssl_load_cert_file(&cert, + get_srcdir_file(tb->pool, + "test/serftestca.pem"), + tb->pool); CuAssertIntEquals(tc, APR_SUCCESS, status); - pembuf[file_info.size] = '\0'; + CuAssertPtrNotNull(tc, cert); - base64derbuf = serf_ssl_cert_export(cert, tb->pool); + /* A .pem file contains a Base64 encoded DER certificate, which is exactly + what serf_ssl_cert_import expects as input. */ + extractedbuf = load_cert_file_der(tc, + get_srcdir_file(tb->pool, + "test/serftestca.pem"), + tb->pool); + + imported_cert = serf_ssl_cert_import(extractedbuf, tb->pool); + CuAssertPtrNotNull(tc, imported_cert); - CuAssertStrEquals(tc, - extract_cert_from_pem(pembuf, tb->pool), - base64derbuf); + base64derbuf = serf_ssl_cert_export(imported_cert, tb->pool); + CuAssertStrEquals(tc, extractedbuf, base64derbuf); } /***************************************************************************** @@ -2265,6 +2306,7 @@ CuSuite *test_ssl(void) SUITE_ADD_TEST(suite, test_ssl_cert_issuer); SUITE_ADD_TEST(suite, test_ssl_cert_certificate); SUITE_ADD_TEST(suite, test_ssl_cert_export); + SUITE_ADD_TEST(suite, test_ssl_cert_import); SUITE_ADD_TEST(suite, test_ssl_handshake); SUITE_ADD_TEST(suite, test_ssl_handshake_nosslv2); SUITE_ADD_TEST(suite, test_ssl_trust_rootca);