// reads the request req_filename and creates a modified creq_filename with the commitment extension added
void writeCommitmentCSR(BIGNUM *commitment_c, char *privkey_filename, char *req_filename, char *creq_filename) {
	FILE *fp;

	/* read in the request */
	X509_REQ *req;
	if (!(fp = fopen(req_filename, "r")))
		critical_error("Error reading request file");
	if (!(req = PEM_read_X509_REQ(fp, NULL, NULL, NULL)))
		critical_error("Error reading request in file");
	fclose(fp);

	/*  read in the private key */
	EVP_PKEY *pkey;
	if (!(fp = fopen(privkey_filename, "r")))
		critical_error("Error reading private key file");
	if (!(pkey = PEM_read_PrivateKey(fp, NULL, NULL, NULL)))
		critical_error("Error reading private key in file");
	fclose(fp);

	/* create the new request */
	X509_REQ *creq;
	if (!(creq = X509_REQ_new()))
		critical_error("Failed to create X509_REQ object");

	X509_REQ_set_pubkey(creq, pkey);

	// gets subj from initial requests and adds it to new one
	X509_NAME *subj = X509_REQ_get_subject_name(req);
	if (X509_REQ_set_subject_name(creq, subj) != 1)
			critical_error("Error adding subject to request");

	// enable the commitment extension handling (retrieve/print as string)
	int nid = _commitmentExt_start();

	// get extensions stack of original request
	STACK_OF(X509_EXTENSION) *extlist = X509_REQ_get_extensions(req);

	// if no extensions, create new stack
	if (extlist==NULL) {
		extlist = sk_X509_EXTENSION_new_null();
	} else { // else check that the extension isn't already there (error!)
		X509_EXTENSION *tmp = (X509_EXTENSION*) X509V3_get_d2i(extlist, nid, NULL, NULL);
		if (tmp!=NULL)
			critical_error("Aborting process: CSR already contains commitment extension!\n");		
	}

	// create commitment extension storing C value as a hex string
	X509_EXTENSION *exCommitment = (X509_EXTENSION*) X509V3_EXT_conf_nid(NULL, NULL, nid, BN_bn2hex(commitment_c));
	if (!exCommitment)
		critical_error("error creating commitment extension");

	// push commitment extension into stack
	sk_X509_EXTENSION_push(extlist, exCommitment);

	// assign extensions to the new request
	if (!X509_REQ_add_extensions(creq, extlist))
		critical_error("Error adding extensions to the request");

	sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
	/////////////////////////////////////////////////////////////////////

	/* pick the correct digest and sign the new request */
	EVP_MD *digest;
	if (EVP_PKEY_type(pkey->type) == EVP_PKEY_DSA)
		digest = (EVP_MD*) EVP_dss1();
	else if (EVP_PKEY_type(pkey->type) == EVP_PKEY_RSA)
		digest = (EVP_MD*) EVP_sha1();
	else
		critical_error("Error checking public key for a valid digest");

	if (!(X509_REQ_sign(creq, pkey, digest)))
		critical_error("Error signing request");

	/* write the modified request */
	if (!(fp = fopen(creq_filename, "w")))
		critical_error("Error writing to request file");
	if (PEM_write_X509_REQ(fp, creq) != 1)
		critical_error("Error while writing request");
	fclose(fp);

	// cleanup
	_commitmentExt_end();
	EVP_PKEY_free(pkey);
	X509_REQ_free(req);
	X509_REQ_free(creq);
}
Example #2
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
}
Example #3
0
/* Creates an X509 certificate request (2nd stage). */
int MakeCertificateRequest2(unsigned char *reqbuf, int *reqlen, char *x500dn, EVP_PKEY *usrkey)
{
	X509 *racert = NULL;
	EVP_PKEY *rakey = NULL;
	X509_REQ *x = NULL;
	X509_NAME *subject = NULL;
	unsigned char *p = NULL;
	int ret, len;

	if (reqbuf == NULL || reqlen == NULL || x500dn == NULL || usrkey == NULL)
		return OPENSSLCA_ERR_ARGS;

	/* Create new request */
	if ((x = X509_REQ_new()) == NULL) {
		ret = OPENSSLCA_ERR_REQ_NEW;
		goto err;
	}

	/* Set public key in request */
	if (X509_REQ_set_pubkey(x, usrkey) != 1) {
		ret = OPENSSLCA_ERR_REQ_SET_PUBKEY;
		goto err;
	}

	/* Set subject name */
	subject = X509_REQ_get_subject_name(x);
	if (subject == NULL) {
		ret = OPENSSLCA_ERR_REQ_GET_SUBJECT;
		goto err;
	}
	ret = dn2subject(x500dn, subject);
	if (ret != OPENSSLCA_NO_ERR)
		goto err;

	if (caIni.signRequests) {
		/* Sign request with RA's private key */
		ret = read_key(&rakey, CA_PATH(caIni.raKeyFile), caIni.raKeyPasswd);
		if (ret != OPENSSLCA_NO_ERR)
			goto err;
		if (!X509_REQ_sign(x, rakey, EVP_sha1())) {
			ret = OPENSSLCA_ERR_REQ_SIGN;
			goto err;
		}

		if (caIni.verifyAfterSign) {
			/* Get RA's public key */
			/* TODO: Validate RA certificate */
			ret = read_cert(&racert, CA_PATH(caIni.raCertFile));
			if (ret != OPENSSLCA_NO_ERR)
				goto err;

			EVP_PKEY_free(rakey);
			if ((rakey = X509_get_pubkey(racert)) == NULL) {
				ret = OPENSSLCA_ERR_CERT_GET_PUBKEY;
				goto err;
			}

			/* Verify signature on request */
			if (X509_REQ_verify(x, rakey) != 1) {
				ret = OPENSSLCA_ERR_REQ_VERIFY;
				goto err;
			}
		}
	}

#ifdef _DEBUG /* Output request in PEM format */
	{
		FILE *fp = fopen(DBG_PATH("request.pem"), "w");
		if (fp != NULL) {
			X509_REQ_print_fp(fp, x);
			PEM_write_X509_REQ(fp, x);
			fclose(fp);
		}
	}
#endif

	/* Encode request into DER format */
	len = i2d_X509_REQ(x, NULL);
	if (len < 0) {
		ret = OPENSSLCA_ERR_REQ_ENCODE;
		goto err;
	}
	if (len > *reqlen) {
		ret = OPENSSLCA_ERR_BUF_TOO_SMALL;
		goto err;
	}
	*reqlen = len;
	p = reqbuf;
	i2d_X509_REQ(x, &p);

err:
	if (racert)
		X509_free(racert);
	if (rakey)
		EVP_PKEY_free(rakey);
	if (x)
		X509_REQ_free(x);

	return ret;
}
uint32 CRegProtocol::GenerateCertRequest(char *SubjName,
                                         uchar **Cert,
                                         uint32 *CertLength)
{
    uint32 err; //= TU_ERROR_CRYPTO_FAILED;
    X509_REQ *req;
    X509_NAME *subj;
    EVP_PKEY *pkey;
    int nid;
    X509_NAME_ENTRY *ent;
    FILE *fp;
    int fsize;

    //First, get the private key
    err = GetPrivateKey(SubjName, TU_KEY_ENC, &pkey);
    if(TU_SUCCESS != err)
    {
        TUTRACE((TUTRACE_ERR, "PROTO: Error getting private key\n"));
        goto EXIT;
    }

    //Now create a new request object
    if(!(req = X509_REQ_new()))
    {
        TUTRACE((TUTRACE_ERR, "PROTO: Error creating new X509 Request\n"));
        goto ERR_PKEY;
    }

    //assign the public key to the request
    X509_REQ_set_pubkey (req, pkey);

    //Subject name processing. 
    if(!(subj = X509_NAME_new()))
    {
        TUTRACE((TUTRACE_ERR, "PROTO: Error creating new X509 Subject\n"));
        goto ERR_REQ;
    }

    //First set the predefined subject fields
    for (int i = 0; i < ENTRY_COUNT; i++)
    {
        if((nid = OBJ_txt2nid (entries[i].key)) == NID_undef)
        {
            TUTRACE((TUTRACE_ERR, "PROTO: Error getting NID from text\n"));
            X509_NAME_free(subj);
            goto ERR_REQ;
        }
      
        if(!(ent = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_ASC,
                                                 (uchar *)entries[i].value, -1)))
        {
            TUTRACE((TUTRACE_ERR, "PROTO: Error creating name entry\n"));
            X509_NAME_free(subj);
            goto ERR_REQ;
        }

        if(X509_NAME_add_entry(subj, ent, -1, 0) != 1)
        {
            TUTRACE((TUTRACE_ERR, "PROTO: Error adding name entry to subject\n"));
            X509_NAME_ENTRY_free(ent);
            X509_NAME_free(subj);
            goto ERR_REQ;
        }
    }//for

    //Next set the common name and description
    if((nid = OBJ_txt2nid("commonName")) == NID_undef)
    {
        TUTRACE((TUTRACE_ERR, "PROTO: Error getting NID from text\n"));
        X509_NAME_free(subj);
        goto ERR_REQ;
    }

    if(!(ent = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_ASC,
                                                 (uchar *)SubjName, -1)))
    {
        TUTRACE((TUTRACE_ERR, "PROTO: Error creating name entry\n"));
        X509_NAME_free(subj);
        goto ERR_REQ;
    }

    if(X509_NAME_add_entry(subj, ent, -1, 0) != 1)
    {
        TUTRACE((TUTRACE_ERR, "PROTO: Error adding name entry to subject\n"));
        X509_NAME_ENTRY_free(ent);
        X509_NAME_free(subj);
        goto ERR_REQ;
    }

    //Finally add the subject to the request
    if(X509_REQ_set_subject_name (req, subj) != 1)
    {
        TUTRACE((TUTRACE_ERR, "PROTO: Error setting subject in request\n"));
        X509_NAME_free(subj);
        goto ERR_REQ;
   }

    //Sign the request
    if(!(X509_REQ_sign(req, pkey, EVP_sha1())))
    {
        TUTRACE((TUTRACE_ERR, "PROTO: Error signing request\n"));
        goto ERR_REQ;
    }

    //Now we need to serialize the request. So write it to a file and read it out
    if(!(fp = fopen("protofile", "w")))
    {
        TUTRACE((TUTRACE_ERR, "PROTO: Error opening file for writing\n"));
        err = TU_ERROR_FILEOPEN;
        goto ERR_REQ;
    }

    if(PEM_write_X509_REQ(fp, req) != 1)
    {
        TUTRACE((TUTRACE_ERR, "PROTO: Error writing request to file\n"));
        err = TU_ERROR_FILEWRITE;
        fclose(fp);
        goto ERR_REQ;
    }

    fclose(fp);

    //now open it for reading in binary format
    if(!(fp = fopen("protofile", "rb")))
    {
        TUTRACE((TUTRACE_ERR, "PROTO: Error opening file for reading\n"));
        err = TU_ERROR_FILEOPEN;
        goto ERR_FILE;
    }

    //get the filesize
    fseek(fp, 0, SEEK_END);
    fsize = ftell(fp);
    if(fsize == -1)
    {
        TUTRACE((TUTRACE_ERR, "Couldn't determine file size\n"));
        err = TU_ERROR_FILEREAD;
        goto ERR_FILE;
    }

    //Allocate memory
    *Cert = (uchar *)malloc(fsize);
    if(!*Cert)
    {
        TUTRACE((TUTRACE_ERR, "PROTO: Error allocating memory for cert buffer\n"));
        err = TU_ERROR_OUT_OF_MEMORY;
        goto ERR_FILE;
   }

    *CertLength = fsize;

    rewind(fp);
    fread(*Cert, 1, fsize, fp);

    err = TU_SUCCESS;

