Ejemplo n.º 1
2
void pki_x509req::createReq(pki_key *key, const x509name &dn, const EVP_MD *md, extList el)
{
	int bad_nids[] = { NID_subject_key_identifier, NID_authority_key_identifier,
		NID_issuer_alt_name, NID_undef };

	EVP_PKEY *privkey = NULL;

	if (key->isPubKey()) {
		my_error(tr("Signing key not valid (public key)"));
		return;
	}

	X509_REQ_set_version(request, 0L);
	X509_REQ_set_pubkey(request, key->getPubKey());
	setSubject(dn);
	pki_openssl_error();

	for(int i=0; bad_nids[i] != NID_undef; i++)
		el.delByNid(bad_nids[i]);

	el.delInvalid();

	if (el.count() > 0) {
		STACK_OF(X509_EXTENSION) *sk;
		sk = el.getStack();
		X509_REQ_add_extensions(request, sk);
		sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free);
	}
	pki_openssl_error();

	privkey = key->decryptKey();
	X509_REQ_sign(request, privkey, md);
	pki_openssl_error();
	EVP_PKEY_free(privkey);
}
Ejemplo n.º 2
0
/*
 * Routine used to CSR for est_client_enroll_csr testcases
 */
static int populate_x509_csr (X509_REQ *req, EVP_PKEY *pkey, char *cn)
{
    X509_NAME *subj;

    /* Setup version number */
    if (!X509_REQ_set_version(req, 0L)) {
        printf("\nUnable to set X509 version#\n");
        return (-1);
    }

    /*
     * Add Common Name entry
     */
    subj = X509_REQ_get_subject_name(req);
    if (!X509_NAME_add_entry_by_txt(subj, "CN", MBSTRING_ASC,
                                    (unsigned char*)cn, -1, -1, 0)) {
        printf("\nUnable to create X509 Common Name entry\n");
        return (-1);
    }

    /*
     * Set the public key on the request
     */
    if (!X509_REQ_set_pubkey(req, pkey)) {
        printf("\nUnable to set X509 public key\n");
        return (-1);
    }

    return (0);
}
Ejemplo n.º 3
0
/***
create or generate a new x509_req object.
Note if not give evp_pkey, will create a new x509_req object,or will generate a signed x509_req object.
@function new
@tparam[opt] x509_name subject subject name set to x509_req
@tparam[opt] stack_of_x509_extension extensions add to x509_req
@tparam[opt] stack_of_x509_attribute attributes add to x509_req
@tparam[opt] evp_pkey pkey private key sign the x509_req, and set as public key
@tparam[opt='sha1WithRSAEncryption'] evp_digest|string md_alg,  only used when pkey exist, and should fellow pkey
@treturn x509_req certificate sign request object
@see x509_req
*/
static LUA_FUNCTION(openssl_csr_new)
{
  X509_REQ *csr = X509_REQ_new();
  int i;
  int n = lua_gettop(L);
  int ret = X509_REQ_set_version(csr, 0L);

  for (i = 1; ret == 1 && i <= n; i++)
  {
    luaL_argcheck(L,
                  auxiliar_getclassudata(L, "openssl.x509_name", i) ||
                  auxiliar_getclassudata(L, "openssl.evp_pkey", i),
                  i, "must be x509_name or evp_pkey");
    if (auxiliar_getclassudata(L, "openssl.x509_name", i))
    {
      X509_NAME * subject = CHECK_OBJECT(i, X509_NAME, "openssl.x509_name");
      ret = X509_REQ_set_subject_name(csr, subject);
    }
    if (auxiliar_getclassudata(L, "openssl.evp_pkey", i))
    {
      EVP_PKEY *pkey;
      const EVP_MD *md;
      luaL_argcheck(L, i == n || i == n - 1, i, "must is evp_pkey object");

      pkey = CHECK_OBJECT(i, EVP_PKEY, "openssl.evp_pkey");

      if (i == n - 1)
        md = get_digest(L, n, NULL);
      else
        md = EVP_get_digestbyname("sha256");

      ret = X509_REQ_set_pubkey(csr, pkey);
      if (ret == 1)
      {
        ret = X509_REQ_sign(csr, pkey, md);
        if (ret > 0)
          ret = 1;
      }
      break;
    }
  };

  if (ret == 1)
    PUSH_OBJECT(csr, "openssl.x509_req");
  else
  {
    X509_REQ_free(csr);
    return openssl_pushresult(L, ret);
  }
  return 1;
}
Ejemplo n.º 4
0
static gboolean
ConfigX509CertReq(X509_REQ *req,                 // OUT
                  CONF *config)                  // IN
{
   int idx;
   X509_NAME *subject;
   gboolean ret = FALSE;
   const char *dname;
   gchar *err = NULL;

   if (!X509_REQ_set_version(req, 0L)) {
      Error("Failed to set the certificate request version: %s.\n",
            GetSSLError(&err));
      goto exit;
   }

   subject = X509_REQ_get_subject_name(req);
   if (!subject) {
      Error("Failed to get the certificate request subject name: %s.\n",
            GetSSLError(&err));
      goto exit;
   }

   dname = NCONF_get_string(config, "req", "distinguished_name");
   if (dname) {
      STACK_OF(CONF_VALUE) *dn_sk = NCONF_get_section(config, dname);
      if (!dn_sk) {
         Error("Failed to get section %s: %s.\n",
               dname, GetSSLError(&err));
         goto exit;
      }

      for (idx = 0; idx < sk_CONF_VALUE_num(dn_sk); idx++) {
         CONF_VALUE *v = sk_CONF_VALUE_value(dn_sk, idx);

         if (!X509_NAME_add_entry_by_txt(subject, v->name, MBSTRING_ASC,
                                         v->value, -1, -1, 0)) {
            Error("Failed to set certificate request pair %s/%s: %s.\n",
                  v->name, v->value, GetSSLError(&err));
            goto exit;
         }
      }
   }

   ret = TRUE;

exit:
   g_free(err);
   return ret;
}
Ejemplo n.º 5
0
static LUA_FUNCTION(openssl_csr_version)
{
  X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req");
  if (lua_isnone(L, 2))
  {
    lua_pushinteger(L, X509_REQ_get_version(csr));
    return 1;
  }
  else
  {
    long version = luaL_checkint(L, 2);
    int ret = X509_REQ_set_version(csr, version);
    return openssl_pushresult(L, ret);
  }
}
Ejemplo n.º 6
0
int MakeX509CSR(const char *cn, const char *keyfile, const char *csrfile)
{
	InitializeOpenSSL(); 
	
	RSA *rsa = RSA_generate_key(4096, RSA_F4, NULL, NULL);

	BIO *bio = BIO_new(BIO_s_file());
	BIO_write_filename(bio, const_cast<char *>(keyfile));
	PEM_write_bio_RSAPrivateKey(bio, rsa, NULL, NULL, 0, NULL, NULL);
	BIO_free(bio);

	X509_REQ *req = X509_REQ_new();

	if (!req)
		return 0;

	EVP_PKEY *key = EVP_PKEY_new();
	EVP_PKEY_assign_RSA(key, rsa);
	X509_REQ_set_version(req, 0);
	X509_REQ_set_pubkey(req, key);

	X509_NAME *name = X509_REQ_get_subject_name(req);
	X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char *)cn, -1, -1, 0);

	X509_REQ_sign(req, key, EVP_sha1());

	EVP_PKEY_free(key);

	bio = BIO_new(BIO_s_file());
	BIO_write_filename(bio, const_cast<char *>(csrfile));
	PEM_write_bio_X509_REQ(bio, req);
	BIO_free(bio);

	X509_REQ_free(req);

	return 1;
}
Ejemplo n.º 7
0
int generate_csr(char** pem_csr) {
	FILE* fp;
	RSA * rsa_priv_key;
	int ret = 0;
	int nVersion = 0;
	int keylen = 0;

	X509_REQ *x509_req = NULL;
	X509_NAME *x509_name = NULL;
	EVP_PKEY *pKey = NULL;
	BIO *bio = NULL;

	// 2. set version of x509 req
	x509_req = X509_REQ_new();
	ret = X509_REQ_set_version(x509_req, nVersion);
	if (ret != 1) {
		goto free_all;
	}

	// 3. set subject of x509 req
	x509_name = X509_REQ_get_subject_name(x509_req);

	ret = X509_NAME_add_entry_by_txt(x509_name, "C", V_ASN1_PRINTABLESTRING,
			(const unsigned char*) szCountry, -1, -1, 0);
	if (ret != 1) {
		goto free_all;
	}

	ret = X509_NAME_add_entry_by_txt(x509_name, "ST", V_ASN1_PRINTABLESTRING,
			(const unsigned char*) szProvince, -1, -1, 0);
	if (ret != 1) {
		goto free_all;
	}

	ret = X509_NAME_add_entry_by_txt(x509_name, "L", V_ASN1_PRINTABLESTRING,
			(const unsigned char*) szCity, -1, -1, 0);
	if (ret != 1) {
		goto free_all;
	}

	ret = X509_NAME_add_entry_by_txt(x509_name, "O", V_ASN1_PRINTABLESTRING,
			(const unsigned char*) api_company, -1, -1, 0);
	if (ret != 1) {
		goto free_all;
	}

	ret = X509_NAME_add_entry_by_txt(x509_name, "OU", V_ASN1_PRINTABLESTRING,
			(const unsigned char*) szOrganization, -1, -1, 0);
	if (ret != 1) {
		goto free_all;
	}

	ret = X509_NAME_add_entry_by_txt(x509_name, "CN", V_ASN1_PRINTABLESTRING,
			(const unsigned char*) szCommon, -1, -1, 0);
	if (ret != 1) {
		goto free_all;
	}

	ret = X509_NAME_add_entry_by_txt(x509_name, "emailAddress", V_ASN1_IA5STRING,
			(const unsigned char*) szEmail, -1, -1, 0);
	if (ret != 1) {
		goto free_all;
	}

	ret = X509_NAME_add_entry_by_txt(x509_name, "challengePassword", V_ASN1_PRINTABLESTRING,
			(const unsigned char*) szChallengePassword, -1, -1, 0);
	if (ret != 1) {
		goto free_all;
	}

	// 4. set public key of x509 req
	if (load_rsa_pkey(&rsa_priv_key) < 0)
		goto free_all;

	pKey = EVP_PKEY_new();
	EVP_PKEY_assign_RSA(pKey, rsa_priv_key);

	ret = X509_REQ_set_pubkey(x509_req, pKey);
	if (ret != 1) {
		goto free_all;
	}

	// 5. set sign key of x509 req
	ret = X509_REQ_sign(x509_req, pKey, EVP_sha1()); // return x509_req->signature->length
	if (ret <= 0) {
		goto free_all;
	}

	/* To get the C-string PEM form: */
	bio = BIO_new(BIO_s_mem());
	PEM_write_bio_X509_REQ(bio, x509_req);
	keylen = BIO_pending(bio);
	*pem_csr = malloc(keylen + 1); /* Null-terminate */

	BIO_read(bio, *pem_csr, keylen);

	/* Write to file */
	fp = fopen(f_csr, "w");
	if (fp) {
		fwrite(*pem_csr, keylen, 1, fp);
		fclose(fp);
	}

	LOG(VERBOSE, "[API] CSR created:%s", *pem_csr);
	// 6. free
	free_all: X509_REQ_free(x509_req);
	BIO_free_all(bio);
	return (keylen);
}
Ejemplo n.º 8
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()));
	}
	
}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
0
TokenError _backend_createRequest(const RegutilInfo *info,
                                  const char *hostname,
                                  const char *password,
                                  char **request, size_t *reqlen) {
    // OpenSSL seeds the PRNG automatically, see the manual page for RAND_add.
    if (!RAND_status()) {
        fprintf(stderr, BINNAME ": no random state!\n");
        return TokenError_NoRandomState;
    }
    
    // Abort if there are no requests
    *request = NULL;
    if (!info->pkcs10) return TokenError_Unknown;
    
    // Create certificate requests
    bool ok = true;
    CertReq *reqs = NULL;
    STACK *x509reqs = sk_new_null();
    for (const RegutilPKCS10 *pkcs10 = info->pkcs10; pkcs10 != NULL;
         pkcs10 = pkcs10->next) {
        
        RSA *rsa = NULL;
        EVP_PKEY *privkey = NULL;
        X509_NAME *subject = NULL;
        X509_REQ *x509req = NULL;
        STACK_OF(X509_EXTENSION) *exts = NULL;
        
        // Check the parameters.
        // Maximum key size in OpenSSL:
        // http://www.mail-archive.com/[email protected]/msg58229.html
        if (!pkcs10->subjectDN || pkcs10->keySize < 1024 ||
            pkcs10->keySize > 16384)
            goto req_error;
        
        // Generate key pair
        // FIXME deprecated function
        // TODO use OPENSSL_NO_DEPRECATED
        rsa = RSA_generate_key(pkcs10->keySize, RSA_F4, NULL, NULL);
        if (!rsa) goto req_error;
        privkey = EVP_PKEY_new();
        if (!privkey) goto req_error;
        EVP_PKEY_assign_RSA(privkey, rsa);
        
        // Subject name
        subject = certutil_parse_dn(pkcs10->subjectDN, pkcs10->includeFullDN);
        if (!subject) goto req_error;
        
        // Create request
        x509req = X509_REQ_new();
        if (!x509req ||
            !X509_REQ_set_version(x509req, 0) ||
            !X509_REQ_set_subject_name(x509req, subject) ||
            !X509_REQ_set_pubkey(x509req, privkey)) { // yes this is correct(!)
            
            certutil_updateErrorString();
            goto req_error;
        }
        
        // Set attributes
        exts = sk_X509_EXTENSION_new_null();
        if (!exts) goto req_error;
        
        X509_EXTENSION *ext = makeKeyUsageExt(pkcs10->keyUsage);
        if (!ext || !sk_X509_EXTENSION_push(exts, ext))
            goto req_error;
        
        if (!X509_REQ_add_extensions(x509req, exts)) {
            certutil_updateErrorString();
            goto req_error;
        }
        exts = NULL;
        
        // Add signature
        if (!X509_REQ_sign(x509req, privkey, EVP_sha1())) {
            certutil_updateErrorString();
            goto req_error;
        }
        
        // Store in list
        CertReq *req = malloc(sizeof(CertReq));
        req->pkcs10 = pkcs10;
        req->privkey = privkey;
        req->rsa = rsa;
        req->x509 = x509req;
        req->next = reqs;
        reqs = req;
        
        sk_push(x509reqs, (char*)x509req);
        
        continue;
        
      req_error:
        // Clean up and set error flag
        if (privkey) EVP_PKEY_free(privkey);
        else if (rsa) RSA_free(rsa);
        
        X509_NAME_free(subject);
        sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
        X509_REQ_free(x509req);
        
        ok = false;
    }
    
    TokenError error = TokenError_Unknown;
    
    if (ok) {
        // Determine filename from certificate name
        char *filename = certutil_makeFilename(X509_REQ_get_subject_name(reqs->x509));
        
        // Build the certificate request
        request_wrap(x509reqs, request, reqlen);
        
        if (*request && filename) {
            // Create the key file in ~/cbt/name.p12
            FILE *keyfile = platform_openLocked(filename, Platform_OpenCreate);
            if (!keyfile) {
                error = TokenError_CantCreateFile;
            } else {
                error = saveKeys(reqs, hostname, password, keyfile);
                if (!platform_closeLocked(keyfile) && !error)
                    error = TokenError_CantCreateFile;
            }
            
        }
        
        if (filename) free(filename);
        if (error && *request) free(*request);
    }
    
    // Free reqs
    while (reqs) {
        RSA_free(reqs->rsa); // This free's privkey too
        X509_REQ_free(reqs->x509);
        
        CertReq *next = reqs->next;
        free(reqs);
        reqs = next;
    }
    sk_free(x509reqs);
    
    return error;
}
Ejemplo n.º 11
0
static LUA_FUNCTION(openssl_csr_new)
{
  X509_REQ *csr = X509_REQ_new();
  int i;
  int n = lua_gettop(L);
  int ret = X509_REQ_set_version(csr, 0L);

  for (i = 1; ret == 1 && i <= n; i++)
  {
    luaL_argcheck(L,
                  auxiliar_isclass(L, "openssl.stack_of_x509_extension", i) ||
                  auxiliar_isclass(L, "openssl.stack_of_x509_attribute", i) ||
                  auxiliar_isclass(L, "openssl.x509_name", i) ||
                  auxiliar_isclass(L, "openssl.evp_pkey", i),

                  i, "must be x509_name, stack_of_x509_extension or stack_of_x509_attribute");
    if (auxiliar_isclass(L, "openssl.x509_name", i))
    {
      X509_NAME * subject = CHECK_OBJECT(i, X509_NAME, "openssl.x509_name");
      ret = X509_REQ_set_subject_name(csr, subject);
    }
    if (auxiliar_isclass(L, "openssl.stack_of_x509_attribute", i))
    {
      int j, m;
      STACK_OF(X509_ATTRIBUTE) *attrs = CHECK_OBJECT(i, STACK_OF(X509_ATTRIBUTE), "openssl.stack_of_x509_attribute");
      m = sk_X509_ATTRIBUTE_num(attrs);
      for (j = 0; ret == 1 && j < m; j++)
      {
        ret = X509_REQ_add1_attr(csr, sk_X509_ATTRIBUTE_value(attrs, j));
      }
    }

    if (auxiliar_isclass(L, "openssl.stack_of_x509_extension", i))
    {
      STACK_OF(X509_EXTENSION) *exts =
        CHECK_OBJECT(i, STACK_OF(X509_EXTENSION), "openssl.stack_of_x509_extension");
      ret = X509_REQ_add_extensions(csr, exts);
    }

    if (auxiliar_isclass(L, "openssl.evp_pkey", i))
    {
      EVP_PKEY *pkey;
      const EVP_MD *md;
      luaL_argcheck(L, i == n || i == n - 1, i, "must is evp_pkey object");

      pkey = CHECK_OBJECT(i, EVP_PKEY, "openssl.evp_pkey");

      luaL_argcheck(L, openssl_pkey_is_private(pkey), i, "must be private key");

      if (i == n - 1)
        md = get_digest(L, n);
      else
        md = EVP_get_digestbyname("sha1");

      ret = X509_REQ_set_pubkey(csr, pkey);
      if (ret == 1)
      {
        ret = X509_REQ_sign(csr, pkey, md);
        if (ret > 0)
          ret = 1;
      }
      break;
    }
  };

  if (ret == 1)
    PUSH_OBJECT(csr, "openssl.x509_req");
  else
  {
    X509_REQ_free(csr);
    return openssl_pushresult(L, ret);
  }
  return 1;
}
Ejemplo n.º 12
0
int openssl_x509_cert()
{
	BIO *b;
	FILE *fp;
	RSA *rsa;
	EVP_PKEY *pkey;
	X509_NAME *name;
	const EVP_MD *md;
	X509_REQ *req, **req2;
	X509_NAME_ENTRY *entry;
	unsigned int len;
	char bytes[COMM_LEN];
	const unsigned char *pp;
	unsigned char *p, *der, *mdout, buf[MAX1_LEN];

	OpenSSL_add_all_algorithms();
	printf("\nX509_Cert info:\n");
	return -1;
	
	req = X509_REQ_new();
	X509_REQ_set_version(req, 1);

	name = X509_NAME_new();
	strcpy(bytes, "beike");
	entry = X509_NAME_ENTRY_create_by_txt(&entry, "commonName",
 		V_ASN1_UTF8STRING, (unsigned char *)bytes, strlen(bytes));
	X509_NAME_add_entry(name, entry, 0, -1);
	strcpy(bytes, "BEIJING");
	entry = X509_NAME_ENTRY_create_by_txt(&entry, "countryName",
		V_ASN1_UTF8STRING, (unsigned char *)bytes, strlen(bytes));
	X509_NAME_add_entry(name, entry, 1, -1);
	X509_REQ_set_subject_name(req, name);

	pkey = EVP_PKEY_new();
	rsa = RSA_generate_key(LINE_LEN, RSA_3, NULL, NULL);
	EVP_PKEY_assign_RSA(pkey, rsa);
	X509_REQ_set_pubkey(req, pkey);

	strcpy(bytes, "USTB");
	X509_REQ_add1_attr_by_txt(req, "organizationName",
		V_ASN1_UTF8STRING, (unsigned char *)bytes, strlen(bytes));
	strcpy(bytes, "TECH");
	X509_REQ_add1_attr_by_txt(req, "organizationalUnitName",
		V_ASN1_UTF8STRING, (unsigned char *)bytes, strlen(bytes));

	md = EVP_sha1();
	X509_REQ_digest(req, md, mdout, &len);
	X509_REQ_sign(req, pkey, md);
	b = BIO_new_file("/tmp/certreq.txt", "w");
	PEM_write_bio_X509_REQ(b, req);
	BIO_free(b);

	len = i2d_X509_REQ(req, NULL);
	der = (unsigned char *)malloc(len);
	p = der;
	len = i2d_X509_REQ(req, &p);
	X509_REQ_verify(req, pkey);
	fp = fopen("/tmp/certder.txt", "wb");
	fwrite(der, 1, len, fp);
	fclose(fp);

	free(der);
	X509_REQ_free(req);

	b = BIO_new_file("/tmp/certreq.txt", "r");
	PEM_read_bio_X509_REQ(b, NULL, NULL, NULL);

	fp = fopen("/tmp/certder.txt", "r");
	len = fread(buf, 1, MAX1_LEN, fp);
	fclose(fp);
	pp = buf;
	req2 = (X509_REQ **) malloc(sizeof(X509_REQ *));
	d2i_X509_REQ(req2, &pp, len);

	free(req2);
	X509_REQ_free(*req2);

	return 0;
}
Ejemplo n.º 13
0
BSONObj createCertificateRequest(const BSONObj& a, void* data) {
#ifndef MONGO_CONFIG_SSL
    return BSON(
        "" << BSON("ok" << false << "errmsg"
                        << "Cannot create a certificate signing request without SSL support"));
#else
    if (a.nFields() != 1 || a.firstElement().type() != Object) {
        return BSON(
            "" << BSON("ok" << false << "errmsg"
                            << "createCertificateRequest requires a single object argument"));
    }

    // args can optionally contain some to be determined fields...
    BSONObj args = a.firstElement().embeddedObject();
    if (!args.hasField("CN")) {
        return BSON(
            "" << BSON("ok" << false << "errmsg"
                            << "createCertificateRequest requires a Common Name (\"CN\") field"));
    }

    // Generate key pair and certificate signing request
    RSA* rsa;
    EVP_PKEY* pkey;
    X509_REQ* x509req;
    X509_NAME* name;
    BIO* out;
    char client_key[2048];
    char client_csr[2048];

    pkey = EVP_PKEY_new();
    if (!pkey) {
        return BSON("" << BSON("ok" << false));
        // fail("couldn't generate key");
    }

    rsa = RSA_generate_key(2048, RSA_F4, NULL, NULL);
    if (!EVP_PKEY_assign_RSA(pkey, rsa)) {
        return BSON("" << BSON("ok" << false));
        // fail("couldn't assign the key");
    }

    x509req = X509_REQ_new();
    X509_REQ_set_pubkey(x509req, pkey);

    name = X509_NAME_new();
    X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC, (const unsigned char*)"IS", -1, -1, 0);
    X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, (const unsigned char*)"MongoDB", -1, -1, 0);
    X509_NAME_add_entry_by_txt(
        name, "OU", MBSTRING_ASC, (const unsigned char*)"SkunkWorks client", -1, -1, 0);
    X509_NAME_add_entry_by_txt(
        name, "CN", MBSTRING_ASC, (const unsigned char*)args.getStringField("CN"), -1, -1, 0);

    X509_REQ_set_subject_name(x509req, name);
    X509_REQ_set_version(x509req, 2);

    if (!X509_REQ_sign(x509req, pkey, EVP_sha1())) {
        return BSON("" << BSON("ok" << false));
    }

    // out = BIO_new_file("client.key.pem", "wb");
    out = BIO_new(BIO_s_mem());
    if (!PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, NULL)) {
        return BSON("" << BSON("ok" << false));
        // fail("can't write private key");
    }
    int i = BIO_read(out, &client_key, sizeof client_key);
    client_key[i] = '\0';

    BIO_free_all(out);
    out = BIO_new(BIO_s_mem());
    if (!PEM_write_bio_X509_REQ_NEW(out, x509req)) {
        return BSON("" << BSON("ok" << false));
        // fail("coudln't write csr");
    }
    i = BIO_read(out, &client_csr, sizeof client_csr);
    client_csr[i] = '\0';
    BIO_free_all(out);

    EVP_PKEY_free(pkey);
    X509_REQ_free(x509req);


    return BSON("" << BSON("ok" << true << "certificateRequest" << client_csr << "privateKey"
                                << client_key));
