RSA *d2i_RSAPublicKey(RSA **a, unsigned char **pp, long length)
	{
	int i=ASN1_R_PARSING;
	ASN1_INTEGER *bs=NULL;
	M_ASN1_D2I_vars(a,RSA *,RSA_new);

	M_ASN1_D2I_Init();
	M_ASN1_D2I_start_sequence();
	M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER);
	if ((ret->n=BN_bin2bn(bs->data,bs->length,ret->n)) == NULL) goto err_bn;
	M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER);
	if ((ret->e=BN_bin2bn(bs->data,bs->length,ret->e)) == NULL) goto err_bn;

	M_ASN1_INTEGER_free(bs);
	bs=NULL;

	M_ASN1_D2I_Finish_2(a);

err_bn:
	i=ERR_R_BN_LIB;
err:
	ASN1err(ASN1_F_D2I_RSAPUBLICKEY,i);
	if ((ret != NULL) && ((a == NULL) || (*a != ret))) RSA_free(ret);
	if (bs != NULL) M_ASN1_INTEGER_free(bs);
	return(NULL);
	}
void PBKDF2PARAM_free (PBKDF2PARAM *a)
{
	if(a==NULL) return;
	ASN1_TYPE_free(a->salt);
	M_ASN1_INTEGER_free(a->iter);
	M_ASN1_INTEGER_free(a->keylength);
	X509_ALGOR_free(a->prf);
	OPENSSL_free (a);
}
Beispiel #3
0
ASN1_INTEGER *
d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length)
{
	ASN1_INTEGER *ret = NULL;
	const unsigned char *p;
	unsigned char *s;
	long len;
	int inf, tag, xclass;
	int i;

	if ((a == NULL) || ((*a) == NULL)) {
		if ((ret = M_ASN1_INTEGER_new()) == NULL)
			return (NULL);
		ret->type = V_ASN1_INTEGER;
	} else
		ret = (*a);

	p = *pp;
	inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
	if (inf & 0x80) {
		i = ASN1_R_BAD_OBJECT_HEADER;
		goto err;
	}

	if (tag != V_ASN1_INTEGER) {
		i = ASN1_R_EXPECTING_AN_INTEGER;
		goto err;
	}

	/* We must malloc stuff, even for 0 bytes otherwise it
	 * signifies a missing NULL parameter. */
	s = malloc((int)len + 1);
	if (s == NULL) {
		i = ERR_R_MALLOC_FAILURE;
		goto err;
	}
	ret->type = V_ASN1_INTEGER;
	if (len) {
		if ((*p == 0) && (len != 1)) {
			p++;
			len--;
		}
		memcpy(s, p, len);
		p += len;
	}

	free(ret->data);
	ret->data = s;
	ret->length = (int)len;
	if (a != NULL)
		(*a) = ret;
	*pp = p;
	return (ret);

err:
	ASN1err(ASN1_F_D2I_ASN1_UINTEGER, i);
	if (a == NULL || *a != ret)
		M_ASN1_INTEGER_free(ret);
	return (NULL);
}
Beispiel #4
0
void PKCS7_ENCRYPT_free(PKCS7_ENCRYPT *a)
{
    if (a == NULL) return;
    M_ASN1_INTEGER_free(a->version);
    PKCS7_ENC_CONTENT_free(a->enc_data);
    OPENSSL_free(a);
}
Beispiel #5
0
static void NETSCAPE_PKEY_free(NETSCAPE_PKEY *a)
	{
	if (a == NULL) return;
	M_ASN1_INTEGER_free(a->version);
	X509_ALGOR_free(a->algor);
	M_ASN1_OCTET_STRING_free(a->private_key);
	OPENSSL_free(a);
	}
Beispiel #6
0
void PKCS12_MAC_DATA_free (PKCS12_MAC_DATA *a)
{
	if (a == NULL) return;
	X509_SIG_free (a->dinfo);
	M_ASN1_OCTET_STRING_free(a->salt);
	M_ASN1_INTEGER_free(a->iter);
	OPENSSL_free (a);
}
Beispiel #7
0
RSA *d2i_RSAPrivateKey(RSA **a, unsigned char **pp, long length)
	{
	int i=ASN1_R_PARSING;
	ASN1_INTEGER *bs=NULL;
	M_ASN1_D2I_vars(a,RSA *,RSA_new);

	M_ASN1_D2I_Init();
	M_ASN1_D2I_start_sequence();
	M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER);
	if (bs->length == 0)
		ret->version=0;
	else	ret->version=bs->data[0];
	M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER);
	if ((ret->n=BN_bin2bn(bs->data,bs->length,ret->n)) == NULL) goto err_bn;
	M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER);
	if ((ret->e=BN_bin2bn(bs->data,bs->length,ret->e)) == NULL) goto err_bn;
	M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER);
	if ((ret->d=BN_bin2bn(bs->data,bs->length,ret->d)) == NULL) goto err_bn;
	M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER);
	if ((ret->p=BN_bin2bn(bs->data,bs->length,ret->p)) == NULL) goto err_bn;
	M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER);
	if ((ret->q=BN_bin2bn(bs->data,bs->length,ret->q)) == NULL) goto err_bn;
	M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER);
	if ((ret->dmp1=BN_bin2bn(bs->data,bs->length,ret->dmp1)) == NULL)
		goto err_bn;
	M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER);
	if ((ret->dmq1=BN_bin2bn(bs->data,bs->length,ret->dmq1)) == NULL)
		goto err_bn;
	M_ASN1_D2I_get(bs,d2i_ASN1_INTEGER);
	if ((ret->iqmp=BN_bin2bn(bs->data,bs->length,ret->iqmp)) == NULL)
		goto err_bn;

	M_ASN1_INTEGER_free(bs);

	M_ASN1_D2I_Finish_2(a);
err_bn:
	i=ERR_R_BN_LIB;
err:
	ASN1err(ASN1_F_D2I_RSAPRIVATEKEY,i);
	if ((ret != NULL) && ((a == NULL) || (*a != ret))) RSA_free(ret);
	if (bs != NULL) M_ASN1_INTEGER_free(bs);

	return(NULL);
	}