ERR_FILE:
    if(fp)
        fclose(fp);
    remove("protofile");
ERR_REQ:
    X509_REQ_free(req);
ERR_PKEY:
    EVP_PKEY_free(pkey);
EXIT:
    return err;
}//GenerateCertRequest
Example #5
0
int genrequest(char department[], char cname0[]) {

   X509_REQ 	*webrequest 	 = NULL;
   EVP_PKEY	*pubkey		 = NULL;
   X509_NAME 	*reqname	 = NULL;
   DSA 		*mydsa		 = NULL;
   RSA 		*myrsa		 = NULL;
   BIO 		*outbio		 = NULL;
   X509_NAME_ENTRY      *e;
   int                  i;
   FILE                         *fp, *fp2;

   char         buf[80]		 = "";
   char         country[81]      = "UK";
   char         province[81]     = "Gloucestershire";
   char         locality[81]     = "Tetbury";
   char         organisation[81] = "TETBURY SOFTWARE SERVICES Ltd";
   char 	email_addr[81]   = "*****@*****.**";
   char 	cname1[81]       = "";
   char 	cname2[81]       = "";
   char 	surname[81]      = "";
   char 	givenname[81]    = "";

   char 	keytype[81]      = "rsa";
   int	 	rsastrength	 = 4096;
   int	 	dsastrength	 = 0;


/* we do not accept requests with no data, i.e. being empty with just a 
   public key. Although technically possible to sign and create a cert,
   they don't make much sense. We require here at least one CN supplied.    */

   if(strlen(cname0) == 0 && strlen(cname1) == 0 && strlen(cname2) == 0)
     printf("Error supply at least one CNAME in request subject");

/* -------------------------------------------------------------------------- *
 * These function calls are essential to make many PEM + other openssl        *
 * functions work. It is not well documented, I found out after looking into  *
 * the openssl source directly.                                               *
 * needed by: PEM_read_PrivateKey(), X509_REQ_verify() ...                    *
 * -------------------------------------------------------------------------- */
   OpenSSL_add_all_algorithms();
   ERR_load_crypto_strings();

/* ------------------------------------------------------------------------- *
 * Generate the key pair based on the selected keytype                       *
 * ------------------------------------------------------------------------- */

   if ((pubkey=EVP_PKEY_new()) == NULL)
      printf("Error creating EVP_PKEY structure.");

   if(strcmp(keytype, "rsa") == 0) {

      myrsa = RSA_new();
      if (! (myrsa = RSA_generate_key(rsastrength, RSA_F4, NULL, NULL)))
         printf("Error generating the RSA key.");

      if (!EVP_PKEY_assign_RSA(pubkey,myrsa))
         printf("Error assigning RSA key to EVP_PKEY structure.");
   }
   else if(strcmp(keytype, "dsa") == 0) {

      mydsa = DSA_new();
      mydsa = DSA_generate_parameters(dsastrength, NULL, 0, NULL, NULL,
                                                                  NULL, NULL);
      if (! (DSA_generate_key(mydsa)))
         printf("Error generating the DSA key.");

      if (!EVP_PKEY_assign_DSA(pubkey,mydsa))
         printf("Error assigning DSA key to EVP_PKEY structure.");
   }
   else
      printf("Error: Wrong keytype - choose either RSA or DSA.");

/* ------------------------------------------------------------------------- *
 * Generate the certificate request from scratch                             *
 * ------------------------------------------------------------------------- */

   if ((webrequest=X509_REQ_new()) == NULL)
      printf("Error creating new X509_REQ structure.");

   if (X509_REQ_set_pubkey(webrequest, pubkey) == 0)
      printf("Error setting public key for X509_REQ structure.");

   if ((reqname=X509_REQ_get_subject_name(webrequest)) == NULL)
      printf("Error setting public key for X509_REQ structure.");

   /* The following functions create and add the entries, working out  *
    * the correct string type and performing checks on its length.     *
    * We also check the return value for errors...                     */

   if(strlen(country) != 0)
      X509_NAME_add_entry_by_txt(reqname,"C", MBSTRING_ASC, 
                           (unsigned char*) country, -1, -1, 0);
   if(strlen(province) != 0)
      X509_NAME_add_entry_by_txt(reqname,"ST", MBSTRING_ASC,
                           (unsigned char *) province, -1, -1, 0);
   if(strlen(locality) != 0)
      X509_NAME_add_entry_by_txt(reqname,"L", MBSTRING_ASC,
                          (unsigned char *) locality, -1, -1, 0);
   if(strlen(organisation) != 0)
      X509_NAME_add_entry_by_txt(reqname,"O", MBSTRING_ASC,
                      (unsigned char *) organisation, -1, -1, 0);
   if(strlen(department) != 0)
      X509_NAME_add_entry_by_txt(reqname,"OU", MBSTRING_ASC,
                         (unsigned char *) department, -1, -1, 0);
   if(strlen(email_addr) != 0)
      X509_NAME_add_entry_by_txt(reqname,"emailAddress", MBSTRING_ASC,
			(unsigned char *)  email_addr, -1, -1, 0);
   if(strlen(cname0) != 0)
      X509_NAME_add_entry_by_txt(reqname,"CN", MBSTRING_ASC,
                                   (unsigned char *) cname0, -1, -1, 0);
   if(strlen(cname1) != 0)
      X509_NAME_add_entry_by_txt(reqname,"CN", MBSTRING_ASC,
                                   (unsigned char *) cname1, -1, -1, 0);
   if(strlen(cname2) != 0)
      X509_NAME_add_entry_by_txt(reqname,"CN", MBSTRING_ASC,
                                   (unsigned char *) cname2, -1, -1, 0);
   if(strlen(surname) != 0)
      X509_NAME_add_entry_by_txt(reqname,"SN", MBSTRING_ASC,
                                   (unsigned char *) surname, -1, -1, 0);
   if(strlen(givenname) != 0)
      X509_NAME_add_entry_by_txt(reqname,"GN", MBSTRING_ASC,
                                 (unsigned char *) givenname, -1, -1, 0);

/* ------------------------------------------------------------------------- *
 * Sign the certificate request: md5 for RSA keys, dss for DSA keys          *
 * ------------------------------------------------------------------------- */

   if(strcmp(keytype, "rsa") == 0) {
      if (!X509_REQ_sign(webrequest,pubkey,EVP_md5()))
         printf("Error MD5 signing X509_REQ structure.");
   }
   else if(strcmp(keytype, "dsa") == 0) {
      if (!X509_REQ_sign(webrequest,pubkey,EVP_dss()))
         printf("Error DSS signing X509_REQ structure.");
   }

/* ------------------------------------------------------------------------- *
 *  and sort out the content plus start the html output                      *
 * ------------------------------------------------------------------------- */

   if (! (fp=fopen("clave_publica.pem", "w")))
        printf("No puedo crear el fichero de la request");

   if (! (fp2=fopen("clave_privada.pem", "w")))
        printf("No puedo crear el fichero de la clave privada");

   outbio = BIO_new(BIO_s_file());
   BIO_set_fp(outbio, fp, BIO_NOCLOSE);

   if (! PEM_write_bio_X509_REQ(outbio, webrequest))
      printf("Error printing the request");

   for (i = 0; i < X509_NAME_entry_count(reqname); i++) {
      e = X509_NAME_get_entry(reqname, i);
      OBJ_obj2txt(buf, 80, e->object, 0);
   }

   PEM_write_PrivateKey(fp2,pubkey,NULL,NULL,0,0,NULL);


   BIO_free(outbio);
   fclose(fp);
   fclose(fp2);
   return(0);
}
Example #6
0
bool avjackif::async_register_new_user(std::string user_name, boost::asio::yield_context yield_context)
{
	// 先发 client_hello
	if( m_shared_key.empty())
		async_client_hello(yield_context);

	auto digest = EVP_sha1();

	// 先生成 RSA 密钥
	_rsa.reset(RSA_generate_key(2048, 65537, 0, 0), RSA_free);

	// 然后生成 CSR
	boost::shared_ptr<X509_REQ> csr(X509_REQ_new(), X509_REQ_free);

	boost::shared_ptr<EVP_PKEY> pkey(EVP_PKEY_new(), EVP_PKEY_free);
	EVP_PKEY_set1_RSA(pkey.get(), _rsa.get());

	// 添加证书申请信息

	auto subj =X509_REQ_get_subject_name(csr.get());
/*	X509_NAME_add_entry_by_NID(subj, NID_countryName, "CN");
	X509_NAME_add_entry_by_NID(subj, NID_stateOrProvinceName, "Shanghai");
	X509_NAME_add_entry_by_NID(subj, NID_localityName, "Shanghai");
	X509_NAME_add_entry_by_NID(subj, NID_organizationName, "avplayer");
	X509_NAME_add_entry_by_NID(subj, NID_organizationalUnitName, "sales");
*/	X509_NAME_add_entry_by_NID(subj, NID_commonName, user_name);
//	X509_NAME_add_entry_by_NID(subj, NID_pkcs9_emailAddress, "test-client");

	X509_REQ_set_pubkey(csr.get(), pkey.get());

	// 签出 CSR
	X509_REQ_sign(csr.get(), pkey.get(), digest);

	unsigned char * out = NULL;
	auto csr_out_len = i2d_X509_REQ(csr.get(), &out);

	std::string csrout((char*)out, csr_out_len);

	OPENSSL_free(out);
	out = NULL;
	auto rsa_key_out_len = i2d_RSA_PUBKEY(_rsa.get(), &out);

	std::string rsa_key((char*)out, rsa_key_out_len);
	OPENSSL_free(out);

	PEM_write_X509_REQ(stderr, csr.get());

	// 然后发送 注册信息
	proto::user_register user_register;

	user_register.set_user_name(user_name);
	user_register.set_rsa_pubkey(rsa_key);
	user_register.set_csr(csrout);

	boost::asio::async_write(*m_sock, boost::asio::buffer(av_router::encode(user_register)), yield_context);

	// 读取应答
	std::unique_ptr<proto::user_register_result> user_register_result((proto::user_register_result*)async_read_protobuf_message(*m_sock, yield_context));

	return user_register_result->result() == proto::user_register_result::REGISTER_SUCCEED;
}
int CCertificateRequestGenerator::Generate()
//Generate certificate request and write into a file
	{
	FILE*		  fp			= NULL;
	char*		  pbPassword	= NULL;
	EVP_PKEY* 	  pKey			= NULL;
	X509_REQ*	  pReq			= NULL;
	X509_NAME*	  pSubj			= NULL;
	const EVP_MD* pDigest		= NULL;
	DWORD		  bytesWritten;
	struct entry_pack* pEntPack = NULL;

	int retFunc	= FAIL;

	//Get command prompt handle
	HANDLE hndl = GetStdHandle(STD_OUTPUT_HANDLE);
	
	OPENSSL_add_all_algorithms_conf();
	ERR_load_crypto_strings();

	//First read private key from key file
	if(!(fp = _tfopen(m_privateKeyFile, _T("r"))))
		{
		PrintErrorInfo("Error reading key file!", EGeneric, constparams);
		WriteConsole(hndl, m_privateKeyFile, wcslen(m_privateKeyFile), &bytesWritten, 0);
		return retFunc;
		}

	if(m_password[0] != 0)
		{
		DWORD len = 0;
		len = _tcslen(m_password);
		pbPassword = MakeMBCSString(m_password, CP_UTF8, len);
		pKey = PEM_read_PrivateKey(fp, NULL, NULL, pbPassword);
		delete pbPassword;
		}
	else
		{
		pKey = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
		}
			
	fclose(fp); fp = NULL;

	if(!pKey)
		{
		PrintErrorInfo("Error reading private key in key file!", EOPENSSL, constparams);
		return retFunc;
		}
	try
		{
		//Create a new cert request and add the public key into it
		if(!(pReq = X509_REQ_new()))
			{
			PrintErrorInfo("Error creating X509 request object!", EOPENSSL, constparams);
			throw EOPENSSL;
			}

		X509_REQ_set_pubkey(pReq, pKey);

		//Now create DN name entries and assign them to request
		if(!(pSubj = X509_NAME_new()))
			{
			PrintErrorInfo("Error creating X509 name object!", EOPENSSL, constparams);
			throw EOPENSSL;
			}

		//Format DN string
		DoFormatted(m_dname, &pEntPack);

		if(pEntPack->num == 0)
			{
			PrintErrorInfo("Error formatting Distinguished Name!", EGeneric, constparams);
			throw EGeneric;
			}

		for (int i = 0; i < pEntPack->num; i++)
			{
			int nid = 0;
			DWORD lent = 0;
			X509_NAME_ENTRY *pEnt = NULL;
			LPSTR pbMBSTRUTF8 = NULL;

			if((pEntPack->entries[i].value == NULL) || (pEntPack->entries[i].key == NULL))
				{
				PrintErrorInfo("Error in Distinguished Name construction!", EGeneric, constparams);
				throw EGeneric;
				}

			if((nid = OBJ_txt2nid(pEntPack->entries[i].key)) == NID_undef)
				{
				PrintErrorInfo("Error finding NID for a DN entry!", EOPENSSL, constparams);
				throw EOPENSSL;
				}
			lent = _tcslen(pEntPack->entries[i].value);
			pbMBSTRUTF8 = MakeMBCSString(pEntPack->entries[i].value, CP_UTF8, lent);

			if(lent > 64) //OpenSSL does not accept a string longer than 64 
				{
				if(!(pEnt = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_UTF8, (unsigned char *)"dummy", 5)))
					{
					PrintErrorInfo("Error creating name entry from NID!", EOPENSSL, constparams);
					throw EOPENSSL;
					}
				
				pEnt->value->data = (unsigned char *)malloc(lent+1);
				
				for(DWORD j=0; j<lent; j++ )
					{
					pEnt->value->data[j] = pbMBSTRUTF8[j];
					}
				
				pEnt->value->length = lent;

				} 
			else if(!(pEnt = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_UTF8, (unsigned char *)pbMBSTRUTF8, lent)))
				{
				PrintErrorInfo("Error creating name entry from NID!", EOPENSSL, constparams);
				throw EOPENSSL;
				}

			if(X509_NAME_add_entry(pSubj, pEnt, -1, 0) != 1)
				{
				PrintErrorInfo("Error adding entry to X509 Name!", EOPENSSL, constparams);
				throw EOPENSSL;
				}
			delete pbMBSTRUTF8;
			}//for
		
		SYMBIAN_FREE_MEM(pEntPack);

		if(X509_REQ_set_subject_name(pReq, pSubj) != 1)
			{
			PrintErrorInfo("Error adding subject to request!", EOPENSSL, constparams);
			throw EOPENSSL;
			}

			//Find the correct digest and sign the request

		if(EVP_PKEY_type(pKey->type) == EVP_PKEY_DSA)
			{
			pDigest = EVP_dss1();
			}
		else if(EVP_PKEY_type(pKey->type) == EVP_PKEY_RSA)
			{
			pDigest = EVP_sha1();
			}
		else
			{
			PrintErrorInfo("Error checking private key type!", EOPENSSL, constparams);
			throw EOPENSSL;
			}

		if(!(X509_REQ_sign(pReq, pKey, pDigest)))
			{
			PrintErrorInfo("Error signing request!", EOPENSSL, constparams);
			throw EOPENSSL;
			}

		if(!(fp = _tfopen(m_RequestFile, _T("w"))))
			{
			PrintErrorInfo("Error writing to request file!",EGeneric,constparams);
			throw EGeneric;
			}
	
		if(PEM_write_X509_REQ(fp, pReq) != 1)
			{
			PrintErrorInfo("Error while writing to request file!", EOPENSSL, constparams);
			throw EOPENSSL;
			}

		//Free variables
		EVP_PKEY_free(pKey);
		X509_NAME_free(pSubj);
		X509_REQ_free(pReq);
		fclose(fp);

		_tprintf(_T("\nCreated request: "));
		WriteConsole(hndl, m_RequestFile, wcslen(m_RequestFile), &bytesWritten, 0);

		retFunc = SUCCESS;

		}
	catch (...)
		{
		if(pKey)
			{
			EVP_PKEY_free(pKey);
			}
		
		if(pSubj)
			{
			X509_NAME_free(pSubj);
			}

		if(pReq)
			{
			X509_REQ_free(pReq);
			}

		SYMBIAN_FREE_MEM(pEntPack);
		}

	return retFunc;
	}
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 ...");
}
		inline void certificate_request::sign(pkey::pkey pkey, hash::message_digest_algorithm algorithm) const
		{
			error::throw_error_if_not(X509_REQ_sign(ptr().get(), pkey.raw(), algorithm.raw()) != 0);
		}
