Esempio n. 1
3
static X509_REQ *pki_certificate_request(EVP_PKEY *keyring, digital_id_t *digital_id)
{
	jlog(L_DEBUG, "pki_certificate_request");

	X509_REQ *cert_req;
	X509_NAME *subject;
	const EVP_MD *message_digest;

	// create a certificate request
	cert_req = X509_REQ_new();

	// set certificate request 'Subject:'
	subject = X509_NAME_new();

	X509_NAME_add_entry_by_txt(subject, "commonName", MBSTRING_ASC, (unsigned char*)digital_id->commonName, -1, -1, 0);
	X509_NAME_add_entry_by_txt(subject, "countryName", MBSTRING_ASC, (unsigned char*)digital_id->countryName, -1, -1, 0);
	X509_NAME_add_entry_by_txt(subject, "stateOrProvinceName", MBSTRING_ASC, (unsigned char*)digital_id->stateOrProvinceName, -1, -1, 0);
	X509_NAME_add_entry_by_txt(subject, "localityName", MBSTRING_ASC, (unsigned char*)digital_id->localityName, -1, -1, 0);
	X509_NAME_add_entry_by_txt(subject, "emailAddress", MBSTRING_ASC, (unsigned char*)digital_id->emailAddress, -1, -1, 0);
	X509_NAME_add_entry_by_txt(subject, "organizationName", MBSTRING_ASC, (unsigned char*)digital_id->organizationName, -1, -1, 0);

	X509_REQ_set_subject_name(cert_req, subject);
	X509_NAME_free(subject);

	// set certificate request public key
	X509_REQ_set_pubkey(cert_req, keyring);

	// create a message digest
	message_digest = EVP_sha1();

	// sign certificate request
	X509_REQ_sign(cert_req, keyring, message_digest);

	return cert_req;
}
Esempio n. 2
0
void mkreq(X509_REQ** reqp, EVP_PKEY** pkeyp, int bits, int serial, int days)
{
	X509_REQ* req = X509_REQ_new();
	assert(req != NULL);

	EVP_PKEY* userpkey = EVP_PKEY_new();
	assert(userpkey != NULL);

	RSA* rsa;
	X509_NAME* name = NULL;

	rsa = RSA_generate_key(bits, RSA_F4, NULL, NULL);
	assert(EVP_PKEY_assign_RSA(userpkey, rsa) > 0);

	rsa = NULL;

	X509_REQ_set_pubkey(req, userpkey);

	name = X509_REQ_get_subject_name(req);
	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*)"OpenSSL Group", -1, -1, 0);

	assert(X509_REQ_sign(req, userpkey, EVP_sha1()) > 0);

	*reqp = req;
	*pkeyp = userpkey;
}
		inline certificate_request certificate_request::create()
		{
			pointer _ptr = X509_REQ_new();

			error::throw_error_if_not(_ptr);

			return take_ownership(_ptr);
		}
