Example #1
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;
}
Example #2
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;
}
Example #3
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;
}
Example #4
0
int X509V3_EXT_CRL_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
	     X509_CRL *crl)
{
	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(crl) X509_CRL_add_ext(crl, ext, -1);
		X509_EXTENSION_free(ext);
	}
	return 1;
}
Example #5
0
int X509V3_EXT_REQ_add_conf(LHASH *conf, X509V3_CTX *ctx, char *section,
	     X509_REQ *req)
{
	X509_EXTENSION *ext;
	STACK_OF(X509_EXTENSION) *extlist = NULL;
	STACK_OF(CONF_VALUE) *nval;
	CONF_VALUE *val;	
	int i;
	if(!(nval = CONF_get_section(conf, section))) return 0;
	for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
		val = sk_CONF_VALUE_value(nval, i);
		if(!(ext = X509V3_EXT_conf(conf, ctx, val->name, val->value)))
								return 0;
		if(!extlist) extlist = sk_X509_EXTENSION_new_null();
		sk_X509_EXTENSION_push(extlist, ext);
	}
	if(req) i = X509_REQ_add_extensions(req, extlist);
	else i = 1;
	sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free);
	return i;
}
Example #6
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;
}
Example #7
0
PKI_X509_EXTENSION *PKI_X509_EXTENSION_value_new_profile ( 
		PKI_X509_PROFILE *profile, PKI_CONFIG *oids, 
			PKI_CONFIG_ELEMENT *extNode, PKI_TOKEN *tk ) {

	/* TODO: Implement the extended version of the extensions, this
	   should allow better extensions management. That is, the value
	   will be encoded as:

		extName=@section

		[ section ]
		extName=value
		otherVal=val
		otherVal=val
		...

	   The corresponding XML should be:

		<pki:extension name=".." critical=".." >
		   <pki:value name="" type=".." tag=".."> .. </pki:value>
		   <pki:value name="" type=".." tag=".."> .. </pki:value>
		</pki:extension>

	  */

	PKI_CONFIG_ELEMENT *valNode = NULL;
	PKI_X509_EXTENSION *ret = NULL;
	PKI_X509_EXTENSION_VALUE *ext = NULL;

	xmlChar *type_s = NULL;
	xmlChar *tag_s = NULL;
	xmlChar *oid_s = NULL;
	xmlChar *value_s = NULL;
	xmlChar *name_s = NULL;
	xmlChar *crit_s = NULL;

	PKI_OID *oid = NULL;


	X509V3_CTX v3_ctx;
	CONF *conf = NULL;

	char *envValString = NULL;
	char *valString = NULL;
	int crit = 0;

	if( !profile || !extNode ) {
		PKI_log_debug("ERROR, no profile or extNode provided in "
				"PKI_X509_EXTENSION_value_new_profile()");
		return (NULL);
	}

	if((crit_s = xmlGetProp( extNode, BAD_CAST "critical" )) != NULL ) {
		if( strncmp_nocase( (char *) crit_s, "n", 1 ) == 0) {
			crit = 0;
		} else {
			crit = 1;
		}
	}

	if((name_s = xmlGetProp( extNode, BAD_CAST "name" )) == NULL ) {
		PKI_log_debug("ERROR, no name property in node %s", 
							extNode->name);
		if( crit_s ) xmlFree ( crit_s );
		return (NULL);
	}

	if ((oid = PKI_OID_get((char *) name_s)) == NULL)
	{
		if ((oid = PKI_CONFIG_OID_search(oids, (char *)name_s)) == NULL)
		{
			PKI_ERROR(PKI_ERR_OBJECT_CREATE, NULL);
			return NULL;
		}
	}
	else
	{
		PKI_OID_free ( oid );
	}

	/*
	int nid = NID_undef;
	if((nid = OBJ_sn2nid( (char *) name_s )) == NID_undef ) {
		PKI_OID *oid = NULL;

		oid = PKI_CONFIG_OID_search ( oids, (char *) name_s );
		if( !oid ) {
			PKI_log_debug( "ERROR, can not create object (%s)!",
				name_s );
			return( NULL );
		}
	}
	*/

	if ((valString = (char *) PKI_Malloc(BUFF_MAX_SIZE)) == NULL)
	{
		PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
		if( name_s ) xmlFree ( name_s );
		if( crit_s ) xmlFree (crit_s);
		return( NULL );
	}

	memset( valString, 0, BUFF_MAX_SIZE );

	if( crit == 1 ) snprintf( valString, BUFF_MAX_SIZE -1, "%s", "critical" );

	for (valNode = extNode->children; valNode; valNode = valNode->next)
	{
		if ((valNode->type == XML_ELEMENT_NODE) &&
				((strncmp_nocase((char *)(valNode->name),"value",5)) == 0))
		{
			char tmp[BUFF_MAX_SIZE];

			type_s = xmlGetProp( valNode, BAD_CAST "type" );
			tag_s = xmlGetProp( valNode, BAD_CAST "tag" );
			oid_s = xmlGetProp( valNode, BAD_CAST "oid" );

			value_s = xmlNodeListGetString( profile, 
						valNode->xmlChildrenNode, 0);

			if( oid_s ) {
				/* Let's be sure the OID is created */
				if((oid = PKI_CONFIG_OID_search(oids, 
						(char *) value_s)) == NULL ) {
					PKI_log_debug ("WARNING, no oid "
						"created for %s!", oid_s );
				} else {
					PKI_OID_free ( oid );
				}
			}

			memset((unsigned char * )tmp, 0, BUFF_MAX_SIZE );

			if( tag_s ) {
				snprintf( tmp, BUFF_MAX_SIZE - 1, "%s;", 
					_ext_txt( tag_s ) );
			}

			if( type_s == NULL ) {
				if( !oid_s ) {
					strncat( tmp, (char *) value_s, 
							BUFF_MAX_SIZE - strlen( tmp ));
				} else {
					if( value_s && (strlen((char *) value_s) > 0) ) {
						strncat( tmp, (char *) oid_s, 
						 	BUFF_MAX_SIZE - strlen( tmp ) );
						strncat( tmp, ":", 
							BUFF_MAX_SIZE - strlen ( tmp ));
						strncat( tmp, (char *) value_s,
							BUFF_MAX_SIZE - strlen (tmp ));
					} else {
						strncat( tmp, "OID:", 
							BUFF_MAX_SIZE - strlen(tmp));
						strncat( tmp, (char *) oid_s, 
							BUFF_MAX_SIZE - strlen( tmp ));
					}
				}
			} else {
				strncat( tmp, (char *) _ext_txt(type_s), 
						BUFF_MAX_SIZE - strlen( tmp ));
				if( value_s && (strlen((char*)value_s) > 0) ) {
					if(strcmp_nocase( (char*) type_s, "ia5org")) {
					    strncat( tmp, ":", 
						BUFF_MAX_SIZE - strlen( tmp ));
					} else {
					    strncat( tmp, ",", 
						BUFF_MAX_SIZE - strlen( tmp ));
					}
					strncat( tmp, (char *) value_s, 
						BUFF_MAX_SIZE - strlen( tmp ));
				}
			}
				
			if( strlen( valString ) > 0 ) {
				strncat( valString, ",", BUFF_MAX_SIZE - 1);
			}

			strncat( valString, (char *) tmp, BUFF_MAX_SIZE - 1 );

			if( type_s ) xmlFree ( type_s );
			if( oid_s ) xmlFree ( oid_s );
			if( tag_s ) xmlFree ( tag_s );
			if( value_s ) xmlFree ( value_s );
        	}
	}
	//PKI_log_debug("INFO, Encoding %s=%s", name_s, valString);

	v3_ctx.db = NULL;
	v3_ctx.db_meth = NULL;
	v3_ctx.crl = NULL;
	v3_ctx.flags = 0;

	if ( tk ) {
		v3_ctx.issuer_cert  =  (X509 *)
			PKI_X509_get_value ( tk->cacert );
		v3_ctx.subject_cert =  (X509 *)
			PKI_X509_get_value ( tk->cert );
		v3_ctx.subject_req  =  (X509_REQ *)
			PKI_X509_get_value ( tk->req );
	} else {
		v3_ctx.issuer_cert = NULL;
		v3_ctx.subject_cert = NULL;
		v3_ctx.subject_req = NULL;
	}

	/* Sets the ctx.db and ctx.method */
	conf = NCONF_new( NULL );
	X509V3_set_nconf(&v3_ctx, conf);

	if((envValString = get_env_string( valString )) != NULL ) {
		PKI_log_debug("EXT STRING => %s=%s", name_s, envValString);
		ext = X509V3_EXT_conf(NULL, &v3_ctx, (char *) name_s, 
						(char *) envValString);
		PKI_Free ( envValString );
	} else {
		ext = X509V3_EXT_conf(NULL, &v3_ctx, (char *) name_s, 
						(char *) valString);
	}

	if( !ext ) {
		PKI_log_debug("EXT::ERR::%s",
			ERR_error_string(ERR_get_error(), NULL ));
		return NULL;
	}

	if(( ret = PKI_X509_EXTENSION_new()) == NULL ) {
		PKI_ERROR(PKI_ERR_MEMORY_ALLOC, NULL);
		X509_EXTENSION_free ( ext );
		return NULL;
	}

	ret->value = ext;
	ret->oid = ext->object;

	if( name_s ) xmlFree ( name_s );
	if( crit_s ) xmlFree (crit_s );

	if( valString ) PKI_Free ( valString );
	if( conf ) NCONF_free ( conf );

	return ( ret );
}