/* int max_len:  for returned value    */
int
ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num, unsigned char *data,
    int max_len)
{
	int ret = -1, n;
	ASN1_INTEGER *ai = NULL;
	ASN1_OCTET_STRING *os = NULL;
	const unsigned char *p;
	long length;
	ASN1_const_CTX c;

	if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL)) {
		goto err;
	}
	p = M_ASN1_STRING_data(a->value.sequence);
	length = M_ASN1_STRING_length(a->value.sequence);

	c.pp = &p;
	c.p = p;
	c.max = p + length;
	c.error = ASN1_R_DATA_IS_WRONG;

	M_ASN1_D2I_start_sequence();
	c.q = c.p;
	if ((ai = d2i_ASN1_INTEGER(NULL, &c.p, c.slen)) == NULL)
		goto err;
	c.slen -= (c.p - c.q);
	c.q = c.p;
	if ((os = d2i_ASN1_OCTET_STRING(NULL, &c.p, c.slen)) == NULL)
		goto err;
	c.slen -= (c.p - c.q);
	if (!M_ASN1_D2I_end_sequence())
		goto err;

	if (num != NULL)
		*num = ASN1_INTEGER_get(ai);

	ret = M_ASN1_STRING_length(os);
	if (max_len > ret)
		n = ret;
	else
		n = max_len;

	if (data != NULL)
		memcpy(data, M_ASN1_STRING_data(os), n);
	if (0) {
err:
		ASN1err(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING,
		    ASN1_R_DATA_IS_WRONG);
	}
	if (os != NULL)
		M_ASN1_OCTET_STRING_free(os);
	if (ai != NULL)
		M_ASN1_INTEGER_free(ai);
	return (ret);
}
Beispiel #9
0
void PKCS8_PRIV_KEY_INFO_free (PKCS8_PRIV_KEY_INFO *a)
{
	if (a == NULL) return;
	M_ASN1_INTEGER_free (a->version);
	X509_ALGOR_free(a->pkeyalg);
	/* Clear sensitive data */
	if (a->pkey->value.octet_string)
		OPENSSL_cleanse(a->pkey->value.octet_string->data,
				a->pkey->value.octet_string->length);
	ASN1_TYPE_free (a->pkey);
	sk_X509_ATTRIBUTE_pop_free (a->attributes, X509_ATTRIBUTE_free);
	OPENSSL_free (a);
}
Beispiel #10
0
int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
	{
	int ret;
	EVP_PKEY *pkey = NULL;
	if (!ASN1_INTEGER_set(p7i->version,0))
		return 0;
	if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
		X509_get_issuer_name(x509)))
		return 0;

	M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
	if (!(p7i->issuer_and_serial->serial=
		M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
		return 0;

	pkey = X509_get_pubkey(x509);

	if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl)
		{
		PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
			PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
		goto err;
		}

	ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT,
						0, p7i);
	if (ret == -2)
		{
		PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
			PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
		goto err;
		}
	if (ret <= 0)
		{
		PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
				PKCS7_R_ENCRYPTION_CTRL_FAILURE);
		goto err;
		}

	EVP_PKEY_free(pkey);

	CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
	p7i->cert=x509;

	return 1;

	err:
	if (pkey)
		EVP_PKEY_free(pkey);
	return 0;
	}
Beispiel #11
0
void PKCS7_SIGNER_INFO_free(PKCS7_SIGNER_INFO *a)
	{
	if (a == NULL) return;
	M_ASN1_INTEGER_free(a->version);
	PKCS7_ISSUER_AND_SERIAL_free(a->issuer_and_serial);
	X509_ALGOR_free(a->digest_alg);
	sk_X509_ATTRIBUTE_pop_free(a->auth_attr,X509_ATTRIBUTE_free);
	X509_ALGOR_free(a->digest_enc_alg);
	M_ASN1_OCTET_STRING_free(a->enc_digest);
	sk_X509_ATTRIBUTE_pop_free(a->unauth_attr,X509_ATTRIBUTE_free);
	if (a->pkey != NULL)
		EVP_PKEY_free(a->pkey);
	OPENSSL_free(a);
	}
Beispiel #12
0
int X509_set_version(X509 *x, long version)
{
    if (x == NULL)
        return (0);
    if (version == 0) {
        M_ASN1_INTEGER_free(x->cert_info->version);
        x->cert_info->version = NULL;
        return (1);
    }
    if (x->cert_info->version == NULL) {
        if ((x->cert_info->version = M_ASN1_INTEGER_new()) == NULL)
            return (0);
    }
    return (ASN1_INTEGER_set(x->cert_info->version, version));
}
Beispiel #13
0
int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial)
{
	ASN1_INTEGER *in;

	if (x == NULL) return(0);
	in=x->serialNumber;
	if (in != serial) {
		in=M_ASN1_INTEGER_dup(serial);
		if (in != NULL) {
			M_ASN1_INTEGER_free(x->serialNumber);
			x->serialNumber=in;
		}
	}
	return(in != NULL);
}
int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
	     EVP_MD *dgst)
	{
	char is_dsa;
	if (pkey->type == EVP_PKEY_DSA) is_dsa = 1;
	else is_dsa = 0;
	/* We now need to add another PKCS7_SIGNER_INFO entry */
	ASN1_INTEGER_set(p7i->version,1);
	X509_NAME_set(&p7i->issuer_and_serial->issuer,
		X509_get_issuer_name(x509));

	/* because ASN1_INTEGER_set is used to set a 'long' we will do
	 * things the ugly way. */
	M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
	p7i->issuer_and_serial->serial=
		M_ASN1_INTEGER_dup(X509_get_serialNumber(x509));

	/* lets keep the pkey around for a while */
	CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
	p7i->pkey=pkey;

	/* Set the algorithms */
	if (is_dsa) p7i->digest_alg->algorithm=OBJ_nid2obj(NID_sha1);
	else	
		p7i->digest_alg->algorithm=OBJ_nid2obj(EVP_MD_type(dgst));

	if (p7i->digest_alg->parameter != NULL)
		ASN1_TYPE_free(p7i->digest_alg->parameter);
	if ((p7i->digest_alg->parameter=ASN1_TYPE_new()) == NULL)
		goto err;
	p7i->digest_alg->parameter->type=V_ASN1_NULL;

	p7i->digest_enc_alg->algorithm=OBJ_nid2obj(EVP_PKEY_type(pkey->type));

	if (p7i->digest_enc_alg->parameter != NULL)
		ASN1_TYPE_free(p7i->digest_enc_alg->parameter);
	if(is_dsa) p7i->digest_enc_alg->parameter = NULL;
	else {
		if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new()))
			goto err;
		p7i->digest_enc_alg->parameter->type=V_ASN1_NULL;
	}

	return(1);
err:
	return(0);
	}
Beispiel #15
0
int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
	     const EVP_MD *dgst)
	{
	int ret;

	/* We now need to add another PKCS7_SIGNER_INFO entry */
	if (!ASN1_INTEGER_set(p7i->version,1))
		goto err;
	if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
			X509_get_issuer_name(x509)))
		goto err;

	/* because ASN1_INTEGER_set is used to set a 'long' we will do
	 * things the ugly way. */
	M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
	if (!(p7i->issuer_and_serial->serial=
			M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
		goto err;

	/* lets keep the pkey around for a while */
	CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY);
	p7i->pkey=pkey;

	/* Set the algorithms */

	X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)),
				V_ASN1_NULL, NULL);

	if (pkey->ameth && pkey->ameth->pkey_ctrl)
		{
		ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN,
						0, p7i);
		if (ret > 0)
			return 1;
		if (ret != -2)
			{
			PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
					PKCS7_R_SIGNING_CTRL_FAILURE);
			return 0;
			}
		}
	PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
			PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
err:
	return 0;
	}
