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
/* Adds X509v3 extensions to a certificate. */
int add_ext(X509 *cacert, X509 *usrcert)
{
	X509_EXTENSION *ext = NULL;
	X509V3_CTX ctx;
	int i = 0;

	if (cacert == NULL || usrcert == NULL)
		return OPENSSLCA_ERR_ARGS;

	/* Set extension context */
	X509V3_set_ctx_nodb(&ctx);
	X509V3_set_ctx(&ctx, cacert, usrcert, NULL, NULL, 0);

	/* Add all specified extensions */
	while (ext_entries[i].nid) {
		if ((ext = X509V3_EXT_conf_nid(NULL, &ctx, ext_entries[i].nid, ext_entries[i].value)) == NULL)
			return OPENSSLCA_ERR_EXT_MAKE;

		if (!X509_add_ext(usrcert, ext, -1))
			return OPENSSLCA_ERR_EXT_ADD;

		X509_EXTENSION_free(ext);
		i++;
	}

	return OPENSSLCA_NO_ERR;
}
Beispiel #4
0
sqbind::SQINT COsslCert::SetExtension( const sqbind::stdString &sField, const sqbind::stdString &sValue )
{ _STT();

	if ( !m_pX509 )
		return 0;

	if ( !sField.length() )
		return 0;

	// Find this extension by short name
	const ASN1_OBJECT* pObj = COSSLCERT_SnToObj( oexStrToMb( sqbind::std2oex( sField ) ).Ptr() );
	if ( !pObj )
		return 0;

	// Create extension
	X509_EXTENSION *ex = X509V3_EXT_conf_nid( oexNULL, oexNULL, pObj->nid, (char*)oexStrToMb( sqbind::std2oex( sValue ) ).Ptr() );
	if ( !ex )
		return 0;

	// Add to cert
	X509_add_ext( m_pX509, ex, -1 );

	X509_EXTENSION_free( ex );

	return 1;
}
/**
 * Returns true on success, false on failure
 *
 * Example:
 * @code
 * <#example#>
 * @endcode
 */
static bool
_addCertificateExtension(X509 *cert, int nid, char *value)
{
    X509_EXTENSION *extension = X509V3_EXT_conf_nid(NULL, NULL, nid, value);
    if (extension == NULL) {
        return false;
    }
    X509_add_ext(cert, extension, -1);
    X509_EXTENSION_free(extension);
    return true;
}
Beispiel #6
0
int PKI_X509_CERT_add_extension(PKI_X509_CERT *x, PKI_X509_EXTENSION *ext) {

	PKI_X509_CERT_VALUE *val = NULL;

	if( !x || !x->value || !ext || !ext->value ) return (PKI_ERR);

	val = x->value;

	if (!X509_add_ext(val, ext->value, -1)) return (PKI_ERR);

	return (PKI_OK);
}
Beispiel #7
0
int add_ext(X509 *cert, int nid, char *value)
{
	X509_EXTENSION *ex;
	X509V3_CTX ctx;
	X509V3_set_ctx_nodb(&ctx);
	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;
}
int SDMMD__add_ext(X509 *cert, int flag, char *name)
{
	int result = 0;
	X509V3_CTX ctx;
	X509V3_set_ctx(&ctx, cert, cert, 0, 0, 0);
	X509_EXTENSION *ex = X509V3_EXT_conf_nid(0, &ctx, flag, name);
	if (ex) {
		result = X509_add_ext(cert, ex, -1);
		X509_EXTENSION_free(ex);
	}
	return result;
}
Beispiel #9
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 ;
}
/*============================================================================
 * OpcUa_P_OpenSSL_X509_AddCustomExtension
 *===========================================================================*/
