int signRequest(char* pemRequest, int days, char* pemCAKey, char* pemCaCert,  int certType, char *url, char* result)  {

  BIO* bioReq = BIO_new_mem_buf(pemRequest, -1);
  BIO* bioCAKey = BIO_new_mem_buf(pemCAKey, -1);

  BIO* bioCert = BIO_new_mem_buf(pemCaCert, -1);
  X509* caCert = PEM_read_bio_X509(bioCert, NULL, NULL, NULL);

  int err = 0;

  X509_REQ *req=NULL;
  if (!(req=PEM_read_bio_X509_REQ(bioReq, NULL, NULL, NULL))) {
    BIO_free(bioReq);
    BIO_free(bioCert);
    BIO_free(bioCAKey);
    return ERR_peek_error();
  }

  EVP_PKEY* caKey = PEM_read_bio_PrivateKey(bioCAKey, NULL, NULL, NULL);
  if (!caKey) {
    BIO_free(bioReq);
    BIO_free(bioCert);
    BIO_free(bioCAKey);
    return ERR_peek_error();
  }

  X509* cert = X509_new();
  EVP_PKEY* reqPub;
  if(!(err =  X509_set_version(cert, 2)))
  {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return ERR_peek_error();
  }

  //redo all the certificate details, because OpenSSL wants us to work hard
  X509_set_issuer_name(cert, X509_get_subject_name(caCert));

  ASN1_UTCTIME *s=ASN1_UTCTIME_new();

  // Jira-issue: WP-37
  // This is temp solution for putting pzp validity 5 minutes before current time
  // If there is a small clock difference between machines, it results in cert_not_yet_valid
  // It does set GMT time but is relevant to machine time.
  // A better solution would be to have ntp server contacted to get a proper time.
  if(certType == 2) {
    X509_gmtime_adj(s, long(0-300));
  }
  else {
    X509_gmtime_adj(s, long(0));
  }
  // End of WP-37
  X509_set_notBefore(cert, s);

  X509_gmtime_adj(s, (long)60*60*24*days);
  X509_set_notAfter(cert, s);

  ASN1_UTCTIME_free(s);

  X509_set_subject_name(cert, X509_REQ_get_subject_name(req));
  reqPub = X509_REQ_get_pubkey(req);
  X509_set_pubkey(cert,reqPub);
  EVP_PKEY_free(reqPub);

  //create a serial number at random
  ASN1_INTEGER* serial = getRandomSN();
  X509_set_serialNumber(cert, serial);

  X509_EXTENSION *ex;
  X509V3_CTX ctx;
  X509V3_set_ctx_nodb(&ctx);
  X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);

  char *str = (char*)malloc(strlen("caIssuers;") + strlen(url) + 1);
  if (str == NULL) {
    return -10;
  }
  strcpy(str, "caIssuers;");
  strcat(str, url);

  if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_info_access, (char*)str))) {
    free(str);
    return ERR_peek_error();
  } else {
    X509_add_ext(cert, ex, -1);
  }
  free(str);
  if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_alt_name, (char*)url))) {
    return ERR_peek_error();
  } else {
    X509_add_ext(cert, ex, -1);
  }
  if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_issuer_alt_name, (char*)"issuer:copy"))) {
    return ERR_peek_error();
  } else {
    X509_add_ext(cert, ex, -1);
  }

  if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_key_identifier, (char*)"hash"))) {
    return ERR_peek_error();
  } else {
    X509_add_ext(cert, ex, -1);
  }

  if( certType == 1) {
    if(!(ex = X509V3_EXT_conf_nid(NULL,  &ctx, NID_basic_constraints, (char*)"critical, CA:FALSE"))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }

    if(!(ex = X509V3_EXT_conf_nid(NULL,  &ctx, NID_ext_key_usage, (char*)"critical, clientAuth, serverAuth"))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }
  } else if( certType == 2) {
    if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_basic_constraints, (char*)"critical, CA:FALSE"))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }

    if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_ext_key_usage, (char*)"critical, clientAuth, serverAuth"))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }
  }

  if (!(err = X509_sign(cert,caKey,EVP_sha1())))
  {
    BIO_free(bioReq);
    BIO_free(bioCert);
    BIO_free(bioCAKey);
    return err;
  }

  BIO *mem = BIO_new(BIO_s_mem());
  PEM_write_bio_X509(mem,cert);

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

  BIO_free(mem);
  BIO_free(bioReq);
  BIO_free(bioCert);
  BIO_free(bioCAKey);

  return 0;
}
int selfSignRequest(char* pemRequest, int days, char* pemCAKey, int certType, char *url, char* result)  {
  BIO* bioReq = BIO_new_mem_buf(pemRequest, -1);
  BIO* bioCAKey = BIO_new_mem_buf(pemCAKey, -1);

  int err = 0;

  X509_REQ *req=NULL;
  if (!(req=PEM_read_bio_X509_REQ(bioReq, NULL, NULL, NULL))) {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return -5;
  }

  EVP_PKEY* caKey = PEM_read_bio_PrivateKey(bioCAKey, NULL, NULL, NULL);
  if (!caKey) {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return -6;
  }

  X509* cert = X509_new();
  EVP_PKEY* reqPub;

  //redo all the certificate details, because OpenSSL wants us to work hard
  if(!(err =  X509_set_version(cert, 2)))
  {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return err;
  }

  if(!(err = X509_set_issuer_name(cert, X509_REQ_get_subject_name(req))))
  {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return err;
  }

  ASN1_UTCTIME *s=ASN1_UTCTIME_new();
  // Jira-issue: WP-37
  // This is temp solution for putting pzp validity 5 minutes before current time
  // If there is a small clock difference between machines, it results in cert_not_yet_valid
  // It does set GMT time but is relevant to machine time.
  // A better solution would be to have ntp server contacted to get proper time.
  if(certType == 2) {
    X509_gmtime_adj(s, long(0-300));
  }
  else {
    X509_gmtime_adj(s, long(0));
  }
  // End of WP-37
  X509_set_notBefore(cert, s);

  X509_gmtime_adj(s, (long)60*60*24*days);
  X509_set_notAfter(cert, s);

  ASN1_UTCTIME_free(s);

  if(!(err = X509_set_subject_name(cert, X509_REQ_get_subject_name(req)))) {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return err;
  }

  if (!(reqPub = X509_REQ_get_pubkey(req))) {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return -7;
  }
  err = X509_set_pubkey(cert,reqPub);
  EVP_PKEY_free(reqPub);
  if (!err) {
    return err; // an error occurred, this is terrible style.
  }

  //create a serial number at random
  ASN1_INTEGER* serial = getRandomSN();
  X509_set_serialNumber(cert, serial);

  // V3 extensions
  X509_EXTENSION *ex;
  X509V3_CTX ctx;
  X509V3_set_ctx_nodb(&ctx);
  X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);

  if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_alt_name, (char*)url))) {
    return ERR_peek_error();
  } else {
    X509_add_ext(cert, ex, -1);
  }

  if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_key_identifier, (char*)"hash"))) {
    return ERR_peek_error();
  } else {
    X509_add_ext(cert, ex, -1);
  }

  if( certType == 0) {
    if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_basic_constraints, (char*)"critical, CA:TRUE"))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }

    if(!(ex = X509V3_EXT_conf_nid(NULL,  &ctx, NID_key_usage, (char*)"critical, keyCertSign, digitalSignature, cRLSign"))) { /* critical, keyCertSign,cRLSign, nonRepudiation,*/
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }

    if(!(ex = X509V3_EXT_conf_nid(NULL,  &ctx, NID_ext_key_usage, (char*)"critical, serverAuth"))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }

    if(!(ex = X509V3_EXT_conf_nid(NULL,  &ctx, NID_inhibit_any_policy, (char*)"0"))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }

    if(!(ex = X509V3_EXT_conf_nid(NULL, &ctx, NID_crl_distribution_points, (char*)url))) {
      return ERR_peek_error();
    } else {
      X509_add_ext(cert, ex, -1);
    }
  }

  if (!(err = X509_sign(cert,caKey,EVP_sha1()))) {
    BIO_free(bioReq);
    BIO_free(bioCAKey);
    return err;
  }

  BIO *mem = BIO_new(BIO_s_mem());
  PEM_write_bio_X509(mem,cert);

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

  BIO_free(mem);
  BIO_free(bioReq);
  BIO_free(bioCAKey);
  return 0;

}
Beispiel #3
0
static int add_ext(X509 * crt, int nid, char *value) {
	X509_EXTENSION *ex;
	X509V3_CTX ctx;
	X509V3_set_ctx_nodb(&ctx);
	X509V3_set_ctx(&ctx, crt, crt, NULL, NULL, 0);
	ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
	if (!ex)
		return 0;

	X509_add_ext(crt, ex, -1);
	X509_EXTENSION_free(ex);
	return 1;
}
Beispiel #4
0
/**
 * Adds a key usage extension to the list of extensions in a request.
 */