Beispiel #16
0
ASN1_INTEGER *BN_to_ASN1_INTEGER (const BIGNUM * bn, ASN1_INTEGER * ai)
{
    ASN1_INTEGER *ret;

    int len, j;

    if (ai == NULL)
        ret = M_ASN1_INTEGER_new ();
    else
        ret = ai;
    if (ret == NULL)
    {
        ASN1err (ASN1_F_BN_TO_ASN1_INTEGER, ERR_R_NESTED_ASN1_ERROR);
        goto err;
    }
    if (BN_is_negative (bn))
        ret->type = V_ASN1_NEG_INTEGER;
    else
        ret->type = V_ASN1_INTEGER;
    j = BN_num_bits (bn);
    len = ((j == 0) ? 0 : ((j / 8) + 1));
    if (ret->length < len + 4)
    {
        unsigned char *new_data = OPENSSL_realloc (ret->data, len + 4);

        if (!new_data)
        {
            ASN1err (ASN1_F_BN_TO_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
            goto err;
        }
        ret->data = new_data;
    }
    ret->length = BN_bn2bin (bn, ret->data);
    /* Correct zero case */
    if (!ret->length)
    {
        ret->data[0] = 0;
        ret->length = 1;
    }
    return (ret);
  err:
    if (ret != ai)
        M_ASN1_INTEGER_free (ret);
    return (NULL);
}
int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
	{
	ASN1_INTEGER_set(p7i->version,0);
	X509_NAME_set(&p7i->issuer_and_serial->issuer,
		X509_get_issuer_name(x509));

	M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
	p7i->issuer_and_serial->serial=
		M_ASN1_INTEGER_dup(X509_get_serialNumber(x509));

	X509_ALGOR_free(p7i->key_enc_algor);
	p7i->key_enc_algor=(X509_ALGOR *)ASN1_dup((i2d_func_t)i2d_X509_ALGOR,
		(char *(*)())d2i_X509_ALGOR,
		(char *)x509->cert_info->key->algor);

	CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
	p7i->cert=x509;

	return(1);
	}
Beispiel #18
0
int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
{
    if (!ASN1_INTEGER_set(p7i->version, 0))
        return 0;
    if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
                       X509_get_issuer_name(x509)))
        return 0;

    M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
    if (!(p7i->issuer_and_serial->serial =
          M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
        return 0;

    X509_ALGOR_free(p7i->key_enc_algor);
    if (!(p7i->key_enc_algor = X509_ALGOR_dup(x509->cert_info->key->algor)))
        return 0;

    CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509);
    p7i->cert = x509;

    return (1);
}
Beispiel #19
0
ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
                               long len)
{
    ASN1_INTEGER *ret = NULL;
    const unsigned char *p, *pend;
    unsigned char *to, *s;
    int i;

    if ((a == NULL) || ((*a) == NULL)) {
        if ((ret = M_ASN1_INTEGER_new()) == NULL)
            return (NULL);
        ret->type = V_ASN1_INTEGER;
    } else
        ret = (*a);

    p = *pp;
    pend = p + len;

    /*
     * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
     * a missing NULL parameter.
     */
    s = (unsigned char *)OPENSSL_malloc((int)len + 1);
    if (s == NULL) {
        i = ERR_R_MALLOC_FAILURE;
        goto err;
    }
    to = s;
    if (!len) {
        /*
         * Strictly speaking this is an illegal INTEGER but we tolerate it.
         */
        ret->type = V_ASN1_INTEGER;
    } else if (*p & 0x80) {     /* a negative number */
        ret->type = V_ASN1_NEG_INTEGER;
        if ((*p == 0xff) && (len != 1)) {
            p++;
            len--;
        }
        i = len;
        p += i - 1;
        to += i - 1;
        while ((!*p) && i) {
            *(to--) = 0;
            i--;
            p--;
        }
        /*
         * Special case: if all zeros then the number will be of the form FF
         * followed by n zero bytes: this corresponds to 1 followed by n zero
         * bytes. We've already written n zeros so we just append an extra
         * one and set the first byte to a 1. This is treated separately
         * because it is the only case where the number of bytes is larger
         * than len.
         */
        if (!i) {
            *s = 1;
            s[len] = 0;
            len++;
        } else {
            *(to--) = (*(p--) ^ 0xff) + 1;
            i--;
            for (; i > 0; i--)
                *(to--) = *(p--) ^ 0xff;
        }
    } else {
        ret->type = V_ASN1_INTEGER;
        if ((*p == 0) && (len != 1)) {
            p++;
            len--;
        }
        memcpy(s, p, (int)len);
    }

    if (ret->data != NULL)
        OPENSSL_free(ret->data);
    ret->data = s;
    ret->length = (int)len;
    if (a != NULL)
        (*a) = ret;
    *pp = pend;
    return (ret);
 err:
    ASN1err(ASN1_F_C2I_ASN1_INTEGER, i);
    if ((ret != NULL) && ((a == NULL) || (*a != ret)))
        M_ASN1_INTEGER_free(ret);
    return (NULL);
}
Beispiel #20
0
int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
                          const EVP_MD *dgst)
{
    int nid;
    char is_dsa;

    if (pkey->type == EVP_PKEY_DSA || pkey->type == EVP_PKEY_EC)
        is_dsa = 1;
    else
        is_dsa = 0;
    /* We now need to add another PKCS7_SIGNER_INFO entry */
    if (!ASN1_INTEGER_set(p7i->version, 1))
        goto err;
    if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
                       X509_get_issuer_name(x509)))
        goto err;

    /*
     * because ASN1_INTEGER_set is used to set a 'long' we will do things the
     * ugly way.
     */
    M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
    if (!(p7i->issuer_and_serial->serial =
          M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
        goto err;

    /* lets keep the pkey around for a while */
    CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
    p7i->pkey = pkey;

    /* Set the algorithms */
    if (is_dsa)
        p7i->digest_alg->algorithm = OBJ_nid2obj(NID_sha1);
    else
        p7i->digest_alg->algorithm = OBJ_nid2obj(EVP_MD_type(dgst));

    if (p7i->digest_alg->parameter != NULL)
        ASN1_TYPE_free(p7i->digest_alg->parameter);
    if ((p7i->digest_alg->parameter = ASN1_TYPE_new()) == NULL)
        goto err;
    p7i->digest_alg->parameter->type = V_ASN1_NULL;

    if (p7i->digest_enc_alg->parameter != NULL)
        ASN1_TYPE_free(p7i->digest_enc_alg->parameter);
    nid = EVP_PKEY_type(pkey->type);
    if (nid == EVP_PKEY_RSA) {
        p7i->digest_enc_alg->algorithm = OBJ_nid2obj(NID_rsaEncryption);
        if (!(p7i->digest_enc_alg->parameter = ASN1_TYPE_new()))
            goto err;
        p7i->digest_enc_alg->parameter->type = V_ASN1_NULL;
    } else if (nid == EVP_PKEY_DSA) {
#if 1
        /*
         * use 'dsaEncryption' OID for compatibility with other software
         * (PKCS #7 v1.5 does specify how to handle DSA) ...
         */
        p7i->digest_enc_alg->algorithm = OBJ_nid2obj(NID_dsa);
#else
        /*
         * ... although the 'dsaWithSHA1' OID (as required by RFC 2630 for
         * CMS) would make more sense.
         */
        p7i->digest_enc_alg->algorithm = OBJ_nid2obj(NID_dsaWithSHA1);
#endif
        p7i->digest_enc_alg->parameter = NULL; /* special case for DSA: omit
                                                * 'parameter'! */
    } else if (nid == EVP_PKEY_EC) {
        p7i->digest_enc_alg->algorithm = OBJ_nid2obj(NID_ecdsa_with_SHA1);
        if (!(p7i->digest_enc_alg->parameter = ASN1_TYPE_new()))
            goto err;
        p7i->digest_enc_alg->parameter->type = V_ASN1_NULL;
    } else
        return (0);

    return (1);
 err:
    return (0);
}
static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
                       int offset, int depth, int indent, int dump)
{
    const unsigned char *p, *ep, *tot, *op, *opp;
    long len;
    int tag, xclass, ret = 0;
    int nl, hl, j, r;
    ASN1_OBJECT *o = NULL;
    ASN1_OCTET_STRING *os = NULL;
    /* ASN1_BMPSTRING *bmp=NULL; */
    int dump_indent;

#if 0
    dump_indent = indent;
#else
    dump_indent = 6;            /* Because we know BIO_dump_indent() */
#endif

    if (depth > ASN1_PARSE_MAXDEPTH) {
        BIO_puts(bp, "BAD RECURSION DEPTH\n");
        return 0;
    }

    p = *pp;
    tot = p + length;
    op = p - 1;
    while ((p < tot) && (op < p)) {
        op = p;
        j = ASN1_get_object(&p, &len, &tag, &xclass, length);
#ifdef LINT
        j = j;
#endif
        if (j & 0x80) {
            if (BIO_puts(bp, "Error in encoding\n") <= 0)
                goto end;
            ret = 0;
            goto end;
        }
        hl = (p - op);
        length -= hl;
        /*
         * if j == 0x21 it is a constructed indefinite length object
         */
        if (BIO_printf(bp, "%5ld:", (long)offset + (long)(op - *pp))
            <= 0)
            goto end;

        if (j != (V_ASN1_CONSTRUCTED | 1)) {
            if (BIO_printf(bp, "d=%-2d hl=%ld l=%4ld ",
                           depth, (long)hl, len) <= 0)
                goto end;
        } else {
            if (BIO_printf(bp, "d=%-2d hl=%ld l=inf  ", depth, (long)hl) <= 0)
                goto end;
        }
        if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0))
            goto end;
        if (j & V_ASN1_CONSTRUCTED) {
            ep = p + len;
            if (BIO_puts(bp, "\n") <= 0)
                goto end;
            if (len > length) {
                BIO_printf(bp, "length is greater than %ld\n", length);
                ret = 0;
                goto end;
            }
            if ((j == 0x21) && (len == 0)) {
                for (;;) {
                    r = asn1_parse2(bp, &p, (long)(tot - p),
                                    offset + (p - *pp), depth + 1,
                                    indent, dump);
                    if (r == 0) {
                        ret = 0;
                        goto end;
                    }
                    if ((r == 2) || (p >= tot))
                        break;
                }
            } else
                while (p < ep) {
                    r = asn1_parse2(bp, &p, (long)len,
                                    offset + (p - *pp), depth + 1,
                                    indent, dump);
                    if (r == 0) {
                        ret = 0;
                        goto end;
                    }
                }
        } else if (xclass != 0) {
            p += len;
            if (BIO_puts(bp, "\n") <= 0)
                goto end;
        } else {
            nl = 0;
            if ((tag == V_ASN1_PRINTABLESTRING) ||
                (tag == V_ASN1_T61STRING) ||
                (tag == V_ASN1_IA5STRING) ||
                (tag == V_ASN1_VISIBLESTRING) ||
                (tag == V_ASN1_NUMERICSTRING) ||
                (tag == V_ASN1_UTF8STRING) ||
                (tag == V_ASN1_UTCTIME) || (tag == V_ASN1_GENERALIZEDTIME)) {
                if (BIO_puts(bp, ":") <= 0)
                    goto end;
                if ((len > 0) && BIO_write(bp, (const char *)p, (int)len)
                    != (int)len)
                    goto end;
            } else if (tag == V_ASN1_OBJECT) {
                opp = op;
                if (d2i_ASN1_OBJECT(&o, &opp, len + hl) != NULL) {
                    if (BIO_puts(bp, ":") <= 0)
                        goto end;
                    i2a_ASN1_OBJECT(bp, o);
                } else {
                    if (BIO_puts(bp, ":BAD OBJECT") <= 0)
                        goto end;
                }
            } else if (tag == V_ASN1_BOOLEAN) {
                int ii;

                opp = op;
                ii = d2i_ASN1_BOOLEAN(NULL, &opp, len + hl);
                if (ii < 0) {
                    if (BIO_puts(bp, "Bad boolean\n") <= 0)
                        goto end;
                }
                BIO_printf(bp, ":%d", ii);
            } else if (tag == V_ASN1_BMPSTRING) {
                /* do the BMP thang */
            } else if (tag == V_ASN1_OCTET_STRING) {
                int i, printable = 1;

                opp = op;
                os = d2i_ASN1_OCTET_STRING(NULL, &opp, len + hl);
                if (os != NULL && os->length > 0) {
                    opp = os->data;
                    /*
                     * testing whether the octet string is printable
                     */
                    for (i = 0; i < os->length; i++) {
                        if (((opp[i] < ' ') &&
                             (opp[i] != '\n') &&
                             (opp[i] != '\r') &&
                             (opp[i] != '\t')) || (opp[i] > '~')) {
                            printable = 0;
                            break;
                        }
                    }
                    if (printable)
                        /* printable string */
                    {
                        if (BIO_puts(bp, ":") <= 0)
                            goto end;
                        if (BIO_write(bp, (const char *)opp, os->length) <= 0)
                            goto end;
                    } else if (!dump)
                        /*
                         * not printable => print octet string as hex dump
                         */
                    {
                        if (BIO_puts(bp, "[HEX DUMP]:") <= 0)
                            goto end;
                        for (i = 0; i < os->length; i++) {
                            if (BIO_printf(bp, "%02X", opp[i]) <= 0)
                                goto end;
                        }
                    } else
                        /* print the normal dump */
                    {
                        if (!nl) {
                            if (BIO_puts(bp, "\n") <= 0)
                                goto end;
                        }
                        if (!BIO_hexdump(bp, opp,
                                         ((dump == -1 || dump >
                                           os->length) ? os->length : dump),
                                         dump_indent))
                            goto end;
                        nl = 1;
                    }
                }
                if (os != NULL) {
                    M_ASN1_OCTET_STRING_free(os);
                    os = NULL;
                }
            } else if (tag == V_ASN1_INTEGER) {
                ASN1_INTEGER *bs;
                int i;

                opp = op;
                bs = d2i_ASN1_INTEGER(NULL, &opp, len + hl);
                if (bs != NULL) {
                    if (BIO_puts(bp, ":") <= 0)
                        goto end;
                    if (bs->type == V_ASN1_NEG_INTEGER)
                        if (BIO_puts(bp, "-") <= 0)
                            goto end;
                    for (i = 0; i < bs->length; i++) {
                        if (BIO_printf(bp, "%02X", bs->data[i]) <= 0)
                            goto end;
                    }
                    if (bs->length == 0) {
                        if (BIO_puts(bp, "00") <= 0)
                            goto end;
                    }
                } else {
                    if (BIO_puts(bp, "BAD INTEGER") <= 0)
                        goto end;
                }
                M_ASN1_INTEGER_free(bs);
            } else if (tag == V_ASN1_ENUMERATED) {
                ASN1_ENUMERATED *bs;
                int i;

                opp = op;
                bs = d2i_ASN1_ENUMERATED(NULL, &opp, len + hl);
                if (bs != NULL) {
                    if (BIO_puts(bp, ":") <= 0)
                        goto end;
                    if (bs->type == V_ASN1_NEG_ENUMERATED)
                        if (BIO_puts(bp, "-") <= 0)
                            goto end;
                    for (i = 0; i < bs->length; i++) {
                        if (BIO_printf(bp, "%02X", bs->data[i]) <= 0)
                            goto end;
                    }
                    if (bs->length == 0) {
                        if (BIO_puts(bp, "00") <= 0)
                            goto end;
                    }
                } else {
                    if (BIO_puts(bp, "BAD ENUMERATED") <= 0)
                        goto end;
                }
                M_ASN1_ENUMERATED_free(bs);
            } else if (len > 0 && dump) {
                if (!nl) {
                    if (BIO_puts(bp, "\n") <= 0)
                        goto end;
                }
                if (!BIO_hexdump(bp, p,
                                 ((dump == -1 || dump > len) ? len : dump),
                                 dump_indent))
                    goto end;
                nl = 1;
            }

            if (!nl) {
                if (BIO_puts(bp, "\n") <= 0)
                    goto end;
            }
            p += len;
            if ((tag == V_ASN1_EOC) && (xclass == 0)) {
                ret = 2;        /* End of sequence */
                goto end;
            }
        }
        length -= len;
    }
    ret = 1;
 end:
    if (o != NULL)
        ASN1_OBJECT_free(o);
    if (os != NULL)
        M_ASN1_OCTET_STRING_free(os);
    *pp = p;
    return (ret);
}
Beispiel #22
0
static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
{
  ASN1_STRING *params = NULL;
  ASN1_INTEGER *prkey = NULL;
  ASN1_TYPE *ttmp = NULL;
  STACK_OF(ASN1_TYPE) *ndsa = NULL;
  unsigned char *p = NULL, *q;
  int len;

  p8->pkeyalg->algorithm = OBJ_nid2obj(NID_dsa);
  len = i2d_DSAparams (pkey->pkey.dsa, NULL);
  if (!(p = OPENSSL_malloc(len))) {
    EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
    goto err;
  }
  q = p;
  i2d_DSAparams (pkey->pkey.dsa, &q);
  if (!(params = ASN1_STRING_new())) {
    EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
    goto err;
  }
  if (!ASN1_STRING_set(params, p, len)) {
    EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
    goto err;
  }
  OPENSSL_free(p);
  p = NULL;
  /* Get private key into integer */
  if (!(prkey = BN_to_ASN1_INTEGER (pkey->pkey.dsa->priv_key, NULL))) {
    EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
    goto err;
  }

  switch(p8->broken) {

    case PKCS8_OK:
    case PKCS8_NO_OCTET:

    if (!ASN1_pack_string_of(ASN1_INTEGER,prkey, i2d_ASN1_INTEGER,
           &p8->pkey->value.octet_string)) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }

    M_ASN1_INTEGER_free (prkey);
    prkey = NULL;
    p8->pkeyalg->parameter->value.sequence = params;
    params = NULL;
    p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;

    break;

    case PKCS8_NS_DB:

    p8->pkeyalg->parameter->value.sequence = params;
    params = NULL;
    p8->pkeyalg->parameter->type = V_ASN1_SEQUENCE;
    if (!(ndsa = sk_ASN1_TYPE_new_null())) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }
    if (!(ttmp = ASN1_TYPE_new())) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }
    if (!(ttmp->value.integer =
      BN_to_ASN1_INTEGER(pkey->pkey.dsa->pub_key, NULL))) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
      goto err;
    }
    ttmp->type = V_ASN1_INTEGER;
    if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }

    if (!(ttmp = ASN1_TYPE_new())) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }
    ttmp->value.integer = prkey;
    prkey = NULL;
    ttmp->type = V_ASN1_INTEGER;
    if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }
    ttmp = NULL;

    if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }

    if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE,
           &p8->pkey->value.octet_string->data,
           &p8->pkey->value.octet_string->length)) {

      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }
    sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
    break;

    case PKCS8_EMBEDDED_PARAM:

    p8->pkeyalg->parameter->type = V_ASN1_NULL;
    if (!(ndsa = sk_ASN1_TYPE_new_null())) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }
    if (!(ttmp = ASN1_TYPE_new())) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }
    ttmp->value.sequence = params;
    params = NULL;
    ttmp->type = V_ASN1_SEQUENCE;
    if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }

    if (!(ttmp = ASN1_TYPE_new())) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }
    ttmp->value.integer = prkey;
    prkey = NULL;
    ttmp->type = V_ASN1_INTEGER;
    if (!sk_ASN1_TYPE_push(ndsa, ttmp)) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }
    ttmp = NULL;

    if (!(p8->pkey->value.octet_string = ASN1_OCTET_STRING_new())) {
      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }

    if (!ASN1_seq_pack_ASN1_TYPE(ndsa, i2d_ASN1_TYPE,
           &p8->pkey->value.octet_string->data,
           &p8->pkey->value.octet_string->length)) {

      EVPerr(EVP_F_DSA_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
      goto err;
    }
    sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
    break;
  }
  return 1;