OpcUa_StatusCode OpcUa_P_OpenSSL_X509_AddCustomExtension(
    X509**                   a_ppCertificate,
    OpcUa_Crypto_Extension*  a_pExtension,
    X509V3_CTX*              a_pX509V3Context)
{
    X509_EXTENSION*     pExtension   = OpcUa_Null;
    char*               pName        = OpcUa_Null;
    char*               pValue       = OpcUa_Null;

OpcUa_InitializeStatus(OpcUa_Module_P_OpenSSL, "X509_AddCustomExtension");

    OpcUa_ReturnErrorIfArgumentNull(a_pX509V3Context);
    OpcUa_ReturnErrorIfArgumentNull(a_pExtension->key);
    OpcUa_ReturnErrorIfArgumentNull(a_pExtension->value);

    pName = (char*)a_pExtension->key;
    pValue = (char*)a_pExtension->value;

    /* create the extension. */
    pExtension = X509V3_EXT_conf(
        OpcUa_Null,
        a_pX509V3Context,
        pName,
        pValue);

    if(pExtension == OpcUa_Null)
    {
        OpcUa_GotoErrorWithStatus(OpcUa_Bad);
    }

    /* add it to the certificate. */
    if(!X509_add_ext(*a_ppCertificate, pExtension, -1))
    {
        OpcUa_GotoErrorWithStatus(OpcUa_Bad);
    }

    /* free the extension. */
    X509_EXTENSION_free(pExtension);

OpcUa_ReturnStatusCode;
OpcUa_BeginErrorHandling;

    if(pExtension != OpcUa_Null)
    {
        X509_EXTENSION_free(pExtension);
    }

OpcUa_FinishErrorHandling;
}
Beispiel #11
0
/*
 * Add a X509v3 extension to a certificate and handle errors.
 * Returns -1 on errors, 0 on success.
 */
int
ssl_x509_v3ext_add(X509V3_CTX *ctx, X509 *crt, char *k, char *v)
{
	X509_EXTENSION *ext;

	if (!(ext = X509V3_EXT_conf(NULL, ctx, k, v))) {
		return -1;
	}
	if (X509_add_ext(crt, ext, -1) != 1) {
		X509_EXTENSION_free(ext);
		return -1;
	}
	X509_EXTENSION_free(ext);
	return 0;
}
Beispiel #12
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;
}
Beispiel #13
0
static X509 *pki_certificate(X509_NAME *issuer, EVP_PKEY *keyring, X509_REQ *cert_req,
				uint8_t is_cert_authority, uint32_t serial, uint32_t expiration_delay)
{
	jlog(L_DEBUG, "pki_certificate");

	X509 *certificate;
	X509_NAME *subject;

	X509V3_CTX ctx;
	X509_EXTENSION *ext;

	// create a new certificate
	certificate = X509_new();

	// set certificate unique serial number
	ASN1_INTEGER_set(X509_get_serialNumber(certificate), serial);

	// set certificate 'Subject:'
	subject = X509_REQ_get_subject_name(cert_req);
	X509_set_subject_name(certificate, subject);

	// set certificate 'Issuer:'
	X509_set_issuer_name(certificate, issuer);

	// set X509v3 extension "basicConstraints" CA:TRUE/FALSE
	X509V3_set_ctx(&ctx, NULL, certificate, cert_req, NULL, 0);

	if (is_cert_authority == true)
		ext = X509V3_EXT_conf(NULL, &ctx, "basicConstraints", "CA:TRUE");
	else
		ext = X509V3_EXT_conf(NULL, &ctx, "basicConstraints", "CA:FALSE");

	X509_add_ext(certificate, ext, -1);
	X509_EXTENSION_free(ext);

	// set certificate version 3
	X509_set_version(certificate, 0x2);

	// set certificate public key
	X509_set_pubkey(certificate, keyring);

	// set the 'notBefore' to yersterday
	X509_gmtime_adj(X509_get_notBefore(certificate), -(24*60*60));
	// set certificate expiration delay
	X509_gmtime_adj(X509_get_notAfter(certificate), expiration_delay);

	return certificate;
}
Beispiel #14
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 #15
0
/*
 * Copy a X509v3 extension from one certificate to another.
 * If the extension is not present in the original certificate,
 * the extension will not be added to the destination certificate.
 * Returns 1 if ext was copied, 0 if not present in origcrt, -1 on error.
 */