static X509_EXTENSION *makeKeyUsageExt(KeyUsage keyUsage) {
    char *ku_str;
    switch (keyUsage) {
        case KeyUsage_Signing:
            ku_str = "nonRepudiation";
            break;
        case KeyUsage_Authentication:
            ku_str = "digitalSignature";
            break;
        default:
            ku_str = NULL;
    }
    return X509V3_EXT_conf_nid(NULL, NULL, NID_key_usage, ku_str);
}
Beispiel #5
0
/*
 * Set one extension in a given certificate
 */
static int set_extension(X509 * issuer, X509 * cert, int nid, char * value)
{
    X509_EXTENSION * ext ;
    X509V3_CTX ctx ;

    X509V3_set_ctx(&ctx, issuer, cert, NULL, NULL, 0);
    ext = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
    if (!ext)
        return -1;

    X509_add_ext(cert, ext, -1);
    X509_EXTENSION_free(ext);
    return 0 ;
}
Beispiel #6
0
// Add extension using V3 code: we can set the config file as NULL because we wont reference any other sections.
int __fastcall util_add_ext(X509 *cert, int nid, char *value)
{
	X509_EXTENSION *ex;
	X509V3_CTX ctx;
	// This sets the 'context' of the extensions. No configuration database
	X509V3_set_ctx_nodb(&ctx);
	// Issuer and subject certs: both the target since it is self signed, no request and no CRL
	X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);
	ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
	if (!ex) return 0;

	X509_add_ext(cert,ex,-1);
	X509_EXTENSION_free(ex);
	return 1;
}
/**
 * Returns true on success, false on failure
 *
 * Example:
 * @code
 * <#example#>
 * @endcode
 */
