]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
PolarSSL-1.2 support
authorSteffan Karger <steffan.karger@fox-it.com>
Fri, 22 Mar 2013 08:54:20 +0000 (09:54 +0100)
committerGert Doering <gert@greenie.muc.de>
Fri, 22 Mar 2013 15:53:23 +0000 (16:53 +0100)
Add support for PolarSSL-1.2, which has changed the API in several places.
This is a minimal port, new features have not been enabled. Only PolarSSL
1.2.5 and newer are accepted, as earlier versions contain unresolved
(security) issues.

Signed-off-by: Joachim Schipper <joachim.schipper@fox-it.com>
Signed-off-by: Steffan Karger <steffan.karger@fox-it.com>
Acked-by: Adriaan de Jong <dejong@fox-it.com>
Message-Id: <1363942465-3251-2-git-send-email-steffan.karger@fox-it.com>
URL: http://article.gmane.org/gmane.network.openvpn.devel/7436
Signed-off-by: Gert Doering <gert@greenie.muc.de>
configure.ac
src/openvpn/crypto_polarssl.c
src/openvpn/crypto_polarssl.h
src/openvpn/ssl_polarssl.c
src/openvpn/ssl_polarssl.h
src/openvpn/ssl_verify_polarssl.c
src/openvpn/ssl_verify_polarssl.h

index ddd322c1fc8aa2620e20870b006f4d754416e893..785fc4e738c2e4dab0043e96689327e541e49037 100644 (file)
@@ -805,8 +805,8 @@ if test "${with_crypto_library}" = "polarssl" ; then
 #include <polarssl/version.h>
                        ]],
                        [[
-#if POLARSSL_VERSION_NUMBER < 0x01010000
-#error invalid version
+#if POLARSSL_VERSION_NUMBER < 0x01020500
+#error invalid version PolarSSL-1.2.5 or newer required
 #endif
                        ]]
                )],
index 3978a3c616b0a420347729e13db01b9e5a810083..ed9db53a874d59d5901b5ab0c600d8e5534c3b9b 100644 (file)
@@ -114,7 +114,7 @@ show_available_ciphers ()
 
       if (info && info->mode == POLARSSL_MODE_CBC)
        printf ("%s %d bit default key\n",
-               info->name, info->key_length);
+               info->name, cipher_kt_key_size(info) * 8);
 
       ciphers++;
     }
@@ -339,6 +339,9 @@ cipher_kt_key_size (const cipher_info_t *cipher_kt)
 {
   if (NULL == cipher_kt)
     return 0;
+  if (POLARSSL_CIPHER_ID_BLOWFISH == cipher_kt->base->cipher)
+    return 128/8; /* Override PolarSSL 32 bit default key size with sane 128 bit default */
+
   return cipher_kt->key_length/8;
 }
 
index bfabb91b58904051e5313ac1c0fe8cf49acf273d..b6da43636beb3ac76028ebef2be0f77f2abde2a6 100644 (file)
@@ -30,7 +30,6 @@
 #ifndef CRYPTO_POLARSSL_H_
 #define CRYPTO_POLARSSL_H_
 
-#include <polarssl/version.h>
 #include <polarssl/cipher.h>
 #include <polarssl/md.h>
 #include <polarssl/ctr_drbg.h>
@@ -60,7 +59,7 @@ typedef md_context_t hmac_ctx_t;
 #define OPENVPN_MODE_OFB       POLARSSL_MODE_OFB
 
 /** Cipher is in CFB mode */
-#define OPENVPN_MODE_CFB       POLARSSL_MODE_CFB128
+#define OPENVPN_MODE_CFB       POLARSSL_MODE_CFB
 
 /** Cipher should encrypt */
 #define OPENVPN_OP_ENCRYPT     POLARSSL_ENCRYPT
index 12318b333f7eaf639ec92b421973693f87f35618..4d00ad6cdb5dde598d0b4d4877afa9d3070c4e69 100644 (file)
@@ -65,23 +65,6 @@ tls_clear_error()
 {
 }
 
-static int default_ciphersuites[] =
-{
-    SSL_EDH_RSA_AES_256_SHA,
-    SSL_EDH_RSA_CAMELLIA_256_SHA,
-    SSL_EDH_RSA_AES_128_SHA,
-    SSL_EDH_RSA_CAMELLIA_128_SHA,
-    SSL_EDH_RSA_DES_168_SHA,
-    SSL_RSA_AES_256_SHA,
-    SSL_RSA_CAMELLIA_256_SHA,
-    SSL_RSA_AES_128_SHA,
-    SSL_RSA_CAMELLIA_128_SHA,
-    SSL_RSA_DES_168_SHA,
-    SSL_RSA_RC4_128_SHA,
-    SSL_RSA_RC4_128_MD5,
-    0
-};
-
 void
 tls_ctx_server_new(struct tls_root_ctx *ctx)
 {
@@ -514,20 +497,17 @@ void key_state_ssl_init(struct key_state_ssl *ks_ssl,
 
       ssl_set_rng (ks_ssl->ctx, ctr_drbg_random, rand_ctx_get());
 
-      ALLOC_OBJ_CLEAR (ks_ssl->ssn, ssl_session);
-      ssl_set_session (ks_ssl->ctx, 0, 0, ks_ssl->ssn );
       if (ssl_ctx->allowed_ciphers)
        ssl_set_ciphersuites (ks_ssl->ctx, ssl_ctx->allowed_ciphers);
-      else
-       ssl_set_ciphersuites (ks_ssl->ctx, default_ciphersuites);
 
       /* Initialise authentication information */
       if (is_server)
        ssl_set_dh_param_ctx (ks_ssl->ctx, ssl_ctx->dhm_ctx );
 #if defined(ENABLE_PKCS11)
       if (ssl_ctx->priv_key_pkcs11 != NULL)
-       ssl_set_own_cert_pkcs11( ks_ssl->ctx, ssl_ctx->crt_chain,
-           ssl_ctx->priv_key_pkcs11 );
+       ssl_set_own_cert_alt( ks_ssl->ctx, ssl_ctx->crt_chain,
+           ssl_ctx->priv_key_pkcs11, ssl_pkcs11_decrypt, ssl_pkcs11_sign,
+           ssl_pkcs11_key_len );
       else
 #endif
        ssl_set_own_cert( ks_ssl->ctx, ssl_ctx->crt_chain, ssl_ctx->priv_key );
@@ -543,7 +523,6 @@ void key_state_ssl_init(struct key_state_ssl *ks_ssl,
       ALLOC_OBJ_CLEAR (ks_ssl->ct_out, endless_buffer);
       ssl_set_bio (ks_ssl->ctx, endless_buf_read, ks_ssl->ct_in,
          endless_buf_write, ks_ssl->ct_out);
-
     }
 }
 
@@ -556,8 +535,6 @@ key_state_ssl_free(struct key_state_ssl *ks_ssl)
          ssl_free(ks_ssl->ctx);
          free(ks_ssl->ctx);
        }
-      if (ks_ssl->ssn)
-       free(ks_ssl->ssn);
       if (ks_ssl->ct_in) {
        buf_free_entries(ks_ssl->ct_in);
        free(ks_ssl->ct_in);
@@ -818,7 +795,7 @@ key_state_read_plaintext (struct key_state_ssl *ks, struct buffer *buf,
 void
 print_details (struct key_state_ssl * ks_ssl, const char *prefix)
 {
-  x509_cert *cert;
+  const x509_cert *cert;
   char s1[256];
   char s2[256];
 
@@ -828,7 +805,7 @@ print_details (struct key_state_ssl * ks_ssl, const char *prefix)
                    ssl_get_version (ks_ssl->ctx),
                    ssl_get_ciphersuite(ks_ssl->ctx));
 
-  cert = ks_ssl->ctx->peer_cert;
+  cert = ssl_get_peer_cert(ks_ssl->ctx);
   if (cert != NULL)
     {
       openvpn_snprintf (s2, sizeof (s2), ", " counter_format " bit RSA", (counter_type) cert->rsa.len * 8);
index 456573f590cde737de9803eb79fca96d8324aae2..da936998104f0442ab8c0891e9055830c0e642a1 100644 (file)
@@ -73,7 +73,6 @@ struct tls_root_ctx {
 
 struct key_state_ssl {
         ssl_context *ctx;
-        ssl_session *ssn;
         endless_buffer *ct_in;
         endless_buffer *ct_out;
 };
index a32db8df1b9364400ae7003c1649cb8b6b230e2d..653248f2acd1d844ae2f0a60dff2feff9bc51c4d 100644 (file)
 
 int
 verify_callback (void *session_obj, x509_cert *cert, int cert_depth,
-    int preverify_ok)
+    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,7 +58,7 @@ 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);
 
@@ -69,21 +68,19 @@ verify_callback (void *session_obj, x509_cert *cert, int cert_depth,
        msg (D_TLS_ERRORS, "VERIFY ERROR: depth=%d, could not extract X509 "
              "subject string from certificate", 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
index fceee66733c02c79c56ef9b9689128941f320c21..b259081f6bc122fda93eb3490f608efc1dd7d129 100644 (file)
@@ -55,27 +55,25 @@ typedef x509_cert openvpn_x509_cert_t;
  * calls the PolarSSL library's \c ssl_set_verify_callback() function with \c
  * verify_callback() as its callback argument.
  *
- * It checks preverify_ok, and registers the certificate hash. If these steps
- * succeed, it calls the \c verify_cert() function, which performs
- * OpenVPN-specific verification.
+ * It checks *flags and registers the certificate hash. If these steps succeed,
+ * it calls the \c verify_cert() function, which performs OpenVPN-specific
+ * verification.
  *
  * @param session_obj  - The OpenVPN \c tls_session associated with this object,
  *                       as set during SSL session setup.
  * @param cert         - The certificate used by PolarSSL.
  * @param cert_depth   - The depth of the current certificate in the chain, with
  *                       0 being the actual certificate.
- * @param preverify_ok - Whether the remote OpenVPN peer's certificate
- *                       past verification.  A value of 1 means it
- *                       verified successfully, 0 means it failed.
+ * @param flags        - Whether the remote OpenVPN peer's certificate
+ *                       passed verification.  A value of 0 means it
+ *                       verified successfully, any other value means it
+ *                       failed. \c verify_callback() is considered to have
+ *                       ok'ed this certificate if flags is 0 when it returns.
  *
- * @return The return value indicates whether the supplied certificate is
- *     allowed to set up a VPN tunnel.  The following values can be
- *     returned:
- *      - \c 0: failure, this certificate is not allowed to connect.
- *      - \c 1: success, this certificate is allowed to connect.
+ * @return The return value is 0 unless a fatal error occurred.
  */
 int verify_callback (void *session_obj, x509_cert *cert, int cert_depth,
-    int preverify_ok);
+    int *flags);
 
 /** @} name Function for authenticating a new connection from a remote OpenVPN peer */