예제 #1
0
/*
 * Creates a x509v3 extension containing a hash
 *
 * DigestInfo ::= SEQUENCE {
 *     digestAlgorithm  AlgorithmIdentifier,
 *     digest           OCTET STRING
 * }
 *
 * AlgorithmIdentifier ::=  SEQUENCE  {
 *     algorithm        OBJECT IDENTIFIER,
 *     parameters       ANY DEFINED BY algorithm OPTIONAL
 * }
 *
 * Parameters:
 *   nid: extension identifier
 *   crit: extension critical (EXT_NON_CRIT, EXT_CRIT)
 *   md: hash algorithm
 *   buf: pointer to the buffer that contains the hash
 *   len: size of the hash in bytes
 *
 * Return: Extension address, NULL if error
 */
X509_EXTENSION *ext_new_hash(int nid, int crit, const EVP_MD *md,
		unsigned char *buf, size_t len)
{
	X509_EXTENSION *ex;
	ASN1_OCTET_STRING *octet;
	HASH *hash;
	ASN1_OBJECT *algorithm;
	X509_ALGOR *x509_algor;
	unsigned char *p = NULL;
	int sz;

	/* OBJECT_IDENTIFIER with hash algorithm */
	algorithm = OBJ_nid2obj(EVP_MD_type(md));
	if (algorithm == NULL) {
		return NULL;
	}

	/* Create X509_ALGOR */
	x509_algor = X509_ALGOR_new();
	if (x509_algor == NULL) {
		return NULL;
	}
	x509_algor->algorithm = algorithm;
	x509_algor->parameter = ASN1_TYPE_new();
	ASN1_TYPE_set(x509_algor->parameter, V_ASN1_NULL, NULL);

	/* OCTET_STRING with the actual hash */
	octet = ASN1_OCTET_STRING_new();
	if (octet == NULL) {
		X509_ALGOR_free(x509_algor);
		return NULL;
	}
	ASN1_OCTET_STRING_set(octet, buf, len);

	/* HASH structure containing algorithm + hash */
	hash = HASH_new();
	if (hash == NULL) {
		ASN1_OCTET_STRING_free(octet);
		X509_ALGOR_free(x509_algor);
		return NULL;
	}
	hash->hashAlgorithm = x509_algor;
	hash->dataHash = octet;

	/* DER encoded HASH */
	sz = i2d_HASH(hash, &p);
	if ((sz <= 0) || (p == NULL)) {
		HASH_free(hash);
		X509_ALGOR_free(x509_algor);
		return NULL;
	}

	/* Create the extension */
	ex = ext_new(nid, crit, p, sz);

	/* Clean up */
	OPENSSL_free(p);
	HASH_free(hash);

	return ex;
}
예제 #2
0
파일: pk7_doit.c 프로젝트: bmeck/openssl
int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
{
    int ret = 0;
    int i, j;
    BIO *btmp;
    PKCS7_SIGNER_INFO *si;
    EVP_MD_CTX *mdc, ctx_tmp;
    STACK_OF(X509_ATTRIBUTE) *sk;
    STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
    ASN1_OCTET_STRING *os = NULL;

    if (p7 == NULL) {
        PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER);
        return 0;
    }

    if (p7->d.ptr == NULL) {
        PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT);
        return 0;
    }

    EVP_MD_CTX_init(&ctx_tmp);
    i = OBJ_obj2nid(p7->type);
    p7->state = PKCS7_S_HEADER;

    switch (i) {
    case NID_pkcs7_data:
        os = p7->d.data;
        break;
    case NID_pkcs7_signedAndEnveloped:
        /* XXXXXXXXXXXXXXXX */
        si_sk = p7->d.signed_and_enveloped->signer_info;
        os = p7->d.signed_and_enveloped->enc_data->enc_data;
        if (!os) {
            os = ASN1_OCTET_STRING_new();
            if (!os) {
                PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
                goto err;
            }
            p7->d.signed_and_enveloped->enc_data->enc_data = os;
        }
        break;
    case NID_pkcs7_enveloped:
        /* XXXXXXXXXXXXXXXX */
        os = p7->d.enveloped->enc_data->enc_data;
        if (!os) {
            os = ASN1_OCTET_STRING_new();
            if (!os) {
                PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
                goto err;
            }
            p7->d.enveloped->enc_data->enc_data = os;
        }
        break;
    case NID_pkcs7_signed:
        si_sk = p7->d.sign->signer_info;
        os = PKCS7_get_octet_string(p7->d.sign->contents);
        /* If detached data then the content is excluded */
        if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
            ASN1_OCTET_STRING_free(os);
            os = NULL;
            p7->d.sign->contents->d.data = NULL;
        }
        break;

    case NID_pkcs7_digest:
        os = PKCS7_get_octet_string(p7->d.digest->contents);
        /* If detached data then the content is excluded */
        if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) {
            ASN1_OCTET_STRING_free(os);
            os = NULL;
            p7->d.digest->contents->d.data = NULL;
        }
        break;

    default:
        PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
        goto err;
    }

    if (si_sk != NULL) {
        for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) {
            si = sk_PKCS7_SIGNER_INFO_value(si_sk, i);
            if (si->pkey == NULL)
                continue;

            j = OBJ_obj2nid(si->digest_alg->algorithm);

            btmp = bio;

            btmp = PKCS7_find_digest(&mdc, btmp, j);

            if (btmp == NULL)
                goto err;

            /*
             * We now have the EVP_MD_CTX, lets do the signing.
             */
            if (!EVP_MD_CTX_copy_ex(&ctx_tmp, mdc))
                goto err;

            sk = si->auth_attr;

            /*
             * If there are attributes, we add the digest attribute and only
             * sign the attributes
             */
            if (sk_X509_ATTRIBUTE_num(sk) > 0) {
                if (!do_pkcs7_signed_attrib(si, &ctx_tmp))
                    goto err;
            } else {
                unsigned char *abuf = NULL;
                unsigned int abuflen;
                abuflen = EVP_PKEY_size(si->pkey);
                abuf = OPENSSL_malloc(abuflen);
                if (!abuf)
                    goto err;

                if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen, si->pkey)) {
                    PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB);
                    goto err;
                }
                ASN1_STRING_set0(si->enc_digest, abuf, abuflen);
            }
        }
    } else if (i == NID_pkcs7_digest) {
        unsigned char md_data[EVP_MAX_MD_SIZE];
        unsigned int md_len;
        if (!PKCS7_find_digest(&mdc, bio,
                               OBJ_obj2nid(p7->d.digest->md->algorithm)))
            goto err;
        if (!EVP_DigestFinal_ex(mdc, md_data, &md_len))
            goto err;
        ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
    }

    if (!PKCS7_is_detached(p7)) {
        /*
         * NOTE(emilia): I think we only reach os == NULL here because detached
         * digested data support is broken.
         */
        if (os == NULL)
            goto err;
        if (!(os->flags & ASN1_STRING_FLAG_NDEF)) {
            char *cont;
            long contlen;
            btmp = BIO_find_type(bio, BIO_TYPE_MEM);
            if (btmp == NULL) {
                PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
                goto err;
            }
            contlen = BIO_get_mem_data(btmp, &cont);
            /*
             * Mark the BIO read only then we can use its copy of the data
             * instead of making an extra copy.
             */
            BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
            BIO_set_mem_eof_return(btmp, 0);
            ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
        }
    }
    ret = 1;
 err:
    EVP_MD_CTX_cleanup(&ctx_tmp);
    return (ret);
}
static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass)
{
	STACK_OF(PKCS7) *asafes, *newsafes;
	STACK_OF(PKCS12_SAFEBAG) *bags;
	int i, bagnid, pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0;
	PKCS7 *p7, *p7new;
	ASN1_OCTET_STRING *p12_data_tmp = NULL, *macnew = NULL;
	unsigned char mac[EVP_MAX_MD_SIZE];
	unsigned int maclen;

	if (!(asafes = PKCS12_unpack_authsafes(p12))) return 0;
	if(!(newsafes = sk_PKCS7_new_null())) return 0;
	for (i = 0; i < sk_PKCS7_num (asafes); i++) {
		p7 = sk_PKCS7_value(asafes, i);
		bagnid = OBJ_obj2nid(p7->type);
		if (bagnid == NID_pkcs7_data) {
			bags = PKCS12_unpack_p7data(p7);
		} else if (bagnid == NID_pkcs7_encrypted) {
			bags = PKCS12_unpack_p7encdata(p7, oldpass, -1);
			if (!alg_get(p7->d.encrypted->enc_data->algorithm,
				&pbe_nid, &pbe_iter, &pbe_saltlen))
				{
				sk_PKCS12_SAFEBAG_pop_free(bags,
						PKCS12_SAFEBAG_free);
				bags = NULL;
				}
		} else continue;
		if (!bags) {
			sk_PKCS7_pop_free(asafes, PKCS7_free);
			return 0;
		}
	    	if (!newpass_bags(bags, oldpass, newpass)) {
			sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
			sk_PKCS7_pop_free(asafes, PKCS7_free);
			return 0;
		}
		/* Repack bag in same form with new password */
		if (bagnid == NID_pkcs7_data) p7new = PKCS12_pack_p7data(bags);
		else p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1, NULL,
						 pbe_saltlen, pbe_iter, bags);
		sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
		if(!p7new) {
			sk_PKCS7_pop_free(asafes, PKCS7_free);
			return 0;
		}
		sk_PKCS7_push(newsafes, p7new);
	}
	sk_PKCS7_pop_free(asafes, PKCS7_free);

	/* Repack safe: save old safe in case of error */

	p12_data_tmp = p12->authsafes->d.data;
	if(!(p12->authsafes->d.data = ASN1_OCTET_STRING_new())) goto saferr;
	if(!PKCS12_pack_authsafes(p12, newsafes)) goto saferr;

	if(!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen)) goto saferr;
	if(!(macnew = ASN1_OCTET_STRING_new())) goto saferr;
	if(!ASN1_OCTET_STRING_set(macnew, mac, maclen)) goto saferr;
	ASN1_OCTET_STRING_free(p12->mac->dinfo->digest);
	p12->mac->dinfo->digest = macnew;
	ASN1_OCTET_STRING_free(p12_data_tmp);

	return 1;

	saferr:
	/* Restore old safe */
	ASN1_OCTET_STRING_free(p12->authsafes->d.data);
	ASN1_OCTET_STRING_free(macnew);
	p12->authsafes->d.data = p12_data_tmp;
	return 0;

}
예제 #4
0
X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
                             int prf_nid, int keylen)
{
    X509_ALGOR *keyfunc = NULL;
    PBKDF2PARAM *kdf = NULL;
    ASN1_OCTET_STRING *osalt = NULL;

    if ((kdf = PBKDF2PARAM_new()) == NULL)
        goto merr;
    if ((osalt = ASN1_OCTET_STRING_new()) == NULL)
        goto merr;

    kdf->salt->value.octet_string = osalt;
    kdf->salt->type = V_ASN1_OCTET_STRING;

    if (saltlen == 0)
        saltlen = PKCS5_SALT_LEN;
    if ((osalt->data = OPENSSL_malloc(saltlen)) == NULL)
        goto merr;

    osalt->length = saltlen;

    if (salt)
        memcpy(osalt->data, salt, saltlen);
    else if (RAND_bytes(osalt->data, saltlen) <= 0)
        goto merr;

    if (iter <= 0)
        iter = PKCS5_DEFAULT_ITER;

    if (!ASN1_INTEGER_set(kdf->iter, iter))
        goto merr;

    /* If have a key len set it up */

    if (keylen > 0) {
        if ((kdf->keylength = ASN1_INTEGER_new()) == NULL)
            goto merr;
        if (!ASN1_INTEGER_set(kdf->keylength, keylen))
            goto merr;
    }

    /* prf can stay NULL if we are using hmacWithSHA1 */
    if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1) {
        kdf->prf = X509_ALGOR_new();
        if (!kdf->prf)
            goto merr;
        X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid), V_ASN1_NULL, NULL);
    }

    /* Finally setup the keyfunc structure */

    keyfunc = X509_ALGOR_new();
    if (!keyfunc)
        goto merr;

    keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);

    /* Encode PBKDF2PARAM into parameter of pbe2 */

    if (!ASN1_TYPE_pack_sequence(ASN1_ITEM_rptr(PBKDF2PARAM), kdf,
                                 &keyfunc->parameter))
         goto merr;

    PBKDF2PARAM_free(kdf);
    return keyfunc;

 merr:
    ASN1err(ASN1_F_PKCS5_PBKDF2_SET, ERR_R_MALLOC_FAILURE);
    PBKDF2PARAM_free(kdf);
    X509_ALGOR_free(keyfunc);
    return NULL;
}
예제 #5
0
static void *ocsp_nonce_new(void)
{
    return ASN1_OCTET_STRING_new();
}
예제 #6
0
static int rsa_cms_encrypt(CMS_RecipientInfo *ri)
{
    const EVP_MD *md, *mgf1md;
    RSA_OAEP_PARAMS *oaep = NULL;
    ASN1_STRING *os = NULL;
    X509_ALGOR *alg;
    EVP_PKEY_CTX *pkctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
    int pad_mode = RSA_PKCS1_PADDING, rv = 0, labellen;
    unsigned char *label;

    CMS_RecipientInfo_ktri_get0_algs(ri, NULL, NULL, &alg);
    if (pkctx) {
        if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0)
            return 0;
    }
    if (pad_mode == RSA_PKCS1_PADDING) {
        X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
        return 1;
    }
    /* Not supported */
    if (pad_mode != RSA_PKCS1_OAEP_PADDING)
        return 0;
    if (EVP_PKEY_CTX_get_rsa_oaep_md(pkctx, &md) <= 0)
        goto err;
    if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0)
        goto err;
    labellen = EVP_PKEY_CTX_get0_rsa_oaep_label(pkctx, &label);
    if (labellen < 0)
        goto err;
    oaep = RSA_OAEP_PARAMS_new();
    if (oaep == NULL)
        goto err;
    if (!rsa_md_to_algor(&oaep->hashFunc, md))
        goto err;
    if (!rsa_md_to_mgf1(&oaep->maskGenFunc, mgf1md))
        goto err;
    if (labellen > 0) {
        ASN1_OCTET_STRING *los;
        oaep->pSourceFunc = X509_ALGOR_new();
        if (oaep->pSourceFunc == NULL)
            goto err;
        los = ASN1_OCTET_STRING_new();
        if (los == NULL)
            goto err;
        if (!ASN1_OCTET_STRING_set(los, label, labellen)) {
            ASN1_OCTET_STRING_free(los);
            goto err;
        }
        X509_ALGOR_set0(oaep->pSourceFunc, OBJ_nid2obj(NID_pSpecified),
                        V_ASN1_OCTET_STRING, los);
    }
    /* create string with pss parameter encoding. */
    if (!ASN1_item_pack(oaep, ASN1_ITEM_rptr(RSA_OAEP_PARAMS), &os))
         goto err;
    X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaesOaep), V_ASN1_SEQUENCE, os);
    os = NULL;
    rv = 1;
 err:
    RSA_OAEP_PARAMS_free(oaep);
    ASN1_STRING_free(os);
    return rv;
}
예제 #7
0
파일: pk7_lib.c 프로젝트: AndreV84/openssl
int PKCS7_set_type(PKCS7 *p7, int type)
{
    ASN1_OBJECT *obj;

    /*
     * PKCS7_content_free(p7);
     */
    obj = OBJ_nid2obj(type);    /* will not fail */

    switch (type) {
    case NID_pkcs7_signed:
        p7->type = obj;
        if ((p7->d.sign = PKCS7_SIGNED_new()) == NULL)
            goto err;
        if (!ASN1_INTEGER_set(p7->d.sign->version, 1)) {
            PKCS7_SIGNED_free(p7->d.sign);
            p7->d.sign = NULL;
            goto err;
        }
        break;
    case NID_pkcs7_data:
        p7->type = obj;
        if ((p7->d.data = ASN1_OCTET_STRING_new()) == NULL)
            goto err;
        break;
    case NID_pkcs7_signedAndEnveloped:
        p7->type = obj;
        if ((p7->d.signed_and_enveloped = PKCS7_SIGN_ENVELOPE_new())
            == NULL)
            goto err;
        ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1);
        if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1))
            goto err;
        p7->d.signed_and_enveloped->enc_data->content_type
            = OBJ_nid2obj(NID_pkcs7_data);
        break;
    case NID_pkcs7_enveloped:
        p7->type = obj;
        if ((p7->d.enveloped = PKCS7_ENVELOPE_new())
            == NULL)
            goto err;
        if (!ASN1_INTEGER_set(p7->d.enveloped->version, 0))
            goto err;
        p7->d.enveloped->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data);
        break;
    case NID_pkcs7_encrypted:
        p7->type = obj;
        if ((p7->d.encrypted = PKCS7_ENCRYPT_new())
            == NULL)
            goto err;
        if (!ASN1_INTEGER_set(p7->d.encrypted->version, 0))
            goto err;
        p7->d.encrypted->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data);
        break;

    case NID_pkcs7_digest:
        p7->type = obj;
        if ((p7->d.digest = PKCS7_DIGEST_new())
            == NULL)
            goto err;
        if (!ASN1_INTEGER_set(p7->d.digest->version, 0))
            goto err;
        break;
    default:
        PKCS7err(PKCS7_F_PKCS7_SET_TYPE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
        goto err;
    }
    return (1);
 err:
    return (0);
}
예제 #8
0
static int dsa_pkey2pkcs8(PKCS8_PRIV_KEY_INFO *p8, EVP_PKEY *pkey)
{
    ASN1_STRING *params;
    ASN1_INTEGER *prkey;
    ASN1_TYPE *ttmp;
    STACK_OF(ASN1_TYPE) *ndsa;
    unsigned char *p, *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_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
        PKCS8_PRIV_KEY_INFO_free (p8);
        return 0;
    }
    q = p;
    i2d_DSAparams (pkey->pkey.dsa, &q);
    params = ASN1_STRING_new();
    ASN1_STRING_set(params, p, len);
    OPENSSL_free(p);
    /* Get private key into integer */
    if (!(prkey = BN_to_ASN1_INTEGER (pkey->pkey.dsa->priv_key, NULL))) {
        EVPerr(EVP_F_EVP_PKEY2PKCS8,EVP_R_ENCODE_ERROR);
        return 0;
    }

    switch(p8->broken) {

    case PKCS8_OK:
    case PKCS8_NO_OCTET:

        if (!ASN1_pack_string((char *)prkey, i2d_ASN1_INTEGER,
                              &p8->pkey->value.octet_string)) {
            EVPerr(EVP_F_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
            M_ASN1_INTEGER_free (prkey);
            return 0;
        }

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

        break;

    case PKCS8_NS_DB:

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

        ttmp = ASN1_TYPE_new();
        ttmp->value.integer = prkey;
        ttmp->type = V_ASN1_INTEGER;
        sk_ASN1_TYPE_push(ndsa, ttmp);

        p8->pkey->value.octet_string = ASN1_OCTET_STRING_new();

        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_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
            sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
            M_ASN1_INTEGER_free(prkey);
            return 0;
        }
        sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
        break;

    case PKCS8_EMBEDDED_PARAM:

        p8->pkeyalg->parameter->type = V_ASN1_NULL;
        ndsa = sk_ASN1_TYPE_new_null();
        ttmp = ASN1_TYPE_new();
        ttmp->value.sequence = params;
        ttmp->type = V_ASN1_SEQUENCE;
        sk_ASN1_TYPE_push(ndsa, ttmp);

        ttmp = ASN1_TYPE_new();
        ttmp->value.integer = prkey;
        ttmp->type = V_ASN1_INTEGER;
        sk_ASN1_TYPE_push(ndsa, ttmp);

        p8->pkey->value.octet_string = ASN1_OCTET_STRING_new();

        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_EVP_PKEY2PKCS8,ERR_R_MALLOC_FAILURE);
            sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
            M_ASN1_INTEGER_free (prkey);
            return 0;
        }
        sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
        break;
    }
    return 1;
}