Migrated x509_get_subject to use of the garbage collector

This also cleans up a messy call in pkcs11.c to _openssl_get_subject, as discussed at FOSDEM.

Signed-off-by: Adriaan de Jong <dejong@fox-it.com>
Acked-by: James Yonan <james@openvpn.net>
Acked-by: David Sommerseth <davids@redhat.com>
Signed-off-by: David Sommerseth <davids@redhat.com>
This commit is contained in:
Adriaan de Jong 2012-02-14 11:11:24 +01:00 committed by David Sommerseth
parent 3144411183
commit 00b973f8af
8 changed files with 51 additions and 75 deletions

View File

@ -834,7 +834,8 @@ show_pkcs11_ids (
);
for (current = user_certificates;current != NULL; current = current->next) {
pkcs11h_certificate_t certificate = NULL;
char dn[1024] = {0};
struct gc_arena gc = gc_new();
char *dn = NULL;
char serial[1024] = {0};
char *ser = NULL;
size_t ser_len = 0;
@ -883,10 +884,9 @@ show_pkcs11_ids (
}
if (
(pkcs11_certificate_dn (
(dn = pkcs11_certificate_dn (
certificate,
dn,
sizeof(dn)
&gc
))
) {
goto cleanup1;
@ -927,6 +927,8 @@ show_pkcs11_ids (
free (ser);
ser = NULL;
}
gc_free (&gc);
}
cleanup:

View File

@ -42,13 +42,11 @@
* Retrieve PKCS #11 Certificate's DN in a printable format.
*
* @param certificate The PKCS #11 helper certificate object
* @param dn Buffer that the certificate subject DN will be placed in.
* @param dn_len Size of said buffer.
* @param gc Garbage collection pool to allocate memory in
*
* @return 1 on failure, 0 on success
* @return Certificate's DN on success, NULL on failure
*/
int pkcs11_certificate_dn (pkcs11h_certificate_t certificate, char *dn,
size_t dn_len);
char * pkcs11_certificate_dn (pkcs11h_certificate_t certificate, struct gc_arena *gc);
/**
* Retrieve PKCS #11 Certificate's serial number in a printable format.

View File

@ -39,6 +39,7 @@
#include "errlevel.h"
#include "pkcs11_backend.h"
#include "ssl_verify.h"
#include <pkcs11-helper-1.0/pkcs11h-openssl.h>
int
@ -121,23 +122,20 @@ cleanup:
return ret;
}
int
pkcs11_certificate_dn (pkcs11h_certificate_t certificate, char *dn,
size_t dn_len)
char *
pkcs11_certificate_dn (pkcs11h_certificate_t certificate, struct gc_arena *gc)
{
X509 *x509 = NULL;
int ret = 1;
char *dn = NULL;
if ((x509 = pkcs11h_openssl_getX509 (certificate)) == NULL)
{
msg (M_FATAL, "PKCS#11: Cannot get X509");
ret = 1;
goto cleanup;
}
_openssl_get_subject (x509, dn, dn_len);
ret = 0;
dn = x509_get_subject (x509, gc);
cleanup:
if (x509 != NULL)
@ -146,7 +144,7 @@ cleanup:
x509 = NULL;
}
return ret;
return dn;
}
int

View File

@ -72,11 +72,11 @@ cleanup:
return ret;
}
int
pkcs11_certificate_dn (pkcs11h_certificate_t cert, char *dn,
size_t dn_len)
char *
pkcs11_certificate_dn (pkcs11h_certificate_t cert, struct gc_arena *gc)
{
int ret = 1;
char dn[1024] = {0};
x509_cert polar_cert = {0};
@ -85,7 +85,7 @@ pkcs11_certificate_dn (pkcs11h_certificate_t cert, char *dn,
goto cleanup;
}
if (-1 == x509parse_dn_gets (dn, dn_len, &polar_cert.subject)) {
if (-1 == x509parse_dn_gets (dn, sizeof(dn), &polar_cert.subject)) {
msg (M_FATAL, "PKCS#11: PolarSSL cannot parse subject");
goto cleanup;
}
@ -95,7 +95,9 @@ pkcs11_certificate_dn (pkcs11h_certificate_t cert, char *dn,
cleanup:
x509_free(&polar_cert);
return ret;
if (ret == 0)
return string_alloc(dn, gc);
return NULL;
}
int

View File

@ -571,6 +571,7 @@ verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_dep
char *subject = NULL;
char common_name[TLS_USERNAME_LEN] = {0};
const struct tls_options *opt;
struct gc_arena gc = gc_new();
opt = session->opt;
ASSERT (opt);
@ -578,7 +579,7 @@ verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_dep
session->verified = false;
/* get the X509 name */
subject = x509_get_subject(cert);
subject = x509_get_subject(cert, &gc);
if (!subject)
{
msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, could not extract X509 "
@ -676,13 +677,13 @@ verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_dep
msg (D_HANDSHAKE, "VERIFY OK: depth=%d, %s", cert_depth, subject);
session->verified = true;
x509_free_subject (subject);
gc_free(&gc);
return SUCCESS;
err:
tls_clear_error();
session->verified = false;
x509_free_subject (subject);
gc_free(&gc);
return FAILURE;
}

View File

@ -80,20 +80,12 @@ void cert_hash_remember (struct tls_session *session, const int cert_depth,
/*
* Retrieve certificate's subject name.
*
* The returned string must be freed with \c verify_free_subject()
*
* @param cert Certificate to retrieve the subject from.
* @param gc Garbage collection arena to use when allocating string.
*
* @return a string containing the subject
*/
char *x509_get_subject (openvpn_x509_cert_t *cert);
/*
* Free a subject string as returned by \c verify_get_subject()
*
* @param subject The subject to be freed.
*/
void x509_free_subject (char *subject);
char *x509_get_subject (openvpn_x509_cert_t *cert, struct gc_arena *gc);
/* Retrieve the certificate's SHA1 hash.
*

View File

@ -48,6 +48,7 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx)
{
struct tls_session *session;
SSL *ssl;
struct gc_arena gc = gc_new();
unsigned char *sha1_hash = NULL;
/* get the tls_session pointer */
@ -64,7 +65,7 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx)
if (!preverify_ok)
{
/* get the X509 name */
char *subject = x509_get_subject(ctx->current_cert);
char *subject = x509_get_subject(ctx->current_cert, &gc);
if (subject)
{
@ -73,16 +74,18 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx)
ctx->error_depth,
X509_verify_cert_error_string (ctx->error),
subject);
x509_free_subject(subject);
}
ERR_clear_error();
gc_free(&gc);
session->verified = false;
return 0;
}
gc_free(&gc);
if (SUCCESS == verify_cert(session, ctx->current_cert, ctx->error_depth))
return 1;
return 0;
@ -253,12 +256,12 @@ x509_free_sha1_hash (unsigned char *hash)
}
char *
_openssl_get_subject (X509 *cert, char *buf, int size)
x509_get_subject (X509 *cert, struct gc_arena *gc)
{
BIO *subject_bio = NULL;
BUF_MEM *subject_mem;
char *subject = buf;
int maxlen = size;
char *subject = NULL;
int maxlen = 0;
subject_bio = BIO_new (BIO_s_mem ());
if (subject_bio == NULL)
@ -272,12 +275,9 @@ _openssl_get_subject (X509 *cert, char *buf, int size)
goto err;
BIO_get_mem_ptr (subject_bio, &subject_mem);
if (subject == NULL)
{
maxlen = subject_mem->length + 1;
subject = malloc (maxlen);
check_malloc_return (subject);
}
maxlen = subject_mem->length + 1;
subject = gc_malloc (maxlen, false, gc);
memcpy (subject, subject_mem->data, maxlen);
subject[maxlen - 1] = '\0';
@ -289,19 +289,6 @@ err:
return subject;
}
char *
x509_get_subject (X509 *cert)
{
return _openssl_get_subject (cert, NULL, 0);
}
void
x509_free_subject (char *subject)
{
if (subject)
free(subject);
}
#ifdef ENABLE_X509_TRACK