#endif
}
void LFNetConfigLoader::retrieveConfig()
{
    this->notifyStatus("Loading OpenSSL stuff ...");
    OpenSSL_add_all_algorithms();
    ERR_load_BIO_strings();
    ERR_load_crypto_strings();

    this->notifyStatus("Generating private key ...");

    BIGNUM* e = BN_new();
    BN_set_word(e, RSA_F4);

    RSA* key = RSA_new();
    RSA_generate_key_ex(key, 4096, e, NULL);

    this->notifyStatus("Saving private key ...");

    BIO* privateKey = BIO_new_file((_configLocation + "/private.key").toLocal8Bit().data(), "w");
    PEM_write_bio_RSAPrivateKey(privateKey, key, NULL, NULL, 0, NULL, NULL);
    BIO_free(privateKey);

    this->notifyStatus("Generating csr ...");

    EVP_PKEY* pkey = EVP_PKEY_new();
    EVP_PKEY_assign_RSA(pkey, key);

    X509_NAME* name = X509_NAME_new();
    X509_NAME_add_entry_by_txt(name, "O",  MBSTRING_UTF8, (unsigned char*)"LF-Net", -1, -1, 0);
    X509_NAME_add_entry_by_txt(name, "OU", MBSTRING_UTF8, (unsigned char*)"VPN", -1, -1, 0);
    X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_UTF8, (unsigned char*)(_username.toUpper() + "_" + _computerName.toUpper()).toUtf8().data(), -1, -1, 0);

    X509_REQ* req = X509_REQ_new();
    X509_REQ_set_pubkey(req, pkey);
    X509_REQ_set_subject_name(req, name);
    X509_REQ_set_version(req, 1);
    X509_REQ_sign(req, pkey, EVP_sha512());

    BIO* request = BIO_new(BIO_s_mem());
    PEM_write_bio_X509_REQ(request, req);

    BUF_MEM* requestData;
    BIO_get_mem_ptr(request, &requestData);

    this->notifyStatus("Request certificate using generated csr ...");

    QNetworkAccessManager *mgr = new QNetworkAccessManager(this);
    connect(mgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(certificateRequestFinished(QNetworkReply*)));
    connect(mgr, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(authenticationRequired(QNetworkReply*,QAuthenticator*)));

    QNetworkRequest netRequest(QUrl("https://mokoscha.lf-net.org/request_certificate"));
    netRequest.setHeader(QNetworkRequest::ContentTypeHeader, "text/plain");

    mgr->post(netRequest, QByteArray(requestData->data, requestData->length));

    this->notifyStatus("Cleaning up temporary data ...");
    BIO_free(request);
    X509_REQ_free(req);
    X509_NAME_free(name);
    EVP_PKEY_free(pkey);
    BN_free(e);

    this->notifyStatus("Waiting for certificate ...");
}
int createCertificateRequest(char* result, char* keyToCertify, char * country, char* state, char* loc, char* organisation, char *organisationUnit, char* cname, char* email)
{
  BIO *mem = BIO_new(BIO_s_mem());
  X509_REQ *req=X509_REQ_new();
  X509_NAME *nm = X509_NAME_new();
  int err=0;

  //fill in details
  if (strlen(country) > 0) {
    if(!(err = X509_NAME_add_entry_by_txt(nm,"C",
      MBSTRING_UTF8, (unsigned char*)country, -1, -1, 0))) {
      return err;
    }
  }
  if (strlen(state) > 0) {
    if(!(err = X509_NAME_add_entry_by_txt(nm,"ST",
      MBSTRING_UTF8, (unsigned char*)state, -1, -1, 0))) {
      return err;
    }
  }
  if (strlen(loc) > 0) {
    if(!(err = X509_NAME_add_entry_by_txt(nm,"L",
      MBSTRING_UTF8, (unsigned char*)loc, -1, -1, 0))) {
      return err;
    }
  }
  if (strlen(organisation) > 0) {
    if(!(err = X509_NAME_add_entry_by_txt(nm,"O",
      MBSTRING_UTF8, (unsigned char*)organisation, -1, -1, 0))) {
      return err;
    }
  }

  if (strlen(organisationUnit) > 0) {
    if(!(err = X509_NAME_add_entry_by_txt(nm,"OU",
      MBSTRING_UTF8, (unsigned char*)organisationUnit, -1, -1, 0))) {
      return err;
    }
  }

   // This is mandatory to have, rest are optional
  if(!(err = X509_NAME_add_entry_by_txt(nm,"CN", MBSTRING_UTF8, (unsigned char*) cname, -1, -1, 0))) {
    return err;
  }

  if (strlen(email) > 0) {
    if(!(err = X509_NAME_add_entry_by_txt(nm,"emailAddress",MBSTRING_UTF8, (unsigned char*)email, -1, -1, 0))) {
      return err;
    }
  }

  if(!(err = X509_REQ_set_subject_name(req, nm))) {
    return err;
  }

    //Set the public key
  //...convert PEM private key into a BIO

  BIO* bmem = BIO_new_mem_buf(keyToCertify, -1);
  if (!bmem) {
    BIO_free(bmem);
    return -3;
  }

  // read the private key into an EVP_PKEY structure
  EVP_PKEY* privkey = PEM_read_bio_PrivateKey(bmem, NULL, NULL, NULL);
  if (!privkey) {
    BIO_free(bmem);
    return -4;
  }


  if(!(err = X509_REQ_set_pubkey(req, privkey)))
  {
    BIO_free(bmem);
    return err;
  }

  if(!(err = X509_REQ_set_version(req,3)))
  {
    BIO_free(bmem);
    return err;
  }

  //write it to PEM format
  if (!(err = PEM_write_bio_X509_REQ(mem, req))) {
    BIO_free(mem);
    BIO_free(bmem);
    return err;
  }


  BUF_MEM *bptr;
  BIO_get_mem_ptr(mem, &bptr);
  BIO_read(mem, result, bptr->length);

  BIO_free(bmem);
  BIO_free(mem);
  return 0;
}
Ejemplo n.º 16
0
		inline void certificate_request::set_version(long _version) const
		{
			error::throw_error_if_not(X509_REQ_set_version(ptr().get(), _version) != 0);
		}