Browse code

Final cleanup before PolarSSL addition:

- Remove stray X509 entries
- Remove unnecessary USE_OPENSSL ifdefs
- Normalised x509_get_sha1_hash to look similar to x509_get_* functions

Signed-off-by: Adriaan de Jong <dejong@fox-it.com>
Acked-by: James Yonan <james@openvpn.net>
Signed-off-by: David Sommerseth <davids@redhat.com>

Adriaan de Jong authored on 2011/07/01 21:39:13
Showing 6 changed files
... ...
@@ -345,7 +345,7 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)
345 345
 #ifdef MANAGMENT_EXTERNAL_KEY
346 346
   else if ((options->management_flags & MF_EXTERNAL_KEY) && options->cert_file)
347 347
     {
348
-      X509 *my_cert = NULL;
348
+      x509_cert_t *my_cert = NULL;
349 349
       tls_ctx_load_cert_file(new_ctx, options->cert_file, options->cert_file_inline,
350 350
 	  &my_cert);
351 351
       tls_ctx_use_external_private_key(new_ctx, my_cert);
... ...
@@ -173,6 +173,8 @@ void tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert
173 173
  * Load certificate file into the given TLS context. If the given certificate
174 174
  * file contains a certificate chain, load the whole chain.
175 175
  *
176
+ * If the x509 parameter is not NULL, the certificate will be returned in it.
177
+ *
176 178
  * @param ctx			TLS context to use
177 179
  * @param cert_file		The file name to load the certificate from, or
178 180
  * 				"[[INLINE]]" in the case of inline files.
... ...
@@ -186,7 +188,7 @@ void tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file,
186 186
 #if ENABLE_INLINE_FILES
187 187
     const char *cert_file_inline,
188 188
 #endif
189
-    X509 **x509
189
+    x509_cert_t **x509
190 190
     );
191 191
 
192 192
 /**
... ...
@@ -219,7 +221,7 @@ int tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file
219 219
  * @return 			1 if an error occurred, 0 if parsing was
220 220
  * 				successful.
221 221
  */
222
-int tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, X509 *cert);
222
+int tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, x509_cert_t *cert);
223 223
 
224 224
 #endif
225 225
 
... ...
@@ -809,7 +809,41 @@ tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file,
809 809
       msg (M_SSLERR, "Cannot load CA certificate file %s (SSL_load_client_CA_file)", ca_file);
810 810
     SSL_CTX_set_client_CA_list (ctx->ctx, cert_names);
811 811
   }
812
+}
813
+
812 814
 
815
+void
816
+tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file
817
+#if ENABLE_INLINE_FILES
818
+    , const char *extra_certs_file_inline
819
+#endif
820
+    )
821
+{
822
+  BIO *bio;
823
+  X509 *cert;
824
+#if ENABLE_INLINE_FILES
825
+  if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_file_inline)
826
+    {
827
+      bio = BIO_new_mem_buf ((char *)extra_certs_file_inline, -1);
828
+    }
829
+  else
830
+#endif
831
+    {
832
+      bio = BIO_new(BIO_s_file());
833
+      if (BIO_read_filename(bio, extra_certs_file) <= 0)
834
+	msg (M_SSLERR, "Cannot load extra-certs file: %s", extra_certs_file);
835
+    }
836
+  for (;;)
837
+    {
838
+      cert = NULL;
839
+      if (!PEM_read_bio_X509 (bio, &cert, 0, NULL)) /* takes ownership of cert */
840
+	break;
841
+      if (!cert)
842
+	msg (M_SSLERR, "Error reading extra-certs certificate");
843
+      if (SSL_CTX_add_extra_chain_cert(ctx->ctx, cert) != 1)
844
+	msg (M_SSLERR, "Error adding extra-certs certificate");
845
+    }
846
+  BIO_free (bio);
813 847
 }
814 848
 