int
ssl_x509_v3ext_copy_by_nid(X509 *crt, X509 *origcrt, int nid)
{
	X509_EXTENSION *ext;
	int pos;

	pos = X509_get_ext_by_NID(origcrt, nid, -1);
	if (pos == -1)
		return 0;
	ext = X509_get_ext(origcrt, pos);
	if (!ext)
		return -1;
	if (X509_add_ext(crt, ext, -1) != 1)
		return -1;
	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 #17
0
int X509V3_EXT_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
	     X509 *cert)
{
	X509_EXTENSION *ext;
	STACK_OF(CONF_VALUE) *nval;
	CONF_VALUE *val;	
	int i;
	if(!(nval = CONF_get_section(conf, section))) return 0;
	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
		val = sk_CONF_VALUE_value(nval, i);
		if(!(ext = X509V3_EXT_conf(conf, ctx, val->name, val->value)))
								return 0;
		if(cert) X509_add_ext(cert, ext, -1);
		X509_EXTENSION_free(ext);
	}
	return 1;
}
Beispiel #18
0
int PKI_X509_CERT_add_extension_stack(PKI_X509_CERT *x, 
          			      const PKI_X509_EXTENSION_STACK *ext) {

  int i = 0;
  PKI_X509_EXTENSION *ossl_ext = NULL;

  if( !x || !x->value || !ext ) return (PKI_ERR);

  for( i = 0; i < PKI_STACK_X509_EXTENSION_elements(ext); i++ ) {
    
    ossl_ext = PKI_STACK_X509_EXTENSION_get_num( ext, i);
    if( !ossl_ext ) continue;

    if(!X509_add_ext ((X509 *) x->value, ossl_ext->value, -1 )) {
      PKI_log_err ( "Adding Extensions::%s", 
        ERR_error_string( ERR_get_error(), NULL ) );
      return ( PKI_ERR );
    };
  }

  return (PKI_OK);
}
Beispiel #19
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 #20
0
/*
 * Create a fake X509v3 certificate, signed by the provided CA,
 * based on the original certificate retrieved from the real server.
 * The returned certificate is created using X509_new() and thus must
 * be freed by the caller using X509_free().
 * The optional argument extraname is added to subjectAltNames if provided.
 */
