Exemple #1
0
int main(int argc, char *argv[]){
    BIO *root = BIO_new_file("root.crt", "r");
    BIO *rootkey = BIO_new_file("root.key", "r");
    BIO *out = BIO_new_file("root_256.crt", "w");

    X509 *cert = PEM_read_bio_X509(root, NULL, 0, NULL);
    EVP_PKEY *pkey = PEM_read_bio_PrivateKey(rootkey, NULL, 0, NULL);
    if (!cert || !pkey){
        printf("Reading the keys failed\n");
        return -1;
    }
    if( !add_ext( cert, cert, NID_crl_distribution_points, "URI:http://crl.cacert.org/revoke.crl" ) ){
        printf("Error while adding extension\n");
        return -1;
    }
    X509_sign(cert, pkey, EVP_sha256());

    PEM_write_bio_X509(out, cert);
    
    BIO_free(root);
    BIO_free(rootkey);
    BIO_free(out);
    X509_free(cert);
    EVP_PKEY_free(pkey);

    ERR_load_crypto_strings();
    ERR_print_errors_fp(stdout);
    printf("Success\n");
    ERR_free_strings();
    return 0;
}
Exemple #2
0
/* creates a self-signed certificate for a key */
X509 *
ship_create_selfsigned_cert(char *subject, int ttl, RSA* signer_key)
{
	X509 *x = 0, *ret = 0;
	X509_NAME *tmp = 0;
	EVP_PKEY *pr_key = 0;
	
	ASSERT_TRUE(x = X509_new(), err);
	ASSERT_TRUE(pr_key = EVP_PKEY_new(), err);
	ASSERT_TRUE(EVP_PKEY_set1_RSA(pr_key, signer_key), err);
	
	ASSERT_TRUE(X509_set_version(x, 2), err); /* version 3 certificate */
	ASN1_INTEGER_set(X509_get_serialNumber(x), 0);
        ASSERT_TRUE(X509_gmtime_adj(X509_get_notBefore(x), 0), err);
	ASSERT_TRUE(X509_gmtime_adj(X509_get_notAfter(x), (long)ttl), err);
	
	ASSERT_TRUE(tmp = X509_get_subject_name(x), err);
	ASSERT_TRUE(X509_NAME_add_entry_by_txt(tmp, "CN", MBSTRING_ASC, 
					       (unsigned char*)subject, -1, -1, 0), err);
	ASSERT_TRUE(X509_set_subject_name(x, tmp), err);

	ASSERT_TRUE(X509_set_pubkey(x, pr_key), err);
	ASSERT_TRUE(X509_sign(x, pr_key, EVP_sha1()), err);
	ret = x;
	x = NULL;
 err:
	if (x)
		X509_free(x);
	if (pr_key)
		EVP_PKEY_free(pr_key);
	return ret;
}
void AuthorityCertificateManager::getCertificateForTarget(boost::asio::ip::tcp::endpoint &endpoint,
							  bool wildcardOK,
							  X509 *serverCertificate,
							  Certificate **cert,
							  std::list<Certificate*> **chainList)
{
  X509_NAME *serverName   = X509_get_subject_name(serverCertificate);
  X509_NAME *issuerName   = X509_get_subject_name(authority->getCert());
  X509 *request           = X509_new();

  X509_set_version(request, 3);
  X509_set_subject_name(request, serverName);
  X509_set_issuer_name(request, issuerName);

  ASN1_INTEGER_set(X509_get_serialNumber(request), generateRandomSerial());
  X509_gmtime_adj(X509_get_notBefore(request), -365);
  X509_gmtime_adj(X509_get_notAfter(request), (long)60*60*24*365);
  X509_set_pubkey(request, this->leafPair);

  X509_sign(request, authority->getKey(), EVP_sha1());

  Certificate *leaf = new Certificate();
  leaf->setCert(request);
  leaf->setKey(this->leafPair);

  *cert  = leaf;
  *chainList = &(this->chainList);
  // *chain = this->authority;
}
gboolean
CertKey_GenerateKeyCert(int bits,                 // IN
                        int days,                 // IN
                        const gchar *confFile,    // IN
                        const gchar *keyFile,     // IN
                        const gchar *certFile)    // IN
{
   gboolean ret = FALSE;
   X509 *cert = NULL;
   X509_REQ *req = NULL;
   EVP_PKEY *pkey = NULL;
   CONF *config;
   gchar *err = NULL;

   config = LoadOpenSSLConf(confFile);
   if (!config) {
      goto exit;
   }

   req = GenerateX509CertReq(&pkey, config, bits);
   if (!req) {
      goto exit;
   }

   cert = GenerateX509Cert(req, config, days);
   if (!cert) {
      goto exit;
   }

   if (!X509_set_pubkey(cert, pkey)) {
      Error("Failed to set certificate public key: %s.\n",
            GetSSLError(&err));
      goto exit;
   }

   if (!X509_sign(cert, pkey, EVP_sha256())) {
      Error("Failed to sign the X509 certificate: %s.\n",
            GetSSLError(&err));
      goto exit;
   }

   /*
    * Write private key and certificate PEM files.
    */
   if (WritePemFile(pkey, keyFile, cert, certFile)) {
      ret = TRUE;
   }

exit:
   g_free(err);
   NCONF_free(config);
   EVP_PKEY_free(pkey);
   X509_REQ_free(req);
   X509_free(cert);

   return ret;
}
void init_certs(EC_GROUP *group, char *passwd, char *server, char *client) {
    EVP_PKEY *server_pk, *client_pk;

    X509 *server_cert = make_server_cert(group, &server_pk, SERVER_CN);
    X509 *client_cert = make_client_cert(group, &client_pk, CLIENT_CN, server_cert);

    const EVP_MD *md = EVP_get_digestbyname(X509_DIGEST_NAME);
    X509_sign(server_cert, server_pk, md);
    X509_sign(client_cert, server_pk, md);

    write_pem(server, (uint8_t *) passwd, strlen(passwd), server_pk, group, 1, server_cert);
    write_pem(client, (uint8_t *) passwd, strlen(passwd), client_pk, group, 2, server_cert, client_cert);

    X509_free(server_cert);
    X509_free(client_cert);
    EVP_PKEY_free(server_pk);
    EVP_PKEY_free(client_pk);
}
Exemple #6
0
// Generate a self-signed certificate, with the public key from the
// given key pair. Caller is responsible for freeing the returned object.
static X509* MakeCertificate(EVP_PKEY* pkey, const char* common_name) {
  LOG(LS_INFO) << "Making certificate for " << common_name;
  X509* x509 = NULL;
  BIGNUM* serial_number = NULL;
  X509_NAME* name = NULL;

  if ((x509=X509_new()) == NULL)
    goto error;

  if (!X509_set_pubkey(x509, pkey))
    goto error;

  // serial number
  // temporary reference to serial number inside x509 struct
  ASN1_INTEGER* asn1_serial_number;
  if (!(serial_number = BN_new()) ||
      !BN_pseudo_rand(serial_number, SERIAL_RAND_BITS, 0, 0) ||
      !(asn1_serial_number = X509_get_serialNumber(x509)) ||
      !BN_to_ASN1_INTEGER(serial_number, asn1_serial_number))
    goto error;

  if (!X509_set_version(x509, 0L))  // version 1
    goto error;

  // There are a lot of possible components for the name entries. In
  // our P2P SSL mode however, the certificates are pre-exchanged
  // (through the secure XMPP channel), and so the certificate
  // identification is arbitrary. It can't be empty, so we set some
  // arbitrary common_name. Note that this certificate goes out in
  // clear during SSL negotiation, so there may be a privacy issue in
  // putting anything recognizable here.
  if (!(name = X509_NAME_new()) ||
      !X509_NAME_add_entry_by_NID(name, NID_commonName, MBSTRING_UTF8,
                                     (unsigned char*)common_name, -1, -1, 0) ||
      !X509_set_subject_name(x509, name) ||
      !X509_set_issuer_name(x509, name))
    goto error;

  if (!X509_gmtime_adj(X509_get_notBefore(x509), 0) ||
      !X509_gmtime_adj(X509_get_notAfter(x509), CERTIFICATE_LIFETIME))
    goto error;

  if (!X509_sign(x509, pkey, EVP_sha1()))
    goto error;

  BN_free(serial_number);
  X509_NAME_free(name);
  LOG(LS_INFO) << "Returning certificate";
  return x509;

 error:
  BN_free(serial_number);
  X509_NAME_free(name);
  X509_free(x509);
  return NULL;
}
Exemple #7
0
static X509 *X509_REQ_to_X509_ex(X509_REQ *r, int days, EVP_PKEY *pkey, const EVP_MD* md)
{
  X509 *ret = NULL;
  X509_CINF *xi = NULL;
  X509_NAME *xn;
  EVP_PKEY *pubkey = NULL;
  int res;

  if ((ret = X509_new()) == NULL)
  {
    X509err(X509_F_X509_REQ_TO_X509, ERR_R_MALLOC_FAILURE);
    return NULL;
  }

  /* duplicate the request */
  xi = ret->cert_info;

  if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0)
  {
    if ((xi->version = M_ASN1_INTEGER_new()) == NULL)
      goto err;
    if (!ASN1_INTEGER_set(xi->version, 2))
      goto err;
    /*-     xi->extensions=ri->attributes; <- bad, should not ever be done
    ri->attributes=NULL; */
  }

  xn = X509_REQ_get_subject_name(r);
  if (X509_set_subject_name(ret, xn) == 0)
    goto err;
  if (X509_set_issuer_name(ret, xn) == 0)
    goto err;

  if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL)
    goto err;
  if (X509_gmtime_adj(xi->validity->notAfter, (long)60 * 60 * 24 * days) ==
      NULL)
    goto err;

  pubkey = X509_REQ_get_pubkey(r);
  res = X509_set_pubkey(ret, pubkey);
  EVP_PKEY_free(pubkey);

  if (!md)
    goto err;
  if (!res || !X509_sign(ret, pkey, md))
    goto err;
  if (0)
  {
err:
    X509_free(ret);
    ret = NULL;
  }
  return (ret);
}
Exemple #8
0
static void mkcert(std::shared_ptr<X509> &cert,
                  std::shared_ptr<EVP_PKEY> &pkey, int bits, int serial,
                  int days)
{
    RSA *rsa;
    X509_NAME *name=NULL;

    pkey.reset(EVP_PKEY_new(), &EVP_PKEY_free);
    if (!pkey)
        throw std::bad_alloc();
    cert.reset(X509_new(), &X509_free);
    if (!cert)
        throw std::bad_alloc();

    rsa = RSA_generate_key(bits,RSA_F4,NULL,NULL);
    MORDOR_VERIFY(EVP_PKEY_assign_RSA(pkey.get(),rsa));

    X509_set_version(cert.get(),2);
    ASN1_INTEGER_set(X509_get_serialNumber(cert.get()),serial);
    X509_gmtime_adj(X509_get_notBefore(cert.get()),0);
    X509_gmtime_adj(X509_get_notAfter(cert.get()),(long)60*60*24*days);
    X509_set_pubkey(cert.get(),pkey.get());

    name=X509_get_subject_name(cert.get());

    /* This function creates and adds the entry, working out the
     * correct string type and performing checks on its length.
     * Normally we'd check the return value for errors...
     */
    X509_NAME_add_entry_by_txt(name,"C",
                            MBSTRING_ASC,
                            (const unsigned char *)"United States",
                            -1, -1, 0);
    X509_NAME_add_entry_by_txt(name,"CN",
                            MBSTRING_ASC,
                            (const unsigned char *)"Mordor Default Self-signed Certificate",
                            -1, -1, 0);

    /* Its self signed so set the issuer name to be the same as the
     * subject.
     */
    X509_set_issuer_name(cert.get(),name);

    /* Add various extensions: standard extensions */
    add_ext(cert.get(), NID_basic_constraints, "critical,CA:TRUE");
    add_ext(cert.get(), NID_key_usage, "critical,keyCertSign,cRLSign");

    add_ext(cert.get(), NID_subject_key_identifier, "hash");

    /* Some Netscape specific extensions */
    add_ext(cert.get(), NID_netscape_cert_type, "sslCA");

    MORDOR_VERIFY(X509_sign(cert.get(),pkey.get(),EVP_md5()));
}
Exemple #9
0
sqbind::SQINT COsslCert::Sign( COsslKey *x_pKey )
{_STT();

	if ( !m_pX509 || !x_pKey )
		return 0;

	// Sign the cert
	X509_sign( m_pX509, x_pKey->getPublicKeyPtr(), EVP_sha1() );

	return 1;
}
Exemple #10
0
X509* DsaCa_SignCertificate(DsaCa ca, X509* cert_in)
{
  CHECK_CALL(X509_verify(cert_in, DsaParams_GetEaPublicKey(ca->params)));
  CHECK_CALL(cert_in);
  X509* cert_out = X509_dup(cert_in);
  CHECK_CALL(cert_out);

  CHECK_CALL(X509_sign(cert_in, DsaParams_GetCaPrivateKey(ca->params), EVP_sha1()));
  
  return cert_out;
}
Exemple #11
0
bool Certificate::sign(EVP_PKEY *key)
{
	bool res = false;
	
	if (key && X509_sign(x, key, EVP_sha1())) 
		hasSignature = res = true;
	else {
		writeErrors("");
	}

	return res;
}
const std::string BEX509::generate ( )
{
	if ( ! X509_set_issuer_name ( x509, name ) ) {
		throw BEPlugin_Exception ( (fmx::errcode)ERR_get_error() );
	}

	if ( ! X509_sign ( x509, private_key, EVP_sha1() ) ) {
		throw BEPlugin_Exception ( (fmx::errcode)ERR_get_error() );
	}

	std::unique_ptr<BEBio> bio ( new BEBio );

	return bio->extract ( x509 );
	
}
Exemple #13
0
X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey)
{
    X509 *ret = NULL;
    X509_CINF *xi = NULL;
    X509_NAME *xn;

    if ((ret = X509_new()) == NULL) {
        OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    /* duplicate the request */
    xi = ret->cert_info;

    if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0) {
        if ((xi->version = M_ASN1_INTEGER_new()) == NULL)
            goto err;
        if (!ASN1_INTEGER_set(xi->version, 2))
            goto err;
        /*
         * xi->extensions=ri->attributes; <- bad, should not ever be done
         * ri->attributes=NULL;
         */
    }

    xn = X509_REQ_get_subject_name(r);
    if (X509_set_subject_name(ret, X509_NAME_dup(xn)) == 0)
        goto err;
    if (X509_set_issuer_name(ret, X509_NAME_dup(xn)) == 0)
        goto err;

    if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL)
        goto err;
    if (X509_gmtime_adj(xi->validity->notAfter, (long)60 * 60 * 24 * days) ==
        NULL)
        goto err;

    X509_set_pubkey(ret, X509_REQ_get_pubkey(r));

    if (!X509_sign(ret, pkey, EVP_md5()))
        goto err;
    if (0) {
 err:
        X509_free(ret);
        ret = NULL;
    }
    return (ret);
}
Exemple #14
0
Settings::KeyPair CertWizard::generateNewCert(QString qsname, const QString &qsemail) {
	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

	X509 *x509 = X509_new();
	EVP_PKEY *pkey = EVP_PKEY_new();
	RSA *rsa = RSA_generate_key(2048,RSA_F4,NULL,NULL);
	EVP_PKEY_assign_RSA(pkey, rsa);

	X509_set_version(x509, 2);
	ASN1_INTEGER_set(X509_get_serialNumber(x509),1);
	X509_gmtime_adj(X509_get_notBefore(x509),0);
	X509_gmtime_adj(X509_get_notAfter(x509),60*60*24*365*20);
	X509_set_pubkey(x509, pkey);

	X509_NAME *name=X509_get_subject_name(x509);

	if (qsname.isEmpty())
		qsname = tr("Mumble User");

	X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, reinterpret_cast<unsigned char *>(qsname.toUtf8().data()), -1, -1, 0);
	X509_set_issuer_name(x509, name);
	add_ext(x509, NID_basic_constraints, SSL_STRING("critical,CA:FALSE"));
	add_ext(x509, NID_ext_key_usage, SSL_STRING("clientAuth"));
	add_ext(x509, NID_subject_key_identifier, SSL_STRING("hash"));
	add_ext(x509, NID_netscape_comment, SSL_STRING("Generated by Mumble"));
	add_ext(x509, NID_subject_alt_name, QString::fromLatin1("email:%1").arg(qsemail).toUtf8().data());

	X509_sign(x509, pkey, EVP_sha1());

	QByteArray crt, key;

	crt.resize(i2d_X509(x509, NULL));
	unsigned char *dptr=reinterpret_cast<unsigned char *>(crt.data());
	i2d_X509(x509, &dptr);

	QSslCertificate qscCert = QSslCertificate(crt, QSsl::Der);

	key.resize(i2d_PrivateKey(pkey, NULL));
	dptr=reinterpret_cast<unsigned char *>(key.data());
	i2d_PrivateKey(pkey, &dptr);

	QSslKey qskKey = QSslKey(key, QSsl::Rsa, QSsl::Der);

	QList<QSslCertificate> qlCert;
	qlCert << qscCert;

	return Settings::KeyPair(qlCert, qskKey);
}
Exemple #15
0
static X509 *
gen_cert(EVP_PKEY* pkey, const char *common, int days) {
  X509 *x509 = NULL;
  BIGNUM *serial_number = NULL;
  X509_NAME *name = NULL;

  if ((x509 = X509_new()) == NULL)
    return NULL;

  if (!X509_set_pubkey(x509, pkey))
    return NULL;

  ASN1_INTEGER* asn1_serial_number;
  if ((serial_number = BN_new()) == NULL ||
      !BN_pseudo_rand(serial_number, 64, 0, 0) ||
      (asn1_serial_number = X509_get_serialNumber(x509)) == NULL ||
      !BN_to_ASN1_INTEGER(serial_number, asn1_serial_number))
    goto cert_err;

  if (!X509_set_version(x509, 0L)) // version 1
    goto cert_err;

  if ((name = X509_NAME_new()) == NULL ||
      !X509_NAME_add_entry_by_NID(
          name, NID_commonName, MBSTRING_UTF8,
          (unsigned char*)common, -1, -1, 0) ||
      !X509_set_subject_name(x509, name) ||
      !X509_set_issuer_name(x509, name))
    goto cert_err;

  if (!X509_gmtime_adj(X509_get_notBefore(x509), 0) ||
      !X509_gmtime_adj(X509_get_notAfter(x509), days * 24 * 3600))
    goto cert_err;

  if (!X509_sign(x509, pkey, EVP_sha1()))
    goto cert_err;

  if (0) {
cert_err:  
    X509_free(x509);
    x509 = NULL;
  }
  BN_free(serial_number);
  X509_NAME_free(name);

  return x509;
}
bool
parcSelfSignedCertificate_CreateRSACertificate(const char *subjectname, unsigned keylength, unsigned validityDays, X509 *cert, RSA *rsa, EVP_PKEY *private_key)
{
    int res;
    bool return_value = false;
    BIGNUM *pub_exp;

    pub_exp = BN_new();

    BN_set_word(pub_exp, RSA_F4);
    res = 1;
    if (RSA_generate_key_ex(rsa, keylength, pub_exp, NULL)) {
        if (EVP_PKEY_set1_RSA(private_key, rsa)) {
            if (X509_set_version(cert, 2)) { // 2 => X509v3
                return_value = true;
            }
        }
    }
    if (return_value) {
        // add serial number
        if (_addRandomSerial(cert) == true) {
            if (_addValidityPeriod(cert, validityDays) == true) {
                if (X509_set_pubkey(cert, private_key) == 1) {
                    if (_addSubjectName(cert, subjectname) == true) {
                        if (_addExtensions(cert) == true) {
                            if (_addKeyIdentifier(cert) == true) {
                                // The certificate is complete, sign it.
                                if (X509_sign(cert, private_key, EVP_sha256())) {
                                    return_value = true;
                                } else {
                                    printf("error: (%d) %s\n", res, ERR_lib_error_string(res));
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    ERR_print_errors_fp(stdout);

    BN_free(pub_exp);

    return return_value;
}
Exemple #17
0
void mkcert(X509_REQ* req, const char* rootkey, const char* rootcert, const char* passwd)
{
	RSA* rsa_key = EVP_PKEY_get1_RSA(X509_PUBKEY_get(req->req_info->pubkey));
	int key_length = RSA_size(rsa_key);
	if (key_len != 128) {
		fprintf(stderr, "CA::key length of req is %d, not long enough\n");      
		return NULL;
	}

	X509* cacert = X509_new();
	assert(cacert != NULL);

	load_cacert(&cacert, rootcert);

	EVP_PKEY* cakey = EVP_PKEY_new();
	load_cakey(&cakey, rootkey, passwd);

	PEM_write_PrivateKey(stdout, cakey, NULL, NULL, 0, NULL, NULL);
	PEM_write_PUBKEY(stdout, cakey);

	X509* x = X509_new();
	X509_set_version(x, 3);
	ASN1_INTEGER_set(X509_get_serialNumber(x), 1024);
	X509_gmtime_adj(X509_get_notBefore(x), 0);
	X509_gmtime_adj(X509_get_notAfter(x), (long)60 * 60 * 24 * 365);

	X509_set_pubkey(x, X509_PUBKEY_get(req->req_info->pubkey));

	X509_set_subject_name(x, X509_REQ_get_subject_name(req));
	X509_set_issuer_name(x, X509_get_subject_name(cacert));

	assert(X509_sign(x, cakey, EVP_sha1()) > 0);

	FILE* f = fopen("usercert.pem", "wb");
	PEM_write_X509(f, x);
	fclose(f);

	X509_print_fp(stdout, x);
	PEM_write_X509(stdout, x);

	X509_free(cacert);
	EVP_PKEY_free(cakey);
}
Exemple #18
0
        RSA* Rsa::ssl_generateKeys (int size) {
            Rsa::size = size;


            RSA* key_pair = RSA_generate_key(size, 3, NULL, NULL);
            /*PEM_write_bio_RSAPublicKey(pub, keypair);
            pub_len = BIO_pending(pub);
            pub_key = (char*) malloc(pub_len + 1);
            BIO_read(pub, pub_key, pub_len);
            pub_key[pub_len] = '\0';*/
            EVP_PKEY_set1_RSA(evp_pkey, key_pair);
            X509_set_version(x,2);
            ASN1_INTEGER_set(X509_get_serialNumber(x),0);
            X509_gmtime_adj(X509_get_notBefore(x),0);
            X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*365);
            X509_set_pubkey(x,evp_pkey);
            //X509_NAME* name = X509_get_subject_name(x);

            /* This function creates and adds the entry, working out the
             * correct string type and performing checks on its length.
             * Normally we'd check the return value for errors...
             */
           /* X509_NAME_add_entry_by_txt(name,"C", MBSTRING_ASC, (unsigned char*) "BE", -1, -1, 0);
            X509_NAME_add_entry_by_txt(name,"Falior",
            MBSTRING_ASC, (unsigned char*) "Falior Group", -1, -1, 0);*/

            /* Its self signed so set the issuer name to be the same as the
                * subject.
            */
            //X509_set_issuer_name(x,name);
            /* Add various extensions: standard extensions */
            /*add_ext(x, NID_basic_constraints, "critical,CA:TRUE");
            add_ext(x, NID_key_usage, "critical,keyCertSign,cRLSign");

            add_ext(x, NID_subject_key_identifier, "hash");


            add_ext(x, NID_netscape_cert_type, "sslCA");

            add_ext(x, NID_netscape_comment, "example comment extension");*/
            X509_sign(x,evp_pkey,EVP_sha1());
            return key_pair;
        }
Exemple #19
0
static X509 *
getcert(void)
{
	/* Dummy code to make a quick-and-dirty valid certificate with
	   OpenSSL.  Don't copy this code into your own program! It does a
	   number of things in a stupid and insecure way. */
	X509 *x509 = NULL;
	X509_NAME *name = NULL;
	EVP_PKEY *key = getkey();
	int nid;
	time_t now = time(NULL);

	tt_assert(key);

	x509 = X509_new();
	tt_assert(x509);
	tt_assert(0 != X509_set_version(x509, 2));
	tt_assert(0 != ASN1_INTEGER_set(X509_get_serialNumber(x509),
		(long)now));

	name = X509_NAME_new();
	tt_assert(name);
	nid = OBJ_txt2nid("commonName");
	tt_assert(NID_undef != nid);
	tt_assert(0 != X509_NAME_add_entry_by_NID(
		    name, nid, MBSTRING_ASC, (unsigned char*)"example.com",
		    -1, -1, 0));

	X509_set_subject_name(x509, name);
	X509_set_issuer_name(x509, name);

	X509_time_adj(X509_get_notBefore(x509), 0, &now);
	now += 3600;
	X509_time_adj(X509_get_notAfter(x509), 0, &now);
	X509_set_pubkey(x509, key);
	tt_assert(0 != X509_sign(x509, key, EVP_sha1()));

	return x509;
end:
	X509_free(x509);
	return NULL;
}
Exemple #20
0
X509 *
ssl_update_certificate(X509 *oldcert, EVP_PKEY *pkey, EVP_PKEY *capkey,
    X509 *cacert)
{
	char		 name[2][TLS_NAME_SIZE];
	X509		*cert = NULL;

	name[0][0] = name[1][0] = '\0';
	if (!X509_NAME_oneline(X509_get_subject_name(oldcert),
	    name[0], sizeof(name[0])) ||
	    !X509_NAME_oneline(X509_get_issuer_name(oldcert),
	    name[1], sizeof(name[1])))
		goto done;

	if ((cert = X509_dup(oldcert)) == NULL)
		goto done;

	/* Update certificate key and use our CA as the issuer */
	X509_set_pubkey(cert, pkey);
	X509_set_issuer_name(cert, X509_get_subject_name(cacert));

	/* Sign with our CA */
	if (!X509_sign(cert, capkey, EVP_sha1())) {
		X509_free(cert);
		cert = NULL;
	}

#if DEBUG_CERT
	log_debug("%s: subject %s", __func__, name[0]);
	log_debug("%s: issuer %s", __func__, name[1]);
#if DEBUG > 2
	X509_print_fp(stdout, cert);
#endif
#endif

 done:
	if (cert == NULL)
		ssl_error(__func__, name[0]);

	return (cert);
}
Exemple #21
0
/* self sign */
static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext, const EVP_MD *digest, 
						CONF *conf, char *section)
	{

	EVP_PKEY *pktmp;

	pktmp = X509_get_pubkey(x);
	EVP_PKEY_copy_parameters(pktmp,pkey);
	EVP_PKEY_save_parameters(pktmp,1);
	EVP_PKEY_free(pktmp);

	if (!X509_set_issuer_name(x,X509_get_subject_name(x))) goto err;
	if (X509_gmtime_adj(X509_get_notBefore(x),0) == NULL) goto err;

	/* Lets just make it 12:00am GMT, Jan 1 1970 */
	/* memcpy(x->cert_info->validity->notBefore,"700101120000Z",13); */
	/* 28 days to be certified */

	if (X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days) == NULL)
		goto err;

	if (!X509_set_pubkey(x,pkey)) goto err;
	if (clrext)
		{
		while (X509_get_ext_count(x) > 0) X509_delete_ext(x, 0);
		}
	if (conf)
		{
		X509V3_CTX ctx;
		X509_set_version(x,2); /* version 3 certificate */
                X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0);
                X509V3_set_nconf(&ctx, conf);
                if (!X509V3_EXT_add_nconf(conf, &ctx, section, x)) goto err;
		}
	if (!X509_sign(x,pkey,digest)) goto err;
	return 1;
err:
	ERR_print_errors(bio_err);
	return 0;
	}
//Self signed
X509* generate_x509(EVP_PKEY* pkey)
{
	printf("....Generating Cert....\n");
	X509 * x509;
	x509 = X509_new();

	// Set serial no to 1 for now
	ASN1_INTEGER_set(X509_get_serialNumber(x509), 1);
	// Set validity
	X509_gmtime_adj(X509_get_notBefore(x509), 0);
	X509_gmtime_adj(X509_get_notAfter(x509), 3153600L);
	// Set pubkey
	X509_set_pubkey(x509, pkey);

	X509_NAME *name;
	name = X509_get_subject_name(x509);

	// Country
	X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC,
							 (unsigned char*)"IE", -1, -1, 0);
	// Company/Organization
	X509_NAME_add_entry_by_txt(name, "O",  MBSTRING_ASC,
                             (unsigned char*)"MyCompany Inc.", -1, -1, 0);
	// Common Name
	X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
                             (unsigned char*)"localhost", -1, -1, 0);

	// Set issuer name
	X509_set_issuer_name(x509, name);

	// Self-signed for now
	X509_sign(x509, pkey, EVP_sha1());

    if(x509 == NULL) { printf("!!!!!!!X509 IS NULL!!!!!!!"); }


	return x509;
}
Exemple #23
0
static int mkcert(X509 **x509p, EVP_PKEY **pkeyp, int bits, int serial, int days)
	{
	X509 *x;
	EVP_PKEY *pk;
	RSA *rsa;
	X509_NAME *name=NULL;
	
	if ((pkeyp == NULL) || (*pkeyp == NULL))
		{
		if ((pk=EVP_PKEY_new()) == NULL)
			{
			abort(); 
			return(0);
			}
		}
	else
		pk= *pkeyp;

	if ((x509p == NULL) || (*x509p == NULL))
		{
		if ((x=X509_new()) == NULL)
			goto err;
		}
	else
		x= *x509p;

    if (bits != 0){
        rsa=RSA_generate_key(bits,RSA_F4,callback,NULL);
        if (!EVP_PKEY_assign_RSA(pk,rsa))
        {
            abort();
            goto err;
        }
        rsa=NULL;
    }

	X509_set_version(x,2);
	ASN1_INTEGER_set(X509_get_serialNumber(x),serial);
	X509_gmtime_adj(X509_get_notBefore(x),0);
	X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);
	X509_set_pubkey(x,pk);

	name=X509_get_subject_name(x);

	/* This function creates and adds the entry, working out the
	 * correct string type and performing checks on its length.
	 * Normally we'd check the return value for errors...
	 */
	X509_NAME_add_entry_by_txt(name,"C",
				MBSTRING_ASC,(const unsigned char *) "UK", -1, -1, 0);
	X509_NAME_add_entry_by_txt(name,"CN",
				MBSTRING_ASC, (const unsigned char *) _cert_cn, -1, -1, 0);

	/* Its self signed so set the issuer name to be the same as the
 	 * subject.
	 */
	X509_set_issuer_name(x,name);

	/* Add various extensions: standard extensions */
	add_ext(x, NID_basic_constraints, "critical,CA:TRUE");
	add_ext(x, NID_key_usage, "critical,keyCertSign,cRLSign");

	add_ext(x, NID_subject_key_identifier, "hash");

	/* Some Netscape specific extensions */
	add_ext(x, NID_netscape_cert_type, "sslCA");

	add_ext(x, NID_netscape_comment, "example comment extension");


#ifdef CUSTOM_EXT
	/* Maybe even add our own extension based on existing */
	{
		int nid;
		nid = OBJ_create("1.2.3.4", "MyAlias", "My Test Alias Extension");
		X509V3_EXT_add_alias(nid, NID_netscape_comment);
		add_ext(x, nid, "example comment alias");
	}
#endif
	
	if (!X509_sign(x,pk,EVP_sha1()))
		goto err;

	*x509p=x;
	*pkeyp=pk;
	return(1);
err:
	return(0);
}
Exemple #24
0
Try<X509*> generate_x509(
    EVP_PKEY* subject_key,
    EVP_PKEY* sign_key,
    const Option<X509*>& parent_certificate,
    int serial,
    int days,
    Option<std::string> hostname)
{
  Option<X509_NAME*> issuer_name = None();
  if (parent_certificate.isNone()) {
    // If there is no parent certificate, then the subject and
    // signing key must be the same.
    if (subject_key != sign_key) {
      return Error("Subject vs signing key mismatch");
    }
  } else {
    // If there is a parent certificate, then set the issuer name to
    // be that of the parent.
    issuer_name = X509_get_subject_name(parent_certificate.get());

    if (issuer_name.get() == NULL) {
      return Error("Failed to get subject name of parent certificate: "
        "X509_get_subject_name");
    }
  }

  // Allocate the in-memory structure for the certificate.
  X509* x509 = X509_new();
  if (x509 == NULL) {
    return Error("Failed to allocate certification: X509_new");
  }

  // Set the version to V3.
  if (X509_set_version(x509, 2) != 1) {
    X509_free(x509);
    return Error("Failed to set version: X509_set_version");
  }

  // Set the serial number.
  if (ASN1_INTEGER_set(X509_get_serialNumber(x509), serial) != 1) {
    X509_free(x509);
    return Error("Failed to set serial number: ASN1_INTEGER_set");
  }

  // Make this certificate valid for 'days' number of days from now.
  if (X509_gmtime_adj(X509_get_notBefore(x509), 0) == NULL ||
      X509_gmtime_adj(X509_get_notAfter(x509),
                      60L * 60L * 24L * days) == NULL) {
    X509_free(x509);
    return Error("Failed to set valid days of certificate: X509_gmtime_adj");
  }

  // Set the public key for our certificate based on the subject key.
  if (X509_set_pubkey(x509, subject_key) != 1) {
    X509_free(x509);
    return Error("Failed to set public key: X509_set_pubkey");
  }

  // Figure out our hostname if one was not provided.
  if (hostname.isNone()) {
    const Try<std::string> _hostname = net::hostname();
    if (_hostname.isError()) {
      X509_free(x509);
      return Error("Failed to determine hostname");
    }

    hostname = _hostname.get();
  }

  // Grab the subject name of the new certificate.
  X509_NAME* name = X509_get_subject_name(x509);
  if (name == NULL) {
    X509_free(x509);
    return Error("Failed to get subject name: X509_get_subject_name");
  }

  // Set the country code, organization, and common name.
  if (X509_NAME_add_entry_by_txt(
          name,
          "C",
          MBSTRING_ASC,
          reinterpret_cast<const unsigned char*>("US"),
          -1,
          -1,
          0) != 1) {
    X509_free(x509);
    return Error("Failed to set country code: X509_NAME_add_entry_by_txt");
  }

  if (X509_NAME_add_entry_by_txt(
          name,
          "O",
          MBSTRING_ASC,
          reinterpret_cast<const unsigned char*>("Test"),
          -1,
          -1,
          0) != 1) {
    X509_free(x509);
    return Error("Failed to set organization name: X509_NAME_add_entry_by_txt");
  }

  if (X509_NAME_add_entry_by_txt(
          name,
          "CN",
          MBSTRING_ASC,
          reinterpret_cast<const unsigned char*>(hostname.get().c_str()),
          -1,
          -1,
          0) != 1) {
    X509_free(x509);
    return Error("Failed to set common name: X509_NAME_add_entry_by_txt");
  }

  // Set the issuer name to be the same as the subject if it is not
  // already set (this is a self-signed certificate).
  if (issuer_name.isNone()) {
    issuer_name = name;
  }

  CHECK_SOME(issuer_name);
  if (X509_set_issuer_name(x509, issuer_name.get()) != 1) {
    X509_free(x509);
    return Error("Failed to set issuer name: X509_set_issuer_name");
  }

  // Sign the certificate with the sign key.
  if (X509_sign(x509, sign_key, EVP_sha1()) == 0) {
    X509_free(x509);
    return Error("Failed to sign certificate: X509_sign");
  }

  return x509;
}
Exemple #25
0
static int cert_init() {
	X509 *x509 = NULL;
	EVP_PKEY *pkey = NULL;
	BIGNUM *exponent = NULL, *serial_number = NULL;
	RSA *rsa = NULL;
	ASN1_INTEGER *asn1_serial_number;
	X509_NAME *name;
	struct dtls_cert *new_cert;

	ilog(LOG_INFO, "Generating new DTLS certificate");

	/* objects */

	pkey = EVP_PKEY_new();
	exponent = BN_new();
	rsa = RSA_new();
	serial_number = BN_new();
	name = X509_NAME_new();
	x509 = X509_new();
	if (!exponent || !pkey || !rsa || !serial_number || !name || !x509)
		goto err;

	/* key */

	if (!BN_set_word(exponent, 0x10001))
		goto err;

	if (!RSA_generate_key_ex(rsa, 1024, exponent, NULL))
		goto err;

	if (!EVP_PKEY_assign_RSA(pkey, rsa))
		goto err;

	/* x509 cert */

	if (!X509_set_pubkey(x509, pkey))
		goto err;

	/* serial */

	if (!BN_pseudo_rand(serial_number, 64, 0, 0))
		goto err;

	asn1_serial_number = X509_get_serialNumber(x509);
	if (!asn1_serial_number)
		goto err;

	if (!BN_to_ASN1_INTEGER(serial_number, asn1_serial_number))
		goto err;

	/* version 1 */

	if (!X509_set_version(x509, 0L))
		goto err;

	/* common name */

	if (!X509_NAME_add_entry_by_NID(name, NID_commonName, MBSTRING_UTF8,
				(unsigned char *) "rtpengine", -1, -1, 0))
		goto err;

	if (!X509_set_subject_name(x509, name))
		goto err;

	if (!X509_set_issuer_name(x509, name))
		goto err;

	/* cert lifetime */

	if (!X509_gmtime_adj(X509_get_notBefore(x509), -60*60*24))
		goto err;

	if (!X509_gmtime_adj(X509_get_notAfter(x509), CERT_EXPIRY_TIME))
		goto err;

	/* sign it */

	if (!X509_sign(x509, pkey, EVP_sha1()))
		goto err;

	/* digest */

	new_cert = obj_alloc0("dtls_cert", sizeof(*new_cert), cert_free);
	new_cert->fingerprint.hash_func = &hash_funcs[0];
	dtls_fingerprint_hash(&new_cert->fingerprint, x509);

	new_cert->x509 = x509;
	new_cert->pkey = pkey;
	new_cert->expires = time(NULL) + CERT_EXPIRY_TIME;

	dump_cert(new_cert);

	/* swap out certs */

	rwlock_lock_w(&__dtls_cert_lock);

	if (__dtls_cert)
		obj_put(__dtls_cert);
	__dtls_cert = new_cert;

	rwlock_unlock_w(&__dtls_cert_lock);

	/* cleanup */

	BN_free(exponent);
	BN_free(serial_number);
	X509_NAME_free(name);

	return 0;

err:
	ilog(LOG_ERROR, "Failed to generate DTLS certificate");

	if (pkey)
		EVP_PKEY_free(pkey);
	if (exponent)
		BN_free(exponent);
	if (rsa)
		RSA_free(rsa);
	if (x509)
		X509_free(x509);
	if (serial_number)
		BN_free(serial_number);

	return -1;
}
Exemple #26
0
static void pki_sign_certificate(EVP_PKEY *keyring, X509 *certificate)
{
	jlog(L_NOTICE, "pki_sign_certificate");

	X509_sign(certificate, keyring, EVP_sha1());
}
Exemple #27
0
DVT_STATUS CERTIFICATE_CLASS::generateFiles(LOG_CLASS* logger_ptr,
											const char* signerCredentialsFile_ptr, 
											const char* credentialsPassword_ptr,
											const char* keyPassword_ptr,
											const char* keyFile_ptr, 
											const char* certificateFile_ptr)

//  DESCRIPTION     : Generate a certificate and key files from this class.
//  PRECONDITIONS   :
//  POSTCONDITIONS  :
//  EXCEPTIONS      : 
//  NOTES           : If signerCredentialsFile_ptr is NULL, a self signed 
//					: certificate will be generated.
//					:
//					: Returns:  MSG_OK, MSG_LIB_NOT_EXIST, MSG_FILE_NOT_EXIST, 
//					: MSG_ERROR, MSG_INVALID_PASSWORD 
//<<===========================================================================
{
	DVT_STATUS ret = MSG_ERROR;
	unsigned long err;
	OPENSSL_CLASS* openSsl_ptr;
	BIO* caBio_ptr = NULL;
	EVP_PKEY* caPrivateKey_ptr = NULL;
	X509* caCertificate_ptr = NULL;
	EVP_PKEY* key_ptr = NULL;
	X509* cert_ptr = NULL;
	X509_NAME* name_ptr;
	time_t effectiveTime;
	time_t expirationTime;
	EVP_PKEY* tmpKey_ptr;
	const EVP_MD *digest_ptr;
	BIO* pkBio_ptr = NULL;
	const EVP_CIPHER *cipher_ptr;
	BIO* certBio_ptr = NULL;

	// check for the existence of the OpenSSL DLLs
	openSsl_ptr = OPENSSL_CLASS::getInstance();
	if (openSsl_ptr == NULL)
	{
		return MSG_LIB_NOT_EXIST;
	}

	// clear the error queue
	ERR_clear_error();

	if (signerCredentialsFile_ptr != NULL)
	{
		// open the credentials file
		caBio_ptr = BIO_new(BIO_s_file_internal());
		if (caBio_ptr == NULL)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting up to read CA credentials file");
			goto end;
		}
		if (BIO_read_filename(caBio_ptr, signerCredentialsFile_ptr) <= 0)
		{
			err = ERR_peek_error();
			if ((ERR_GET_LIB(err) == ERR_LIB_SYS) && (ERR_GET_REASON(err) == ERROR_FILE_NOT_FOUND))
			{
				// file does not exist
				ERR_clear_error(); // eat any errors
				ret = MSG_FILE_NOT_EXIST;
			}
			else
			{
				openSsl_ptr->printError(logger_ptr, LOG_ERROR, "opening CA credentials file for reading");
			}
			goto end;
		}

		// read the certificate authority's private key
		caPrivateKey_ptr = PEM_read_bio_PrivateKey(caBio_ptr, NULL, NULL, (void*)credentialsPassword_ptr);
		if (caPrivateKey_ptr == NULL)
		{
			err = ERR_peek_error();
			if ((ERR_GET_LIB(err) == ERR_LIB_EVP) && (ERR_GET_REASON(err) == EVP_R_BAD_DECRYPT))
			{
				// bad password
				ERR_clear_error(); // eat any errors
				ret = MSG_INVALID_PASSWORD;
			}
			else
			{
				openSsl_ptr->printError(logger_ptr, LOG_ERROR, "reading private key from CA credentials file");
			}
			goto end;
		}

		// read the certificate authority's certificate
		caCertificate_ptr = PEM_read_bio_X509(caBio_ptr, NULL, NULL, (void*)credentialsPassword_ptr);
		if (caCertificate_ptr == NULL)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "reading CA certificate from CA credentials file");
			goto end;
		}
	}

	// generate the new private/public key pair
	if (signatureAlgorithmM.compare("RSA") == 0)
	{
		// RSA key
		RSA* rsa_key;

		rsa_key = RSA_generate_key(signatureKeyLengthM, RSA_3, NULL, 0);
		if (rsa_key == NULL)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "generating RSA key");
			goto end;
		}

		key_ptr = EVP_PKEY_new();
		if (key_ptr == NULL)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "creating RSA key");
			RSA_free(rsa_key);
			goto end;
		}

		EVP_PKEY_assign_RSA(key_ptr, rsa_key);
	}
	else
	{
		// DSA key
		DSA* dsa_key;

		dsa_key = DSA_generate_parameters(signatureKeyLengthM, NULL, 0, NULL, NULL, NULL, 0);
		if (dsa_key == NULL)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "generating DSA parameters");
			goto end;
		}

		if (DSA_generate_key(dsa_key) == 0)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "generating DSA key");
			DSA_free(dsa_key);
			goto end;
		}

		key_ptr = EVP_PKEY_new();
		if (key_ptr == NULL)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "creating DSA key");
			DSA_free(dsa_key);
			goto end;
		}

		EVP_PKEY_assign_DSA(key_ptr, dsa_key);
	}

	// create the certificate
	cert_ptr = X509_new();
	if (cert_ptr == NULL)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "creating certificate object");
		goto end;
	}

	// version
	if (X509_set_version(cert_ptr, (versionM - 1)) != 1)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting certificate version");
		goto end;
	}

	// subject
	name_ptr = openSsl_ptr->onelineName2Name(subjectM.c_str());
	if (name_ptr == NULL)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "parsing owner name");
		goto end;
	}

	if (X509_set_subject_name(cert_ptr, name_ptr) != 1)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting owner name in certificate");
		goto end;
	}

	// issuer
	if (signerCredentialsFile_ptr != NULL)
	{
		// CA signed
		name_ptr = X509_get_subject_name(caCertificate_ptr);
		if (name_ptr == NULL)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "getting name from CA certificate");
			goto end;
		}

		if (X509_set_issuer_name(cert_ptr, name_ptr) != 1)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting issuer name in certificate");
			goto end;
		}
	}
	else
	{
		// self signed
		name_ptr = X509_NAME_dup(name_ptr); // duplicate the name so it can be used again
		if (name_ptr == NULL)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "duplicating owner name");
			goto end;
		}

		if (X509_set_issuer_name(cert_ptr, name_ptr) != 1)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting issuer name in certificate");
			goto end;
		}
	}
	
	// public key
	if (X509_set_pubkey(cert_ptr, key_ptr) != 1)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting public key in certificate");
		goto end;
	}

	// valid dates
	effectiveTime = mktime(&effectiveDateM);
	expirationTime = mktime(&expirationDateM);
	if ((X509_time_adj(X509_get_notBefore(cert_ptr), 0, &effectiveTime) == NULL) ||
		(X509_time_adj(X509_get_notAfter(cert_ptr), 0, &expirationTime) == NULL))
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting valid dates in certificate");
		goto end;
	}

	// serial number, use the current time_t
	ASN1_INTEGER_set(X509_get_serialNumber(cert_ptr), (unsigned)time(NULL));

	// sign the certificate
	if (signerCredentialsFile_ptr != NULL)
	{
		// CA signed
		tmpKey_ptr = caPrivateKey_ptr;
	}
	else
	{
		// self signed
		tmpKey_ptr = key_ptr;
	}

	if (EVP_PKEY_type(tmpKey_ptr->type) == EVP_PKEY_RSA)
	{
		digest_ptr = EVP_sha1();
	}
	else if (EVP_PKEY_type(tmpKey_ptr->type) == EVP_PKEY_DSA)
	{
		digest_ptr = EVP_dss1();
	}
	else
	{
		if (logger_ptr)
		{
			logger_ptr->text(LOG_ERROR, 1, "Unsupported key type in CA private key");
		}
		goto end;
	}

	if (!X509_sign(cert_ptr, tmpKey_ptr, digest_ptr))
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "signing certificate");
		goto end;
	}

	// write out the private key
	// open the private key file
	pkBio_ptr = BIO_new(BIO_s_file_internal());
	if (pkBio_ptr == NULL)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting up to write private key file");
		goto end;
	}
	if (BIO_write_filename(pkBio_ptr, (void *)keyFile_ptr) <= 0)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "opening to write private key file");
		goto end;
	}

	if ((keyPassword_ptr != NULL) && (strlen(keyPassword_ptr) > 0))
	{
		// we have a password, use 3DES to encrypt the key
		cipher_ptr = EVP_des_ede3_cbc();
	}
	else
	{
		// there is no password, don't encrypt the key
		cipher_ptr = NULL;
	}

	// write out the private key
	if (PEM_write_bio_PKCS8PrivateKey(pkBio_ptr, key_ptr, cipher_ptr, 
										NULL, 0, NULL, (void *)keyPassword_ptr) != 1)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "writing private key");
		goto end;
	}

	// write the certificate file
	// open the certificate file
	certBio_ptr = BIO_new(BIO_s_file_internal());
	if (certBio_ptr == NULL)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "setting up to write certificate file");
		goto end;
	}
	if (BIO_write_filename(certBio_ptr, (void *)certificateFile_ptr) <= 0)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "opening to write certificate file");
		goto end;
	}

	// write the new certificate
	if (PEM_write_bio_X509(certBio_ptr, cert_ptr) != 1)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "writing certificate");
		goto end;
	}

	// write the new certificate into the credential file 
	if (PEM_write_bio_X509(pkBio_ptr, cert_ptr) != 1)
	{
		openSsl_ptr->printError(logger_ptr, LOG_ERROR, "writing certificate");
		goto end;
	}


	if (signerCredentialsFile_ptr != NULL)
	{
		// write the CA certificate
		if (PEM_write_bio_X509(certBio_ptr, caCertificate_ptr) != 1)
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "writing CA certificate");
			goto end;
		}

		// loop reading certificates from the CA credentials file and writing them to the certificate file
		X509_free(caCertificate_ptr);
		while ((caCertificate_ptr = PEM_read_bio_X509(caBio_ptr, NULL, NULL, (void*)credentialsPassword_ptr)) != NULL)
		{
			// write the certificate
			if (PEM_write_bio_X509(certBio_ptr, caCertificate_ptr) != 1)
			{
				openSsl_ptr->printError(logger_ptr, LOG_ERROR, "writing certificate chain");
				goto end;
			}

			X509_free(caCertificate_ptr);
		}
		// check the error
		err = ERR_peek_error();
		if ((ERR_GET_LIB(err) == ERR_LIB_PEM) && (ERR_GET_REASON(err) == PEM_R_NO_START_LINE))
		{
			// end of data - this is normal
			ERR_clear_error();
		}
		else
		{
			openSsl_ptr->printError(logger_ptr, LOG_ERROR, "reading certificates from CA credentials file");
			goto end;
		}
	}


	ret = MSG_OK;

