Increase the timeout after SIGUSR1 restart when restart is not
due to server_poll_timeout.
Version 2.1.3v
git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@7215 e7ae566f-a301-0410-adde-c780ea21d3b5
... | ... |
@@ -1706,9 +1706,11 @@ socket_restart_pause (struct context *c) |
1706 | 1706 |
if (auth_retry_get () == AR_NOINTERACT) |
1707 | 1707 |
sec = 10; |
1708 | 1708 |
|
1709 |
+#if 0 /* not really needed because of c->persist.restart_sleep_seconds */ |
|
1709 | 1710 |
if (c->options.server_poll_timeout && sec > 1) |
1710 | 1711 |
sec = 1; |
1711 | 1712 |
#endif |
1713 |
+#endif |
|
1712 | 1714 |
|
1713 | 1715 |
if (c->persist.restart_sleep_seconds > 0 && c->persist.restart_sleep_seconds > sec) |
1714 | 1716 |
sec = c->persist.restart_sleep_seconds; |
... | ... |
@@ -2057,6 +2059,7 @@ do_init_crypto_tls (struct context *c, const unsigned int flags) |
2057 | 2057 |
to.ns_cert_type = options->ns_cert_type; |
2058 | 2058 |
memmove (to.remote_cert_ku, options->remote_cert_ku, sizeof (to.remote_cert_ku)); |
2059 | 2059 |
to.remote_cert_eku = options->remote_cert_eku; |
2060 |
+ to.verify_hash = options->verify_hash; |
|
2060 | 2061 |
to.es = c->c2.es; |
2061 | 2062 |
|
2062 | 2063 |
#ifdef ENABLE_DEBUG |
... | ... |
@@ -3887,6 +3887,22 @@ that for certificate authority functions, you must set up the files |
3887 | 3887 |
). |
3888 | 3888 |
.\"********************************************************* |
3889 | 3889 |
.TP |
3890 |
+.B --extra-certs file |
|
3891 |
+Specify a |
|
3892 |
+.B file |
|
3893 |
+containing one or more PEM certs (concatenated together) |
|
3894 |
+that complete the |
|
3895 |
+local certificate chain. |
|
3896 |
+ |
|
3897 |
+This option is useful for "split" CAs, where the CA for server |
|
3898 |
+certs is different than the CA for client certs. Putting certs |
|
3899 |
+in this file allows them to be used to complete the local |
|
3900 |
+certificate chain without trusting them to verify the peer-submitted |
|
3901 |
+certificate, as would be the case if the certs were placed in the |
|
3902 |
+.B ca |
|
3903 |
+file. |
|
3904 |
+.\"********************************************************* |
|
3905 |
+.TP |
|
3890 | 3906 |
.B --key file |
3891 | 3907 |
Local peer's private key in .pem format. Use the private key which was generated |
3892 | 3908 |
when you built your peer's certificate (see |
... | ... |
@@ -3903,6 +3919,17 @@ and |
3903 | 3903 |
.B --key. |
3904 | 3904 |
.\"********************************************************* |
3905 | 3905 |
.TP |
3906 |
+.B --verify-hash hash |
|
3907 |
+Specify SHA1 fingerprint for level-1 cert. The level-1 cert is the |
|
3908 |
+CA (or intermediate cert) that signs the leaf certificate, and is |
|
3909 |
+one removed from the leaf certificate in the direction of the root. |
|
3910 |
+When accepting a connection from a peer, the level-1 cert |
|
3911 |
+fingerprint must match |
|
3912 |
+.B hash |
|
3913 |
+or certificate verification will fail. Hash is specified |
|
3914 |
+as XX:XX:... For example: AD:B0:95:D8:09:C8:36:45:12:A9:89:C8:90:09:CB:13:72:A6:AD:16 |
|
3915 |
+.\"********************************************************* |
|
3916 |
+.TP |
|
3906 | 3917 |
.B --pkcs11-cert-private [0|1]... |
3907 | 3918 |
Set if access to certificate object should be performed after login. |
3908 | 3919 |
Every provider has its own setting. |
... | ... |
@@ -507,9 +507,11 @@ static const char usage_message[] = |
507 | 507 |
" Use \"openssl dhparam -out dh1024.pem 1024\" to generate.\n" |
508 | 508 |
"--cert file : Local certificate in .pem format -- must be signed\n" |
509 | 509 |
" by a Certificate Authority in --ca file.\n" |
510 |
+ "--extra-certs file : one or more PEM certs that complete the cert chain.\n" |
|
510 | 511 |
"--key file : Local private key in .pem format.\n" |
511 | 512 |
"--pkcs12 file : PKCS#12 file containing local private key, local certificate\n" |
512 | 513 |
" and optionally the root CA certificate.\n" |
514 |
+ "--verify-hash : Specify SHA1 fingerprint for level-1 cert.\n" |
|
513 | 515 |
#ifdef WIN32 |
514 | 516 |
"--cryptoapicert select-string : Load the certificate and private key from the\n" |
515 | 517 |
" Windows Certificate System Store.\n" |
... | ... |
@@ -894,6 +896,40 @@ is_stateful_restart (const struct options *o) |
894 | 894 |
return is_persist_option (o) || connection_list_defined (o); |
895 | 895 |
} |
896 | 896 |
|
897 |
+#ifdef USE_SSL |
|
898 |
+static uint8_t * |
|
899 |
+parse_hash_fingerprint(const char *str, int nbytes, int msglevel, struct gc_arena *gc) |
|
900 |
+{ |
|
901 |
+ int i; |
|
902 |
+ const char *cp = str; |
|
903 |
+ uint8_t *ret = (uint8_t *) gc_malloc (nbytes, true, gc); |
|
904 |
+ char term = 1; |
|
905 |
+ int byte; |
|
906 |
+ char bs[3]; |
|
907 |
+ |
|
908 |
+ for (i = 0; i < nbytes; ++i) |
|
909 |
+ { |
|
910 |
+ if (strlen(cp) < 2) |
|
911 |
+ msg (msglevel, "format error in hash fingerprint: %s", str); |
|
912 |
+ bs[0] = *cp++; |
|
913 |
+ bs[1] = *cp++; |
|
914 |
+ bs[2] = 0; |
|
915 |
+ byte = 0; |
|
916 |
+ if (sscanf(bs, "%x", &byte) != 1) |
|
917 |
+ msg (msglevel, "format error in hash fingerprint hex byte: %s", str); |
|
918 |
+ ret[i] = (uint8_t)byte; |
|
919 |
+ term = *cp++; |
|
920 |
+ if (term != ':' && term != 0) |
|
921 |
+ msg (msglevel, "format error in hash fingerprint delimiter: %s", str); |
|
922 |
+ if (term == 0) |
|
923 |
+ break; |
|
924 |
+ } |
|
925 |
+ if (term != 0 || i != nbytes-1) |
|
926 |
+ msg (msglevel, "hash fingerprint is different length than expected (%d bytes): %s", nbytes, str); |
|
927 |
+ return ret; |
|
928 |
+} |
|
929 |
+#endif |
|
930 |
+ |
|
897 | 931 |
#ifdef WIN32 |
898 | 932 |
|
899 | 933 |
#ifdef ENABLE_DEBUG |
... | ... |
@@ -5758,6 +5794,22 @@ add_option (struct options *options, |
5758 | 5758 |
} |
5759 | 5759 |
#endif |
5760 | 5760 |
} |
5761 |
+ else if (streq (p[0], "extra-certs") && p[1]) |
|
5762 |
+ { |
|
5763 |
+ VERIFY_PERMISSION (OPT_P_GENERAL); |
|
5764 |
+ options->extra_certs_file = p[1]; |
|
5765 |
+#if ENABLE_INLINE_FILES |
|
5766 |
+ if (streq (p[1], INLINE_FILE_TAG) && p[2]) |
|
5767 |
+ { |
|
5768 |
+ options->extra_certs_file_inline = p[2]; |
|
5769 |
+ } |
|
5770 |
+#endif |
|
5771 |
+ } |
|
5772 |
+ else if (streq (p[0], "verify-hash") && p[1]) |
|
5773 |
+ { |
|
5774 |
+ VERIFY_PERMISSION (OPT_P_GENERAL); |
|
5775 |
+ options->verify_hash = parse_hash_fingerprint(p[1], SHA_DIGEST_LENGTH, msglevel, &options->gc); |
|
5776 |
+ } |
|
5761 | 5777 |
#ifdef WIN32 |
5762 | 5778 |
else if (streq (p[0], "cryptoapicert") && p[1]) |
5763 | 5779 |
{ |
... | ... |
@@ -477,6 +477,7 @@ struct options |
477 | 477 |
const char *ca_path; |
478 | 478 |
const char *dh_file; |
479 | 479 |
const char *cert_file; |
480 |
+ const char *extra_certs_file; |
|
480 | 481 |
const char *priv_key_file; |
481 | 482 |
const char *pkcs12_file; |
482 | 483 |
const char *cipher_list; |
... | ... |
@@ -487,6 +488,7 @@ struct options |
487 | 487 |
#if ENABLE_INLINE_FILES |
488 | 488 |
const char *ca_file_inline; |
489 | 489 |
const char *cert_file_inline; |
490 |
+ const char *extra_certs_file_inline; |
|
490 | 491 |
char *priv_key_file_inline; |
491 | 492 |
const char *dh_file_inline; |
492 | 493 |
const char *pkcs12_file_inline; /* contains the base64 encoding of pkcs12 file */ |
... | ... |
@@ -495,6 +497,7 @@ struct options |
495 | 495 |
int ns_cert_type; /* set to 0, NS_SSL_SERVER, or NS_SSL_CLIENT */ |
496 | 496 |
unsigned remote_cert_ku[MAX_PARMS]; |
497 | 497 |
const char *remote_cert_eku; |
498 |
+ uint8_t *verify_hash; |
|
498 | 499 |
|
499 | 500 |
#ifdef ENABLE_PKCS11 |
500 | 501 |
const char *pkcs11_providers[MAX_PARMS]; |
... | ... |
@@ -910,6 +910,16 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx) |
910 | 910 |
goto err; /* Reject connection */ |
911 | 911 |
} |
912 | 912 |
|
913 |
+ /* verify level 1 cert, i.e. the CA that signed our leaf cert */ |
|
914 |
+ if (ctx->error_depth == 1 && opt->verify_hash) |
|
915 |
+ { |
|
916 |
+ if (memcmp (ctx->current_cert->sha1_hash, opt->verify_hash, SHA_DIGEST_LENGTH)) |
|
917 |
+ { |
|
918 |
+ msg (D_TLS_ERRORS, "TLS Error: level-1 certificate hash verification failed"); |
|
919 |
+ goto err; |
|
920 |
+ } |
|
921 |
+ } |
|
922 |
+ |
|
913 | 923 |
/* save common name in session object */ |
914 | 924 |
if (ctx->error_depth == 0) |
915 | 925 |
set_common_name (session, common_name); |
... | ... |
@@ -2140,6 +2150,37 @@ init_ssl (const struct options *options) |
2140 | 2140 |
msg (M_SSLERR, "Cannot load certificate chain file %s (SSL_use_certificate_chain_file)", options->cert_file); |
2141 | 2141 |
} |
2142 | 2142 |
|
2143 |
+ /* Load extra certificates that are part of our own certificate |
|
2144 |
+ chain but shouldn't be included in the verify chain */ |
|
2145 |
+ if (options->extra_certs_file || options->extra_certs_file_inline) |
|
2146 |
+ { |
|
2147 |
+ BIO *bio; |
|
2148 |
+ X509 *cert; |
|
2149 |
+#if ENABLE_INLINE_FILES |
|
2150 |
+ if (!strcmp (options->extra_certs_file, INLINE_FILE_TAG) && options->extra_certs_file_inline) |
|
2151 |
+ { |
|
2152 |
+ bio = BIO_new_mem_buf ((char *)options->extra_certs_file_inline, -1); |
|
2153 |
+ } |
|
2154 |
+ else |
|
2155 |
+#endif |
|
2156 |
+ { |
|
2157 |
+ bio = BIO_new(BIO_s_file()); |
|
2158 |
+ if (BIO_read_filename(bio, options->extra_certs_file) <= 0) |
|
2159 |
+ msg (M_SSLERR, "Cannot load extra-certs file: %s", options->extra_certs_file); |
|
2160 |
+ } |
|
2161 |
+ for (;;) |
|
2162 |
+ { |
|
2163 |
+ cert = NULL; |
|
2164 |
+ if (!PEM_read_bio_X509 (bio, &cert, 0, NULL)) /* takes ownership of cert */ |
|
2165 |
+ break; |
|
2166 |
+ if (!cert) |
|
2167 |
+ msg (M_SSLERR, "Error reading extra-certs certificate"); |
|
2168 |
+ if (SSL_CTX_add_extra_chain_cert(ctx, cert) != 1) |
|
2169 |
+ msg (M_SSLERR, "Error adding extra-certs certificate"); |
|
2170 |
+ } |
|
2171 |
+ BIO_free (bio); |
|
2172 |
+ } |
|
2173 |
+ |
|
2143 | 2174 |
/* Require peer certificate verification */ |
2144 | 2175 |
#if P2MP_SERVER |
2145 | 2176 |
if (options->ssl_flags & SSLF_CLIENT_CERT_NOT_REQUIRED) |