Exemplo n.º 1
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;
}
Exemplo n.º 2
0
/*
 * Constructor for X509Extension, never called by Python code directly
 *
 * Arguments: type_name - ???
 *            critical  - ???
 *            value     - ???
 *            subject   - An x509v3 certificate which is the subject for this extension.
 *            issuer    - An x509v3 certificate which is the issuer for this extension.
 * Returns:   The newly created X509Extension object
 */
crypto_X509ExtensionObj *
crypto_X509Extension_New(char *type_name, int critical, char *value,
                         crypto_X509Obj *subject, crypto_X509Obj  *issuer) {
    X509V3_CTX ctx;
    crypto_X509ExtensionObj *self;
    char* value_with_critical = NULL;


    /*
     * A context is necessary for any extension which uses the r2i conversion
     * method.  That is, X509V3_EXT_nconf may segfault if passed a NULL ctx.
     * Start off by initializing most of the fields to NULL.
     */
    X509V3_set_ctx(&ctx, NULL, NULL, NULL, NULL, 0);

    /*
     * We have no configuration database - but perhaps we should (some
     * extensions may require it).
     */
    X509V3_set_ctx_nodb(&ctx);

    /*
     * Initialize the subject and issuer, if appropriate.  ctx is a local, and
     * as far as I can tell none of the X509V3_* APIs invoked here steal any
     * references, so no need to incref subject or issuer.
     */
    if (subject) {
            ctx.subject_cert = subject->x509;
    }

    if (issuer) {
            ctx.issuer_cert = issuer->x509;
    }

    self = PyObject_New(crypto_X509ExtensionObj, &crypto_X509Extension_Type);

    if (self == NULL) {
	    goto error;
    }

    self->dealloc = 0;

    /* There are other OpenSSL APIs which would let us pass in critical
     * separately, but they're harder to use, and since value is already a pile
     * of crappy junk smuggling a ton of utterly important structured data,
     * what's the point of trying to avoid nasty stuff with strings? (However,
     * X509V3_EXT_i2d in particular seems like it would be a better API to
     * invoke.  I do not know where to get the ext_struc it desires for its
     * last parameter, though.) */
    value_with_critical = malloc(strlen("critical,") + strlen(value) + 1);
    if (!value_with_critical) {
	    goto critical_malloc_error;
    }

    if (critical) {
	    strcpy(value_with_critical, "critical,");
	    strcpy(value_with_critical + strlen("critical,"), value);
    } else {
	    strcpy(value_with_critical, value);
    }

    self->x509_extension = X509V3_EXT_nconf(
	    NULL, &ctx, type_name, value_with_critical);

    free(value_with_critical);

    if (!self->x509_extension) {
	    goto nconf_error;
    }

    self->dealloc = 1;
    return self;

  nconf_error:
    exception_from_error_queue(crypto_Error);

  critical_malloc_error:
    Py_XDECREF(self);

  error:
    return NULL;

}