end:
	if (certBio_ptr != NULL) BIO_free(certBio_ptr);
	if (pkBio_ptr != NULL) BIO_free(pkBio_ptr);
	if (cert_ptr != NULL) X509_free(cert_ptr);
	if (key_ptr != NULL) EVP_PKEY_free(key_ptr);
	if (caCertificate_ptr != NULL) X509_free(caCertificate_ptr);
	if (caPrivateKey_ptr != NULL) EVP_PKEY_free(caPrivateKey_ptr);
	if (caBio_ptr != NULL) BIO_free(caBio_ptr);

	return ret;
}
Exemple #28
0
/*
 * initialize ssl engine, load certs and initialize openssl internals
 */
void init_ssl(void)
{
	const SSL_METHOD *ssl_method;
	RSA *rsa=NULL;
	X509_REQ *req = NULL;
	X509 *cer = NULL;
	EVP_PKEY *pk = NULL;
	EVP_PKEY *req_pkey = NULL;
	X509_NAME *name = NULL;
	FILE *fp;
	char buf[SIZ];
	int rv = 0;

	if (!access("/var/run/egd-pool", F_OK)) {
		RAND_egd("/var/run/egd-pool");
	}

	if (!RAND_status()) {
		syslog(LOG_WARNING, "PRNG not adequately seeded, won't do SSL/TLS\n");
		return;
	}
	SSLCritters = malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t *));
	if (!SSLCritters) {
		syslog(LOG_ERR, "citserver: can't allocate memory!!\n");
		/* Nothing's been initialized, just die */
		ShutDownWebcit();
		exit(WC_EXIT_SSL);
	} else {
		int a;

		for (a = 0; a < CRYPTO_num_locks(); a++) {
			SSLCritters[a] = malloc(sizeof(pthread_mutex_t));
			if (!SSLCritters[a]) {
				syslog(LOG_EMERG,
					"citserver: can't allocate memory!!\n");
				/** Nothing's been initialized, just die */
				ShutDownWebcit();
				exit(WC_EXIT_SSL);
			}
			pthread_mutex_init(SSLCritters[a], NULL);
		}
	}

	/*
	 * Initialize SSL transport layer
	 */
	SSL_library_init();
	SSL_load_error_strings();
	ssl_method = SSLv23_server_method();
	if (!(ssl_ctx = SSL_CTX_new(ssl_method))) {
		syslog(LOG_WARNING, "SSL_CTX_new failed: %s\n", ERR_reason_error_string(ERR_get_error()));
		return;
	}

	syslog(LOG_INFO, "Requesting cipher list: %s\n", ssl_cipher_list);
	if (!(SSL_CTX_set_cipher_list(ssl_ctx, ssl_cipher_list))) {
		syslog(LOG_WARNING, "SSL_CTX_set_cipher_list failed: %s\n", ERR_reason_error_string(ERR_get_error()));
		return;
	}

	CRYPTO_set_locking_callback(ssl_lock);
	CRYPTO_set_id_callback(id_callback);

	/*
	 * Get our certificates in order. (FIXME: dirify. this is a setup job.)
	 * First, create the key/cert directory if it's not there already...
	 */
	mkdir(CTDL_CRYPTO_DIR, 0700);

	/*
	 * Before attempting to generate keys/certificates, first try
	 * link to them from the Citadel server if it's on the same host.
	 * We ignore any error return because it either meant that there
	 * was nothing in Citadel to link from (in which case we just
	 * generate new files) or the target files already exist (which
	 * is not fatal either).
	 */
	if (!strcasecmp(ctdlhost, "uds")) {
		sprintf(buf, "%s/keys/citadel.key", ctdlport);
		rv = symlink(buf, CTDL_KEY_PATH);
		if (!rv) syslog(LOG_DEBUG, "%s\n", strerror(errno));
		sprintf(buf, "%s/keys/citadel.csr", ctdlport);
		rv = symlink(buf, CTDL_CSR_PATH);
		if (!rv) syslog(LOG_DEBUG, "%s\n", strerror(errno));
		sprintf(buf, "%s/keys/citadel.cer", ctdlport);
		rv = symlink(buf, CTDL_CER_PATH);
		if (!rv) syslog(LOG_DEBUG, "%s\n", strerror(errno));
	}

	/*
	 * If we still don't have a private key, generate one.
	 */
	if (access(CTDL_KEY_PATH, R_OK) != 0) {
		syslog(LOG_INFO, "Generating RSA key pair.\n");
		rsa = RSA_generate_key(1024,	/* modulus size */
					65537,	/* exponent */
					NULL,	/* no callback */
					NULL	/* no callback */
		);
		if (rsa == NULL) {
			syslog(LOG_WARNING, "Key generation failed: %s\n", ERR_reason_error_string(ERR_get_error()));
		}
		if (rsa != NULL) {
			fp = fopen(CTDL_KEY_PATH, "w");
			if (fp != NULL) {
				chmod(CTDL_KEY_PATH, 0600);
				if (PEM_write_RSAPrivateKey(fp,	/* the file */
							rsa,	/* the key */
							NULL,	/* no enc */
							NULL,	/* no passphr */
							0,	/* no passphr */
							NULL,	/* no callbk */
							NULL	/* no callbk */
				) != 1) {
					syslog(LOG_WARNING, "Cannot write key: %s\n",
						ERR_reason_error_string(ERR_get_error()));
					unlink(CTDL_KEY_PATH);
				}
				fclose(fp);
			}
			else {
				syslog(LOG_WARNING, "Cannot write key: %s\n", CTDL_KEY_PATH);
				ShutDownWebcit();
				exit(0);
			}
			RSA_free(rsa);
		}
	}

	/*
	 * If there is no certificate file on disk, we will be generating a self-signed certificate
	 * in the next step.  Therefore, if we have neither a CSR nor a certificate, generate
	 * the CSR in this step so that the next step may commence.
	 */
	if ( (access(CTDL_CER_PATH, R_OK) != 0) && (access(CTDL_CSR_PATH, R_OK) != 0) ) {
		syslog(LOG_INFO, "Generating a certificate signing request.\n");

		/*
		 * Read our key from the file.  No, we don't just keep this
		 * in memory from the above key-generation function, because
		 * there is the possibility that the key was already on disk
		 * and we didn't just generate it now.
		 */
		fp = fopen(CTDL_KEY_PATH, "r");
		if (fp) {
			rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
			fclose(fp);
		}

		if (rsa) {

			/** Create a public key from the private key */
			if (pk=EVP_PKEY_new(), pk != NULL) {
				EVP_PKEY_assign_RSA(pk, rsa);
				if (req = X509_REQ_new(), req != NULL) {
					const char *env;
					/* Set the public key */
					X509_REQ_set_pubkey(req, pk);
					X509_REQ_set_version(req, 0L);

					name = X509_REQ_get_subject_name(req);

					/* Tell it who we are */

					/*
					 * We used to add these fields to the subject, but
					 * now we don't.  Someone doing this for real isn't
					 * going to use the webcit-generated CSR anyway.
					 *
					X509_NAME_add_entry_by_txt(name, "C",
						MBSTRING_ASC, "US", -1, -1, 0);
					*
					X509_NAME_add_entry_by_txt(name, "ST",
						MBSTRING_ASC, "New York", -1, -1, 0);
					*
					X509_NAME_add_entry_by_txt(name, "L",
						MBSTRING_ASC, "Mount Kisco", -1, -1, 0);
					*/

					env = getenv("O");
					if (env == NULL)
						env = "Organization name",

					X509_NAME_add_entry_by_txt(
						name, "O",
						MBSTRING_ASC, 
						(unsigned char*)env, 
						-1, -1, 0
					);

					env = getenv("OU");
					if (env == NULL)
						env = "Citadel server";

					X509_NAME_add_entry_by_txt(
						name, "OU",
						MBSTRING_ASC, 
						(unsigned char*)env, 
						-1, -1, 0
					);

					env = getenv("CN");
					if (env == NULL)
						env = "*";

					X509_NAME_add_entry_by_txt(
						name, "CN",
						MBSTRING_ASC, 
						(unsigned char*)env,
						-1, -1, 0
					);
				
					X509_REQ_set_subject_name(req, name);

					/* Sign the CSR */
					if (!X509_REQ_sign(req, pk, EVP_md5())) {
						syslog(LOG_WARNING, "X509_REQ_sign(): error\n");
					}
					else {
						/* Write it to disk. */	
						fp = fopen(CTDL_CSR_PATH, "w");
						if (fp != NULL) {
							chmod(CTDL_CSR_PATH, 0600);
							PEM_write_X509_REQ(fp, req);
							fclose(fp);
						}
						else {
							syslog(LOG_WARNING, "Cannot write key: %s\n", CTDL_CSR_PATH);
							ShutDownWebcit();
							exit(0);
						}
					}

					X509_REQ_free(req);
				}
			}

			RSA_free(rsa);
		}

		else {
			syslog(LOG_WARNING, "Unable to read private key.\n");
		}
	}



	/*
	 * Generate a self-signed certificate if we don't have one.
	 */
	if (access(CTDL_CER_PATH, R_OK) != 0) {
		syslog(LOG_INFO, "Generating a self-signed certificate.\n");

		/* Same deal as before: always read the key from disk because
		 * it may or may not have just been generated.
		 */
		fp = fopen(CTDL_KEY_PATH, "r");
		if (fp) {
			rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
			fclose(fp);
		}

		/* This also holds true for the CSR. */
		req = NULL;
		cer = NULL;
		pk = NULL;
		if (rsa) {
			if (pk=EVP_PKEY_new(), pk != NULL) {
				EVP_PKEY_assign_RSA(pk, rsa);
			}

			fp = fopen(CTDL_CSR_PATH, "r");
			if (fp) {
				req = PEM_read_X509_REQ(fp, NULL, NULL, NULL);
				fclose(fp);
			}

			if (req) {
				if (cer = X509_new(), cer != NULL) {

					ASN1_INTEGER_set(X509_get_serialNumber(cer), 0);
					X509_set_issuer_name(cer, req->req_info->subject);
					X509_set_subject_name(cer, req->req_info->subject);
					X509_gmtime_adj(X509_get_notBefore(cer), 0);
					X509_gmtime_adj(X509_get_notAfter(cer),(long)60*60*24*SIGN_DAYS);

					req_pkey = X509_REQ_get_pubkey(req);
					X509_set_pubkey(cer, req_pkey);
					EVP_PKEY_free(req_pkey);
					
					/* Sign the cert */
					if (!X509_sign(cer, pk, EVP_md5())) {
						syslog(LOG_WARNING, "X509_sign(): error\n");
					}
					else {
						/* Write it to disk. */	
						fp = fopen(CTDL_CER_PATH, "w");
						if (fp != NULL) {
							chmod(CTDL_CER_PATH, 0600);
							PEM_write_X509(fp, cer);
							fclose(fp);
						}
						else {
							syslog(LOG_WARNING, "Cannot write key: %s\n", CTDL_CER_PATH);
							ShutDownWebcit();
							exit(0);
						}
					}
					X509_free(cer);
				}
			}

			RSA_free(rsa);
		}
	}

	/*
	 * Now try to bind to the key and certificate.
	 * Note that we use SSL_CTX_use_certificate_chain_file() which allows
	 * the certificate file to contain intermediate certificates.
	 */
	SSL_CTX_use_certificate_chain_file(ssl_ctx, CTDL_CER_PATH);
	SSL_CTX_use_PrivateKey_file(ssl_ctx, CTDL_KEY_PATH, SSL_FILETYPE_PEM);
	if ( !SSL_CTX_check_private_key(ssl_ctx) ) {
		syslog(LOG_WARNING, "Cannot install certificate: %s\n",
				ERR_reason_error_string(ERR_get_error()));
	}
	
}
Exemple #29
0
static ERL_NIF_TERM x509_make_cert_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
  int expiry, serial;
  ASN1_INTEGER *asn1serial = NULL;
  BIGNUM *bn_rsa_genkey=NULL;
  BIO *bio_signing_private=NULL, *bio_issuer_cert = NULL, *bio_newcert_public = NULL;
  BIO *bio_x509=NULL;
  char *issuer_cert_pem=NULL;
  X509 *pX509 = NULL;
  X509 *pIssuerX509 = NULL;
  X509_NAME *pX509Name = NULL;
  X509_NAME *pIssuerName = NULL;
  x509_subject_entry *subject_entries;
  int num_subject_entries;
  int iret = 0;
  RSA *rsa=NULL;
  unsigned long f4=RSA_F4;
  unsigned args_len=-1;
  char *signing_keys[2], *cert_keys[2];
  ERL_NIF_TERM tail, *arg_terms=NULL;
  int idx;
  ERL_NIF_TERM ret, x509term;
  int x509len;
  unsigned char *x509data;

  EVP_PKEY *evp_signing_private = EVP_PKEY_new();
  EVP_PKEY *evp_newcert_public_key = EVP_PKEY_new();
  /* set RSA key gen type */
  bn_rsa_genkey = BN_new();
  BN_set_word(bn_rsa_genkey, f4);

  //
  // 1. stick subject of CA cert into NewCert
  // 2. stick public key of NewKeypair into NewCert
  // 3. sign NewCert with CA keypair

  /* Should be 6 elements in the list of X509 parameters.  We'll check each */
  if(!enif_get_list_length(env, argv[0], &args_len) || args_len != 6 ||
     NULL == (arg_terms = (ERL_NIF_TERM*)malloc(args_len * sizeof(ERL_NIF_TERM)))) return enif_make_badarg(env);
  
  enif_get_list_cell(env, argv[0], &arg_terms[0], &tail);
  for(idx=1; idx<args_len; idx++){
    if(!enif_get_list_cell(env, tail, &arg_terms[idx], &tail)){
      free(arg_terms);
      return enif_make_badarg(env);
    }
  }
  
  idx=0;
  /* get the signing private key */
  x509_parse_keypair(env, "signing_key", arg_terms[idx++], signing_keys);

  /* get the issuer cert */
  x509_parse_issuer_cert(env, arg_terms[idx++], &issuer_cert_pem);

  /* get the soon-to-be cert's public key */
  x509_parse_keypair(env, "newcert_public_key", arg_terms[idx++], cert_keys);

  /* get the subject */
  x509_parse_subject(env, arg_terms[idx++], &num_subject_entries, &subject_entries);

  /* get the serial number */
  x509_parse_int_tuple(env, arg_terms[idx++], "serial", &serial);

  /* get the expiry */
  x509_parse_int_tuple(env, arg_terms[idx++], "expiry", &expiry);

  /* work the OpenSSL cert creation magic */
  if ((bio_signing_private = BIO_new_mem_buf(signing_keys[1], -1))
      && (rsa = PEM_read_bio_RSAPrivateKey(bio_signing_private, NULL, NULL, NULL))
      && (iret = EVP_PKEY_assign_RSA(evp_signing_private, rsa))
              
      && (bio_newcert_public = BIO_new_mem_buf(cert_keys[0], -1))
      && (evp_newcert_public_key = PEM_read_bio_PUBKEY(bio_newcert_public, NULL, NULL, NULL))
              
      && (bio_issuer_cert = BIO_new_mem_buf(issuer_cert_pem, -1))
      && (pIssuerX509 = PEM_read_bio_X509(bio_issuer_cert, NULL, NULL, NULL))
      && (pX509 = X509_new())) {
    /* if we've managed to generate a key and allocate structure memory,
       set X509 fields */
    asn1serial = ASN1_INTEGER_new();
    X509_set_version(pX509, 2); /* cert_helper uses '3' here */
    ASN1_INTEGER_set(asn1serial, serial);
    X509_set_serialNumber(pX509, asn1serial);
    X509_gmtime_adj(X509_get_notBefore(pX509),0);
    X509_gmtime_adj(X509_get_notAfter(pX509),(long)60*60*24*expiry);
    X509_set_pubkey(pX509, evp_newcert_public_key);
    pX509Name = X509_get_subject_name(pX509);
    
    while(--num_subject_entries >= 0){
      X509_NAME_add_entry_by_txt(pX509Name, (subject_entries[num_subject_entries]).name,
                                 MBSTRING_ASC, (unsigned char*)(subject_entries[num_subject_entries]).value, -1, -1, 0);
    }
    
    pIssuerName = X509_get_issuer_name(pIssuerX509);
    X509_set_issuer_name(pX509, pIssuerName);
    X509_sign(pX509, evp_signing_private, digest);
    
    bio_x509 = BIO_new(BIO_s_mem());
    PEM_write_bio_X509(bio_x509, pX509);
    
    x509len = BIO_get_mem_data(bio_x509, &x509data);
    memcpy(enif_make_new_binary(env, x509len, &x509term), x509data, x509len);
    ret = enif_make_tuple2(env, atom_x509_cert, x509term);
  }
    
 done:
  if(arg_terms) free(arg_terms);
  free_keys(signing_keys);
  free_keys(cert_keys);
  free_subject_entries(num_subject_entries, subject_entries);
  if(pX509) X509_free(pX509);
  if(pIssuerX509) X509_free(pIssuerX509);
  if(issuer_cert_pem) free(issuer_cert_pem);
  if(bio_issuer_cert) { BIO_set_close(bio_issuer_cert, BIO_NOCLOSE); BIO_free_all(bio_issuer_cert); }
  if(bio_signing_private) { BIO_set_close(bio_signing_private, BIO_NOCLOSE); BIO_free_all(bio_signing_private); }
  if(bio_newcert_public) { BIO_set_close(bio_newcert_public, BIO_NOCLOSE); BIO_free_all(bio_newcert_public); }
  if(bio_x509) BIO_free_all(bio_x509);
  if(asn1serial) ASN1_INTEGER_free(asn1serial);
  if(bn_rsa_genkey) BN_free(bn_rsa_genkey);
  if(rsa) RSA_free(rsa);

  return ret;
}
Exemple #30
0
wi_x509_t * wi_x509_init_with_common_name(wi_x509_t *x509, wi_rsa_t *rsa, wi_string_t *common_name) {
	X509_REQ		*req;
	EVP_PKEY		*pkey = NULL;
	X509_NAME		*name = NULL;
	BIGNUM			*bn = NULL;
	
	req = X509_REQ_new();
	
	if(!req)
		goto err;

	if(X509_REQ_set_version(req, 0) != 1)
		goto err;
	
	name = X509_NAME_new();
	
	if(X509_NAME_add_entry_by_NID(name,
								  NID_commonName,
								  MBSTRING_ASC,
								  (unsigned char *) wi_string_cstring(common_name),
								  -1,
								  -1,
								  0) != 1)
		goto err;

	if(X509_REQ_set_subject_name(req, name) != 1)
		goto err;

	pkey = EVP_PKEY_new();
	EVP_PKEY_set1_RSA(pkey, wi_rsa_rsa(rsa));
	
	if(X509_REQ_set_pubkey(req, pkey) != 1)
		goto err;
	
	x509->x509 = X509_new();
	
	if(!x509->x509)
		goto err;
	
	bn = BN_new();
	
	if(!bn)
		goto err;
	
	if(BN_pseudo_rand(bn, 64, 0, 0) != 1)
		goto err;
	
	if(!BN_to_ASN1_INTEGER(bn, X509_get_serialNumber(x509->x509)))
		goto err;
	
	if(X509_set_issuer_name(x509->x509, X509_REQ_get_subject_name(req)) != 1)
		goto err;

	if(!X509_gmtime_adj(X509_get_notBefore(x509->x509), 0))
		goto err;

	if(!X509_gmtime_adj(X509_get_notAfter(x509->x509), 3600 * 24 * 365))
		goto err;

	if(X509_set_subject_name(x509->x509, X509_REQ_get_subject_name(req)) != 1)
		goto end;

	if(X509_set_pubkey(x509->x509, pkey) != 1)
		goto err;
	
	if(X509_sign(x509->x509, pkey, EVP_sha1()) == 0)
		goto err;
	
	goto end;
	
err:
	wi_error_set_openssl_error();

	wi_release(x509);

	x509 = NULL;
	
end:
	if(req)
		X509_REQ_free(req);
	
	if(pkey)
		EVP_PKEY_free(pkey);
	
	if(name)
		X509_NAME_free(name);

	if(bn)
		BN_free(bn);
	
	return x509;
}