err:
  if (p != NULL) OPENSSL_free(p);
  if (params != NULL) ASN1_STRING_free(params);
  if (prkey != NULL) M_ASN1_INTEGER_free(prkey);
  if (ttmp != NULL) ASN1_TYPE_free(ttmp);
  if (ndsa != NULL) sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
  return 0;
}
Beispiel #23
0
void HsOpenSSL_M_ASN1_INTEGER_free(ASN1_INTEGER* intPtr) {
    M_ASN1_INTEGER_free(intPtr);
}
Beispiel #24
0
int
x509_main(int argc, char **argv)
{
	ENGINE *e = NULL;
	int ret = 1;
	X509_REQ *req = NULL;
	X509 *x = NULL, *xca = NULL;
	ASN1_OBJECT *objtmp;
	STACK_OF(OPENSSL_STRING) *sigopts = NULL;
	EVP_PKEY *Upkey = NULL, *CApkey = NULL;
	ASN1_INTEGER *sno = NULL;
	int i, num, badops = 0;
	BIO *out = NULL;
	BIO *STDout = NULL;
	STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
	int informat, outformat, keyformat, CAformat, CAkeyformat;
	char *infile = NULL, *outfile = NULL, *keyfile = NULL, *CAfile = NULL;
	char *CAkeyfile = NULL, *CAserial = NULL;
	char *alias = NULL;
	int text = 0, serial = 0, subject = 0, issuer = 0, startdate = 0,
	    enddate = 0;
	int next_serial = 0;
	int subject_hash = 0, issuer_hash = 0, ocspid = 0;
#ifndef OPENSSL_NO_MD5
	int subject_hash_old = 0, issuer_hash_old = 0;
#endif
	int noout = 0, sign_flag = 0, CA_flag = 0, CA_createserial = 0,
	    email = 0;
	int ocsp_uri = 0;
	int trustout = 0, clrtrust = 0, clrreject = 0, aliasout = 0, clrext = 0;
	int C = 0;
	int x509req = 0, days = DEF_DAYS, modulus = 0, pubkey = 0;
	int pprint = 0;
	const char **pp;
	X509_STORE *ctx = NULL;
	X509_REQ *rq = NULL;
	int fingerprint = 0;
	char buf[256];
	const EVP_MD *md_alg, *digest = NULL;
	CONF *extconf = NULL;
	char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL;
	int checkend = 0, checkoffset = 0;
	unsigned long nmflag = 0, certflag = 0;
#ifndef OPENSSL_NO_ENGINE
	char *engine = NULL;
#endif
	const char *errstr = NULL;

	reqfile = 0;

	STDout = BIO_new_fp(stdout, BIO_NOCLOSE);

	informat = FORMAT_PEM;
	outformat = FORMAT_PEM;
	keyformat = FORMAT_PEM;
	CAformat = FORMAT_PEM;
	CAkeyformat = FORMAT_PEM;

	ctx = X509_STORE_new();
	if (ctx == NULL)
		goto end;
	X509_STORE_set_verify_cb(ctx, callb);

	argc--;
	argv++;
	num = 0;
	while (argc >= 1) {
		if (strcmp(*argv, "-inform") == 0) {
			if (--argc < 1)
				goto bad;
			informat = str2fmt(*(++argv));
		} else if (strcmp(*argv, "-outform") == 0) {
			if (--argc < 1)
				goto bad;
			outformat = str2fmt(*(++argv));
		} else if (strcmp(*argv, "-keyform") == 0) {
			if (--argc < 1)
				goto bad;
			keyformat = str2fmt(*(++argv));
		} else if (strcmp(*argv, "-req") == 0) {
			reqfile = 1;
		} else if (strcmp(*argv, "-CAform") == 0) {
			if (--argc < 1)
				goto bad;
			CAformat = str2fmt(*(++argv));
		} else if (strcmp(*argv, "-CAkeyform") == 0) {
			if (--argc < 1)
				goto bad;
			CAkeyformat = str2fmt(*(++argv));
		} else if (strcmp(*argv, "-sigopt") == 0) {
			if (--argc < 1)
				goto bad;
			if (!sigopts)
				sigopts = sk_OPENSSL_STRING_new_null();
			if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
				goto bad;
		} else if (strcmp(*argv, "-days") == 0) {
			if (--argc < 1)
				goto bad;
			days = strtonum(*(++argv), 1, INT_MAX, &errstr);
			if (errstr) {
				BIO_printf(bio_err, "bad number of days: %s\n", errstr);
				goto bad;
			}
		} else if (strcmp(*argv, "-passin") == 0) {
			if (--argc < 1)
				goto bad;
			passargin = *(++argv);
		} else if (strcmp(*argv, "-extfile") == 0) {
			if (--argc < 1)
				goto bad;
			extfile = *(++argv);
		} else if (strcmp(*argv, "-extensions") == 0) {
			if (--argc < 1)
				goto bad;
			extsect = *(++argv);
		} else if (strcmp(*argv, "-in") == 0) {
			if (--argc < 1)
				goto bad;
			infile = *(++argv);
		} else if (strcmp(*argv, "-out") == 0) {
			if (--argc < 1)
				goto bad;
			outfile = *(++argv);
		} else if (strcmp(*argv, "-signkey") == 0) {
			if (--argc < 1)
				goto bad;
			keyfile = *(++argv);
			sign_flag = ++num;
		} else if (strcmp(*argv, "-CA") == 0) {
			if (--argc < 1)
				goto bad;
			CAfile = *(++argv);
			CA_flag = ++num;
		} else if (strcmp(*argv, "-CAkey") == 0) {
			if (--argc < 1)
				goto bad;
			CAkeyfile = *(++argv);
		} else if (strcmp(*argv, "-CAserial") == 0) {
			if (--argc < 1)
				goto bad;
			CAserial = *(++argv);
		} else if (strcmp(*argv, "-set_serial") == 0) {
			if (--argc < 1)
				goto bad;
			M_ASN1_INTEGER_free(sno);
			if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv))))
				goto bad;
		} else if (strcmp(*argv, "-addtrust") == 0) {
			if (--argc < 1)
				goto bad;
			if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) {
				BIO_printf(bio_err,
				    "Invalid trust object value %s\n", *argv);
				goto bad;
			}
			if (!trust)
				trust = sk_ASN1_OBJECT_new_null();
			sk_ASN1_OBJECT_push(trust, objtmp);
			trustout = 1;
		} else if (strcmp(*argv, "-addreject") == 0) {
			if (--argc < 1)
				goto bad;
			if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) {
				BIO_printf(bio_err,
				    "Invalid reject object value %s\n", *argv);
				goto bad;
			}
			if (!reject)
				reject = sk_ASN1_OBJECT_new_null();
			sk_ASN1_OBJECT_push(reject, objtmp);
			trustout = 1;
		} else if (strcmp(*argv, "-setalias") == 0) {
			if (--argc < 1)
				goto bad;
			alias = *(++argv);
			trustout = 1;
		} else if (strcmp(*argv, "-certopt") == 0) {
			if (--argc < 1)
				goto bad;
			if (!set_cert_ex(&certflag, *(++argv)))
				goto bad;
		} else if (strcmp(*argv, "-nameopt") == 0) {
			if (--argc < 1)
				goto bad;
			if (!set_name_ex(&nmflag, *(++argv)))
				goto bad;
		}