X509 *
ssl_x509_forge(X509 *cacrt, EVP_PKEY *cakey, X509 *origcrt,
               const char *extraname, EVP_PKEY *key)
{
	X509_NAME *subject, *issuer;
	GENERAL_NAMES *names;
	GENERAL_NAME *gn;
	X509 *crt;

	subject = X509_get_subject_name(origcrt);
	issuer = X509_get_subject_name(cacrt);
	if (!subject || !issuer)
		return NULL;

	crt = X509_new();
	if (!crt)
		return NULL;

	if (!X509_set_version(crt, 0x02) ||
	    !X509_set_subject_name(crt, subject) ||
	    !X509_set_issuer_name(crt, issuer) ||
	    ssl_x509_serial_copyrand(crt, origcrt) == -1 ||
	    !X509_gmtime_adj(X509_get_notBefore(crt), (long)-60*60*24) ||
	    !X509_gmtime_adj(X509_get_notAfter(crt), (long)60*60*24*364) ||
	    !X509_set_pubkey(crt, key))
		goto errout;

	/* add standard v3 extensions; cf. RFC 2459 */
	X509V3_CTX ctx;
	X509V3_set_ctx(&ctx, cacrt, crt, NULL, NULL, 0);
	if (ssl_x509_v3ext_add(&ctx, crt, "basicConstraints",
	                                  "CA:FALSE") == -1 ||
	    ssl_x509_v3ext_add(&ctx, crt, "keyUsage",
	                                  "digitalSignature,"
	                                  "keyEncipherment") == -1 ||
	    ssl_x509_v3ext_add(&ctx, crt, "extendedKeyUsage",
	                                  "serverAuth") == -1 ||
	    ssl_x509_v3ext_add(&ctx, crt, "subjectKeyIdentifier",
	                                  "hash") == -1 ||
	    ssl_x509_v3ext_add(&ctx, crt, "authorityKeyIdentifier",
	                                  "keyid,issuer:always") == -1)
		goto errout;

	if (!extraname) {
		/* no extraname provided: copy original subjectAltName ext */
		if (ssl_x509_v3ext_copy_by_nid(crt, origcrt,
		                               NID_subject_alt_name) == -1)
			goto errout;
	} else {
		names = X509_get_ext_d2i(origcrt, NID_subject_alt_name, 0, 0);
		if (!names) {
			/* no subjectAltName present: add new one */
			char *cfval;
			if (asprintf(&cfval, "DNS:%s", extraname) < 0)
				goto errout;
			if (ssl_x509_v3ext_add(&ctx, crt, "subjectAltName",
			                       cfval) == -1) {
				free(cfval);
				goto errout;
			}
			free(cfval);
		} else {
			/* add extraname to original subjectAltName
			 * and add it to the new certificate */
			gn = GENERAL_NAME_new();
			if (!gn)
				goto errout2;
			gn->type = GEN_DNS;
			gn->d.dNSName = M_ASN1_IA5STRING_new();
			if (!gn->d.dNSName)
				goto errout3;
			ASN1_STRING_set(gn->d.dNSName,
			                (unsigned char *)extraname,
			                strlen(extraname));
			sk_GENERAL_NAME_push(names, gn);
			X509_EXTENSION *ext = X509V3_EXT_i2d(
			                      NID_subject_alt_name, 0, names);
			if (!X509_add_ext(crt, ext, -1)) {
				if (ext) {
					X509_EXTENSION_free(ext);
				}
				goto errout3;
			}
			X509_EXTENSION_free(ext);
			sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
		}
	}
#ifdef DEBUG_CERTIFICATE
	ssl_x509_v3ext_add(&ctx, crt, "nsComment", "Generated by " PNAME);
#endif /* DEBUG_CERTIFICATE */

	const EVP_MD *md;
	switch (EVP_PKEY_type(cakey->type)) {
#ifndef OPENSSL_NO_RSA
		case EVP_PKEY_RSA:
			md = EVP_sha1();
			break;
#endif /* !OPENSSL_NO_RSA */
#ifndef OPENSSL_NO_DSA
		case EVP_PKEY_DSA:
			md = EVP_dss1();
			break;
#endif /* !OPENSSL_NO_DSA */
#ifndef OPENSSL_NO_ECDSA
		case EVP_PKEY_EC:
			md = EVP_ecdsa();
			break;
#endif /* !OPENSSL_NO_ECDSA */
		default:
			goto errout;
	}
	if (!X509_sign(crt, cakey, md))
		goto errout;

	return crt;

errout3:
	GENERAL_NAME_free(gn);
errout2:
	sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
errout:
	X509_free(crt);
	return NULL;
}
Beispiel #21
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);
}
Beispiel #22
0
int
gen_cert (X509 ** cert, EVP_PKEY ** key)
{
  RSA *rsa;
  X509_NAME *subj;
  X509_EXTENSION *ext;
  X509V3_CTX ctx;
  const char *commonName = "localhost";
  char dNSName[128];
  int rc;

  *cert = NULL;
  *key = NULL;

  /* Generate a private key. */
  *key = EVP_PKEY_new ();
  if (*key == NULL) {
#ifdef DEBUG
    fprintf (stderr, "Error generating key.\n");
#endif
    exit (1);
  }

  do {
    rsa = RSA_generate_key (DEFAULT_KEY_BITS, RSA_F4, NULL, NULL);
    if (rsa == NULL) {
#ifdef DEBUG
      fprintf (stderr, "Error generating RSA key.\n");
#endif
      exit (1);
    }
    rc = RSA_check_key (rsa);
  }
  while (rc == 0);
  if (rc == -1) {
#ifdef DEBUG
    fprintf (stderr, "Error generating RSA key.\n");
#endif
    exit (1);
  }
  if (EVP_PKEY_assign_RSA (*key, rsa) == 0) {
    RSA_free (rsa);
#ifdef DEBUG
    fprintf (stderr, "Error with EVP and PKEY.\n");
#endif
    exit (1);
  }

  /* Generate a certificate. */
  *cert = X509_new ();
  if (*cert == NULL) {
#ifdef DEBUG
    fprintf (stderr, "Couldn't generate 509 cert.\n");
#endif
    exit (1);
  }
  if (X509_set_version (*cert, 2) == 0) {	/* Version 3. */
#ifdef DEBUG
    fprintf (stderr, "Couldn't set x509 version.\n");
#endif
    exit (1);
  }

  /* Set the commonName. */
  subj = X509_get_subject_name (*cert);
  if (X509_NAME_add_entry_by_txt (subj, "commonName", MBSTRING_ASC,
				  (unsigned char *) commonName, -1, -1,
				  0) == 0) {
#ifdef DEBUG
    fprintf (stderr, "Couldn't set common name.\n");
#endif
    exit (1);
  }

  /* Set the dNSName. */
  rc = snprintf (dNSName, sizeof (dNSName), "DNS:%s", commonName);
  if (rc < 0 || rc >= sizeof (dNSName)) {
#ifdef DEBUG
    fprintf (stderr, "Unable to set dns name.\n");
#endif
    exit (1);
  }
  X509V3_set_ctx (&ctx, *cert, *cert, NULL, NULL, 0);
  ext = X509V3_EXT_conf (NULL, &ctx, "subjectAltName", dNSName);
  if (ext == NULL) {
#ifdef DEBUG
    fprintf (stderr, "Unable to get subjectaltname.\n");
#endif
    exit (1);
  }
  if (X509_add_ext (*cert, ext, -1) == 0) {
#ifdef DEBUG
    fprintf (stderr, "x509_add_ext error.\n");
#endif
    exit (1);
  }

  /* Set a comment. */
  ext = X509V3_EXT_conf (NULL, &ctx, "nsComment", CERTIFICATE_COMMENT);
  if (ext == NULL) {
#ifdef DEBUG
    fprintf (stderr, "x509v3_ext_conf error.\n");
#endif
    exit (1);
  }
  if (X509_add_ext (*cert, ext, -1) == 0) {
#ifdef DEBUG
    fprintf (stderr, "x509_add_ext error.\n");
#endif
    exit (1);
  }

  X509_set_issuer_name (*cert, X509_get_subject_name (*cert));
  X509_gmtime_adj (X509_get_notBefore (*cert), 0);
  X509_gmtime_adj (X509_get_notAfter (*cert), DEFAULT_CERT_DURATION);
  X509_set_pubkey (*cert, *key);

  /* Sign it. */
  if (X509_sign (*cert, *key, EVP_sha1 ()) == 0) {
#ifdef DEBUG
    fprintf (stderr, "x509_sign error.\n");
#endif
    exit (1);
  }

  return 1;
}
Beispiel #23
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 #24
0
static int autoca_gencert( Operation *op, genargs *args )
{
	X509_NAME *subj_name, *issuer_name;
	X509 *subj_cert;
	struct berval derdn;
	unsigned char *pp;
	EVP_PKEY *evpk = NULL;
	int rc;

	if ((subj_cert = X509_new()) == NULL)
		return -1;

	autoca_dnbv2der( op, args->subjectDN, &derdn );
	pp = (unsigned char *)derdn.bv_val;
	subj_name = d2i_X509_NAME( NULL, (const unsigned char **)&pp, derdn.bv_len );
	op->o_tmpfree( derdn.bv_val, op->o_tmpmemctx );
	if ( subj_name == NULL )
	{
fail1:
		X509_free( subj_cert );
		return -1;
	}

	rc = autoca_genpkey( args->keybits, &evpk );
	if ( rc <= 0 )
	{
fail2:
		if ( subj_name ) X509_NAME_free( subj_name );
		goto fail1;
	}
	/* encode DER in PKCS#8 */
	{
		PKCS8_PRIV_KEY_INFO *p8inf;
		if (( p8inf = EVP_PKEY2PKCS8( evpk )) == NULL )
			goto fail2;
		args->derpkey.bv_len = i2d_PKCS8_PRIV_KEY_INFO( p8inf, NULL );
		args->derpkey.bv_val = op->o_tmpalloc( args->derpkey.bv_len, op->o_tmpmemctx );
		pp = (unsigned char *)args->derpkey.bv_val;
		i2d_PKCS8_PRIV_KEY_INFO( p8inf, &pp );
		PKCS8_PRIV_KEY_INFO_free( p8inf );
	}
	args->newpkey = evpk;

	/* set random serial */
	{
		BIGNUM *bn = BN_new();
		if ( bn == NULL )
		{
fail3:
			EVP_PKEY_free( evpk );
			goto fail2;
		}
		if (!BN_pseudo_rand(bn, SERIAL_BITS, 0, 0))
		{
			BN_free( bn );
			goto fail3;
		}
		if (!BN_to_ASN1_INTEGER(bn, X509_get_serialNumber(subj_cert)))
		{
			BN_free( bn );
			goto fail3;
		}
		BN_free(bn);
	}
	if (args->issuer_cert) {
		issuer_name = X509_get_subject_name(args->issuer_cert);
	} else {
		issuer_name = subj_name;
		args->issuer_cert = subj_cert;
		args->issuer_pkey = evpk;
	}
	if (!X509_set_version(subj_cert, 2) ||	/* set version to V3 */
		!X509_set_issuer_name(subj_cert, issuer_name) ||
		!X509_set_subject_name(subj_cert, subj_name) ||
		!X509_gmtime_adj(X509_get_notBefore(subj_cert), 0) ||
		!X509_time_adj_ex(X509_get_notAfter(subj_cert), args->days, 0, NULL) ||
		!X509_set_pubkey(subj_cert, evpk))
	{
		goto fail3;
	}
	X509_NAME_free(subj_name);
	subj_name = NULL;

	/* set cert extensions */
	{
		X509V3_CTX ctx;
		X509_EXTENSION *ext;
		int i;

		X509V3_set_ctx(&ctx, args->issuer_cert, subj_cert, NULL, NULL, 0);
		for (i=0; args->cert_exts[i].name; i++) {
			ext = X509V3_EXT_nconf(NULL, &ctx, args->cert_exts[i].name, args->cert_exts[i].value);
			if ( ext == NULL )
				goto fail3;
			rc = X509_add_ext(subj_cert, ext, -1);
			X509_EXTENSION_free(ext);
			if ( !rc )
				goto fail3;
		}
		if (args->more_exts) {
			for (i=0; args->more_exts[i].name; i++) {
				ext = X509V3_EXT_nconf(NULL, &ctx, args->more_exts[i].name, args->more_exts[i].value);
				if ( ext == NULL )
					goto fail3;
				rc = X509_add_ext(subj_cert, ext, -1);
				X509_EXTENSION_free(ext);
				if ( !rc )
					goto fail3;
			}
		}
	}
	rc = autoca_signcert( subj_cert, args->issuer_pkey );
	if ( rc < 0 )
		goto fail3;
	args->dercert.bv_len = i2d_X509( subj_cert, NULL );
	args->dercert.bv_val = op->o_tmpalloc( args->dercert.bv_len, op->o_tmpmemctx );
	pp = (unsigned char *)args->dercert.bv_val;
	i2d_X509( subj_cert, &pp );
	args->newcert = subj_cert;
	return 0;
}
Beispiel #25
0
static TokenError saveKeys(const CertReq *reqs, const char *hostname,
                           const char *password, FILE *file) {
    TokenError error = TokenError_Unknown;
    PKCS12 *p12 = NULL;
    
    // Add PKCS7 safes with the keys
    STACK_OF(PKCS7) *authsafes = NULL;
    uint32_t localKeyId = 0;
    size_t error_count = 0;
    while (reqs) {
        STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
        X509 *cert = NULL;
        ASN1_OBJECT *objOwningHost = NULL;
        uint32_t keyid = htonl(localKeyId++);
        bool success = false;
        
        // Add private key
        PKCS12_SAFEBAG *bag = PKCS12_add_key(&bags, reqs->privkey,
            opensslKeyUsages[reqs->pkcs10->keyUsage], ENC_ITER, ENC_NID, (char*)password);
        if (!bag) goto loop_end;
        
        // Add name and localKeyId to the key bag
        // TODO extract name from subject DN
        char *name = "names are not implemented yet";
        if (!X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName, MBSTRING_UTF8,
                                     (unsigned char*)name, strlen(name)) ||
            !PKCS12_add_localkeyid(bag, (unsigned char*)&keyid, sizeof(keyid)))
            goto loop_end;
        
        // Add a certificate so we can find the key by the subject name
        cert = X509_REQ_to_X509(reqs->x509, 3650, reqs->privkey);
        if (!cert ||
            !X509_keyid_set1(cert, (unsigned char*)&keyid, sizeof(keyid)))
            goto loop_end;
        
        if (!X509_add_ext(cert, makeKeyUsageExt(reqs->pkcs10->keyUsage), -1))
            goto loop_end;
        
        if (!PKCS12_add_cert(&bags, cert))
            goto loop_end;
        
        // Add hostname (FriBID extension) so we can do same-origin checks
        // TODO maybe we should use document.domain instead of document.location.hostname?
        objOwningHost = OBJ_txt2obj(OID_OWNING_HOST, 1);
        if (!objOwningHost) goto loop_end;
        
        bag = sk_PKCS12_SAFEBAG_value(bags, sk_PKCS12_SAFEBAG_num(bags)-1);
        if (!X509at_add1_attr_by_OBJ(&bag->attrib, objOwningHost, MBSTRING_UTF8,
                                     (unsigned char*)hostname, strlen(hostname)))
            goto loop_end;
        
        
        // Add a new authsafe
        if (!PKCS12_add_safe(&authsafes, bags, -1, 0, NULL))
            goto loop_end;
        
        
        // Success!
        success = true;
        
      loop_end:
        if (!success) {
            error_count--;
            certutil_updateErrorString();
        }
        ASN1_OBJECT_free(objOwningHost);
        X509_free(cert);
        sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
        reqs = reqs->next;
    }
    
    if (error_count != 0)
        goto end;
    
    // Create the PKCS12 wrapper
    p12 = PKCS12_add_safes(authsafes, 0);
    if (!p12) {
        certutil_updateErrorString();
        goto end;
    }
    PKCS12_set_mac(p12, (char*)password, -1, NULL, 0, MAC_ITER, NULL);
    
    // Save file
    if (i2d_PKCS12_fp(file, p12)) {
        error = TokenError_Success;
    }
    
  end:
    sk_PKCS7_pop_free(authsafes, PKCS7_free);
    PKCS12_free(p12);
    return error;
}
Beispiel #26
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;
}