static bool
_addCertificateExtensionWithContext(X509 *cert, int nid, char *value)
{
    X509_EXTENSION *extension;
    X509V3_CTX context;

    X509V3_set_ctx_nodb(&context);
    X509V3_set_ctx(&context, cert, cert, NULL, NULL, 0);
    extension = X509V3_EXT_conf_nid(NULL, &context, nid, value);
    if (extension == NULL) {
        return false;
    }
    X509_add_ext(cert, extension, -1);
    X509_EXTENSION_free(extension);
    return true;
}
Beispiel #8
0
void add_ext(X509 *cert, int nid, const char *value)
{
    X509_EXTENSION *ex = NULL;
    X509V3_CTX ctx;
    /* This sets the 'context' of the extensions. */
    /* No configuration database */
    X509V3_set_ctx_nodb(&ctx);
    /* Issuer and subject certs: both the target since it is self signed,
     * no request and no CRL
     */
    X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);
    MORDOR_VERIFY(X509V3_EXT_conf_nid(NULL, &ctx, nid, (char*) value));

    X509_add_ext(cert,ex,-1);
    X509_EXTENSION_free(ex);
}
Beispiel #9
0
// verify if prefix is part of the resources listed in cert
// CA and untrusted are needed, because the resources in cert could be inherited
// prefix_as_ext is the text-representation of an ip-address block like you would specify in an extension file
// when creating a certificate, e.g. IPv6:2001:0638::/32
int verify_prefix_with_cert(
    int CA_der_count,
    int CA_der_length,
    const char* CAs_der, 
    int untrusted_der_count,
    int untrusted_der_length,
    const char* untrusted_der,
    int cert_der_length,
    const char* cert_der,
    char* prefix_as_ext
) 
{
    X509_EXTENSION *prefix_ext;
    IPAddrBlocks *prefix_blocks = NULL;
    STACK_OF(X509) *chain = NULL;

    int allow_inheritance = 0; // router prefix cannot inherit
    int ret = 0;
    if ((prefix_ext = X509V3_EXT_conf_nid(NULL, NULL, NID_sbgp_ipAddrBlock, prefix_as_ext)) == NULL){
        ret = -1;
        goto end;
    }
    prefix_blocks = (IPAddrBlocks *) X509V3_EXT_d2i(prefix_ext);
    X509_EXTENSION_free(prefix_ext);

    chain = get_verified_chain(
        CA_der_count,
        CA_der_length,
        CAs_der,
        untrusted_der_count,
        untrusted_der_length,
        untrusted_der,
        cert_der_length,
        cert_der
    );

    if (chain == NULL) {
        ret = 0;
    } else {
        ret = v3_addr_validate_resource_set(chain, prefix_blocks, allow_inheritance);
    }
end:
    if (prefix_blocks != NULL) sk_IPAddressFamily_pop_free(prefix_blocks, IPAddressFamily_free);
    if (chain != NULL) sk_X509_pop_free(chain, X509_free);

    return ret;
}
Beispiel #10
0
int add_ext( X509 *issuer, X509 *subj, int nid, const char* value ) {
    X509V3_CTX ctx;

    X509V3_set_ctx( &ctx, issuer, subj, NULL, NULL, 0 );
    X509_EXTENSION *ex = X509V3_EXT_conf_nid( NULL, &ctx, nid, (char *) value );

    if( !ex ) {
        return 0;
    }

    // removing old extensions of the same type
    int loc = -1;
    while( ( loc = X509_get_ext_by_NID(subj, nid, loc) ) != -1 ){
        printf("Removing old extension number %d\n", loc);
        X509_EXTENSION *old = X509_delete_ext(subj, loc);
        X509_EXTENSION_free(old);
    }

    // adding the new extension
    X509_add_ext( subj, ex, -1 );
    X509_EXTENSION_free( ex );

    return 1;
}
Beispiel #11
0
	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);
	}