#ifndef OPENSSL_NO_ENGINE
		else if (strcmp(*argv, "-engine") == 0) {
			if (--argc < 1)
				goto bad;
			engine = *(++argv);
		}
#endif
		else if (strcmp(*argv, "-C") == 0)
			C = ++num;
		else if (strcmp(*argv, "-email") == 0)
			email = ++num;
		else if (strcmp(*argv, "-ocsp_uri") == 0)
			ocsp_uri = ++num;
		else if (strcmp(*argv, "-serial") == 0)
			serial = ++num;
		else if (strcmp(*argv, "-next_serial") == 0)
			next_serial = ++num;
		else if (strcmp(*argv, "-modulus") == 0)
			modulus = ++num;
		else if (strcmp(*argv, "-pubkey") == 0)
			pubkey = ++num;
		else if (strcmp(*argv, "-x509toreq") == 0)
			x509req = ++num;
		else if (strcmp(*argv, "-text") == 0)
			text = ++num;
		else if (strcmp(*argv, "-hash") == 0 ||
		    strcmp(*argv, "-subject_hash") == 0)
			subject_hash = ++num;
#ifndef OPENSSL_NO_MD5
		else if (strcmp(*argv, "-subject_hash_old") == 0)
			subject_hash_old = ++num;
#endif
		else if (strcmp(*argv, "-issuer_hash") == 0)
			issuer_hash = ++num;