Esempio n. 4
0
pki_x509req::pki_x509req(const QString name)
	: pki_x509super(name)
{
	privkey = NULL;
	request = X509_REQ_new();
	pki_openssl_error();
	pkiType=x509_req;
	done = false;
}
Esempio n. 5
0
pki_x509req::pki_x509req(const QString name)
	: pki_x509super(name)
{
	privkey = NULL;
	class_name = "pki_x509req";
	request = X509_REQ_new();
	pki_openssl_error();
	spki = NULL;
	dataVersion=1;
	pkiType=x509_req;
	done = false;
}
Esempio n. 6
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;
}
Esempio n. 7
0
X509_REQ *
X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
{
	X509_REQ *ret;
	X509_REQ_INFO *ri;
	int i;
	EVP_PKEY *pktmp;

	ret = X509_REQ_new();
	if (ret == NULL) {
		X509error(ERR_R_MALLOC_FAILURE);
		goto err;
	}

	ri = ret->req_info;

	if ((ri->version = ASN1_INTEGER_new()) == NULL)
		goto err;
	if (ASN1_INTEGER_set(ri->version, 0) == 0)
		goto err;

	if (!X509_REQ_set_subject_name(ret, X509_get_subject_name(x)))
		goto err;

	if ((pktmp = X509_get_pubkey(x)) == NULL)
		goto err;

	i = X509_REQ_set_pubkey(ret, pktmp);
	EVP_PKEY_free(pktmp);
	if (!i)
		goto err;

	if (pkey != NULL) {
		if (!X509_REQ_sign(ret, pkey, md))
			goto err;
	}
	return (ret);

err:
	X509_REQ_free(ret);
	return (NULL);
}
Esempio n. 8
0
X509_REQ *
X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
{
	X509_REQ *ret;
	X509_REQ_INFO *ri;
	int i;
	EVP_PKEY *pktmp;

	ret = X509_REQ_new();
	if (ret == NULL) {
		X509err(X509_F_X509_TO_X509_REQ, ERR_R_MALLOC_FAILURE);
		goto err;
	}

	ri = ret->req_info;

	ri->version->length = 1;
	ri->version->data = malloc(1);
	if (ri->version->data == NULL)
		goto err;
	ri->version->data[0] = 0; /* version == 0 */

	if (!X509_REQ_set_subject_name(ret, X509_get_subject_name(x)))
		goto err;

	pktmp = X509_get_pubkey(x);
	i = X509_REQ_set_pubkey(ret, pktmp);
	EVP_PKEY_free(pktmp);
	if (!i)
		goto err;

	if (pkey != NULL) {
		if (!X509_REQ_sign(ret, pkey, md))
			goto err;
	}
	return (ret);

err:
	X509_REQ_free(ret);
	return (NULL);
}
Esempio n. 9
0
static X509_REQ *
GenerateX509CertReq(EVP_PKEY **pkey,             // OUT
                    CONF *config,                // IN
                    int bits)                    // IN
{
   X509_REQ *req = NULL;
   gboolean ret = FALSE;
   gchar *err = NULL;

   *pkey = GenerateRSAPrivateKey(bits);
   if (!*pkey) {
      goto exit;
   }

   req = X509_REQ_new();
   if (!req) {
      Error("Failed to allocate a X509 certificate request.\n");
      goto exit;
   }

   if (!ConfigX509CertReq(req, config)) {
      goto exit;
   }

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

   ret = TRUE;

exit:
   if (!ret) {
      X509_REQ_free(req);
      req = NULL;
   }
   g_free(err);

   return req;
}
Esempio n. 10
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;
}
Esempio n. 11
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;
}
Esempio n. 12
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;
}
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;
	}
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
Esempio n. 15
0
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);
	}
