예제 #1
2
파일: pki_x509req.cpp 프로젝트: jbfavre/xca
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);
}
예제 #2
0
int X509V3_EXT_REQ_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
	     X509_REQ *req)
{
	X509_EXTENSION *ext;
	STACK_OF(X509_EXTENSION) *extlist = NULL;
	STACK_OF(CONF_VALUE) *nval;
	CONF_VALUE *val;	
	int i;
	if(!(nval = CONF_get_section(conf, section))) return 0;
	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
		val = sk_CONF_VALUE_value(nval, i);
		if(!(ext = X509V3_EXT_conf(conf, ctx, val->name, val->value)))
								return 0;
		if(!extlist) extlist = sk_X509_EXTENSION_new_null();
		sk_X509_EXTENSION_push(extlist, ext);
	}
	if(req) i = X509_REQ_add_extensions(req, extlist);
	else i = 1;
	sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
	return i;
}
예제 #3
0
static LUA_FUNCTION(openssl_csr_extensions)
{
  X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req");
  if (lua_isnone(L, 2))
  {
    STACK_OF(X509_EXTENSION) *sk = X509_REQ_get_extensions(csr);
    if (sk)
    {
      PUSH_OBJECT(sk, "openssl.stack_of_x509_extension");
    }
    else
      lua_pushnil(L);
    return 1;
  }
  else
  {
    STACK_OF(X509_EXTENSION) *sk = CHECK_OBJECT(2,  STACK_OF(X509_EXTENSION), "openssl.stack_of_x509_extension");
    int ret = X509_REQ_add_extensions(csr, sk);
    return openssl_pushresult(L, ret);
  }
}
예제 #4
0
파일: csr.c 프로젝트: fiendish/lua-openssl
/***
set extension of x509_req object
@function extensions
@tparam stack_of_x509_extension extensions
@treturn boolean result true for success
*/
static LUA_FUNCTION(openssl_csr_extensions)
{
  X509_REQ *csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req");
  if (lua_isnone(L, 2))
  {
    STACK_OF(X509_EXTENSION) *sk = X509_REQ_get_extensions(csr);
    if (sk)
    {
      openssl_sk_x509_extension_totable(L, sk);
      sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free);
    }
    else
      lua_pushnil(L);
    return 1;
  }
  else
  {
    STACK_OF(X509_EXTENSION) *sk = openssl_sk_x509_extension_fromtable(L, 2);
    int ret = X509_REQ_add_extensions(csr, sk);
    sk_X509_EXTENSION_pop_free(sk, X509_EXTENSION_free);
    return openssl_pushresult(L, ret);
  }
}
예제 #5
0
파일: pkcs12.c 프로젝트: xranby/fribid
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;
}
예제 #6
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;
}
예제 #7
0
파일: mkreq.c 프로젝트: LucidOne/Rovio
int mkreq(X509_REQ **req, EVP_PKEY **pkeyp, int bits, int serial, int days)
	{
	X509_REQ *x;
	EVP_PKEY *pk;
	RSA *rsa;
	X509_NAME *name=NULL;
	STACK_OF(X509_EXTENSION) *exts = NULL;
	
	if ((pk=EVP_PKEY_new()) == NULL)
		goto err;

	if ((x=X509_REQ_new()) == NULL)
		goto err;

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

	rsa=NULL;

	X509_REQ_set_pubkey(x,pk);

	name=X509_REQ_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, "UK", -1, -1, 0);
	X509_NAME_add_entry_by_txt(name,"CN",
				MBSTRING_ASC, "OpenSSL Group", -1, -1, 0);

#ifdef REQUEST_EXTENSIONS
	/* Certificate requests can contain extensions, which can be used
	 * to indicate the extensions the requestor would like added to 
	 * their certificate. CAs might ignore them however or even choke
	 * if they are present.
	 */

	/* For request extensions they are all packed in a single attribute.
	 * We save them in a STACK and add them all at once later...
	 */

	exts = sk_X509_EXTENSION_new_null();
	/* Standard extenions */

	add_ext(exts, NID_key_usage, "critical,digitalSignature,keyEncipherment");

	/* This is a typical use for request extensions: requesting a value for
	 * subject alternative name.
	 */

	add_ext(exts, NID_subject_alt_name, "email:[email protected]");

	/* Some Netscape specific extensions */
	add_ext(exts, NID_netscape_cert_type, "client,email");



#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

	/* Now we've created the extensions we add them to the request */

	X509_REQ_add_extensions(x, exts);

	sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);

