summaryrefslogtreecommitdiff
path: root/app/openvpn/src/openvpn/ssl_verify_polarssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/openvpn/src/openvpn/ssl_verify_polarssl.c')
-rw-r--r--app/openvpn/src/openvpn/ssl_verify_polarssl.c178
1 files changed, 86 insertions, 92 deletions
diff --git a/app/openvpn/src/openvpn/ssl_verify_polarssl.c b/app/openvpn/src/openvpn/ssl_verify_polarssl.c
index a32db8df..71d38a9d 100644
--- a/app/openvpn/src/openvpn/ssl_verify_polarssl.c
+++ b/app/openvpn/src/openvpn/ssl_verify_polarssl.c
@@ -38,17 +38,19 @@
#if defined(ENABLE_SSL) && defined(ENABLE_CRYPTO_POLARSSL)
#include "ssl_verify.h"
+#include <polarssl/error.h>
+#include <polarssl/bignum.h>
+#include <polarssl/oid.h>
#include <polarssl/sha1.h>
#define MAX_SUBJECT_LENGTH 256
int
-verify_callback (void *session_obj, x509_cert *cert, int cert_depth,
- int preverify_ok)
+verify_callback (void *session_obj, x509_crt *cert, int cert_depth,
+ int *flags)
{
struct tls_session *session = (struct tls_session *) session_obj;
struct gc_arena gc = gc_new();
- int ret = 1;
ASSERT (cert);
ASSERT (session);
@@ -59,31 +61,29 @@ verify_callback (void *session_obj, x509_cert *cert, int cert_depth,
cert_hash_remember (session, cert_depth, x509_get_sha1_hash(cert, &gc));
/* did peer present cert which was signed by our root cert? */
- if (!preverify_ok)
+ if (*flags != 0)
{
char *subject = x509_get_subject(cert, &gc);
if (subject)
- msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, %s", cert_depth, subject);
+ msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, flags=%x, %s", cert_depth, *flags, subject);
else
- msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, could not extract X509 "
- "subject string from certificate", cert_depth);
+ msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, flags=%x, could not extract X509 "
+ "subject string from certificate", *flags, cert_depth);
- goto cleanup;
+ /* Leave flags set to non-zero to indicate that the cert is not ok */
+ }
+ else if (SUCCESS != verify_cert(session, cert, cert_depth))
+ {
+ *flags |= BADCERT_OTHER;
}
- if (SUCCESS != verify_cert(session, cert, cert_depth))
- goto cleanup;
-
- ret = 0;
-
-cleanup:
gc_free(&gc);
/*
- * PolarSSL expects 1 on failure, 0 on success
+ * PolarSSL-1.2.0+ expects 0 on anything except fatal errors.
*/
- return ret;
+ return 0;
}
#ifdef ENABLE_X509ALTUSERNAME
@@ -91,8 +91,8 @@ cleanup:
#endif
result_t
-x509_get_username (char *cn, int cn_len,
- char *x509_username_field, x509_cert *cert)
+backend_x509_get_username (char *cn, int cn_len,
+ char *x509_username_field, x509_crt *cert)
{
x509_name *name;
@@ -103,7 +103,7 @@ x509_get_username (char *cn, int cn_len,
/* Find common name */
while( name != NULL )
{
- if( memcmp( name->oid.p, OID_CN, OID_SIZE(OID_CN) ) == 0)
+ if( memcmp( name->oid.p, OID_AT_CN, OID_SIZE(OID_AT_CN) ) == 0)
break;
name = name->next;
@@ -126,23 +126,59 @@ x509_get_username (char *cn, int cn_len,
}
char *
-x509_get_serial (x509_cert *cert, struct gc_arena *gc)
+backend_x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc)
+{
+ char *buf = NULL;
+ size_t buflen = 0;
+ mpi serial_mpi = { 0 };
+ int retval = 0;
+
+ /* Transform asn1 integer serial into PolarSSL MPI */
+ mpi_init(&serial_mpi);
+ retval = mpi_read_binary(&serial_mpi, cert->serial.p, cert->serial.len);
+ if (retval < 0)
+ {
+ char errbuf[128];
+ polarssl_strerror(retval, errbuf, sizeof(errbuf));
+
+ msg(M_WARN, "Failed to retrieve serial from certificate: %s.", errbuf);
+ return NULL;
+ }
+
+ /* Determine decimal representation length, allocate buffer */
+ mpi_write_string(&serial_mpi, 10, buf, &buflen);
+ buf = gc_malloc(buflen, true, gc);
+
+ /* Write MPI serial as decimal string into buffer */
+ retval = mpi_write_string(&serial_mpi, 10, buf, &buflen);
+ if (retval < 0)
+ {
+ char errbuf[128];
+ polarssl_strerror(retval, errbuf, sizeof(errbuf));
+
+ msg(M_WARN, "Failed to write serial to string: %s.", errbuf);
+ return NULL;
+ }
+
+ return buf;
+}
+
+char *
+backend_x509_get_serial_hex (openvpn_x509_cert_t *cert, struct gc_arena *gc)
{
- int ret = 0;
- int i = 0;
char *buf = NULL;
size_t len = cert->serial.len * 3 + 1;
buf = gc_malloc(len, true, gc);
- if(x509parse_serial_gets(buf, len-1, &cert->serial) < 0)
+ if(x509_serial_gets(buf, len-1, &cert->serial) < 0)
buf = NULL;
return buf;
}
unsigned char *
-x509_get_sha1_hash (x509_cert *cert, struct gc_arena *gc)
+x509_get_sha1_hash (x509_crt *cert, struct gc_arena *gc)
{
unsigned char *sha1_hash = gc_malloc(SHA_DIGEST_LENGTH, false, gc);
sha1(cert->tbs.p, cert->tbs.len, sha1_hash);
@@ -150,14 +186,14 @@ x509_get_sha1_hash (x509_cert *cert, struct gc_arena *gc)
}
char *
-x509_get_subject(x509_cert *cert, struct gc_arena *gc)
+x509_get_subject(x509_crt *cert, struct gc_arena *gc)
{
char tmp_subject[MAX_SUBJECT_LENGTH] = {0};
char *subject = NULL;
int ret = 0;
- ret = x509parse_dn_gets( tmp_subject, MAX_SUBJECT_LENGTH-1, &cert->subject );
+ ret = x509_dn_gets( tmp_subject, MAX_SUBJECT_LENGTH-1, &cert->subject );
if (ret > 0)
{
/* Allocate the required space for the subject */
@@ -187,70 +223,28 @@ x509_setenv (struct env_set *es, int cert_depth, openvpn_x509_cert_t *cert)
while( name != NULL )
{
char name_expand[64+8];
+ const char *shortname;
- if( name->oid.len == 2 && memcmp( name->oid.p, OID_X520, 2 ) == 0 )
+ if( 0 == oid_get_attr_short_name(&name->oid, &shortname) )
{
- switch( name->oid.p[2] )
- {
- case X520_COMMON_NAME:
- openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_CN",
- cert_depth); break;
-
- case X520_COUNTRY:
- openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_C",
- cert_depth); break;
-
- case X520_LOCALITY:
- openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_L",
- cert_depth); break;
-
- case X520_STATE:
- openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_ST",
- cert_depth); break;
-
- case X520_ORGANIZATION:
- openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_O",
- cert_depth); break;
-
- case X520_ORG_UNIT:
- openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_OU",
- cert_depth); break;
-
- default:
- openvpn_snprintf (name_expand, sizeof(name_expand),
- "X509_%d_0x%02X", cert_depth, name->oid.p[2]);
- break;
- }
+ openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_%s",
+ cert_depth, shortname);
}
- else if( name->oid.len == 8 && memcmp( name->oid.p, OID_PKCS9, 8 ) == 0 )
- {
- switch( name->oid.p[8] )
- {
- case PKCS9_EMAIL:
- openvpn_snprintf (name_expand, sizeof(name_expand),
- "X509_%d_emailAddress", cert_depth); break;
-
- default:
- openvpn_snprintf (name_expand, sizeof(name_expand),
- "X509_%d_0x%02X", cert_depth, name->oid.p[8]);
- break;
- }
- }
- else
- {
- openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_\?\?",
- cert_depth);
- }
-
- for( i = 0; i < name->val.len; i++ )
+ else
+ {
+ openvpn_snprintf (name_expand, sizeof(name_expand), "X509_%d_\?\?",
+ cert_depth);
+ }
+
+ for( i = 0; i < name->val.len; i++ )
{
- if( i >= (int) sizeof( s ) - 1 )
- break;
+ if( i >= (int) sizeof( s ) - 1 )
+ break;
- c = name->val.p[i];
- if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
- s[i] = '?';
- else s[i] = c;
+ c = name->val.p[i];
+ if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
+ s[i] = '?';
+ else s[i] = c;
}
s[i] = '\0';
@@ -264,7 +258,7 @@ x509_setenv (struct env_set *es, int cert_depth, openvpn_x509_cert_t *cert)
}
result_t
-x509_verify_ns_cert_type(const x509_cert *cert, const int usage)
+x509_verify_ns_cert_type(const x509_crt *cert, const int usage)
{
if (usage == NS_CERT_CHECK_NONE)
return SUCCESS;
@@ -279,7 +273,7 @@ x509_verify_ns_cert_type(const x509_cert *cert, const int usage)
}
result_t
-x509_verify_cert_ku (x509_cert *cert, const unsigned * const expected_ku,
+x509_verify_cert_ku (x509_crt *cert, const unsigned * const expected_ku,
int expected_len)
{
result_t fFound = FAILURE;
@@ -312,7 +306,7 @@ x509_verify_cert_ku (x509_cert *cert, const unsigned * const expected_ku,
}
result_t
-x509_verify_cert_eku (x509_cert *cert, const char * const expected_oid)
+x509_verify_cert_eku (x509_crt *cert, const char * const expected_oid)
{
result_t fFound = FAILURE;
@@ -362,7 +356,7 @@ x509_verify_cert_eku (x509_cert *cert, const char * const expected_oid)
}
result_t
-x509_write_pem(FILE *peercert_file, x509_cert *peercert)
+x509_write_pem(FILE *peercert_file, x509_crt *peercert)
{
msg (M_WARN, "PolarSSL does not support writing peer certificate in PEM format");
return FAILURE;
@@ -372,12 +366,12 @@ x509_write_pem(FILE *peercert_file, x509_cert *peercert)
* check peer cert against CRL
*/
result_t
-x509_verify_crl(const char *crl_file, x509_cert *cert, const char *subject)
+x509_verify_crl(const char *crl_file, x509_crt *cert, const char *subject)
{
result_t retval = FAILURE;
x509_crl crl = {0};
- if (x509parse_crlfile(&crl, crl_file) != 0)
+ if (x509_crl_parse_file(&crl, crl_file) != 0)
{
msg (M_ERR, "CRL: cannot read CRL from file %s", crl_file);
goto end;
@@ -392,7 +386,7 @@ x509_verify_crl(const char *crl_file, x509_cert *cert, const char *subject)
goto end;
}
- if (0 != x509parse_revoked(cert, &crl))
+ if (0 != x509_crt_revoked(cert, &crl))
{
msg (D_HANDSHAKE, "CRL CHECK FAILED: %s is REVOKED", subject);
goto end;