Esempio n. 16
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;
}
Esempio n. 17
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()));
	}
	
}
Esempio n. 18
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);
}
Esempio n. 19
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);
}
// 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);
}
Esempio n. 21
0
void RunEaSession(SSL* ssl, void* data) 
{
  int rfd, wfd;
  FILE* rfp;
  FILE* wfp;
  SetupFileDescriptors(ssl, &rfd, &rfp, &wfd, &wfp);

  RsaDevice device = (RsaDevice)data;

  // Device makes entropy request
  BIGNUM* v1 = BN_new();
  BIGNUM* v2 = BN_new(); 
  BIGNUM* v3 = BN_new(); 
  BIGNUM* v4 = BN_new(); 

  CHECK_CALL(v1);
  CHECK_CALL(v2);
  CHECK_CALL(RsaDevice_GenEntropyRequest(device, v1, v2));

  PrintTime("Sending commits to EA");
  // Send mode flag
  CHECK_CALL(fprintf(wfp, "%d\n", RSA_CLIENT));
  CHECK_CALL(!fflush(wfp));

  CHECK_CALL(WriteOneBignum(STRING_COMMIT_X, sizeof(STRING_COMMIT_X), wfp, v1));
  CHECK_CALL(WriteOneBignum(STRING_COMMIT_Y, sizeof(STRING_COMMIT_Y), wfp, v2));
  CHECK_CALL(!fflush(wfp));

  PrintTime("...done");

  // Read x', y' from EA
  PrintTime("Reading entropy from EA");
  CHECK_CALL(ReadOneBignum(&v1, rfp, STRING_X_PRIME));
  CHECK_CALL(ReadOneBignum(&v2, rfp, STRING_Y_PRIME));
  PrintTime("...done");

  CHECK_CALL(RsaDevice_SetEntropyResponse(device, v1, v2));

  // Send proof to EA 
  ProductEvidence ev;
  CHECK_CALL(ev);
  X509_REQ* req = X509_REQ_new();
  CHECK_CALL(req);
  CHECK_CALL(RsaDevice_GenEaSigningRequest(device, req, v1, v2, v3, &ev));

  PrintTime("Sending cert to EA");
  CHECK_CALL(i2d_X509_REQ_fp(wfp, req));
  //fprintf(wfp, "\n");
  CHECK_CALL(!fflush(wfp));

  CHECK_CALL(WriteOneBignum(STRING_DELTA_X, sizeof(STRING_DELTA_X), wfp, v1));
  CHECK_CALL(WriteOneBignum(STRING_DELTA_Y, sizeof(STRING_DELTA_Y), wfp, v2));
  CHECK_CALL(WriteOneBignum(STRING_MODULUS_RAND, sizeof(STRING_MODULUS_RAND), wfp, v3));
  CHECK_CALL(ProductEvidence_Serialize(ev, wfp));
  CHECK_CALL(!fflush(wfp));
  PrintTime("...done");

  X509_REQ_free(req);

  ProductEvidence_Free(ev);

  X509* cert = NULL;
  PrintTime("Reading cert from EA");
  if(!(cert = d2i_X509_fp(rfp, NULL))) {
    fatal("Could not read X509 response");
  }
  PrintTime("...done");

  fclose(rfp);
  fclose(wfp);

  BN_clear_free(v1);
  BN_clear_free(v2);
  BN_clear_free(v3);
  BN_clear_free(v4);

  // Give EA signature back to device
  CHECK_CALL(RsaDevice_SetEaCertResponse(device, cert));

  X509_free(cert);
  return;
}
Esempio n. 22
0
/* Creates an X509 certificate from a certificate request. */
EXPORT int IssueUserCertificate(unsigned char *certbuf, int *certlen, unsigned char *reqbuf, int reqlen)
{
	X509_REQ *req = NULL;
	EVP_PKEY *cakey = NULL, *rakey = NULL, *usrkey = NULL;
	X509 *cacert = NULL, *racert = NULL, *usrcert = NULL;
	X509_NAME *subject = NULL, *issuer = NULL;
	unsigned char *p = NULL;
	int ret = OPENSSLCA_NO_ERR, len;

	if (certbuf == NULL || certlen == NULL || reqbuf == NULL || reqlen == 0)
		return OPENSSLCA_ERR_ARGS;

	/* Decode request */
	if ((req = X509_REQ_new()) == NULL) {
		ret = OPENSSLCA_ERR_REQ_NEW;
		goto err;
	}
	p = reqbuf;
	if (d2i_X509_REQ(&req, &p, reqlen) == NULL) {
		ret = OPENSSLCA_ERR_REQ_DECODE;
		goto err;
	}

	/* Get public key from request */
	if ((usrkey = X509_REQ_get_pubkey(req)) == NULL) {
		ret = OPENSSLCA_ERR_REQ_GET_PUBKEY;
		goto err;
	}

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

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

	/* Get CA certificate */
	/* TODO: Validate CA certificate */
	ret = read_cert(&cacert, CA_PATH(caIni.caCertFile));
	if (ret != OPENSSLCA_NO_ERR)
		goto err;

	/* Get CA private key */
	ret = read_key(&cakey, CA_PATH(caIni.caKeyFile), caIni.caKeyPasswd);
	if (ret != OPENSSLCA_NO_ERR)
		goto err;

	/* Create user certificate */
	if ((usrcert = X509_new()) == NULL)
		return OPENSSLCA_ERR_CERT_NEW;

	/* Set version and serial number for certificate */
	if (X509_set_version(usrcert, 2) != 1) { /* V3 */
		ret = OPENSSLCA_ERR_CERT_SET_VERSION;
		goto err;
	}
	if (ASN1_INTEGER_set(X509_get_serialNumber(usrcert), get_serial()) != 1) {
		ret = OPENSSLCA_ERR_CERT_SET_SERIAL;
		goto err;
	}

	/* Set duration for certificate */
	if (X509_gmtime_adj(X509_get_notBefore(usrcert), 0) == NULL) {
		ret = OPENSSLCA_ERR_CERT_SET_NOTBEFORE;
		goto err;
	}
	if (X509_gmtime_adj(X509_get_notAfter(usrcert), EXPIRE_SECS(caIni.daysTillExpire)) == NULL) {
		ret = OPENSSLCA_ERR_CERT_SET_NOTAFTER;
		goto err;
	}

	/* Set public key */
	if (X509_set_pubkey(usrcert, usrkey) != 1) {
		ret = OPENSSLCA_ERR_CERT_SET_PUBKEY;
		goto err;
	}

	/* Set subject name */
	subject = X509_REQ_get_subject_name(req);
	if (subject == NULL) {
		ret = OPENSSLCA_ERR_REQ_GET_SUBJECT;
		goto err;
	}
	if (X509_set_subject_name(usrcert, subject) != 1) {
		ret = OPENSSLCA_ERR_CERT_SET_SUBJECT;
		goto err;
	}

	/* Set issuer name */
	issuer = X509_get_issuer_name(cacert);
	if (issuer == NULL) {
		ret = OPENSSLCA_ERR_CERT_GET_ISSUER;
		goto err;
	}
	if (X509_set_issuer_name(usrcert, issuer) != 1) {
		ret = OPENSSLCA_ERR_CERT_SET_ISSUER;
		goto err;
	}

	/* Add extensions */
	ret = add_ext(cacert, usrcert);
	if (ret != OPENSSLCA_NO_ERR)
		goto err;

	/* Sign user certificate with CA's private key */
	if (!X509_sign(usrcert, cakey, EVP_sha1()))
		return OPENSSLCA_ERR_CERT_SIGN;

	if (caIni.verifyAfterSign) {
		if (X509_verify(usrcert, cakey) != 1) {
			ret = OPENSSLCA_ERR_CERT_VERIFY;
			goto err;
		}
	}

#ifdef _DEBUG /* Output certificate in DER and PEM format */
	{
		FILE *fp = fopen(DBG_PATH("usrcert.der"), "wb");
		if (fp != NULL) {
			i2d_X509_fp(fp, usrcert);
			fclose(fp);
		}
		fp = fopen(DBG_PATH("usrcert.pem"), "w");
		if (fp != NULL) {
			X509_print_fp(fp, usrcert);
			PEM_write_X509(fp, usrcert);
			fclose(fp);
		}
	}
#endif

	/* Encode user certificate into DER format */
	len = i2d_X509(usrcert, NULL);
	if (len < 0) {
		ret = OPENSSLCA_ERR_CERT_ENCODE;
		goto err;
	}
	if (len > *certlen) {
		ret = OPENSSLCA_ERR_BUF_TOO_SMALL;
		goto err;
	}
	*certlen = len;
	p = certbuf;
	i2d_X509(usrcert, &p);

	if (caIni.addToIndex)
		add_to_index(usrcert);

	if (caIni.addToNewCerts)
		write_cert(usrcert);

err:
	print_err("IssueUserCertificate()", ret);

	/* Clean up */
	if (cacert)
		X509_free(cacert);
	if (cakey)
		EVP_PKEY_free(cakey);
	if (racert)
		X509_free(racert);
	if (rakey)
		EVP_PKEY_free(rakey);
	if (req)
		X509_REQ_free(req);
	if (usrcert != NULL)
		X509_free(usrcert);
	if (usrkey)
		EVP_PKEY_free(usrkey);

	return ret;
}
Esempio n. 23
0
static int regular_enroll_attempt (EST_CTX *ectx)
{
    int pkcs7_len = 0;
    int rv;
    char file_name[MAX_FILENAME_LEN];
    unsigned char *new_client_cert;
    unsigned char *attr_data = NULL;
    unsigned char *der_ptr = NULL;
    int attr_len, der_len, nid;
    X509_REQ *csr;

    /*
     * We need to get the CSR attributes first, which allows libest
     * to know if the challengePassword needs to be included in the
     * CSR.
     */
    rv = est_client_get_csrattrs(ectx, &attr_data, &attr_len);
    if (rv != EST_ERR_NONE) {
        printf("\nWarning: CSR attributes were not available");
        return (rv);
    }

    /* Generate a CSR */
    csr = X509_REQ_new();

    if (csr == NULL) {
        printf("\nFailed to get X509_REQ");
        return (EST_ERR_NO_CSR);
    }
    rv = populate_x509_csr(csr, priv_key, "EST-client");

    if (rv) {
        printf("\nFailed to populate X509_REQ");
        return (EST_ERR_X509_PUBKEY);
    }


    rv = est_decode_attributes_helper((char*)attr_data, attr_len, &der_ptr, &der_len);
    if (rv != EST_ERR_NONE) {
        printf("\nFailed to decode attributes");
        return (rv);
    }

    while (der_len) {
        rv = est_get_attributes_helper(&der_ptr, &der_len, &nid);

        if (rv == EST_ERR_NONE) {
            /*
             * This switch can be enhanced to include all NID values
             * of interest by the client/server.  In addition the last
             * parameter can be enhanced to provide the character string
             * type information that is included with the NID.
             *
             * Presently only character string types are supported, but at
             * some point OID or groups of strings/OIDs may need to be
             * supported.
             *
             * Note that challenge password should not be included here
             * as it is handled by libest client code.
             */
            switch (nid) {
            case NID_commonName:
                /* add the attribute to the request */
                rv = est_add_attributes_helper(csr, nid, "test\n", 0);
                break;
            case NID_pkcs9_emailAddress:
                /* add the attribute to the request */
                rv = est_add_attributes_helper(csr, nid, "[email protected]\0", 0);
                break;
            case NID_undef:
                printf("\nNID is undefined; skipping it\n");
                break;
            default:
                rv = est_add_attributes_helper(csr, nid, "", 0);
                break;
            }
            if (rv != EST_ERR_NONE) {
                printf("\n Error adding NID=%d", nid);
            }
        }
    }

    X509_REQ_print_fp(stderr, csr);

    rv = est_client_enroll_csr(ectx, csr, &pkcs7_len, priv_key);

    if (verbose) {
        printf("\nenrollment rv = %d (%s) with pkcs7 length = %d\n",
               rv, EST_ERR_NUM_TO_STR(rv), pkcs7_len);
    }
    if (rv == EST_ERR_NONE) {
        /*
         * client library has obtained the new client certificate.
         * now retrieve it from the library
         */
        new_client_cert = malloc(pkcs7_len);
        if (new_client_cert == NULL) {
            if (verbose) {
                printf("\nmalloc of destination buffer for enrollment cert failed\n");
            }
            return (EST_ERR_MALLOC);
        }

        rv = est_client_copy_enrolled_cert(ectx, new_client_cert);
        if (verbose) {
            printf("\nenrollment copy rv = %d\n", rv);
        }
        if (rv == EST_ERR_NONE) {
            /*
             * Enrollment copy worked, dump the pkcs7 cert to stdout
             */
            if (verbose) {
                dumpbin(new_client_cert, pkcs7_len);
            }
        }

        snprintf(file_name, MAX_FILENAME_LEN, "%s/newcert", out_dir);
        save_cert(file_name, new_client_cert, pkcs7_len);
        free(new_client_cert);
    }

    return (rv);
}
CertificateRequestSPKAC* CertificateRequestFactory::fromSPKAC(std::string &path)
	throw (EncodeException, RandomException, NetscapeSPKIException)
{
	STACK_OF(CONF_VALUE) *sk=NULL;
	LHASH_OF(CONF_VALUE) *parms=NULL;
	X509_REQ *req=NULL;
	CONF_VALUE *cv=NULL;
	NETSCAPE_SPKI *spki = NULL;
	X509_REQ_INFO *ri;
	char *type,*buf;
	EVP_PKEY *pktmp=NULL;
	X509_NAME *n=NULL;
	unsigned long chtype = MBSTRING_ASC;
	int i;
	long errline;
	int nid;
	CertificateRequestSPKAC* ret=NULL;

	/*
	 * Load input file into a hash table.  (This is just an easy
	 * way to read and parse the file, then put it into a convenient
	 * STACK format).
	 */
	parms=CONF_load(NULL,path.c_str(),&errline);
	if (parms == NULL)
	{
		throw EncodeException(EncodeException::BUFFER_READING, "CertificateRequestFactory::fromSPKAC");
	}

	sk=CONF_get_section(parms, "default");
	if (sk_CONF_VALUE_num(sk) == 0)
	{
		if (parms != NULL) CONF_free(parms);
		throw EncodeException(EncodeException::BUFFER_READING, "CertificateRequestFactory::fromSPKAC");
	}

	/*
	 * Now create a dummy X509 request structure.  We don't actually
	 * have an X509 request, but we have many of the components
	 * (a public key, various DN components).  The idea is that we
	 * put these components into the right X509 request structure
	 * and we can use the same code as if you had a real X509 request.
	 */
	req=X509_REQ_new();
	if (req == NULL)
	{
		if (parms != NULL) CONF_free(parms);
		throw RandomException(RandomException::INTERNAL_ERROR, "CertificateRequestFactory::fromSPKAC");
	}

	/*
	 * Build up the subject name set.
	 */
	ri=req->req_info;
	n = ri->subject;

	for (i = 0; ; i++)
	{
		if (sk_CONF_VALUE_num(sk) <= i) break;

		cv=sk_CONF_VALUE_value(sk,i);
		type=cv->name;
		/* Skip past any leading X. X: X, etc to allow for
		 * multiple instances
		 */
		for (buf = cv->name; *buf ; buf++)
			if ((*buf == ':') || (*buf == ',') || (*buf == '.'))
			{
				buf++;
				if (*buf) type = buf;
				break;
			}

		buf=cv->value;
		if ((nid=OBJ_txt2nid(type)) == NID_undef)
		{
			if (strcmp(type, "SPKAC") == 0)
			{
				spki = NETSCAPE_SPKI_b64_decode(cv->value, -1);
				if (spki == NULL)
				{
					if (parms != NULL) CONF_free(parms);
					throw EncodeException(EncodeException::BASE64_DECODE, "CertificateRequestFactory::fromSPKAC");
				}
			}
			continue;
		}

		if (!X509_NAME_add_entry_by_NID(n, nid, chtype, (unsigned char *)buf, -1, -1, 0))
		{
			if (parms != NULL) CONF_free(parms);
			if (spki != NULL) NETSCAPE_SPKI_free(spki);
			throw RandomException(RandomException::INTERNAL_ERROR, "CertificateRequestFactory::fromSPKAC");
		}
	}
	if (spki == NULL)
	{
		if (parms != NULL) CONF_free(parms);
		throw NetscapeSPKIException(NetscapeSPKIException::SET_NO_VALUE, "CertificateRequestFactory::fromSPKAC");
	}

	/*
	 * Now extract the key from the SPKI structure.
	 */
	if ((pktmp=NETSCAPE_SPKI_get_pubkey(spki)) == NULL)
	{
		if (parms != NULL) CONF_free(parms);
		if (spki != NULL) NETSCAPE_SPKI_free(spki);
		throw NetscapeSPKIException(NetscapeSPKIException::SET_NO_VALUE, "CertificateRequestFactory::fromSPKAC");
	}
	X509_REQ_set_pubkey(req,pktmp);
	EVP_PKEY_free(pktmp);

	ret = new CertificateRequestSPKAC(req, spki);

	return ret;
}
Esempio n. 25
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;
}
Esempio n. 26
0
HX509Req_t *HttpsCertReqNew( void )
{
  return (X509_REQ_new());
} /* HttpsCertReqNew() */
Esempio n. 27
0
LWS_VISIBLE LWS_EXTERN int
lws_tls_acme_sni_csr_create(struct lws_context *context, const char *elements[],
			    uint8_t *csr, size_t csr_len, char **privkey_pem,
			    size_t *privkey_len)
{
	uint8_t *csr_in = csr;
	RSA *rsakey;
	X509_REQ *req;
	X509_NAME *subj;
	EVP_PKEY *pkey;
	char *p, *end;
	BIO *bio;
	long bio_len;
	int n, ret = -1;

	if (lws_tls_openssl_rsa_new_key(&rsakey, 4096))
		return -1;

	pkey = EVP_PKEY_new();
	if (!pkey)
		goto bail0;
	if (!EVP_PKEY_set1_RSA(pkey, rsakey))
		goto bail1;

	req = X509_REQ_new();
	if (!req)
	        goto bail1;

	X509_REQ_set_pubkey(req, pkey);

	subj = X509_NAME_new();
	if (!subj)
		goto bail2;

	for (n = 0; n < LWS_TLS_REQ_ELEMENT_COUNT; n++)
		if (lws_tls_openssl_add_nid(subj, nid_list[n], elements[n])) {
			lwsl_notice("%s: failed to add element %d\n", __func__,
				    n);
			goto bail3;
		}

	if (X509_REQ_set_subject_name(req, subj) != 1)
		goto bail3;

	if (!X509_REQ_sign(req, pkey, EVP_sha256()))
		goto bail3;

	/*
	 * issue the CSR as PEM to a BIO, and translate to b64urlenc without
	 * headers, trailers, or whitespace
	 */

	bio = BIO_new(BIO_s_mem());
	if (!bio)
		goto bail3;

	if (PEM_write_bio_X509_REQ(bio, req) != 1) {
		BIO_free(bio);
		goto bail3;
	}

	bio_len = BIO_get_mem_data(bio, &p);
	end = p + bio_len;

	/* strip the header line */
	while (p < end && *p != '\n')
		p++;

	while (p < end && csr_len) {
		if (*p == '\n') {
			p++;
			continue;
		}

		if (*p == '-')
			break;

		if (*p == '+')
			*csr++ = '-';
		else
			if (*p == '/')
				*csr++ = '_';
			else
				*csr++ = *p;
		p++;
		csr_len--;
	}
	BIO_free(bio);
	if (!csr_len) {
		lwsl_notice("%s: need %ld for CSR\n", __func__, bio_len);
		goto bail3;
	}

	/*
	 * Also return the private key as a PEM in memory
	 * (platform may not have a filesystem)
	 */
	bio = BIO_new(BIO_s_mem());
	if (!bio)
		goto bail3;

	if (PEM_write_bio_PrivateKey(bio, pkey, NULL, NULL, 0, 0, NULL) != 1) {
		BIO_free(bio);
		goto bail3;
	}
	bio_len = BIO_get_mem_data(bio, &p);
	*privkey_pem = malloc(bio_len); /* malloc so user code can own / free */
	*privkey_len = (size_t)bio_len;
	if (!*privkey_pem) {
		lwsl_notice("%s: need %ld for private key\n", __func__,
			    bio_len);
		BIO_free(bio);
		goto bail3;
	}
	memcpy(*privkey_pem, p, (int)(long long)bio_len);
	BIO_free(bio);

	ret = lws_ptr_diff(csr, csr_in);

bail3:
	X509_NAME_free(subj);
bail2:
	X509_REQ_free(req);
bail1:
	EVP_PKEY_free(pkey);
bail0:
	RSA_free(rsakey);

	return ret;
}
Esempio n. 28
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
}
Esempio n. 29
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;
}
Esempio n. 30
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;
}