#ifndef OPENSSL_NO_MD5
		else if (strcmp(*argv, "-issuer_hash_old") == 0)
			issuer_hash_old = ++num;
#endif
		else if (strcmp(*argv, "-subject") == 0)
			subject = ++num;
		else if (strcmp(*argv, "-issuer") == 0)
			issuer = ++num;
		else if (strcmp(*argv, "-fingerprint") == 0)
			fingerprint = ++num;
		else if (strcmp(*argv, "-dates") == 0) {
			startdate = ++num;
			enddate = ++num;
		} else if (strcmp(*argv, "-purpose") == 0)
			pprint = ++num;
		else if (strcmp(*argv, "-startdate") == 0)
			startdate = ++num;
		else if (strcmp(*argv, "-enddate") == 0)
			enddate = ++num;
		else if (strcmp(*argv, "-checkend") == 0) {
			if (--argc < 1)
				goto bad;
			checkoffset = strtonum(*(++argv), 0, INT_MAX, &errstr);
			if (errstr) {
				BIO_printf(bio_err, "checkend unusable: %s\n", errstr);
				goto bad;
			}
			checkend = 1;
		} else if (strcmp(*argv, "-noout") == 0)
			noout = ++num;
		else if (strcmp(*argv, "-trustout") == 0)
			trustout = 1;
		else if (strcmp(*argv, "-clrtrust") == 0)
			clrtrust = ++num;
		else if (strcmp(*argv, "-clrreject") == 0)
			clrreject = ++num;
		else if (strcmp(*argv, "-alias") == 0)
			aliasout = ++num;
		else if (strcmp(*argv, "-CAcreateserial") == 0)
			CA_createserial = ++num;
		else if (strcmp(*argv, "-clrext") == 0)
			clrext = 1;
		else if (strcmp(*argv, "-ocspid") == 0)
			ocspid = ++num;
		else if ((md_alg = EVP_get_digestbyname(*argv + 1))) {
			/* ok */
			digest = md_alg;
		} else {
			BIO_printf(bio_err, "unknown option %s\n", *argv);
			badops = 1;
			break;
		}
		argc--;
		argv++;
	}

	if (badops) {
bad:
		for (pp = x509_usage; (*pp != NULL); pp++)
			BIO_printf(bio_err, "%s", *pp);
		goto end;
	}
#ifndef OPENSSL_NO_ENGINE
	e = setup_engine(bio_err, engine, 0);