815 849
 /* **************************************
... ...
@@ -1099,11 +1133,9 @@ key_state_write_plaintext_const (struct key_state_ssl *ks_ssl, const uint8_t *da
1099 1099
   int ret = 0;
1100 1100
   perf_push (PERF_BIO_WRITE_PLAINTEXT);
1101 1101
 
1102
-#ifdef USE_OPENSSL
1103 1102
   ASSERT (NULL != ks_ssl);
1104 1103
 
1105 1104
   ret = bio_write (ks_ssl->ssl_bio, data, len, "tls_write_plaintext_const");
1106
-#endif /* USE_OPENSSL */
1107 1105
 
1108 1106
   perf_pop ();
1109 1107
   return ret;
... ...
@@ -1116,11 +1148,9 @@ key_state_read_ciphertext (struct key_state_ssl *ks_ssl, struct buffer *buf,
1116 1116
   int ret = 0;
1117 1117
   perf_push (PERF_BIO_READ_CIPHERTEXT);
1118 1118
 
1119
-#ifdef USE_OPENSSL
1120 1119
   ASSERT (NULL != ks_ssl);
1121 1120
 
1122 1121
   ret = bio_read (ks_ssl->ct_out, buf, maxlen, "tls_read_ciphertext");
1123
-#endif /* USE_OPENSSL */
1124 1122
 
1125 1123
   perf_pop ();
1126 1124
   return ret;
... ...
@@ -1132,12 +1162,10 @@ key_state_write_ciphertext (struct key_state_ssl *ks_ssl, struct buffer *buf)
1132 1132
   int ret = 0;
1133 1133
   perf_push (PERF_BIO_WRITE_CIPHERTEXT);
1134 1134
 
1135
-#ifdef USE_OPENSSL
1136 1135
   ASSERT (NULL != ks_ssl);
1137 1136
 
1138 1137
   ret = bio_write (ks_ssl->ct_in, BPTR(buf), BLEN(buf), "tls_write_ciphertext");
1139 1138
   bio_write_post (ret, buf);
1140
-#endif /* USE_OPENSSL */
1141 1139
 
1142 1140
   perf_pop ();
1143 1141
   return ret;
... ...
@@ -1150,11 +1178,9 @@ key_state_read_plaintext (struct key_state_ssl *ks_ssl, struct buffer *buf,
1150 1150
   int ret = 0;
1151 1151
   perf_push (PERF_BIO_READ_PLAINTEXT);
1152 1152
 
1153
-#ifdef USE_OPENSSL
1154 1153
   ASSERT (NULL != ks_ssl);
1155 1154
 
1156 1155
   ret = bio_read (ks_ssl->ssl_bio, buf, maxlen, "tls_read_plaintext");
1157
-#endif /* USE_OPENSSL */
1158 1156
 
1159 1157
   perf_pop ();
1160 1158
   return ret;
... ...
@@ -1210,40 +1236,6 @@ print_details (struct key_state_ssl * ks_ssl, const char *prefix)
1210 1210
 }
1211 1211
 
1212 1212
 void
1213
-tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file
1214
-#if ENABLE_INLINE_FILES
1215
-    , const char *extra_certs_file_inline
1216
-#endif
1217
-    )
1218
-{
1219
-  BIO *bio;
1220
-  X509 *cert;
1221
-#if ENABLE_INLINE_FILES
1222
-  if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_file_inline)
1223
-    {
1224
-      bio = BIO_new_mem_buf ((char *)extra_certs_file_inline, -1);
1225
-    }
1226
-  else
1227
-#endif
1228
-    {
1229
-      bio = BIO_new(BIO_s_file());
1230
-      if (BIO_read_filename(bio, extra_certs_file) <= 0)
1231
-	msg (M_SSLERR, "Cannot load extra-certs file: %s", extra_certs_file);
1232
-    }
1233
-  for (;;)
1234
-    {
1235
-      cert = NULL;
1236
-      if (!PEM_read_bio_X509 (bio, &cert, 0, NULL)) /* takes ownership of cert */
1237
-	break;
1238
-      if (!cert)
1239
-	msg (M_SSLERR, "Error reading extra-certs certificate");
1240
-      if (SSL_CTX_add_extra_chain_cert(ctx->ctx, cert) != 1)
1241
-	msg (M_SSLERR, "Error adding extra-certs certificate");
1242
-    }
1243
-  BIO_free (bio);
1244
-}
1245
-
1246
-void
1247 1213
 show_available_tls_ciphers ()