#endif
	
	if (!X509_REQ_sign(x,pk,EVP_md5()))
		goto err;

	*req=x;
	*pkeyp=pk;
	return(1);
err:
	return(0);
	}
예제 #8
0
int32_t HttpsGenCertReq( HttpsCertReqInfo_t    *pCertReqInfo,
                         unsigned char              *pPrivbuf,
                         unsigned char              *pCertbuf,
                         HttpsCertReqParams_t  *pParams )
{
  EVP_PKEY                  *pkey         = NULL;
  HX509Req_t                *preq         = NULL;
#ifdef OPENSSL_9_7
  const  EVP_MD             *pDigest;
#else
  EVP_MD                    *pDigest      = NULL;
#endif /*OPENSSL_9_7*/
  int32_t                   iRetVal;
  unsigned char                  aSubAltName[HTTPS_PARAMS_SUB_NAME_LEN];
  bool                   bFlag         = FALSE;
  STACK_OF(X509_EXTENSION)  *skExtensions = NULL;
  X509_EXTENSION            *pSubExt      = NULL;
  unsigned char                  ucCT;
  int32_t                   uileng;

  /**
   * Input Validations...
   */
  if (pCertReqInfo == NULL)
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: Invalid parameters\n");
    return OF_FAILURE;
  }

  /**
   * Allocate space for the public-private key pair..
   */

  if ((pkey = EVP_PKEY_new()) == NULL)
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: MemAlloc failure\n");
    return OF_FAILURE;
  }

  /**
   * Generate a public-private key pair..
   */
  switch (pCertReqInfo->usCertType)
  {
  case RSA_MD5:
  case RSA_SHA1:
    if ((pCertReqInfo->cr_params.rsa_params.usNumBits < MIN_KEY_LENGTH))
    {
      Trace(HTTPS_ID, TRACE_SEVERE,
            "HttpsGenCertReq : Invalid RSA parameters\n");
      EVP_PKEY_free(pkey);
      return OF_FAILURE;
    }

    if (!EVP_PKEY_assign_RSA(pkey,
            RSA_generate_key(pCertReqInfo->cr_params.rsa_params.usNumBits,
            0x10001, NULL, NULL)))
    {
      Trace(HTTPS_ID, TRACE_SEVERE,
            "HttpsGenCertReq: EVP_PKEY assign failed\n");
      EVP_PKEY_free(pkey);
      return OF_FAILURE;
    }

    ucCT='r';

    if (pCertReqInfo->usCertType == RSA_MD5)
    {
      pDigest = (EVP_MD *) EVP_md5();
    }
    else
    {
      pDigest = (EVP_MD *) EVP_sha1();
    }

    break;
  default:
    Trace(HTTPS_ID, TRACE_SEVERE, "HttpsGenCertReq:: Invalid certificate type\n");
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  /**
   * Prepare the Certificate Request..
   */
  if ((preq = HttpsCertReqNew()) == NULL)
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: X509_req_new failed\n");
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  /**
   * Version Number..
   */
  if (!ASN1_INTEGER_set(preq->req_info->version, 0L))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: ASN1_INTEGER_set failed\n");
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  /**
   * Subject Name...Filled with two RDNs...
   */

  /**
   * RDN # 1 : Country Name...
   */

  if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL,
                          NULL, (char *) pParams->ucCn, NID_countryName, 2, 2))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: Httpsadd_DN_object failed\n");
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

#ifdef OPENSSL_9_7
  if (NID_postalCode == 0)
  {
    NID_postalCode = OBJ_create("2.5.4.17", "2.5.4.17",
                                "postal code attribute");
  }