Example #10
0
/***
sign x509_req object

@function sign
@tparam evp_pkey pkey private key which to sign x509_req object
@tparam number|string|evp_md md message digest alg used to sign
@treturn boolean result true for suceess
*/
static LUA_FUNCTION(openssl_csr_sign)
{
  X509_REQ * csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req");
  EVP_PKEY *pubkey = X509_REQ_get_pubkey(csr);
  if (auxiliar_getclassudata(L, "openssl.evp_pkey", 2))
  {
    EVP_PKEY *pkey = CHECK_OBJECT(2, EVP_PKEY, "openssl.evp_pkey");
    const EVP_MD* md = get_digest(L, 3, "sha256");
    int ret = 1;
    if (pubkey == NULL)
    {
      BIO* bio = BIO_new(BIO_s_mem());
      if ((ret = i2d_PUBKEY_bio(bio, pkey)) == 1)
      {
        pubkey = d2i_PUBKEY_bio(bio, NULL);
        if (pubkey)
        {
          ret = X509_REQ_set_pubkey(csr, pubkey);
          EVP_PKEY_free(pubkey);
        }
        else
        {
          ret = 0;
        }
      }
      BIO_free(bio);
    }
    else
    {
      EVP_PKEY_free(pubkey);
    }
    if (ret == 1)
      ret = X509_REQ_sign(csr, pkey, md);
    return openssl_pushresult(L, ret);
  }
  else if (lua_isstring(L, 2))
  {
    size_t siglen;
    unsigned char* sigdata = (unsigned char*)luaL_checklstring(L, 2, &siglen);
    const EVP_MD* md = get_digest(L, 3, NULL);
    ASN1_BIT_STRING *sig = NULL;
    X509_ALGOR *alg = NULL;

    luaL_argcheck(L, pubkey != NULL, 1, "has not set public key!!!");

    X509_REQ_get0_signature(csr, (const ASN1_BIT_STRING **)&sig, (const X509_ALGOR **)&alg);
    /* (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) ? V_ASN1_NULL : V_ASN1_UNDEF, */
    X509_ALGOR_set0((X509_ALGOR *)alg, OBJ_nid2obj(EVP_MD_pkey_type(md)), V_ASN1_NULL, NULL);

    ASN1_BIT_STRING_set((ASN1_BIT_STRING *)sig, sigdata, siglen);
    /*
    * In the interests of compatibility, I'll make sure that the bit string
    * has a 'not-used bits' value of 0
    */
    sig->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
    sig->flags |= ASN1_STRING_FLAG_BITS_LEFT;
    lua_pushboolean(L, 1);
    return 1;
  }
  else
  {
    int inl;
    unsigned char* tosign = NULL;
    luaL_argcheck(L, pubkey != NULL, 1, "has not set public key!!!");

    inl = i2d_re_X509_REQ_tbs(csr, &tosign);
    if (inl > 0 && tosign)
    {
      lua_pushlstring(L, (const char*)tosign, inl);
      OPENSSL_free(tosign);
      return 1;
    }
    return openssl_pushresult(L, 0);
  }
}