1248 1214
 {
1249 1215
   SSL_CTX *ctx;
... ...
@@ -433,9 +433,12 @@ verify_cert_set_env(struct env_set *es, x509_cert_t *peer_cert, int cert_depth,
433 433
   /* export X509 cert SHA1 fingerprint */
434 434
   {
435 435
     struct gc_arena gc = gc_new ();
436
+    unsigned char *sha1_hash = x509_get_sha1_hash(peer_cert);
437
+
436 438
     openvpn_snprintf (envname, sizeof(envname), "tls_digest_%d", cert_depth);
437
-    setenv_str (es, envname,
438
-	  format_hex_ex(peer_cert->sha1_hash, SHA_DIGEST_LENGTH, 0, 1, ":", &gc));
439
+    setenv_str (es, envname, format_hex_ex(sha1_hash, SHA_DIGEST_LENGTH, 0, 1,
440
+					  ":", &gc));
441
+    x509_free_sha1_hash(sha1_hash);
439 442
     gc_free(&gc);
440 443
   }
441 444
 #endif
... ...
@@ -536,7 +539,7 @@ verify_cert_call_command(const char *verify_command, struct env_set *es,
536 536
  * check peer cert against CRL directory
537 537
  */
538 538
 static bool
539
-verify_check_crl_dir(const char *crl_dir, X509 *cert)
539
+verify_check_crl_dir(const char *crl_dir, x509_cert_t *cert)
540 540
 {
541 541
   char fn[256];
542 542
   int fd;
... ...
@@ -615,11 +618,14 @@ verify_cert(struct tls_session *session, x509_cert_t *cert, int cert_depth)
615 615
   /* verify level 1 cert, i.e. the CA that signed our leaf cert */
616 616
   if (cert_depth == 1 && opt->verify_hash)
617 617
     {
618
-      if (memcmp (cert->sha1_hash, opt->verify_hash, SHA_DIGEST_LENGTH))
618
+      unsigned char *sha1_hash = x509_get_sha1_hash(cert);
619
+      if (memcmp (sha1_hash, opt->verify_hash, SHA_DIGEST_LENGTH))
619 620
       {
620 621
 	msg (D_TLS_ERRORS, "TLS Error: level-1 certificate hash verification failed");
622
+	x509_free_sha1_hash(sha1_hash);
621 623
 	goto err;
622 624
       }
625
+      x509_free_sha1_hash(sha1_hash);
623 626
     }
624 627
 
625 628
   /* save common name in session object */
... ...
@@ -73,7 +73,7 @@ void cert_hash_remember (struct tls_session *session, const int cert_depth,
73 73
  */
74 74
 
75 75
 /*
76
- * Retrieve certificate's subject name, and place it in **subject.
76
+ * Retrieve certificate's subject name.
77 77
  *
78 78
  * The returned string must be freed with \c verify_free_subject()
79 79
  *
... ...
@@ -84,12 +84,30 @@ void cert_hash_remember (struct tls_session *session, const int cert_depth,
84 84
 char *x509_get_subject (x509_cert_t *cert);
85 85
 
86 86
 /*
87
- * Free a subjectnumber string as returned by \c verify_get_subject()
87
+ * Free a subject string as returned by \c verify_get_subject()
88 88
  *
89 89
  * @param subject	The subject to be freed.
90 90
  */
91 91
 void x509_free_subject (char *subject);
92 92
 
93
+/* Retrieve the certificate's SHA1 hash.
94
+ *
95
+ * The returned string must be freed with \c verify_free_sha1_hash()
96
+ *
97
+ * @param cert		Certificate to retrieve the hash from.
98
+ *
99
+ * @return 		a string containing the SHA1 hash of the certificate
100
+ */
101
+
102
+unsigned char *x509_get_sha1_hash (x509_cert_t *cert);
103
+
104
+/*
105
+ * Free a hash as returned by \c verify_get_hash()
106
+ *
107
+ * @param hash		The subject to be freed.
108
+ */
109
+void x509_free_sha1_hash (unsigned char *hash);
110
+
93 111
 /*
94 112
  * Retrieve the certificate's username from the specified field.
95 113
  *
... ...
@@ -126,7 +144,9 @@ char *x509_get_serial (x509_cert_t *cert);
126 126
 void x509_free_serial (char *serial);
127 127
 
128 128
 /*
129
- * TODO: document
129
+ * Save X509 fields to environment, using the naming convention:
130
+ *
131
+ * X509_{cert_depth}_{name}={value}
130 132
  *
131 133
  * @param xt
132 134
  * @param es		Environment set to save variables in
... ...
@@ -160,6 +180,8 @@ void x509_setenv (struct env_set *es, int cert_depth, x509_cert_t *cert);
160 160
  */
161 161
 bool x509_verify_ns_cert_type(const x509_cert_t *cert, const int usage);
162 162
 
163
+#if OPENSSL_VERSION_NUMBER >= 0x00907000L || USE_POLARSSL
164
+
163 165
 /*
164 166
  * Verify X.509 key usage extension field.
165 167
  *
... ...
@@ -188,6 +210,8 @@ bool x509_verify_cert_ku (x509_cert_t *x509, const unsigned * const expected_ku,
188 188
  */
189 189
 bool x509_verify_cert_eku (x509_cert_t *x509, const char * const expected_oid);
190 190
 
191
+#endif
192
+
191 193
 /*
192 194
  * Store the given certificate in pem format in a temporary file in tmp_dir
193 195
  *
... ...
@@ -37,6 +37,7 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx)
37 37
 {
38 38
   struct tls_session *session;
39 39
   SSL *ssl;
40
+  unsigned char *sha1_hash = NULL;
40 41
 
41 42
   /* get the tls_session pointer */
42 43
   ssl = X509_STORE_CTX_get_ex_data (ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
... ...
@@ -44,14 +45,15 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx)
44 44
   session = (struct tls_session *) SSL_get_ex_data (ssl, mydata_index);
45 45
   ASSERT (session);
46 46
 
47
-  cert_hash_remember (session, ctx->error_depth, ctx->current_cert->sha1_hash);
47
+  sha1_hash = x509_get_sha1_hash(ctx->current_cert);
48
+  cert_hash_remember (session, ctx->error_depth, sha1_hash);
49
+  x509_free_sha1_hash(sha1_hash);
48 50
 
49 51
   /* did peer present cert which was signed by our root cert? */
50 52
   if (!preverify_ok)
51 53
     {
52 54
       /* get the X509 name */
53
-      char *subject = X509_NAME_oneline (
54
-	  X509_get_subject_name (ctx->current_cert), NULL, 0);
55
+      char *subject = x509_get_serial(ctx->current_cert);
55 56
 
56 57
       if (subject)
57 58
 	{
... ...
@@ -60,7 +62,7 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx)
60 60
 	      ctx->error_depth,
61 61
 	      X509_verify_cert_error_string (ctx->error),
62 62
 	      subject);
63
-	  free (subject);
63
+	  x509_free_subject(subject);
64 64
 	}
65 65
 
66 66
       ERR_clear_error();
... ...
@@ -222,6 +224,21 @@ x509_free_serial (char *serial)
222 222
     OPENSSL_free(serial);
223 223
 }
224 224
 
225
+unsigned char *
226
+x509_get_sha1_hash (X509 *cert)
227
+{
228
+  char *hash = malloc(SHA_DIGEST_LENGTH);
229
+  memcpy(hash, cert->sha1_hash, SHA_DIGEST_LENGTH);
230
+  return cert->sha1_hash;
231
+}
232
+
233
+void
234
+x509_free_sha1_hash (unsigned char *hash)
235
+{
236
+  if (hash)
237
+    free(hash);
238
+}
239
+
225 240
 char *
226 241
 x509_get_subject (X509 *cert)
227 242
 {