Exemplo n.º 1
0
/*
 *	Generate ephemeral RSA keys.
 */
static int generate_eph_rsa_key(SSL_CTX *ctx)
{
	RSA *rsa;

	rsa = RSA_generate_key(512, RSA_F4, NULL, NULL);

	if (!SSL_CTX_set_tmp_rsa(ctx, rsa)) {
		radlog(L_ERR, "rlm_eap_tls: Couldn't set ephemeral RSA key");
		return -1;
	}

	RSA_free(rsa);
	return 0;
}
Exemplo n.º 2
0
Arquivo: ssl.c Projeto: UIKit0/picogui
static void
_SSL_add_random_keypair(SSL_CTX *ctx, int bits)
{
	RSA *rsa;


	rsa = RSA_generate_key(bits, RSA_F4, NULL, NULL);
	if (!SSL_CTX_set_tmp_rsa(ctx, rsa))
		__SSL_critical_error("SSL_CTX_set_tmp_rsa");
	RSA_free(rsa);

	/* force use of this key for key exchange */
	SSL_CTX_set_options(ctx, SSL_OP_EPHEMERAL_RSA);
}
Exemplo n.º 3
0
Arquivo: tls.c Projeto: Zabrane/SPOCP
static int
generate_eph_rsa_key(SSL_CTX * ctx, int keylength)
{
	RSA            *rsa_key;

	LOG(SPOCP_DEBUG) traceLog(LOG_DEBUG,"Generating %d bit RSA key...\n", keylength);

	rsa_key = RSA_generate_key(keylength, RSA_F4, NULL, NULL);

	if (!SSL_CTX_set_tmp_rsa(ctx, rsa_key)) {
		LOG(SPOCP_ERR) traceLog(LOG_ERR,"TLS error (RSA_generate_key): %s",
					ssl_errstring);
		return FALSE;
	}

	RSA_free(rsa_key);

	return TRUE;
}
Exemplo n.º 4
0
int anetSSLAccept( char *err, int fd, struct redisServer server, anetSSLConnection *ctn) {

  ctn->sd = -1;
  ctn->ctx = NULL;
  ctn->ssl = NULL;
  ctn->bio = NULL;
  ctn->conn_str = NULL;

  if( fd == -1 ) {
    return ANET_ERR;
  }
  ctn->sd = fd;

  // Create the SSL Context ( server method )
  SSL_CTX* ctx = SSL_CTX_new(TLSv1_1_server_method());
  ctn->ctx = ctx;

   /*
     You will need to generate certificates, the root certificate authority file, the private key file, and the random file yourself.
     Google will help. The openssl executable created when you compiled OpenSSL can do all this.
   */

    // Load trusted root authorities
    SSL_CTX_load_verify_locations(ctx, server.ssl_root_file, server.ssl_root_dir);

    // Sets the default certificate password callback function. Read more under the Certificate Verification section.
    if( NULL != server.ssl_srvr_cert_passwd ) {
      global_ssl_cert_password = server.ssl_srvr_cert_passwd;
      SSL_CTX_set_default_passwd_cb(ctx, password_callback);
    }

    // Sets the certificate file to be used.
    SSL_CTX_use_certificate_file(ctx, server.ssl_cert_file, SSL_FILETYPE_PEM);

    // Sets the private key file to be used.
    SSL_CTX_use_PrivateKey_file(ctx, server.ssl_pk_file, SSL_FILETYPE_PEM);

    // Set the maximum depth to be used verifying certificates
    // Due to a bug, this is not enforced. The verify callback must enforce it.
    SSL_CTX_set_verify_depth(ctx, 1);

    // Set the certificate verification callback.
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER /* | SSL_VERIFY_FAIL_IF_NO_PEER_CERT */, verify_callback);

    /*
      End certificate verification setup.
    */

    // We need to load the Diffie-Hellman key exchange parameters.
    // First load dh1024.pem (you DID create it, didn't you?)
    BIO* bio = BIO_new_file(server.ssl_dhk_file, "r");

    // Did we get a handle to the file?
    if (bio == NULL) {
      anetSetError(err, "SSL Accept: Couldn't open DH param file");
      anetCleanupSSL( ctn);
      return ANET_ERR;
    }

    // Read in the DH params.
    DH* ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);

    // Free up the BIO object.
    BIO_free(bio);

    // Set up our SSL_CTX to use the DH parameters.
    if (SSL_CTX_set_tmp_dh(ctx, ret) < 0) {
      anetSetError(err, "SSL Accept: Couldn't set DH parameters");
      anetCleanupSSL( ctn );
      return ANET_ERR;
    }

    // Now we need to generate a RSA key for use.
    // 1024-bit key. If you want to use something stronger, go ahead but it must be a power of 2. Upper limit should be 4096.
    RSA* rsa = RSA_generate_key(1024, RSA_F4, NULL, NULL);

    // Set up our SSL_CTX to use the generated RSA key.
    if (!SSL_CTX_set_tmp_rsa(ctx, rsa)) {
      anetSetError(err, "SSL Accept: Couldn't set RSA Key");
      anetCleanupSSL( ctn );
      return ANET_ERR;
    }

    // Free up the RSA structure.
    RSA_free(rsa);

    /*
      For some reason many tutorials don't include this...

      Servers must specify the ciphers they can use, to verify that both the client and the server can use the same cipher.
      If you don't do this, you'll get errors relating to "no shared ciphers" or "no common ciphers".

      Use all ciphers with the exception of: ones with anonymous Diffie-Hellman, low-strength ciphers, export ciphers, md5 hashing. Ordered from strongest to weakest.
      Note that as ciphers become broken, it will be necessary to change the available cipher list to remain secure.
    */

    if( NULL == server.ssl_srvr_cipher_list || 0 == strlen(server.ssl_srvr_cipher_list) )
        SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
    else
    	SSL_CTX_set_cipher_list(ctx, server.ssl_srvr_cipher_list);

    // Set up our SSL object as before
    SSL* ssl = SSL_new(ctx);
    ctn->ssl = ssl;
    
    // Set up our BIO object to use the client socket
    BIO* sslclient = BIO_new_socket(fd, BIO_NOCLOSE);
    ctn->bio = sslclient;

    // Set up our SSL object to use the BIO.
    SSL_set_bio(ssl, sslclient, sslclient);

    // Do SSL handshaking.
    int r = SSL_accept(ssl);

    // Something failed. Print out all the error information, since all of it may be relevant to the problem.
    if (r != 1) {
      char error[65535];

      ERR_error_string_n(ERR_get_error(), error, 65535);

      anetSetError(err, "SSL Accept: Error %d - %s ", SSL_get_error(ssl, r), error );

      // We failed to accept this client connection.
      // Ideally here you'll drop the connection and continue on.
      anetCleanupSSL( ctn );
      return ANET_ERR;
    }

    /* Verify certificate */
    if (SSL_get_verify_result(ssl) != X509_V_OK) {
      anetSetError(err, "SSL Accept: Certificate failed verification!");
      // Ideally here you'll close this connection and continue on.
      anetCleanupSSL( ctn );
      return ANET_ERR;
    }

    return ANET_OK;
}
Exemplo n.º 5
0
static int openssl_ssl_ctx_set_tmp(lua_State *L)
{
  SSL_CTX* ctx = CHECK_OBJECT(1, SSL_CTX, "openssl.ssl_ctx");
  static const char* which[] =
  {
    "dh",
    "rsa",
    "ecdh",
    NULL
  };

  int nwhich = luaL_checkoption(L, 2, NULL, which);
  int ret = 0;

  if (lua_isfunction(L, 3))
  {
    lua_pushvalue(L, 3);
    ret = 1;
    switch (nwhich)
    {
    case 0:
      openssl_setvalue(L, ctx, "tmp_dh_callback");
      SSL_CTX_set_tmp_dh_callback(ctx, tmp_dh_callback);
      break;
    case 1:
      openssl_setvalue(L, ctx, "tmp_rsa_callback");
      SSL_CTX_set_tmp_rsa_callback(ctx, tmp_rsa_callback);
      break;
    case 2:
    {
      luaL_argcheck(L, lua_isstring(L, 4), 4, "must supply curve name");
      openssl_setvalue(L, ctx, "tmp_ecdh_callback");
      SSL_CTX_set_tmp_ecdh_callback(ctx, tmp_ecdh_callback);
      lua_pushvalue(L, 4);
      openssl_setvalue(L, ctx, "curve");
    }
    break;
    }
  }
  else if (lua_isstring(L, 3))
  {
    BIO* bio = load_bio_object(L, 3);
    switch (nwhich)
    {
    case 0:
    {
      DH* dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
      if (dh)
        ret = SSL_CTX_set_tmp_dh(ctx, dh);
      else
        luaL_error(L, "generate new tmp dh fail");
    }
    break;
    case 1:
    {
      RSA* rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
      if (rsa)
        ret = SSL_CTX_set_tmp_rsa(ctx, rsa);
      else
        luaL_error(L, "generate new tmp rsa fail");
    }
    break;
    case 2:
    {
      int nid = NID_undef;

      EC_KEY* ec = PEM_read_bio_ECPrivateKey(bio, NULL, NULL, NULL);
      if (ec == NULL)
      {
        nid = OBJ_txt2nid(lua_tostring(L, 3));
        if (nid != NID_undef)
          ec = EC_KEY_new_by_curve_name(nid);
      }
      if (ec)
        ret = SSL_CTX_set_tmp_ecdh(ctx, ec);
      else
        luaL_error(L, "generate new tmp ec_key fail");
    }
    break;
    }
    BIO_free(bio);
  }
  else if (lua_isuserdata(L, 3))
  {
    luaL_argerror(L, 3, "userdata arg NYI");
  }
  else
    luaL_argerror(L, 3, "should be tmp key callback function or pem string or key object");

  return openssl_pushresult(L, ret);
}
Exemplo n.º 6
0
/* デフォルトの証明書は 自分:/usr/local/ct/cert/tn.pem 認証局:/usr/local/ct/cert/root.pem */
int kTLSInitialize(int sessionMode,int initialmode,int timeout,char *passwd,char *rootPEM,char *myPEM,
		   char *dhPEM,int version,int nagle,int clientveri,int tmprsa,char *enc)
{
    BIO         *bio;
    SSL_METHOD *meth;
    RSA *rsa;
    DH *dh=0;
    struct stat tmp;

    /* Nagleアルゴリズムの無効化フラグの保存 */
    NagleFlag=nagle;

    if(TLSctx){
      /* 強制初期化モードがある場合 */
      if(initialmode){
	TLSClose(NULL,0);
	kLogWrite(L_TLS, "%s: TLS ReInitialize", __FUNCTION__);
      }
      else
	return RETURN_OK;
    }

    /* パラメータの取得 */
    timeout = timeout<=0 ? SESSION_TIMEOUT : timeout;
    TLSSessionMode = sessionMode;
    kLogWrite(L_TLS,"%s: Session cache mode : %s   Session timeout : %d(s)",__FUNCTION__,sessionMode?"Enable":"Disable",timeout);

    rootPEM = (rootPEM && rootPEM[0]) ? rootPEM : ROOT_PEM;
    myPEM   = (myPEM && myPEM[0]) ?   myPEM   : MY_PEM;
    dhPEM   = (dhPEM && dhPEM[0]) ?   dhPEM   : DHFILE1024;
    strcpy(TLSPasswd,(passwd && passwd[0]) ?  passwd  : PASSWORD);

    if(lstat(rootPEM,&tmp)<0){
      kLogWrite(L_ERROR, "%s: TLS Initialize file[%s] not exist", __FUNCTION__,rootPEM);
      return(RETURN_NG);
    }
    if(lstat(myPEM,&tmp)<0){
      kLogWrite(L_ERROR, "%s: TLS Initialize file[%s] not exist", __FUNCTION__,myPEM);
      return(RETURN_NG);
    }
    if(lstat(dhPEM,&tmp)<0){
      kLogWrite(L_ERROR, "%s: TLS Initialize file[%s] not exist", __FUNCTION__,dhPEM);
      return(RETURN_NG);
    }

    /* SSLライブラリの初期化 */
    if(!SSL_library_init()){
      kLogWrite(L_ERROR, "%s: OpenSSL initialization failed!",__FUNCTION__);
      return(RETURN_NG);
    }
    kLogWrite(L_TLS,"%s: SSL_library_init OK",__FUNCTION__);

    /* エラーメッセージの視覚化 */
    SSL_load_error_strings();

    RAND_load_file("/dev/urandom", 1024);
    kLogWrite(L_TLS,"%s: RAND_load_file OK",__FUNCTION__);

    /* SSL_METHODオブジェクトの取得 */
    if(version == 2)
      meth=SSLv2_method();
    else if(version == 3)
      meth=SSLv3_method();
    else if(version == 1)
      meth=TLSv1_method();
    else if(version == 23)
      meth=SSLv23_method();
    else
      meth=TLSv1_method();

    kLogWrite(L_TLS,"%s: SSL verion [%d] 2:SSLv2 23:SSLv23 3:SSLv3 1:TLSv1",__FUNCTION__,version);
    
    /* SSL_CTXオブジェクトの取得 */
    TLSctx=SSL_CTX_new(meth);
    kLogWrite(L_TLS,"%s: SSL_CTX_new OK",__FUNCTION__);

    /* SSL_CTXオブジェクトに証明書と秘密鍵を同時にロードする */
    if(!(SSL_CTX_use_certificate_file(TLSctx,myPEM,SSL_FILETYPE_PEM))){
      TLSClose(NULL,0);
      kLogWrite(L_ERROR, "%s: Couldn't read certificate file",__FUNCTION__);
      return(RETURN_NG);
    }
    kLogWrite(L_TLS,"%s: SSL_CTX_use_certificate_file[%s] OK",__FUNCTION__,myPEM);

    /* パスフレーズのコールバック関数を登録する */
    SSL_CTX_set_default_passwd_cb(TLSctx,password_cb);

    if(!(SSL_CTX_use_PrivateKey_file(TLSctx,myPEM,SSL_FILETYPE_PEM))){
      TLSClose(NULL,0);
      kLogWrite(L_ERROR, "%s: Couldn't read key file",__FUNCTION__);
      return(RETURN_NG);
    }
    kLogWrite(L_TLS,"%s: SSL_CTX_use_PrivateKey_file[%s] OK",__FUNCTION__,myPEM);
  
    /* SSL_CTXオブジェクトに信頼できるCA証明書をロードする */
    if(!(SSL_CTX_load_verify_locations(TLSctx,rootPEM,0))){
      TLSClose(NULL,0);
      kLogWrite(L_ERROR, "%s: Couldn't read CA list",__FUNCTION__);
      return(RETURN_NG);
    }
    kLogWrite(L_TLS,"%s: SSL_CTX_load_verify_locations[%s] OK",__FUNCTION__,rootPEM);

    /* 認証コールバック関数の登録 */
    /* Server Key Exchange オプションを付与する (クライアント認証を行う) */
    kLogWrite(L_TLS,"%s: Server Key Exchange option : %s",__FUNCTION__,clientveri?"Enable":"Disable");
    SSL_CTX_set_verify(TLSctx, clientveri?SSL_VERIFY_PEER:SSL_VERIFY_NONE,VerifyCallback);
    kLogWrite(L_TLS,"%s:  SSL_CTX_set_verify[%s] OK",__FUNCTION__,clientveri?"PEER":"NONE");
    
    /* 信頼できる証明書に到達するまでのチェーンの回数を指定する */
    /* SSL_CTX_set_verify_depth(TLSctx,1); */

    /* SSLv2を選択不可にする */
    if(version != 2 && version != 23){
      SSL_CTX_set_options(TLSctx,SSL_OP_NO_SSLv2);
      kLogWrite(L_TLS,"%s: SSL_CTX_set_options NO_SSLv2",__FUNCTION__);
    }

    /* Certificate Request オプションを付与する (一時的RSAを使う ) */
    kLogWrite(L_TLS,"%s: Certificate Request option : %s",__FUNCTION__,tmprsa?"Enable":"Disable");
    if(tmprsa){

      /* BIOオブジェクトを使ってファイルをオープンする */
      if ((bio=BIO_new_file(dhPEM,"r")) == NULL){
	TLSClose(NULL,0);
	kLogWrite(L_ERROR, "%s: Couldn't open DH file",__FUNCTION__);
	return(RETURN_NG);
      }
      kLogWrite(L_TLS,"%s: BIO_new_file[%s] OK",__FUNCTION__,dhPEM);
    
      /* DHパラメータを読み込む */
      dh=PEM_read_bio_DHparams(bio,NULL,NULL,NULL);
      kLogWrite(L_TLS,"%s: PEM_read_bio_DHparams[%s] OK",__FUNCTION__,dhPEM);
      
      /* ファイルをクローズする */
      BIO_free(bio);
    
      /* DHパラメータをCTXオブジェクトにロードする */
      if(SSL_CTX_set_tmp_dh(TLSctx,dh)<0){
	TLSClose(NULL,0);
	kLogWrite(L_ERROR, "%s: Couldn't set DH parameters",__FUNCTION__);
	return(RETURN_NG);
      }
      kLogWrite(L_TLS,"%s: SSL_CTX_set_tmp_dh OK",__FUNCTION__);
    }

    /* 暗号スイートの選択 */
    if(enc && enc[0]){
      kLogWrite(L_TLS,"%s: Encrypt suit specified",__FUNCTION__);

      if(SSL_CTX_set_cipher_list(TLSctx,enc))
	kLogWrite(L_TLS,"%s:  SSL_CTX_set_cipher_list[%s] OK",__FUNCTION__,enc);
      else
	kLogWrite(L_TLS,"%s:  SSL_CTX_set_cipher_list[%s] invalid",__FUNCTION__,enc);
    }

    /* RSA鍵のペアを生成する */
    rsa=RSA_generate_key(512,RSA_F4,NULL,NULL);
    kLogWrite(L_TLS,"%s: RSA_generate_key OK",__FUNCTION__);
    
    /* RSA鍵をCTXオブジェクトにロードする */
    if (!SSL_CTX_set_tmp_rsa(TLSctx,rsa)){
      TLSClose(NULL,0);
      kLogWrite(L_ERROR, "%s: Couldn't set RSA key", __FUNCTION__);
      return(RETURN_NG);
    }
    kLogWrite(L_TLS,"%s: SSL_CTX_set_tmp_rsa OK",__FUNCTION__);
    
    RSA_free(rsa);
  
    /* セッションキャッシュを有効モードに設定する */
    SSL_CTX_set_session_id_context(TLSctx,(void*)&TLSServerSessionIdContext, sizeof(TLSServerSessionIdContext));
    kLogWrite(L_TLS,"%s: SSL_CTX_set_session_id_context OK", __FUNCTION__);

    /* セッション削除時のコールバック設定 */
    SSL_CTX_sess_set_remove_cb(TLSctx,remove_session_cb);
    SSL_CTX_set_timeout(TLSctx,timeout);

    kLogWrite(L_TLS,"%s: Nagle algorithm : %s",__FUNCTION__,NagleFlag?"Enable":"Disable");

    return(RETURN_OK);
}