In verify_callback, read X509 Subject Name without truncation.
In verify_callback, rather than silently truncating Common Name at
64 bytes, throw an error if Common Name is larger than 64 bytes.
git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@3084 e7ae566f-a301-0410-adde-c780ea21d3b5
... | ... |
@@ -347,8 +347,11 @@ tmp_rsa_cb (SSL * s, int is_export, int keylength) |
347 | 347 |
* /C=US/ST=CO/L=Denver/O=ORG/CN=First-CN/CN=Test-CA/Email=jim@yonan.net |
348 | 348 |
* |
349 | 349 |
* The common name is 'Test-CA' |
350 |
+ * |
|
351 |
+ * Return true on success, false on error (insufficient buffer size in 'out' |
|
352 |
+ * to contain result is grounds for error). |
|
350 | 353 |
*/ |
351 |
-static void |
|
354 |
+static bool |
|
352 | 355 |
extract_x509_field_ssl (X509_NAME *x509, const char *field_name, char *out, int size) |
353 | 356 |
{ |
354 | 357 |
int lastpos = -1; |
... | ... |
@@ -367,21 +370,26 @@ extract_x509_field_ssl (X509_NAME *x509, const char *field_name, char *out, int |
367 | 367 |
|
368 | 368 |
/* Nothing found */ |
369 | 369 |
if (lastpos == -1) |
370 |
- return; |
|
370 |
+ return false; |
|
371 | 371 |
|
372 | 372 |
x509ne = X509_NAME_get_entry(x509, lastpos); |
373 | 373 |
if (!x509ne) |
374 |
- return; |
|
374 |
+ return false; |
|
375 | 375 |
|
376 | 376 |
asn1 = X509_NAME_ENTRY_get_data(x509ne); |
377 | 377 |
if (!asn1) |
378 |
- return; |
|
378 |
+ return false; |
|
379 | 379 |
tmp = ASN1_STRING_to_UTF8(&buf, asn1); |
380 | 380 |
if (tmp <= 0) |
381 |
- return; |
|
381 |
+ return false; |
|
382 | 382 |
|
383 | 383 |
strncpynt(out, (char *)buf, size); |
384 |
- OPENSSL_free(buf); |
|
384 |
+ |
|
385 |
+ { |
|
386 |
+ const bool ret = (strlen ((char *)buf) < size); |
|
387 |
+ OPENSSL_free (buf); |
|
388 |
+ return ret; |
|
389 |
+ } |
|
385 | 390 |
} |
386 | 391 |
|
387 | 392 |
static void |
... | ... |
@@ -529,7 +537,7 @@ print_nsCertType (int type) |
529 | 529 |
static int |
530 | 530 |
verify_callback (int preverify_ok, X509_STORE_CTX * ctx) |
531 | 531 |
{ |
532 |
- char subject[256]; |
|
532 |
+ char *subject = NULL; |
|
533 | 533 |
char envname[64]; |
534 | 534 |
char common_name[TLS_CN_LEN]; |
535 | 535 |
SSL *ssl; |
... | ... |
@@ -548,22 +556,28 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx) |
548 | 548 |
session->verified = false; |
549 | 549 |
|
550 | 550 |
/* get the X509 name */ |
551 |
- X509_NAME_oneline (X509_get_subject_name (ctx->current_cert), subject, |
|
552 |
- sizeof (subject)); |
|
553 |
- subject[sizeof (subject) - 1] = '\0'; |
|
551 |
+ subject = X509_NAME_oneline (X509_get_subject_name (ctx->current_cert), NULL, 0); |
|
552 |
+ if (!subject) |
|
553 |
+ { |
|
554 |
+ msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, could not extract X509 subject string from certificate", ctx->error_depth); |
|
555 |
+ goto err; |
|
556 |
+ } |
|
554 | 557 |
|
555 | 558 |
/* enforce character class restrictions in X509 name */ |
556 | 559 |
string_mod (subject, X509_NAME_CHAR_CLASS, 0, '_'); |
557 | 560 |
string_replace_leading (subject, '-', '_'); |
558 | 561 |
|
559 |
- msg (M_INFO, "X509: '%s'", subject); // JYFIXME |
|
560 |
- |
|
561 | 562 |
/* extract the common name */ |
562 |
-#ifdef USE_OLD_EXTRACT_X509_FIELD |
|
563 |
- extract_x509_field (subject, "CN", common_name, TLS_CN_LEN); |
|
564 |
-#else |
|
565 |
- extract_x509_field_ssl (X509_get_subject_name (ctx->current_cert), "CN", common_name, TLS_CN_LEN); |
|
566 |
-#endif |
|
563 |
+ if (!extract_x509_field_ssl (X509_get_subject_name (ctx->current_cert), "CN", common_name, TLS_CN_LEN)) |
|
564 |
+ { |
|
565 |
+ if (!ctx->error_depth) |
|
566 |
+ { |
|
567 |
+ msg (D_TLS_ERRORS, "VERIFY ERROR: could not extract Common Name from X509 subject string ('%s') -- note that the Common Name length is limited to %d characters", |
|
568 |
+ subject, |
|
569 |
+ TLS_CN_LEN); |
|
570 |
+ goto err; |
|
571 |
+ } |
|
572 |
+ } |
|
567 | 573 |
|
568 | 574 |
string_mod (common_name, COMMON_NAME_CHAR_CLASS, 0, '_'); |
569 | 575 |
|
... | ... |
@@ -786,10 +800,12 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx) |
786 | 786 |
msg (D_HANDSHAKE, "VERIFY OK: depth=%d, %s", ctx->error_depth, subject); |
787 | 787 |
|
788 | 788 |
session->verified = true; |
789 |
+ free (subject); |
|
789 | 790 |
return 1; /* Accept connection */ |
790 | 791 |
|
791 | 792 |
err: |
792 | 793 |
ERR_clear_error (); |
794 |
+ free (subject); |
|
793 | 795 |
return 0; /* Reject connection */ |
794 | 796 |
} |
795 | 797 |
|
... | ... |
@@ -3291,7 +3307,14 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi |
3291 | 3291 |
s1 = verify_user_pass_plugin (session, up, raw_username); |
3292 | 3292 |
if (session->opt->auth_user_pass_verify_script) |
3293 | 3293 |
s2 = verify_user_pass_script (session, up); |
3294 |
- |
|
3294 |
+ |
|
3295 |
+ /* check sizing of username if it will become our common name */ |
|
3296 |
+ if (session->opt->username_as_common_name && strlen (up->username) >= TLS_CN_LEN) |
|
3297 |
+ { |
|
3298 |
+ msg (D_TLS_ERRORS, "TLS Auth Error: --username-as-common name specified and username is longer than the maximum permitted Common Name length of %d characters", TLS_CN_LEN); |
|
3299 |
+ s1 = OPENVPN_PLUGIN_FUNC_ERROR; |
|
3300 |
+ } |
|
3301 |
+ |
|
3295 | 3302 |
/* auth succeeded? */ |
3296 | 3303 |
if ((s1 == OPENVPN_PLUGIN_FUNC_SUCCESS |
3297 | 3304 |
#ifdef PLUGIN_DEF_AUTH |
... | ... |
@@ -4783,25 +4806,6 @@ done: |
4783 | 4783 |
return BSTR (&out); |
4784 | 4784 |
} |
4785 | 4785 |
|
4786 |
-#ifdef EXTRACT_X509_FIELD_TEST |
|
4787 |
- |
|
4788 |
-void |
|
4789 |
-extract_x509_field_test (void) |
|
4790 |
-{ |
|
4791 |
- char line[8]; |
|
4792 |
- char field[4]; |
|
4793 |
- static const char field_name[] = "CN"; |
|
4794 |
- |
|
4795 |
- while (fgets (line, sizeof (line), stdin)) |
|
4796 |
- { |
|
4797 |
- chomp (line); |
|
4798 |
- extract_x509_field (line, field_name, field, sizeof (field)); |
|
4799 |
- printf ("CN: '%s'\n", field); |
|
4800 |
- } |
|
4801 |
-} |
|
4802 |
- |
|
4803 |
-#endif |
|
4804 |
- |
|
4805 | 4786 |
#else |
4806 | 4787 |
static void dummy(void) {} |
4807 | 4788 |
#endif /* USE_CRYPTO && USE_SSL*/ |