View File

@ -47,6 +47,7 @@ verify_callback (void *session_obj, x509_cert *cert, int cert_depth,
int preverify_ok)
{
struct tls_session *session = (struct tls_session *) session_obj;
struct gc_arena gc = gc_new();
unsigned char *sha1_hash = NULL;
ASSERT (cert);
@ -62,21 +63,23 @@ verify_callback (void *session_obj, x509_cert *cert, int cert_depth,
/* did peer present cert which was signed by our root cert? */
if (!preverify_ok)
{
char subject[MAX_SUBJECT_LENGTH] = {0};
char *subject = x509_get_subject(cert, &gc);
/* get the X509 name */
if (x509parse_dn_gets( subject, MAX_SUBJECT_LENGTH, &cert->subject ) < 0)
msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, could not extract X509 "
"subject string from certificate", cert_depth);
else
if (subject)
msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, %s", cert_depth, subject);
else
msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, could not extract X509 "
"subject string from certificate", cert_depth);
gc_free(&gc);
return 1;
}
/*
* PolarSSL expects 1 on failure, 0 on success
*/
gc_free(&gc);
if (SUCCESS == verify_cert(session, cert, cert_depth))
return 0;
return 1;
@ -164,7 +167,7 @@ x509_free_sha1_hash (unsigned char *hash)
}
char *
x509_get_subject(x509_cert *cert)
x509_get_subject(x509_cert *cert, struct gc_arena *gc)
{
char tmp_subject[MAX_SUBJECT_LENGTH] = {0};
char *subject = NULL;
@ -175,19 +178,12 @@ x509_get_subject(x509_cert *cert)
if (ret > 0)
{
/* Allocate the required space for the subject */
subject = malloc(ret + 1);
strncpy(subject, tmp_subject, ret+1);
subject = string_alloc(tmp_subject, gc);
}
return subject;
}
void
x509_free_subject (char *subject)
{
if (subject)
free(subject);
}
/*
* Save X509 fields to environment, using the naming convention: