Exemple #1
0
/* Initialize SSL library; returns non-zero on failure. */
static int init_ssl(void)
{
    SSL_load_error_strings();
    SSL_library_init();
    PKCS12_PBE_add();  /* ### not sure why this is needed. */

    /* Check whether the PRNG has already been seeded. */
    if (RAND_status() == 1)
	return 0;

#ifdef EGD_PATH
    NE_DEBUG(NE_DBG_SOCKET, "Seeding PRNG from " EGD_PATH "...\n");
    if (RAND_egd(EGD_PATH) != -1)
	return 0;
#elif defined(ENABLE_EGD)
    {
	static const char *paths[] = { "/var/run/egd-pool", "/dev/egd-pool",
				       "/etc/egd-pool", "/etc/entropy" };
	size_t n;
	for (n = 0; n < sizeof(paths) / sizeof(char *); n++) {
	    NE_DEBUG(NE_DBG_SOCKET, "Seeding PRNG from %s...\n", paths[n]);
	    if (RAND_egd(paths[n]) != -1)
		return 0;
	}
    }
#endif /* EGD_PATH */

    NE_DEBUG(NE_DBG_SOCKET, "No entropy source found; could not seed PRNG.\n");
    return -1;
}
Exemple #2
0
void * tls_init(void)
{
	SSL_CTX *ssl;

	SSL_load_error_strings();
	SSL_library_init();
	/* TODO: if /dev/urandom is available, PRNG is seeded automatically.
	 * If this is not the case, random data should be added here. */

#ifdef PKCS12_FUNCS
	PKCS12_PBE_add();
#endif  /* PKCS12_FUNCS */

	ssl = SSL_CTX_new(TLSv1_method());
	if (ssl == NULL)
		return NULL;

	SSL_CTX_set_info_callback(ssl, ssl_info_cb);

	return ssl;
}
void OpenSSL_add_all_ciphers(void)
	{

#ifndef OPENSSL_NO_DES
	EVP_add_cipher(EVP_des_cfb());
	EVP_add_cipher(EVP_des_cfb1());
	EVP_add_cipher(EVP_des_cfb8());
	EVP_add_cipher(EVP_des_ede_cfb());
	EVP_add_cipher(EVP_des_ede3_cfb());

	EVP_add_cipher(EVP_des_ofb());
	EVP_add_cipher(EVP_des_ede_ofb());
	EVP_add_cipher(EVP_des_ede3_ofb());

	EVP_add_cipher(EVP_desx_cbc());
	EVP_add_cipher_alias(SN_desx_cbc,"DESX");
	EVP_add_cipher_alias(SN_desx_cbc,"desx");

	EVP_add_cipher(EVP_des_cbc());
	EVP_add_cipher_alias(SN_des_cbc,"DES");
	EVP_add_cipher_alias(SN_des_cbc,"des");
	EVP_add_cipher(EVP_des_ede_cbc());
	EVP_add_cipher(EVP_des_ede3_cbc());
	EVP_add_cipher_alias(SN_des_ede3_cbc,"DES3");
	EVP_add_cipher_alias(SN_des_ede3_cbc,"des3");

	EVP_add_cipher(EVP_des_ecb());
	EVP_add_cipher(EVP_des_ede());
	EVP_add_cipher(EVP_des_ede3());
#endif

#ifndef OPENSSL_NO_RC4
	EVP_add_cipher(EVP_rc4());
	EVP_add_cipher(EVP_rc4_40());
#endif

#ifndef OPENSSL_NO_IDEA
	EVP_add_cipher(EVP_idea_ecb());
	EVP_add_cipher(EVP_idea_cfb());
	EVP_add_cipher(EVP_idea_ofb());
	EVP_add_cipher(EVP_idea_cbc());
	EVP_add_cipher_alias(SN_idea_cbc,"IDEA");
	EVP_add_cipher_alias(SN_idea_cbc,"idea");
#endif

#ifndef OPENSSL_NO_RC2
	EVP_add_cipher(EVP_rc2_ecb());
	EVP_add_cipher(EVP_rc2_cfb());
	EVP_add_cipher(EVP_rc2_ofb());
	EVP_add_cipher(EVP_rc2_cbc());
	EVP_add_cipher(EVP_rc2_40_cbc());
	EVP_add_cipher(EVP_rc2_64_cbc());
	EVP_add_cipher_alias(SN_rc2_cbc,"RC2");
	EVP_add_cipher_alias(SN_rc2_cbc,"rc2");
#endif

#ifndef OPENSSL_NO_BF
	EVP_add_cipher(EVP_bf_ecb());
	EVP_add_cipher(EVP_bf_cfb());
	EVP_add_cipher(EVP_bf_ofb());
	EVP_add_cipher(EVP_bf_cbc());
	EVP_add_cipher_alias(SN_bf_cbc,"BF");
	EVP_add_cipher_alias(SN_bf_cbc,"bf");
	EVP_add_cipher_alias(SN_bf_cbc,"blowfish");
#endif

#ifndef OPENSSL_NO_CAST
	EVP_add_cipher(EVP_cast5_ecb());
	EVP_add_cipher(EVP_cast5_cfb());
	EVP_add_cipher(EVP_cast5_ofb());
	EVP_add_cipher(EVP_cast5_cbc());
	EVP_add_cipher_alias(SN_cast5_cbc,"CAST");
	EVP_add_cipher_alias(SN_cast5_cbc,"cast");
	EVP_add_cipher_alias(SN_cast5_cbc,"CAST-cbc");
	EVP_add_cipher_alias(SN_cast5_cbc,"cast-cbc");
#endif

#ifndef OPENSSL_NO_RC5
	EVP_add_cipher(EVP_rc5_32_12_16_ecb());
	EVP_add_cipher(EVP_rc5_32_12_16_cfb());
	EVP_add_cipher(EVP_rc5_32_12_16_ofb());
	EVP_add_cipher(EVP_rc5_32_12_16_cbc());
	EVP_add_cipher_alias(SN_rc5_cbc,"rc5");
	EVP_add_cipher_alias(SN_rc5_cbc,"RC5");
#endif

#ifndef OPENSSL_NO_AES
	EVP_add_cipher(EVP_aes_128_ecb());
	EVP_add_cipher(EVP_aes_128_cbc());
	EVP_add_cipher(EVP_aes_128_cfb());
	EVP_add_cipher(EVP_aes_128_cfb1());
	EVP_add_cipher(EVP_aes_128_cfb8());
	EVP_add_cipher(EVP_aes_128_ofb());
#if 0
	EVP_add_cipher(EVP_aes_128_ctr());
#endif
	EVP_add_cipher_alias(SN_aes_128_cbc,"AES128");
	EVP_add_cipher_alias(SN_aes_128_cbc,"aes128");
	EVP_add_cipher(EVP_aes_192_ecb());
	EVP_add_cipher(EVP_aes_192_cbc());
	EVP_add_cipher(EVP_aes_192_cfb());
	EVP_add_cipher(EVP_aes_192_cfb1());
	EVP_add_cipher(EVP_aes_192_cfb8());
	EVP_add_cipher(EVP_aes_192_ofb());
#if 0
	EVP_add_cipher(EVP_aes_192_ctr());
#endif
	EVP_add_cipher_alias(SN_aes_192_cbc,"AES192");
	EVP_add_cipher_alias(SN_aes_192_cbc,"aes192");
	EVP_add_cipher(EVP_aes_256_ecb());
	EVP_add_cipher(EVP_aes_256_cbc());
	EVP_add_cipher(EVP_aes_256_cfb());
	EVP_add_cipher(EVP_aes_256_cfb1());
	EVP_add_cipher(EVP_aes_256_cfb8());
	EVP_add_cipher(EVP_aes_256_ofb());
#if 0
	EVP_add_cipher(EVP_aes_256_ctr());
#endif
	EVP_add_cipher_alias(SN_aes_256_cbc,"AES256");
	EVP_add_cipher_alias(SN_aes_256_cbc,"aes256");
#endif
	PKCS12_PBE_add();
	PKCS5_PBE_add();
	}
Exemple #4
0
static
int cert_stuff(struct connectdata *conn,
               SSL_CTX* ctx,
               char *cert_file,
               const char *cert_type,
               char *key_file,
               const char *key_type)
{
  struct SessionHandle *data = conn->data;
  int file_type;

  if(cert_file != NULL) {
    SSL *ssl;
    X509 *x509;
    int cert_done = 0;

    if(data->set.key_passwd) {
#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
      /*
       * If password has been given, we store that in the global
       * area (*shudder*) for a while:
       */
      size_t len = strlen(data->set.key_passwd);
      if(len < sizeof(global_passwd))
        memcpy(global_passwd, data->set.key_passwd, len+1);
#else
      /*
       * We set the password in the callback userdata
       */
      SSL_CTX_set_default_passwd_cb_userdata(ctx,
                                             data->set.key_passwd);
#endif
      /* Set passwd callback: */
      SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
    }

    file_type = do_file_type(cert_type);

#define SSL_CLIENT_CERT_ERR \
    "unable to use client certificate (no key found or wrong pass phrase?)"

    switch(file_type) {
    case SSL_FILETYPE_PEM:
      /* SSL_CTX_use_certificate_chain_file() only works on PEM files */
      if(SSL_CTX_use_certificate_chain_file(ctx,
                                            cert_file) != 1) {
        failf(data, SSL_CLIENT_CERT_ERR);
        return 0;
      }
      break;

    case SSL_FILETYPE_ASN1:
      /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but
         we use the case above for PEM so this can only be performed with
         ASN1 files. */
      if(SSL_CTX_use_certificate_file(ctx,
                                      cert_file,
                                      file_type) != 1) {
        failf(data, SSL_CLIENT_CERT_ERR);
        return 0;
      }
      break;
    case SSL_FILETYPE_ENGINE:
      failf(data, "file type ENG for certificate not implemented");
      return 0;

    case SSL_FILETYPE_PKCS12:
    {
#ifdef HAVE_PKCS12_SUPPORT
      FILE *f;
      PKCS12 *p12;
      EVP_PKEY *pri;

      f = fopen(cert_file,"rb");
      if (!f) {
        failf(data, "could not open PKCS12 file '%s'", cert_file);
        return 0;
      }
      p12 = d2i_PKCS12_fp(f, NULL);
      fclose(f);

      PKCS12_PBE_add();

      if (!PKCS12_parse(p12, data->set.key_passwd, &pri, &x509, NULL)) {
        failf(data,
              "could not parse PKCS12 file, check password, OpenSSL error %s",
              ERR_error_string(ERR_get_error(), NULL) );
        return 0;
      }

      PKCS12_free(p12);

      if(SSL_CTX_use_certificate(ctx, x509) != 1) {
        failf(data, SSL_CLIENT_CERT_ERR);
        EVP_PKEY_free(pri);
        X509_free(x509);
        return 0;
      }

      if(SSL_CTX_use_PrivateKey(ctx, pri) != 1) {
        failf(data, "unable to use private key from PKCS12 file '%s'",
              cert_file);
        EVP_PKEY_free(pri);
        X509_free(x509);
        return 0;
      }

      EVP_PKEY_free(pri);
      X509_free(x509);
      cert_done = 1;
      break;
#else
      failf(data, "file type P12 for certificate not supported");
      return 0;
#endif
    }
    default:
      failf(data, "not supported file type '%s' for certificate", cert_type);
      return 0;
    }

    file_type = do_file_type(key_type);

    switch(file_type) {
    case SSL_FILETYPE_PEM:
      if(cert_done)
        break;
      if(key_file == NULL)
        /* cert & key can only be in PEM case in the same file */
        key_file=cert_file;
    case SSL_FILETYPE_ASN1:
      if(SSL_CTX_use_PrivateKey_file(ctx, key_file, file_type) != 1) {
        failf(data, "unable to set private key file: '%s' type %s\n",
              key_file, key_type?key_type:"PEM");
        return 0;
      }
      break;
    case SSL_FILETYPE_ENGINE:
#ifdef HAVE_OPENSSL_ENGINE_H
      {                         /* XXXX still needs some work */
        EVP_PKEY *priv_key = NULL;
        if(conn && conn->data && conn->data->state.engine) {
#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
          UI_METHOD *ui_method = UI_OpenSSL();
#endif
          if(!key_file || !key_file[0]) {
            failf(data, "no key set to load from crypto engine\n");
            return 0;
          }
          /* the typecast below was added to please mingw32 */
          priv_key = (EVP_PKEY *)
            ENGINE_load_private_key(conn->data->state.engine,key_file,
#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS
                                    ui_method,
#endif
                                    data->set.key_passwd);
          if(!priv_key) {
            failf(data, "failed to load private key from crypto engine\n");
            return 0;
          }
          if(SSL_CTX_use_PrivateKey(ctx, priv_key) != 1) {
            failf(data, "unable to set private key\n");
            EVP_PKEY_free(priv_key);
            return 0;
          }
          EVP_PKEY_free(priv_key);  /* we don't need the handle any more... */
        }
        else {
          failf(data, "crypto engine not set, can't load private key\n");
          return 0;
        }
      }
      break;
#else
      failf(data, "file type ENG for private key not supported\n");
      return 0;
#endif
    case SSL_FILETYPE_PKCS12:
      if(!cert_done) {
        failf(data, "file type P12 for private key not supported\n");
        return 0;
      }
      break;
    default:
      failf(data, "not supported file type for private key\n");
      return 0;
    }

    ssl=SSL_new(ctx);
    if (NULL == ssl) {
      failf(data,"unable to create an SSL structure\n");
      return 0;
    }

    x509=SSL_get_certificate(ssl);

    /* This version was provided by Evan Jordan and is supposed to not
       leak memory as the previous version: */
    if(x509 != NULL) {
      EVP_PKEY *pktmp = X509_get_pubkey(x509);
      EVP_PKEY_copy_parameters(pktmp,SSL_get_privatekey(ssl));
      EVP_PKEY_free(pktmp);
    }

    SSL_free(ssl);

    /* If we are using DSA, we can copy the parameters from
     * the private key */


    /* Now we know that a key and cert have been set against
     * the SSL context */
    if(!SSL_CTX_check_private_key(ctx)) {
      failf(data, "Private key does not match the certificate public key");
      return(0);
    }
#ifndef HAVE_USERDATA_IN_PWD_CALLBACK
    /* erase it now */
    memset(global_passwd, 0, sizeof(global_passwd));
#endif
  }
  return(1);
}