#endif

  /**
   * RDN #New::2: Postal code...
   */
  if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL,
                          NULL, (char *) pParams->aPostalCode, NID_postalCode, 0,
                          10))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: Httpsadd_DN_object failed\n");
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  /**
   * RDN #3: State..
   */
  if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL,
                          NULL, (char *) pParams->aState, NID_stateOrProvinceName,
                          0, 50))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: Httpsadd_DN_object failed\n");
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  /**
   * RDN #New::4: Locality Name...
   */
  if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL,
                          NULL, (char *) pParams->aCity, NID_localityName, 0, 50))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: Httpsadd_DN_object failed\n");
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  /**
   * RDN #5 : Organization ..
   */
  if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL,
                          NULL, (char *) pParams->aOrg, NID_organizationName,
                          0, 50))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: Httpsadd_DN_object failed\n");
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  /**
   * RDN #6 : Department ..
   */
  if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL,
                          NULL, (char *) pParams->aDept, NID_organizationalUnitName,
                          0, 50))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: Httpsadd_DN_object failed\n");
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  /**
   * RDN #7 : Common Name (Subject)...
   */
  if (!Httpsadd_DN_object((HX509Name_t *) preq->req_info->subject, NULL,
                          NULL, (char *) pParams->ucSub, NID_commonName, 0, 50))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: Httpsadd_DN_object failed\n");
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  of_memset( aSubAltName, 0, HTTPS_PARAMS_SUB_NAME_LEN);

  if (strlen((char *) pParams->aIpAddr))
  {
    of_strcat((char *) aSubAltName, "IP:");
    of_strcat((char *) aSubAltName, (char *) pParams->aIpAddr);
    bFlag = TRUE;
  }

  if (strlen((char *) pParams->aEmailId))
  {
    if (bFlag)
    {
      of_strcat((char *) aSubAltName, ",email:");
    }
    else
    {
      of_strcat((char *) aSubAltName, "email:");
    }

    of_strcat((char *) aSubAltName, (char *) pParams->aEmailId);
    bFlag = TRUE;
  }

  if (strlen((char *) pParams->aDomain))
  {
    if (bFlag)
    {
      of_strcat((char *) aSubAltName, ",DNS:");
    }
    else
    {
      of_strcat((char *) aSubAltName, "DNS:");
    }

    of_strcat((char *) aSubAltName, (char *) pParams->aDomain);
    bFlag = TRUE;
  }

  /**
   * Adding subject alt name extension to the request.
   */
  if ( of_strlen((char *) aSubAltName))
  {
    skExtensions = sk_X509_EXTENSION_new_null();

    if (skExtensions == NULL)
    {
      Trace(HTTPS_ID, TRACE_SEVERE,
            "HttpsGenCertReq:: sk_X509_EXTENSION_new_null failed\n");
      HttpsCertReqFree(preq);
      EVP_PKEY_free(pkey);
      return OF_FAILURE;
    }
    pSubExt = X509V3_EXT_conf_nid(NULL, NULL, NID_subject_alt_name,
                                  (char *) aSubAltName);

    if (pSubExt)
    {
      sk_X509_EXTENSION_push(skExtensions, pSubExt);
    }

    iRetVal = X509_REQ_add_extensions(preq, skExtensions);

    if (iRetVal == 0)
    {
      Trace(HTTPS_ID, TRACE_SEVERE,
            "HttpsGenCertReq:: X509_REQ_add_extensions failed\n");
      HttpsCertReqFree(preq);
      EVP_PKEY_free(pkey);
      return OF_FAILURE;
    }

    sk_X509_EXTENSION_pop_free(skExtensions, X509_EXTENSION_free);
  } /* strlen sub alt */

  /**
   * Set the public key..
   */
  if (!X509_REQ_set_pubkey(preq, pkey))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: X509_REQ_sign failed\n");
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  /**
   * Sign the CertReq Info..
   */
  if (!X509_REQ_sign(preq, pkey, pDigest))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: X509_REQ_sign failed\n");
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  /**
   * Write the Private Key into the file...
   */
  if (HttpsWritetoFile(pPrivbuf, HTTPS_PRIV_KEY, pkey, ucCT,
                       pParams->aIdName))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: HttpsWritetoFile failed #1\n");
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  /**
   * Write the Certificate Request into the file...
   */
  if (HttpsWritetoFile(pCertbuf, HTTPS_CERT_REQ, preq, ucCT,
                       pParams->aIdName))
  {
    Trace(HTTPS_ID, TRACE_SEVERE,
          "HttpsGenCertReq:: HttpsWritetoFile failed #2\n");
    HttpsDeleteCerts(pParams->aIdName, 's');
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  uileng=strlen((char *) pCertbuf);

  if (uileng > 2047)
  {
    Trace(HTTPS_ID, TRACE_SEVERE, "pCertbuf length exceeds 2k\n");
    HttpsDeleteCerts(pParams->aIdName, 's');
    HttpsCertReqFree(preq);
    EVP_PKEY_free(pkey);
    return OF_FAILURE;
  }

  Trace(HTTPS_ID, TRACE_INFO, "Generation of Certificate Request done\n");
  HttpsCertReqFree(preq);
  EVP_PKEY_free(pkey);
  return OF_SUCCESS;
} /* HttpsGenCertReq() */
// 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);
}