int i2d_ASN1_SET(STACK *a, unsigned char **pp, int (*func)(), int ex_tag,
	     int ex_class, int is_set)
	{
	int ret=0,r;
	int i;
	unsigned char *p;
        unsigned char *pStart, *pTempMem;
        MYBLOB *rgSetBlob;
        int totSize;
	if (a == NULL) return(0);
	for (i=sk_num(a)-1; i>=0; i--)
		ret+=func(sk_value(a,i),NULL);
	r=ASN1_object_size(1,ret,ex_tag);
	if (pp == NULL) return(r);
	p= *pp;
	ASN1_put_object(&p,1,ret,ex_tag,ex_class);
	if(!is_set || (sk_num(a) < 2))
		{
		for (i=0; i<sk_num(a); i++)
                	func(sk_value(a,i),&p);
		*pp=p;
		return(r);
		}
        pStart  = p;
        rgSetBlob = (MYBLOB *)Malloc( sk_num(a) * sizeof(MYBLOB));
        for (i=0; i<sk_num(a); i++)
	        {
                rgSetBlob[i].pbData = p;
                func(sk_value(a,i),&p);
                rgSetBlob[i].cbData = p - rgSetBlob[i].pbData;
		}
        *pp=p;
        totSize = p - pStart;
        qsort( rgSetBlob, sk_num(a), sizeof(MYBLOB), SetBlobCmp);
        pTempMem = Malloc(totSize);
        p = pTempMem;
        for(i=0; i<sk_num(a); ++i)
		{
                memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData);
                p += rgSetBlob[i].cbData;
		}
        memcpy(pStart, pTempMem, totSize);
        Free(pTempMem);
        Free(rgSetBlob);
        return(r);
        }
['PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,\n\t\t\t\t\t\t\tBIO *data, int flags)\n{\n\tPKCS7 *p7;\n\tPKCS7_SIGNER_INFO *si;\n\tBIO *p7bio;\n\tSTACK *smcap;\n\tint i;\n\tif(!X509_check_private_key(signcert, pkey)) {\n\t\tPKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);\n                return NULL;\n\t}\n\tif(!(p7 = PKCS7_new())) {\n\t\tPKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);\n\t\treturn NULL;\n\t}\n\tPKCS7_set_type(p7, NID_pkcs7_signed);\n\tPKCS7_content_new(p7, NID_pkcs7_data);\n    \tif (!(si = PKCS7_add_signature(p7,signcert,pkey,EVP_sha1()))) {\n\t\tPKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR);\n\t\treturn NULL;\n\t}\n\tif(!(flags & PKCS7_NOCERTS)) {\n\t\tPKCS7_add_certificate(p7, signcert);\n\t\tif(certs) for(i = 0; i < sk_X509_num(certs); i++)\n\t\t\tPKCS7_add_certificate(p7, sk_X509_value(certs, i));\n\t}\n\tif(!(p7bio = PKCS7_dataInit(p7, NULL))) {\n\t\tPKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);\n\t\treturn NULL;\n\t}\n\tSMIME_crlf_copy(data, p7bio, flags);\n\tif(!(flags & PKCS7_NOATTR)) {\n\t\tPKCS7_add_signed_attribute(si, NID_pkcs9_contentType,\n\t\t\t\tV_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data));\n\t\tif(!(smcap = sk_new(NULL))) {\n\t\t\tPKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);\n\t\t\treturn NULL;\n\t\t}\n#ifndef NO_DES\n\t\tPKCS7_simple_smimecap (smcap, NID_des_ede3_cbc, -1);\n#endif\n#ifndef NO_RC2\n\t\tPKCS7_simple_smimecap (smcap, NID_rc2_cbc, 128);\n\t\tPKCS7_simple_smimecap (smcap, NID_rc2_cbc, 64);\n#endif\n#ifndef NO_DES\n\t\tPKCS7_simple_smimecap (smcap, NID_des_cbc, -1);\n#endif\n#ifndef NO_RC2\n\t\tPKCS7_simple_smimecap (smcap, NID_rc2_cbc, 40);\n#endif\n\t\tPKCS7_add_attrib_smimecap (si, smcap);\n\t\tsk_pop_free(smcap, X509_ALGOR_free);\n\t}\n\tif(flags & PKCS7_DETACHED)PKCS7_set_detached(p7, 1);\n        if (!PKCS7_dataFinal(p7,p7bio)) {\n\t\tPKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_DATASIGN);\n\t\treturn NULL;\n\t}\n        BIO_free_all(p7bio);\n\treturn p7;\n}', 'STACK *sk_new(int (*c)())\n\t{\n\tSTACK *ret;\n\tint i;\n\tif ((ret=(STACK *)Malloc(sizeof(STACK))) == NULL)\n\t\tgoto err0;\n\tif ((ret->data=(char **)Malloc(sizeof(char *)*MIN_NODES)) == NULL)\n\t\tgoto err1;\n\tfor (i=0; i<MIN_NODES; i++)\n\t\tret->data[i]=NULL;\n\tret->comp=c;\n\tret->num_alloc=MIN_NODES;\n\tret->num=0;\n\tret->sorted=0;\n\treturn(ret);\nerr1:\n\tFree((char *)ret);\nerr0:\n\treturn(NULL);\n\t}', 'int PKCS7_simple_smimecap(STACK *sk, int nid, int arg)\n{\n\tX509_ALGOR *alg;\n\tif(!(alg = X509_ALGOR_new())) {\n\t\tPKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);\n\t\treturn 0;\n\t}\n\tASN1_OBJECT_free(alg->algorithm);\n\talg->algorithm = OBJ_nid2obj (nid);\n\tif (arg > 0) {\n\t\tASN1_INTEGER *nbit;\n\t\tif(!(alg->parameter = ASN1_TYPE_new())) {\n\t\t\tPKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);\n\t\t\treturn 0;\n\t\t}\n\t\tif(!(nbit = ASN1_INTEGER_new())) {\n\t\t\tPKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);\n\t\t\treturn 0;\n\t\t}\n\t\tif(!ASN1_INTEGER_set (nbit, arg)) {\n\t\t\tPKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP,ERR_R_MALLOC_FAILURE);\n\t\t\treturn 0;\n\t\t}\n\t\talg->parameter->value.integer = nbit;\n\t\talg->parameter->type = V_ASN1_INTEGER;\n\t}\n\tsk_push (sk, (char *)alg);\n\treturn 1;\n}', 'int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, STACK *cap)\n{\n\tASN1_STRING *seq;\n\tunsigned char *p, *pp;\n\tint len;\n\tlen=i2d_ASN1_SET(cap,NULL,i2d_X509_ALGOR, V_ASN1_SEQUENCE,\n\t\t\t\t\t\tV_ASN1_UNIVERSAL, IS_SEQUENCE);\n\tif(!(pp=(unsigned char *)Malloc(len))) {\n\t\tPKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);\n\t\treturn 0;\n\t}\n\tp=pp;\n\ti2d_ASN1_SET(cap,&p,i2d_X509_ALGOR, V_ASN1_SEQUENCE,\n\t\t\t\t\t\tV_ASN1_UNIVERSAL, IS_SEQUENCE);\n\tif(!(seq = ASN1_STRING_new())) {\n\t\tPKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);\n\t\treturn 0;\n\t}\n\tif(!ASN1_STRING_set (seq, pp, len)) {\n\t\tPKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);\n\t\treturn 0;\n\t}\n\tFree (pp);\n        return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities,\n\t\t\t\t\t\t\tV_ASN1_SEQUENCE, seq);\n}', 'int i2d_ASN1_SET(STACK *a, unsigned char **pp, int (*func)(), int ex_tag,\n\t     int ex_class, int is_set)\n\t{\n\tint ret=0,r;\n\tint i;\n\tunsigned char *p;\n        unsigned char *pStart, *pTempMem;\n        MYBLOB *rgSetBlob;\n        int totSize;\n\tif (a == NULL) return(0);\n\tfor (i=sk_num(a)-1; i>=0; i--)\n\t\tret+=func(sk_value(a,i),NULL);\n\tr=ASN1_object_size(1,ret,ex_tag);\n\tif (pp == NULL) return(r);\n\tp= *pp;\n\tASN1_put_object(&p,1,ret,ex_tag,ex_class);\n\tif(!is_set || (sk_num(a) < 2))\n\t\t{\n\t\tfor (i=0; i<sk_num(a); i++)\n                \tfunc(sk_value(a,i),&p);\n\t\t*pp=p;\n\t\treturn(r);\n\t\t}\n        pStart  = p;\n        rgSetBlob = (MYBLOB *)Malloc( sk_num(a) * sizeof(MYBLOB));\n        for (i=0; i<sk_num(a); i++)\n\t        {\n                rgSetBlob[i].pbData = p;\n                func(sk_value(a,i),&p);\n                rgSetBlob[i].cbData = p - rgSetBlob[i].pbData;\n\t\t}\n        *pp=p;\n        totSize = p - pStart;\n        qsort( rgSetBlob, sk_num(a), sizeof(MYBLOB), SetBlobCmp);\n        pTempMem = Malloc(totSize);\n        p = pTempMem;\n        for(i=0; i<sk_num(a); ++i)\n\t\t{\n                memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData);\n                p += rgSetBlob[i].cbData;\n\t\t}\n        memcpy(pStart, pTempMem, totSize);\n        Free(pTempMem);\n        Free(rgSetBlob);\n        return(r);\n        }', 'int sk_num(STACK *st)\n{\n\tif(st == NULL) return -1;\n\treturn st->num;\n}']