/* Add extension using V3 code: we can set the config file as NULL
 * because we wont reference any other sections.
 */

int add_ext(STACK_OF(X509_REQUEST) *sk, int nid, char *value)
	{
	X509_EXTENSION *ex;
	ex = X509V3_EXT_conf_nid(NULL, NULL, nid, value);
	if (!ex)
		return 0;
	sk_X509_EXTENSION_push(sk, ex);

	return 1;
	}
	
Beispiel #12
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() */
Beispiel #13
0
// Creates a X509 certificate, if rootcert is NULL this creates a root (self-signed) certificate.
// Is the name parameter is NULL, the hex value of the hash of the public key will be the subject name.
int __fastcall util_mkCert(struct util_cert *rootcert, struct util_cert* cert, int bits, int days, char* name, enum CERTIFICATE_TYPES certtype, struct util_cert* initialcert)
{
	X509 *x = NULL;
	X509_EXTENSION *ex = NULL;
	EVP_PKEY *pk = NULL;
	RSA *rsa = NULL;
	X509_NAME *cname=NULL;
	X509 **x509p = NULL;
	EVP_PKEY **pkeyp = NULL;
	char hash[UTIL_HASHSIZE];
	char serial[8];
	char nameStr[(UTIL_HASHSIZE * 2) + 2];
	BIGNUM *oBigNbr;

	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

	if (initialcert != NULL)
	{
		pk = X509_get_pubkey(initialcert->x509);
		rsa = EVP_PKEY_get1_RSA(initialcert->pkey);
		if ((x=X509_new()) == NULL) goto err;
	}
	else
	{
		if ((pkeyp == NULL) || (*pkeyp == NULL)) { if ((pk = EVP_PKEY_new()) == NULL) return 0; } else pk = *pkeyp;
		if ((x509p == NULL) || (*x509p == NULL)) { if ((x=X509_new()) == NULL) goto err; } else x = *x509p;
		oBigNbr = BN_new();
		rsa = RSA_new();
		BN_set_word(oBigNbr, RSA_F4);
		if (RSA_generate_key_ex(rsa, bits, oBigNbr, NULL) == -1)
		{
			RSA_free(rsa);
			BN_free(oBigNbr);
			abort();
			goto err;
		}
		BN_free(oBigNbr);
	}

	if (!EVP_PKEY_assign_RSA(pk, rsa))
	{
		RSA_free(rsa);
		abort();
		goto err;
	}
	rsa = NULL;

	util_randomtext(8, serial);
	X509_set_version(x, 2);
	ASN1_STRING_set(X509_get_serialNumber(x), serial, 8);
	X509_gmtime_adj(X509_get_notBefore(x),(long)60*60*24*-2);
	X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);
	X509_set_pubkey(x, pk);

	// Set the subject name
	cname = X509_get_subject_name(x);

	if (name == NULL)
	{
		// Computer the hash of the public key
		util_sha256((char*)x->cert_info->key->public_key->data, x->cert_info->key->public_key->length, hash);
		util_tohex(hash, UTIL_HASHSIZE, nameStr);
		X509_NAME_add_entry_by_txt(cname,"CN", MBSTRING_ASC, (unsigned char*)nameStr, -1, -1, 0);
	}
	else
	{
		// 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(cname,"CN", MBSTRING_ASC, (unsigned char*)name, -1, -1, 0);
	}

	if (rootcert == NULL)
	{
		// Its self signed so set the issuer name to be the same as the subject.
		X509_set_issuer_name(x,cname);

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

		util_add_ext(x, NID_subject_key_identifier, "hash");
		//util_add_ext(x, NID_netscape_cert_type, "sslCA");
		//util_add_ext(x, NID_netscape_comment, "example comment extension");

		if (!X509_sign(x, pk, EVP_sha256())) goto err;
	}
	else
	{
		// This is a sub-certificate
		cname=X509_get_subject_name(rootcert->x509);
		X509_set_issuer_name(x, cname);

		// Add usual cert stuff
		ex = X509V3_EXT_conf_nid(NULL, NULL, NID_key_usage, "digitalSignature, keyEncipherment, keyAgreement");
		X509_add_ext(x, ex, -1);
		X509_EXTENSION_free(ex);

		// Add usages: TLS server, TLS client, Intel(R) AMT Console
		//ex = X509V3_EXT_conf_nid(NULL, NULL, NID_ext_key_usage, "TLS Web Server Authentication, TLS Web Client Authentication, 2.16.840.1.113741.1.2.1, 2.16.840.1.113741.1.2.2");
		if (certtype == CERTIFICATE_TLS_SERVER)
		{
			// TLS server
			ex = X509V3_EXT_conf_nid(NULL, NULL, NID_ext_key_usage, "TLS Web Server Authentication");
			X509_add_ext(x, ex, -1);
			X509_EXTENSION_free(ex);
		}
		else if (certtype == CERTIFICATE_TLS_CLIENT)
		{
			// TLS client
			ex = X509V3_EXT_conf_nid(NULL, NULL, NID_ext_key_usage, "TLS Web Client Authentication");
			X509_add_ext(x, ex, -1);
			X509_EXTENSION_free(ex);
		}

		if (!X509_sign(x, rootcert->pkey, EVP_sha256())) goto err;
	}

	cert->x509 = x;
	cert->pkey = pk;

	return(1);