#endif

	if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
		BIO_printf(bio_err, "Error getting password\n");
		goto end;
	}
	if (!X509_STORE_set_default_paths(ctx)) {
		ERR_print_errors(bio_err);
		goto end;
	}
	if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM)) {
		CAkeyfile = CAfile;
	} else if ((CA_flag) && (CAkeyfile == NULL)) {
		BIO_printf(bio_err,
		    "need to specify a CAkey if using the CA command\n");
		goto end;
	}
	if (extfile) {
		long errorline = -1;
		X509V3_CTX ctx2;
		extconf = NCONF_new(NULL);
		if (!NCONF_load(extconf, extfile, &errorline)) {
			if (errorline <= 0)
				BIO_printf(bio_err,
				    "error loading the config file '%s'\n",
				    extfile);
			else
				BIO_printf(bio_err,
				    "error on line %ld of config file '%s'\n",
				    errorline, extfile);
			goto end;
		}
		if (!extsect) {
			extsect = NCONF_get_string(extconf, "default",
			    "extensions");
			if (!extsect) {
				ERR_clear_error();
				extsect = "default";
			}
		}
		X509V3_set_ctx_test(&ctx2);
		X509V3_set_nconf(&ctx2, extconf);
		if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) {
			BIO_printf(bio_err,
			    "Error Loading extension section %s\n",
			    extsect);
			ERR_print_errors(bio_err);
			goto end;
		}
	}
	if (reqfile) {
		EVP_PKEY *pkey;
		BIO *in;

		if (!sign_flag && !CA_flag) {
			BIO_printf(bio_err, "We need a private key to sign with\n");
			goto end;
		}
		in = BIO_new(BIO_s_file());
		if (in == NULL) {
			ERR_print_errors(bio_err);
			goto end;
		}
		if (infile == NULL)
			BIO_set_fp(in, stdin, BIO_NOCLOSE | BIO_FP_TEXT);
		else {
			if (BIO_read_filename(in, infile) <= 0) {
				perror(infile);
				BIO_free(in);
				goto end;
			}
		}
		req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
		BIO_free(in);

		if (req == NULL) {
			ERR_print_errors(bio_err);
			goto end;
		}
		if ((req->req_info == NULL) ||
		    (req->req_info->pubkey == NULL) ||
		    (req->req_info->pubkey->public_key == NULL) ||
		    (req->req_info->pubkey->public_key->data == NULL)) {
			BIO_printf(bio_err, "The certificate request appears to corrupted\n");
			BIO_printf(bio_err, "It does not contain a public key\n");
			goto end;
		}
		if ((pkey = X509_REQ_get_pubkey(req)) == NULL) {
			BIO_printf(bio_err, "error unpacking public key\n");
			goto end;
		}
		i = X509_REQ_verify(req, pkey);
		EVP_PKEY_free(pkey);
		if (i < 0) {
			BIO_printf(bio_err, "Signature verification error\n");
			ERR_print_errors(bio_err);
			goto end;
		}
		if (i == 0) {
			BIO_printf(bio_err, "Signature did not match the certificate request\n");
			goto end;
		} else
			BIO_printf(bio_err, "Signature ok\n");

		print_name(bio_err, "subject=", X509_REQ_get_subject_name(req), nmflag);

		if ((x = X509_new()) == NULL)
			goto end;

		if (sno == NULL) {
			sno = ASN1_INTEGER_new();
			if (!sno || !rand_serial(NULL, sno))
				goto end;
			if (!X509_set_serialNumber(x, sno))
				goto end;
			ASN1_INTEGER_free(sno);
			sno = NULL;
		} else if (!X509_set_serialNumber(x, sno))
			goto end;

		if (!X509_set_issuer_name(x, req->req_info->subject))
			goto end;
		if (!X509_set_subject_name(x, req->req_info->subject))
			goto end;

		X509_gmtime_adj(X509_get_notBefore(x), 0);
		X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL);

		pkey = X509_REQ_get_pubkey(req);
		X509_set_pubkey(x, pkey);
		EVP_PKEY_free(pkey);
	} else
		x = load_cert(bio_err, infile, informat, NULL, e, "Certificate");

	if (x == NULL)
		goto end;
	if (CA_flag) {
		xca = load_cert(bio_err, CAfile, CAformat, NULL, e, "CA Certificate");
		if (xca == NULL)
			goto end;
	}
	if (!noout || text || next_serial) {
		OBJ_create("2.99999.3",
		    "SET.ex3", "SET x509v3 extension 3");

		out = BIO_new(BIO_s_file());
		if (out == NULL) {
			ERR_print_errors(bio_err);
			goto end;
		}
		if (outfile == NULL) {
			BIO_set_fp(out, stdout, BIO_NOCLOSE);
		} else {
			if (BIO_write_filename(out, outfile) <= 0) {
				perror(outfile);
				goto end;
			}
		}
	}
	if (alias)
		X509_alias_set1(x, (unsigned char *) alias, -1);

	if (clrtrust)
		X509_trust_clear(x);
	if (clrreject)
		X509_reject_clear(x);

	if (trust) {
		for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) {
			objtmp = sk_ASN1_OBJECT_value(trust, i);
			X509_add1_trust_object(x, objtmp);
		}
	}
	if (reject) {
		for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) {
			objtmp = sk_ASN1_OBJECT_value(reject, i);
			X509_add1_reject_object(x, objtmp);
		}
	}
	if (num) {
		for (i = 1; i <= num; i++) {
			if (issuer == i) {
				print_name(STDout, "issuer= ",
				    X509_get_issuer_name(x), nmflag);
			} else if (subject == i) {
				print_name(STDout, "subject= ",
				    X509_get_subject_name(x), nmflag);
			} else if (serial == i) {
				BIO_printf(STDout, "serial=");
				i2a_ASN1_INTEGER(STDout,
				    X509_get_serialNumber(x));
				BIO_printf(STDout, "\n");
			} else if (next_serial == i) {
				BIGNUM *bnser;
				ASN1_INTEGER *ser;
				ser = X509_get_serialNumber(x);
				bnser = ASN1_INTEGER_to_BN(ser, NULL);
				if (!bnser)
					goto end;
				if (!BN_add_word(bnser, 1))
					goto end;
				ser = BN_to_ASN1_INTEGER(bnser, NULL);
				if (!ser)
					goto end;
				BN_free(bnser);
				i2a_ASN1_INTEGER(out, ser);
				ASN1_INTEGER_free(ser);
				BIO_puts(out, "\n");
			} else if ((email == i) || (ocsp_uri == i)) {
				int j;
				STACK_OF(OPENSSL_STRING) *emlst;
				if (email == i)
					emlst = X509_get1_email(x);
				else
					emlst = X509_get1_ocsp(x);
				for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
					BIO_printf(STDout, "%s\n",
					    sk_OPENSSL_STRING_value(emlst, j));
				X509_email_free(emlst);
			} else if (aliasout == i) {
				unsigned char *alstr;
				alstr = X509_alias_get0(x, NULL);
				if (alstr)
					BIO_printf(STDout, "%s\n", alstr);
				else
					BIO_puts(STDout, "<No Alias>\n");
			} else if (subject_hash == i) {
				BIO_printf(STDout, "%08lx\n", X509_subject_name_hash(x));
			}
#ifndef OPENSSL_NO_MD5
			else if (subject_hash_old == i) {
				BIO_printf(STDout, "%08lx\n", X509_subject_name_hash_old(x));
			}
#endif
			else if (issuer_hash == i) {
				BIO_printf(STDout, "%08lx\n", X509_issuer_name_hash(x));
			}
#ifndef OPENSSL_NO_MD5
			else if (issuer_hash_old == i) {
				BIO_printf(STDout, "%08lx\n", X509_issuer_name_hash_old(x));
			}
#endif
			else if (pprint == i) {
				X509_PURPOSE *ptmp;
				int j;
				BIO_printf(STDout, "Certificate purposes:\n");
				for (j = 0; j < X509_PURPOSE_get_count(); j++) {
					ptmp = X509_PURPOSE_get0(j);
					purpose_print(STDout, x, ptmp);
				}
			} else if (modulus == i) {
				EVP_PKEY *pkey;

				pkey = X509_get_pubkey(x);
				if (pkey == NULL) {
					BIO_printf(bio_err, "Modulus=unavailable\n");
					ERR_print_errors(bio_err);
					goto end;
				}
				BIO_printf(STDout, "Modulus=");
				if (pkey->type == EVP_PKEY_RSA)
					BN_print(STDout, pkey->pkey.rsa->n);
				else
						if (pkey->type == EVP_PKEY_DSA)
							BN_print(STDout, pkey->pkey.dsa->pub_key);
				else
						BIO_printf(STDout, "Wrong Algorithm type");
				BIO_printf(STDout, "\n");
				EVP_PKEY_free(pkey);
			} else if (pubkey == i) {
				EVP_PKEY *pkey;

				pkey = X509_get_pubkey(x);
				if (pkey == NULL) {
					BIO_printf(bio_err, "Error getting public key\n");
					ERR_print_errors(bio_err);
					goto end;
				}
				PEM_write_bio_PUBKEY(STDout, pkey);
				EVP_PKEY_free(pkey);
			} else if (C == i) {
				unsigned char *d;
				char *m;
				int y, z;

				X509_NAME_oneline(X509_get_subject_name(x),
				    buf, sizeof buf);
				BIO_printf(STDout, "/* subject:%s */\n", buf);
				m = X509_NAME_oneline(
				    X509_get_issuer_name(x), buf,
				    sizeof buf);
				BIO_printf(STDout, "/* issuer :%s */\n", buf);

				z = i2d_X509(x, NULL);
				m = malloc(z);

				d = (unsigned char *) m;
				z = i2d_X509_NAME(X509_get_subject_name(x), &d);
				BIO_printf(STDout, "unsigned char XXX_subject_name[%d]={\n", z);
				d = (unsigned char *) m;
				for (y = 0; y < z; y++) {
					BIO_printf(STDout, "0x%02X,", d[y]);
					if ((y & 0x0f) == 0x0f)
						BIO_printf(STDout, "\n");
				}
				if (y % 16 != 0)
					BIO_printf(STDout, "\n");
				BIO_printf(STDout, "};\n");

				z = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &d);
				BIO_printf(STDout, "unsigned char XXX_public_key[%d]={\n", z);
				d = (unsigned char *) m;
				for (y = 0; y < z; y++) {
					BIO_printf(STDout, "0x%02X,", d[y]);
					if ((y & 0x0f) == 0x0f)
						BIO_printf(STDout, "\n");
				}
				if (y % 16 != 0)
					BIO_printf(STDout, "\n");
				BIO_printf(STDout, "};\n");

				z = i2d_X509(x, &d);
				BIO_printf(STDout, "unsigned char XXX_certificate[%d]={\n", z);
				d = (unsigned char *) m;
				for (y = 0; y < z; y++) {
					BIO_printf(STDout, "0x%02X,", d[y]);
					if ((y & 0x0f) == 0x0f)
						BIO_printf(STDout, "\n");
				}
				if (y % 16 != 0)
					BIO_printf(STDout, "\n");
				BIO_printf(STDout, "};\n");

				free(m);
			} else if (text == i) {
				X509_print_ex(STDout, x, nmflag, certflag);
			} else if (startdate == i) {
				BIO_puts(STDout, "notBefore=");
				ASN1_TIME_print(STDout, X509_get_notBefore(x));
				BIO_puts(STDout, "\n");
			} else if (enddate == i) {
				BIO_puts(STDout, "notAfter=");
				ASN1_TIME_print(STDout, X509_get_notAfter(x));
				BIO_puts(STDout, "\n");
			} else if (fingerprint == i) {
				int j;
				unsigned int n;
				unsigned char md[EVP_MAX_MD_SIZE];
				const EVP_MD *fdig = digest;

				if (!fdig)
					fdig = EVP_sha1();

				if (!X509_digest(x, fdig, md, &n)) {
					BIO_printf(bio_err, "out of memory\n");
					goto end;
				}
				BIO_printf(STDout, "%s Fingerprint=",
				    OBJ_nid2sn(EVP_MD_type(fdig)));
				for (j = 0; j < (int) n; j++) {
					BIO_printf(STDout, "%02X%c", md[j],
					    (j + 1 == (int)n) ? '\n' : ':');
				}
			}
			/* should be in the library */
			else if ((sign_flag == i) && (x509req == 0)) {
				BIO_printf(bio_err, "Getting Private key\n");
				if (Upkey == NULL) {
					Upkey = load_key(bio_err,
					    keyfile, keyformat, 0,
					    passin, e, "Private key");
					if (Upkey == NULL)
						goto end;
				}
				if (!sign(x, Upkey, days, clrext, digest,
				    extconf, extsect))
					goto end;
			} else if (CA_flag == i) {
				BIO_printf(bio_err, "Getting CA Private Key\n");
				if (CAkeyfile != NULL) {
					CApkey = load_key(bio_err,
					    CAkeyfile, CAkeyformat,
					    0, passin, e,
					    "CA Private Key");
					if (CApkey == NULL)
						goto end;
				}
				if (!x509_certify(ctx, CAfile, digest, x, xca,
				    CApkey, sigopts,
				    CAserial, CA_createserial, days, clrext,
				    extconf, extsect, sno))
					goto end;
			} else if (x509req == i) {
				EVP_PKEY *pk;

				BIO_printf(bio_err, "Getting request Private Key\n");
				if (keyfile == NULL) {
					BIO_printf(bio_err, "no request key file specified\n");
					goto end;
				} else {
					pk = load_key(bio_err,
					    keyfile, keyformat, 0,
					    passin, e, "request key");
					if (pk == NULL)
						goto end;
				}

				BIO_printf(bio_err, "Generating certificate request\n");

				rq = X509_to_X509_REQ(x, pk, digest);
				EVP_PKEY_free(pk);
				if (rq == NULL) {
					ERR_print_errors(bio_err);
					goto end;
				}
				if (!noout) {
					X509_REQ_print(out, rq);
					PEM_write_bio_X509_REQ(out, rq);
				}
				noout = 1;
			} else if (ocspid == i) {
				X509_ocspid_print(out, x);
			}
		}
	}
	if (checkend) {
		time_t tcheck = time(NULL) + checkoffset;

		if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0) {
			BIO_printf(out, "Certificate will expire\n");
			ret = 1;
		} else {
			BIO_printf(out, "Certificate will not expire\n");
			ret = 0;
		}
		goto end;
	}
	if (noout) {
		ret = 0;
		goto end;
	}
	if (outformat == FORMAT_ASN1)
		i = i2d_X509_bio(out, x);
	else if (outformat == FORMAT_PEM) {
		if (trustout)
			i = PEM_write_bio_X509_AUX(out, x);
		else
			i = PEM_write_bio_X509(out, x);
	} else if (outformat == FORMAT_NETSCAPE) {
		NETSCAPE_X509 nx;
		ASN1_OCTET_STRING hdr;

		hdr.data = (unsigned char *) NETSCAPE_CERT_HDR;
		hdr.length = strlen(NETSCAPE_CERT_HDR);
		nx.header = &hdr;
		nx.cert = x;

		i = ASN1_item_i2d_bio(ASN1_ITEM_rptr(NETSCAPE_X509), out, &nx);
	} else {
		BIO_printf(bio_err, "bad output format specified for outfile\n");
		goto end;
	}
	if (!i) {
		BIO_printf(bio_err, "unable to write certificate\n");
		ERR_print_errors(bio_err);
		goto end;
	}
	ret = 0;

end:
	OBJ_cleanup();
	NCONF_free(extconf);
	BIO_free_all(out);
	BIO_free_all(STDout);
	X509_STORE_free(ctx);
	X509_REQ_free(req);
	X509_free(x);
	X509_free(xca);
	EVP_PKEY_free(Upkey);
	EVP_PKEY_free(CApkey);
	if (sigopts)
		sk_OPENSSL_STRING_free(sigopts);
	X509_REQ_free(rq);
	ASN1_INTEGER_free(sno);
	sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
	sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
	free(passin);

	return (ret);
}