示例#1
0
文件: dh_ameth.c 项目: Orav/kbengine
static int dh_cms_encrypt(CMS_RecipientInfo *ri)
{
    EVP_PKEY_CTX *pctx;
    EVP_PKEY *pkey;
    EVP_CIPHER_CTX *ctx;
    int keylen;
    X509_ALGOR *talg, *wrap_alg = NULL;
    ASN1_OBJECT *aoid;
    ASN1_BIT_STRING *pubkey;
    ASN1_STRING *wrap_str;
    ASN1_OCTET_STRING *ukm;
    unsigned char *penc = NULL, *dukm = NULL;
    int penclen;
    size_t dukmlen = 0;
    int rv = 0;
    int kdf_type, wrap_nid;
    const EVP_MD *kdf_md;
    pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
    if (!pctx)
        return 0;
    /* Get ephemeral key */
    pkey = EVP_PKEY_CTX_get0_pkey(pctx);
    if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
                                             NULL, NULL, NULL))
        goto err;
    X509_ALGOR_get0(&aoid, NULL, NULL, talg);
    /* Is everything uninitialised? */
    if (aoid == OBJ_nid2obj(NID_undef)) {
        ASN1_INTEGER *pubk;
        pubk = BN_to_ASN1_INTEGER(pkey->pkey.dh->pub_key, NULL);
        if (!pubk)
            goto err;
        /* Set the key */

        penclen = i2d_ASN1_INTEGER(pubk, &penc);
        ASN1_INTEGER_free(pubk);
        if (penclen <= 0)
            goto err;
        ASN1_STRING_set0(pubkey, penc, penclen);
        pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
        pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT;

        penc = NULL;
        X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber),
                        V_ASN1_UNDEF, NULL);
    }

    /* See if custom paraneters set */
    kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx);
    if (kdf_type <= 0)
        goto err;
    if (!EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md))
        goto err;

    if (kdf_type == EVP_PKEY_DH_KDF_NONE) {
        kdf_type = EVP_PKEY_DH_KDF_X9_42;
        if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, kdf_type) <= 0)
            goto err;
    } else if (kdf_type != EVP_PKEY_DH_KDF_X9_42)
        /* Unknown KDF */
        goto err;
    if (kdf_md == NULL) {
        /* Only SHA1 supported */
        kdf_md = EVP_sha1();
        if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, kdf_md) <= 0)
            goto err;
    } else if (EVP_MD_type(kdf_md) != NID_sha1)
        /* Unsupported digest */
        goto err;

    if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
        goto err;

    /* Get wrap NID */
    ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
    wrap_nid = EVP_CIPHER_CTX_type(ctx);
    if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(wrap_nid)) <= 0)
        goto err;
    keylen = EVP_CIPHER_CTX_key_length(ctx);

    /* Package wrap algorithm in an AlgorithmIdentifier */

    wrap_alg = X509_ALGOR_new();
    if (!wrap_alg)
        goto err;
    wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
    wrap_alg->parameter = ASN1_TYPE_new();
    if (!wrap_alg->parameter)
        goto err;
    if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
        goto err;
    if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) {
        ASN1_TYPE_free(wrap_alg->parameter);
        wrap_alg->parameter = NULL;
    }

    if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0)
        goto err;

    if (ukm) {
        dukmlen = ASN1_STRING_length(ukm);
        dukm = BUF_memdup(ASN1_STRING_data(ukm), dukmlen);
        if (!dukm)
            goto err;
    }

    if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0)
        goto err;
    dukm = NULL;

    /*
     * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter
     * of another AlgorithmIdentifier.
     */
    penc = NULL;
    penclen = i2d_X509_ALGOR(wrap_alg, &penc);
    if (!penc || !penclen)
        goto err;
    wrap_str = ASN1_STRING_new();
    if (!wrap_str)
        goto err;
    ASN1_STRING_set0(wrap_str, penc, penclen);
    penc = NULL;
    X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH),
                    V_ASN1_SEQUENCE, wrap_str);

    rv = 1;

 err:
    if (penc)
        OPENSSL_free(penc);
    if (wrap_alg)
        X509_ALGOR_free(wrap_alg);
    return rv;
}
示例#2
0
int
main (int ac, char **av)
{
	FILE		*f_in;
	FILE		*f_out;
	UINT32		proofLen;
	BYTE		*proof;
	BYTE		*pub;
	UINT32		pubLen;
	BYTE		*certs;
	UINT32		certsLen;
	UINT32		certLen;
	BYTE		key[128/8];
	BYTE		iv[16];
	BYTE		asymPlain[8 + sizeof(key) + SHA_DIGEST_LENGTH];
	unsigned char oaepPad[4] = "TCPA";
	BYTE		*asymPadded;
	UINT32		asymPaddedLength;
	BYTE		*asymEnc;
	UINT32		asymEncLength;
	BYTE		*chal;
	UINT32		chalLen;
	BYTE		*symEnc;
	UINT32		symEncLength;
	BYTE		*symAttest;
	UINT32		symAttestLength;
	EVP_CIPHER_CTX ctx;
	X509		*ekX509;
	X509_NAME	*ekSubj;
	EVP_PKEY	*ekPkey;
	RSA			*ekRsa;
	RSA			*aikRsa;
	UINT32		tt[1];
	int			trousersIVMode = 1;
	int			out1, out2;
	int			nCerts;
	int			result;

	if (ac != 5) {
		fprintf (stderr, "Usage: %s secretfile aikprooffile outchallengefile outrsafile\n", av[0]);
		exit (1);
	}

	/* Read challenge */
	if ((f_in = fopen (av[1], "rb")) == NULL) {
		fprintf (stderr, "Unable to open file %s\n", av[1]);
		exit (1);
	}
	fseek (f_in, 0, SEEK_END);
	chalLen = ftell (f_in);
	fseek (f_in, 0, SEEK_SET);
	chal = malloc (chalLen);
	if (fread (chal, 1, chalLen, f_in) != chalLen) {
		fprintf (stderr, "Unable to read file %s\n", av[1]);
		exit (1);
	}
	fclose (f_in);

	/* Read AIK proof */
	if ((f_in = fopen (av[2], "rb")) == NULL) {
		fprintf (stderr, "Unable to open file %s\n", av[2]);
		exit (1);
	}
	fseek (f_in, 0, SEEK_END);
	proofLen = ftell (f_in);
	fseek (f_in, 0, SEEK_SET);
	proof = malloc (proofLen);
	if (fread (proof, 1, proofLen, f_in) != proofLen) {
		fprintf (stderr, "Unable to read file %s\n", av[2]);
		exit (1);
	}
	fclose (f_in);

	if (proofLen < 3)
		goto badproof;
	pubLen = ntohl (*(UINT32*)proof);
	if (pubLen + 4 + 4 > proofLen)
		goto badproof;
	pub = proof + 4;
	proof += pubLen+4;
	proofLen -= pubLen+4;

	certsLen = ntohl (*(UINT32*)proof);
	if (certsLen + 4 != proofLen)
		goto badproof;
	proof += 4;
	certs = proof;

	nCerts = 0;
	for ( ; ; ) {
		++nCerts;
		if (certsLen < 3)
			goto badproof;
		certLen = (proof[0]<<16) | (proof[1]<<8) | proof[2];
		if (certLen + 3 > certsLen)
			goto badproof;
		proof += certLen + 3;
		certsLen -= certLen + 3;
		if (certsLen == 0)
			break;
	}

	if (verifyCertChain (trustedRoot, sizeof(trustedRoot), nCerts, certs) != 0) {
		fprintf (stderr, "Unable to validate certificate chain in proof file\n");
		exit (1);
	}

	/* Pull endorsement key from 1st cert */
	certLen = (certs[0]<<16) | (certs[1]<<8) | certs[2];
	certs += 3;
	if ((ekX509 = d2i_X509 (NULL, (unsigned char const **)&certs, certLen)) == NULL)
		goto badproof;
	/* One last check: EK certs must have empty subject fields */
	if ((ekSubj = X509_get_subject_name (ekX509)) == NULL)
		goto badproof;
	if (X509_NAME_entry_count (ekSubj) != 0)
		goto badproof;
	/* OpenSSL can't parse EK key due to OAEP OID - fix it */
	{
		X509_PUBKEY *pk = X509_get_X509_PUBKEY(ekX509);
		int algbufLen = i2d_X509_ALGOR(pk->algor, NULL);
		unsigned char *algbuf = malloc(algbufLen);
		unsigned char *algbufPtr = algbuf;
		i2d_X509_ALGOR(pk->algor, &algbufPtr);
		if (algbuf[12] == 7)
			algbuf[12] = 1;
		algbufPtr = algbuf;
		d2i_X509_ALGOR(&pk->algor, (void *)&algbufPtr, algbufLen);
		free (algbuf);
	}
	if ((ekPkey = X509_get_pubkey (ekX509)) == NULL)
		goto badproof;
	if ((ekRsa = EVP_PKEY_get1_RSA (ekPkey)) == NULL)
		goto badproof;

	/* Construct encrypted output challenge */
	RAND_bytes (key, sizeof(key));
	RAND_bytes (iv, sizeof(iv));

	/* Prepare buffer to be RSA encrypted to endorsement key */
	((UINT32 *)asymPlain)[0] = htonl(TPM_ALG_AES);
	((UINT16 *)asymPlain)[2] = htons(TPM_ES_SYM_CBC_PKCS5PAD);
	((UINT16 *)asymPlain)[3] = htons(sizeof(key));
	memcpy (asymPlain+8, key, sizeof(key));
	SHA1 (pub, pubLen, asymPlain + 8 + sizeof(key));

	/* Encrypt to EK */
	/* Must use custom padding for TPM to decrypt it */
	asymPaddedLength = asymEncLength = RSA_size (ekRsa);
	asymPadded = malloc (asymPaddedLength);
	asymEnc = malloc (asymEncLength);
	RSA_padding_add_PKCS1_OAEP(asymPadded, asymPaddedLength, asymPlain,
					sizeof(asymPlain), oaepPad, sizeof(oaepPad));
	RSA_public_encrypt (asymPaddedLength, asymPadded, asymEnc, ekRsa, RSA_NO_PADDING);
	free (asymPadded);
	asymPadded = NULL;

	/* Encrypt challenge with key */
	symEnc = malloc (chalLen + sizeof(iv));
	EVP_CIPHER_CTX_init (&ctx);
	EVP_EncryptInit(&ctx, EVP_aes_128_cbc(), key, iv);
	EVP_EncryptUpdate (&ctx, symEnc, &out1, chal, chalLen);
	EVP_EncryptFinal_ex (&ctx, symEnc+out1, &out2);
	EVP_CIPHER_CTX_cleanup(&ctx);
	symEncLength = out1 + out2;

	/* Create TPM_SYM_CA_ATTESTATION struct to hold encrypted cert */
	symAttestLength = 28 + sizeof(iv) + symEncLength;
	symAttest = malloc (symAttestLength);
	((UINT32 *)symAttest)[0] = htonl(symEncLength);
	((UINT32 *)symAttest)[1] = htonl(TPM_ALG_AES);
	((UINT16 *)symAttest)[4] = htons(TPM_ES_SYM_CBC_PKCS5PAD);
	((UINT16 *)symAttest)[5] = htons(TPM_SS_NONE);
	((UINT32 *)symAttest)[3] = htonl(12+sizeof(iv));
	((UINT32 *)symAttest)[4] = htonl(128);		/* Key length in bits */
	((UINT32 *)symAttest)[5] = htonl(sizeof(iv));	/* Block size in bytes */
	((UINT32 *)symAttest)[6] = htonl(sizeof(iv));	/* IV size in bytes */
	memcpy (symAttest+28, iv, sizeof(iv));
	memcpy (symAttest+28+sizeof(iv), symEnc, symEncLength);
	if (trousersIVMode) {
		((UINT32 *)symAttest)[0] = htonl(symEncLength + sizeof(iv));
		((UINT32 *)symAttest)[3] = htonl(12);		/* Take IV to be start of symEnc */
		((UINT32 *)symAttest)[6] = htonl(0);		/* IV size in bytes */
	}
	free (symEnc);
	symEnc = NULL;

	if ((f_out = fopen (av[3], "wb")) == NULL) {
		fprintf (stderr, "Unable to open file %s for output\n", av[3]);
		exit (1);
	}
	/* Precede the two blocks with 4-byte lengths */
	tt[0] = htonl (asymEncLength);
	fwrite (tt, 1, sizeof(UINT32), f_out);
	fwrite (asymEnc, 1, asymEncLength, f_out);
	tt[0] = htonl (symAttestLength);
	fwrite (tt, 1, sizeof(UINT32), f_out);
	if (fwrite (symAttest, 1, symAttestLength, f_out) != symAttestLength) {
		fprintf (stderr, "Unable to write to file %s\n", av[3]);
		exit (1);
	}
	fclose (f_out);

	/* Output RSA key representing the AIK for future use */
	if ((f_out = fopen (av[4], "wb")) == NULL) {
		fprintf (stderr, "Unable to open file %s for output\n", av[4]);
		exit (1);
	}
	aikRsa = RSA_new();
	aikRsa->n = BN_bin2bn (pub+pubLen-256, 256, NULL);
	aikRsa->e = BN_new();
	BN_set_word (aikRsa->e, 0x10001);
	if (PEM_write_RSA_PUBKEY(f_out, aikRsa) < 0) {
		fprintf (stderr, "Unable to write to file %s\n", av[3]);
		exit (1);
	}
	fclose (f_out);

	printf ("Success!\n");
	return 0;

badproof:
	fprintf (stderr, "Input AIK proof file incorrect format\n");
	return 1;
}
示例#3
0
static int ecdh_cms_encrypt(CMS_RecipientInfo *ri)
{
    EVP_PKEY_CTX *pctx;
    EVP_PKEY *pkey;
    EVP_CIPHER_CTX *ctx;
    int keylen;
    X509_ALGOR *talg, *wrap_alg = NULL;
    ASN1_OBJECT *aoid;
    ASN1_BIT_STRING *pubkey;
    ASN1_STRING *wrap_str;
    ASN1_OCTET_STRING *ukm;
    unsigned char *penc = NULL;
    int penclen;
    int rv = 0;
    int ecdh_nid, kdf_type, kdf_nid, wrap_nid;
    const EVP_MD *kdf_md;
    pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
    if (!pctx)
        return 0;
    /* Get ephemeral key */
    pkey = EVP_PKEY_CTX_get0_pkey(pctx);
    if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
                                             NULL, NULL, NULL))
        goto err;
    X509_ALGOR_get0(&aoid, NULL, NULL, talg);
    /* Is everything uninitialised? */
    if (aoid == OBJ_nid2obj(NID_undef)) {

        EC_KEY *eckey = pkey->pkey.ec;
        /* Set the key */
        unsigned char *p;

        penclen = i2o_ECPublicKey(eckey, NULL);
        if (penclen <= 0)
            goto err;
        penc = OPENSSL_malloc(penclen);
        if (!penc)
            goto err;
        p = penc;
        penclen = i2o_ECPublicKey(eckey, &p);
        if (penclen <= 0)
            goto err;
        ASN1_STRING_set0(pubkey, penc, penclen);
        pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
        pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT;

        penc = NULL;
        X509_ALGOR_set0(talg, OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
                        V_ASN1_UNDEF, NULL);
    }

    /* See if custom paraneters set */
    kdf_type = EVP_PKEY_CTX_get_ecdh_kdf_type(pctx);
    if (kdf_type <= 0)
        goto err;
    if (!EVP_PKEY_CTX_get_ecdh_kdf_md(pctx, &kdf_md))
        goto err;
    ecdh_nid = EVP_PKEY_CTX_get_ecdh_cofactor_mode(pctx);
    if (ecdh_nid < 0)
        goto err;
    else if (ecdh_nid == 0)
        ecdh_nid = NID_dh_std_kdf;
    else if (ecdh_nid == 1)
        ecdh_nid = NID_dh_cofactor_kdf;

    if (kdf_type == EVP_PKEY_ECDH_KDF_NONE) {
        kdf_type = EVP_PKEY_ECDH_KDF_X9_62;
        if (EVP_PKEY_CTX_set_ecdh_kdf_type(pctx, kdf_type) <= 0)
            goto err;
    } else
        /* Uknown KDF */
        goto err;
    if (kdf_md == NULL) {
        /* Fixme later for better MD */
        kdf_md = EVP_sha1();
        if (EVP_PKEY_CTX_set_ecdh_kdf_md(pctx, kdf_md) <= 0)
            goto err;
    }

    if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
        goto err;

    /* Lookup NID for KDF+cofactor+digest */

    if (!OBJ_find_sigid_by_algs(&kdf_nid, EVP_MD_type(kdf_md), ecdh_nid))
        goto err;
    /* Get wrap NID */
    ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
    wrap_nid = EVP_CIPHER_CTX_type(ctx);
    keylen = EVP_CIPHER_CTX_key_length(ctx);

    /* Package wrap algorithm in an AlgorithmIdentifier */

    wrap_alg = X509_ALGOR_new();
    if (!wrap_alg)
        goto err;
    wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
    wrap_alg->parameter = ASN1_TYPE_new();
    if (!wrap_alg->parameter)
        goto err;
    if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
        goto err;
    if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) {
        ASN1_TYPE_free(wrap_alg->parameter);
        wrap_alg->parameter = NULL;
    }

    if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0)
        goto err;

    penclen = CMS_SharedInfo_encode(&penc, wrap_alg, ukm, keylen);

    if (!penclen)
        goto err;

    if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, penc, penclen) <= 0)
        goto err;
    penc = NULL;

    /*
     * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter
     * of another AlgorithmIdentifier.
     */
    penclen = i2d_X509_ALGOR(wrap_alg, &penc);
    if (!penc || !penclen)
        goto err;
    wrap_str = ASN1_STRING_new();
    if (!wrap_str)
        goto err;
    ASN1_STRING_set0(wrap_str, penc, penclen);
    penc = NULL;
    X509_ALGOR_set0(talg, OBJ_nid2obj(kdf_nid), V_ASN1_SEQUENCE, wrap_str);

    rv = 1;

 err:
    OPENSSL_free(penc);
    X509_ALGOR_free(wrap_alg);
    return rv;
}
示例#4
0
int i2d_RSA_NET(RSA *a, unsigned char **pp, int (*cb)(), int sgckey)
	{
	int i,j,l[6];
	NETSCAPE_PKEY *pkey;
	unsigned char buf[256],*zz;
	unsigned char key[EVP_MAX_KEY_LENGTH];
	EVP_CIPHER_CTX ctx;
	X509_ALGOR *alg=NULL;
	ASN1_OCTET_STRING os,os2;
	M_ASN1_I2D_vars(a);

	if (a == NULL) return(0);

#ifdef WIN32
	r=r; /* shut the damn compiler up :-) */
#endif

	os.data=os2.data=NULL;
	if ((pkey=NETSCAPE_PKEY_new()) == NULL) goto err;
	if (!ASN1_INTEGER_set(pkey->version,0)) goto err;

	if (pkey->algor->algorithm != NULL)
		ASN1_OBJECT_free(pkey->algor->algorithm);
	pkey->algor->algorithm=OBJ_nid2obj(NID_rsaEncryption);
	if ((pkey->algor->parameter=ASN1_TYPE_new()) == NULL) goto err;
	pkey->algor->parameter->type=V_ASN1_NULL;

	l[0]=i2d_RSAPrivateKey(a,NULL);
	pkey->private_key->length=l[0];

	os2.length=i2d_NETSCAPE_PKEY(pkey,NULL);
	l[1]=i2d_ASN1_OCTET_STRING(&os2,NULL);

	if ((alg=X509_ALGOR_new()) == NULL) goto err;
	if (alg->algorithm != NULL)
		ASN1_OBJECT_free(alg->algorithm);
	alg->algorithm=OBJ_nid2obj(NID_rc4);
	if ((alg->parameter=ASN1_TYPE_new()) == NULL) goto err;
	alg->parameter->type=V_ASN1_NULL;

	l[2]=i2d_X509_ALGOR(alg,NULL);
	l[3]=ASN1_object_size(1,l[2]+l[1],V_ASN1_SEQUENCE);

#ifndef CONST_STRICT
	os.data=(unsigned char *)"private-key";
#endif
	os.length=11;
	l[4]=i2d_ASN1_OCTET_STRING(&os,NULL);

	l[5]=ASN1_object_size(1,l[4]+l[3],V_ASN1_SEQUENCE);

	if (pp == NULL)
		{
		if (pkey != NULL) NETSCAPE_PKEY_free(pkey);
		if (alg != NULL) X509_ALGOR_free(alg);
		return(l[5]);
		}

	if (pkey->private_key->data != NULL)
		OPENSSL_free(pkey->private_key->data);
	if ((pkey->private_key->data=(unsigned char *)OPENSSL_malloc(l[0])) == NULL)
		{
		ASN1err(ASN1_F_I2D_NETSCAPE_RSA,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	zz=pkey->private_key->data;
	i2d_RSAPrivateKey(a,&zz);

	if ((os2.data=(unsigned char *)OPENSSL_malloc(os2.length)) == NULL)
		{
		ASN1err(ASN1_F_I2D_NETSCAPE_RSA,ERR_R_MALLOC_FAILURE);
		goto err;
		}
	zz=os2.data;
	i2d_NETSCAPE_PKEY(pkey,&zz);
		
	if (cb == NULL)
		cb=EVP_read_pw_string;
	i=cb(buf,256,"Enter Private Key password:"******"SGCKEYSALT", 10);
		i = 26;
	}
		
	EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL);
	memset(buf,0,256);

	EVP_CIPHER_CTX_init(&ctx);
	EVP_EncryptInit(&ctx,EVP_rc4(),key,NULL);
	EVP_EncryptUpdate(&ctx,os2.data,&i,os2.data,os2.length);
	EVP_EncryptFinal(&ctx,&(os2.data[i]),&j);
	EVP_CIPHER_CTX_cleanup(&ctx);

	p= *pp;
	ASN1_put_object(&p,1,l[4]+l[3],V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
	i2d_ASN1_OCTET_STRING(&os,&p);
	ASN1_put_object(&p,1,l[2]+l[1],V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
	i2d_X509_ALGOR(alg,&p);
	i2d_ASN1_OCTET_STRING(&os2,&p);
	ret=l[5];
err:
	if (os2.data != NULL) OPENSSL_free(os2.data);
	if (alg != NULL) X509_ALGOR_free(alg);
	if (pkey != NULL) NETSCAPE_PKEY_free(pkey);
	r=r;
	return(ret);
	}