err:
	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);
}
Beispiel #15
0
void X509V3_add_ext(X509V3_CTX *ctx, X509 *cert, int nid, char *value) {
    X509_EXTENSION *ex = X509V3_EXT_conf_nid(NULL, ctx, nid, value);
    X509_add_ext(cert, ex, -1);
    X509_EXTENSION_free(ex);
}
Beispiel #16
0
int main()
{
    EVP_PKEY *pKey;
    RSA *rsa;
    X509 *x509;
    X509_NAME *name;
    X509_EXTENSION *ex;
    FILE *fp;
    int KEY_SIZE = 2048;
    int days = 365;

    pKey = EVP_PKEY_new(); // Create a private key

    rsa = RSA_generate_key(
        KEY_SIZE, // Key length (bits)
        RSA_F4,   // Exponent
        NULL,     // Callback
        NULL      // Callback argument
        );

    EVP_PKEY_assign_RSA(pKey, rsa);

    x509 = X509_new();

    X509_set_version(x509, 3);
    ASN1_INTEGER_set(X509_get_serialNumber(x509), 1);
    X509_gmtime_adj(X509_get_notBefore(x509), 0);
    X509_gmtime_adj(X509_get_notAfter(x509), (long)60 * 60 * 24 * days);
    X509_set_pubkey(x509, pKey);

    name = X509_get_subject_name(x509);

    X509_NAME_add_entry_by_txt(name, "C",
        MBSTRING_ASC, "Wnmp", -1, -1, 0);
    X509_NAME_add_entry_by_txt(name, "CN",
        MBSTRING_ASC, "Wnmp", -1, -1, 0);

    X509_set_issuer_name(x509, name);

    ex = X509V3_EXT_conf_nid(NULL, NULL, NID_netscape_cert_type, "server");
    X509_add_ext(x509, ex, -1);
    X509_EXTENSION_free(ex);

    ex = X509V3_EXT_conf_nid(NULL, NULL, NID_netscape_comment,
        "Wnmp by Kurt Cancemi");
    X509_add_ext(x509, ex, -1);
    X509_EXTENSION_free(ex);

    ex = X509V3_EXT_conf_nid(NULL, NULL, NID_netscape_ssl_server_name,
        "localhost");

    X509_add_ext(x509, ex, -1);
    X509_EXTENSION_free(ex);

    X509_sign(x509, pKey, EVP_sha1());

    if (!(fp = fopen(KEY_PUB, "w"))) {
        printf("Error writing to public key file");
        return -1;
    }
    if (PEM_write_X509(fp, x509) != 1)
        printf("Error while writing public key");
    fclose(fp);

    if (!(fp = fopen(KEY_PRV, "w"))) {
        printf("Error writing to private key file");
        return -1;
    }
    if (PEM_write_PrivateKey(fp, pKey, NULL, NULL, 0, NULL, NULL) != 1)
        printf("Error while writing private key");
    fclose(fp);

    X509_free(x509);
    EVP_PKEY_free(pKey);

    return 0;
}