p7local.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 1,432 行 · 第 1/3 页

C
1,432
字号
    }    return theTemplate;}static SEC_ChooseASN1TemplateFunc sec_attr_chooser	= sec_attr_choose_attr_value_template;static const SEC_ASN1Template sec_pkcs7_attribute_template[] = {    { SEC_ASN1_SEQUENCE,	  0, NULL, sizeof(SEC_PKCS7Attribute) },    { SEC_ASN1_OBJECT_ID,	  offsetof(SEC_PKCS7Attribute,type) },    { SEC_ASN1_DYNAMIC | SEC_ASN1_SET_OF,	  offsetof(SEC_PKCS7Attribute,values),	  &sec_attr_chooser },    { 0 }};static const SEC_ASN1Template sec_pkcs7_set_of_attribute_template[] = {    { SEC_ASN1_SET_OF, 0, sec_pkcs7_attribute_template },};/* * If you are wondering why this routine does not reorder the attributes * first, and might be tempted to make it do so, see the comment by the * call to ReorderAttributes in p7encode.c.  (Or, see who else calls this * and think long and hard about the implications of making it always * do the reordering.) */SECItem *sec_PKCS7EncodeAttributes (PRArenaPool *poolp, SECItem *dest, void *src){    return SEC_ASN1EncodeItem (poolp, dest, src,			       sec_pkcs7_set_of_attribute_template);}/* * Make sure that the order of the attributes guarantees valid DER * (which must be in lexigraphically ascending order for a SET OF); * if reordering is necessary it will be done in place (in attrs). */SECStatussec_PKCS7ReorderAttributes (SEC_PKCS7Attribute **attrs){    PRArenaPool *poolp;    int num_attrs, i, j, pass, besti;    SECItem **enc_attrs;    SEC_PKCS7Attribute **new_attrs;    /*     * I think we should not be called with NULL.  But if we are,     * call it a success anyway, because the order *is* okay.     */    PORT_Assert (attrs != NULL);    if (attrs == NULL)	return SECSuccess;    /*     * Count how many attributes we are dealing with here.     */    num_attrs = 0;    while (attrs[num_attrs] != NULL)	num_attrs++;    /*     * Again, I think we should have some attributes here.     * But if we do not, or if there is only one, then call it     * a success because it also already has a fine order.     */    PORT_Assert (num_attrs);    if (num_attrs == 0 || num_attrs == 1)	return SECSuccess;    /*     * Allocate an arena for us to work with, so it is easy to     * clean up all of the memory (fairly small pieces, really).     */    poolp = PORT_NewArena (1024);	/* XXX what is right value? */    if (poolp == NULL)	return SECFailure;		/* no memory; nothing we can do... */    /*     * Allocate arrays to hold the individual encodings which we will use     * for comparisons and the reordered attributes as they are sorted.     */    enc_attrs=(SECItem**)PORT_ArenaZAlloc(poolp, num_attrs*sizeof(SECItem *));    new_attrs = (SEC_PKCS7Attribute**)PORT_ArenaZAlloc (poolp,				  num_attrs * sizeof(SEC_PKCS7Attribute *));    if (enc_attrs == NULL || new_attrs == NULL) {	PORT_FreeArena (poolp, PR_FALSE);	return SECFailure;    }    /*     * DER encode each individual attribute.     */    for (i = 0; i < num_attrs; i++) {	enc_attrs[i] = SEC_ASN1EncodeItem (poolp, NULL, attrs[i],					   sec_pkcs7_attribute_template);	if (enc_attrs[i] == NULL) {	    PORT_FreeArena (poolp, PR_FALSE);	    return SECFailure;	}    }    /*     * Now compare and sort them; this is not the most efficient sorting     * method, but it is just fine for the problem at hand, because the     * number of attributes is (always) going to be small.     */    for (pass = 0; pass < num_attrs; pass++) {	/*	 * Find the first not-yet-accepted attribute.  (Once one is	 * sorted into the other array, it is cleared from enc_attrs.)	 */	for (i = 0; i < num_attrs; i++) {	    if (enc_attrs[i] != NULL)		break;	}	PORT_Assert (i < num_attrs);	besti = i;	/*	 * Find the lowest (lexigraphically) encoding.  One that is	 * shorter than all the rest is known to be "less" because each	 * attribute is of the same type (a SEQUENCE) and so thus the	 * first octet of each is the same, and the second octet is	 * the length (or the length of the length with the high bit	 * set, followed by the length, which also works out to always	 * order the shorter first).  Two (or more) that have the	 * same length need to be compared byte by byte until a mismatch	 * is found.	 */	for (i = besti + 1; i < num_attrs; i++) {	    if (enc_attrs[i] == NULL)	/* slot already handled */		continue;	    if (enc_attrs[i]->len != enc_attrs[besti]->len) {		if (enc_attrs[i]->len < enc_attrs[besti]->len)		    besti = i;		continue;	    }	    for (j = 0; j < enc_attrs[i]->len; j++) {		if (enc_attrs[i]->data[j] < enc_attrs[besti]->data[j]) {		    besti = i;		    break;		}	    }	    /*	     * For this not to be true, we would have to have encountered		     * two *identical* attributes, which I think we should not see.	     * So assert if it happens, but even if it does, let it go	     * through; the ordering of the two does not matter.	     */	    PORT_Assert (j < enc_attrs[i]->len);	}	/*	 * Now we have found the next-lowest one; copy it over and	 * remove it from enc_attrs.	 */	new_attrs[pass] = attrs[besti];	enc_attrs[besti] = NULL;    }    /*     * Now new_attrs has the attributes in the order we want;     * copy them back into the attrs array we started with.     */    for (i = 0; i < num_attrs; i++)	attrs[i] = new_attrs[i];    PORT_FreeArena (poolp, PR_FALSE);    return SECSuccess;}/* * End of attribute stuff. * ------------------------------------------------------------------- *//* * Templates and stuff.  Keep these at the end of the file. *//* forward declaration */static const SEC_ASN1Template *sec_pkcs7_choose_content_template(void *src_or_dest, PRBool encoding);static SEC_ChooseASN1TemplateFunc sec_pkcs7_chooser	= sec_pkcs7_choose_content_template;const SEC_ASN1Template sec_PKCS7ContentInfoTemplate[] = {    { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,	  0, NULL, sizeof(SEC_PKCS7ContentInfo) },    { SEC_ASN1_OBJECT_ID,	  offsetof(SEC_PKCS7ContentInfo,contentType) },    { SEC_ASN1_OPTIONAL | SEC_ASN1_DYNAMIC | SEC_ASN1_MAY_STREAM     | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,	  offsetof(SEC_PKCS7ContentInfo,content),	  &sec_pkcs7_chooser },    { 0 }};/* XXX These names should change from external to internal convention. */static const SEC_ASN1Template SEC_PKCS7SignerInfoTemplate[] = {    { SEC_ASN1_SEQUENCE,	  0, NULL, sizeof(SEC_PKCS7SignerInfo) },    { SEC_ASN1_INTEGER,	  offsetof(SEC_PKCS7SignerInfo,version) },    { SEC_ASN1_POINTER,	  offsetof(SEC_PKCS7SignerInfo,issuerAndSN),	  CERT_IssuerAndSNTemplate },    { SEC_ASN1_INLINE,	  offsetof(SEC_PKCS7SignerInfo,digestAlg),	  SECOID_AlgorithmIDTemplate },    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,	  offsetof(SEC_PKCS7SignerInfo,authAttr),	  sec_pkcs7_set_of_attribute_template },    { SEC_ASN1_INLINE,	  offsetof(SEC_PKCS7SignerInfo,digestEncAlg),	  SECOID_AlgorithmIDTemplate },    { SEC_ASN1_OCTET_STRING,	  offsetof(SEC_PKCS7SignerInfo,encDigest) },    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,	  offsetof(SEC_PKCS7SignerInfo,unAuthAttr),	  sec_pkcs7_set_of_attribute_template },    { 0 }};static const SEC_ASN1Template SEC_PKCS7SignedDataTemplate[] = {    { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,	  0, NULL, sizeof(SEC_PKCS7SignedData) },    { SEC_ASN1_INTEGER,	  offsetof(SEC_PKCS7SignedData,version) },    { SEC_ASN1_SET_OF,	  offsetof(SEC_PKCS7SignedData,digestAlgorithms),	  SECOID_AlgorithmIDTemplate },    { SEC_ASN1_INLINE,	  offsetof(SEC_PKCS7SignedData,contentInfo),	  sec_PKCS7ContentInfoTemplate },    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,	  offsetof(SEC_PKCS7SignedData,rawCerts),	  SEC_SetOfAnyTemplate },    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,	  offsetof(SEC_PKCS7SignedData,crls),	  CERT_SetOfSignedCrlTemplate },    { SEC_ASN1_SET_OF,	  offsetof(SEC_PKCS7SignedData,signerInfos),	  SEC_PKCS7SignerInfoTemplate },    { 0 }};static const SEC_ASN1Template SEC_PointerToPKCS7SignedDataTemplate[] = {    { SEC_ASN1_POINTER, 0, SEC_PKCS7SignedDataTemplate }};static const SEC_ASN1Template SEC_PKCS7RecipientInfoTemplate[] = {    { SEC_ASN1_SEQUENCE,	  0, NULL, sizeof(SEC_PKCS7RecipientInfo) },    { SEC_ASN1_INTEGER,	  offsetof(SEC_PKCS7RecipientInfo,version) },    { SEC_ASN1_POINTER,	  offsetof(SEC_PKCS7RecipientInfo,issuerAndSN),	  CERT_IssuerAndSNTemplate },    { SEC_ASN1_INLINE,	  offsetof(SEC_PKCS7RecipientInfo,keyEncAlg),	  SECOID_AlgorithmIDTemplate },    { SEC_ASN1_OCTET_STRING,	  offsetof(SEC_PKCS7RecipientInfo,encKey) },    { 0 }};static const SEC_ASN1Template SEC_PKCS7EncryptedContentInfoTemplate[] = {    { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,	  0, NULL, sizeof(SEC_PKCS7EncryptedContentInfo) },    { SEC_ASN1_OBJECT_ID,	  offsetof(SEC_PKCS7EncryptedContentInfo,contentType) },    { SEC_ASN1_INLINE,	  offsetof(SEC_PKCS7EncryptedContentInfo,contentEncAlg),	  SECOID_AlgorithmIDTemplate },    { SEC_ASN1_OPTIONAL | SEC_ASN1_MAY_STREAM | SEC_ASN1_CONTEXT_SPECIFIC | 0,	  offsetof(SEC_PKCS7EncryptedContentInfo,encContent),	  SEC_OctetStringTemplate },    { 0 }};static const SEC_ASN1Template SEC_PKCS7EnvelopedDataTemplate[] = {    { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,	  0, NULL, sizeof(SEC_PKCS7EnvelopedData) },    { SEC_ASN1_INTEGER,	  offsetof(SEC_PKCS7EnvelopedData,version) },    { SEC_ASN1_SET_OF,	  offsetof(SEC_PKCS7EnvelopedData,recipientInfos),	  SEC_PKCS7RecipientInfoTemplate },    { SEC_ASN1_INLINE,	  offsetof(SEC_PKCS7EnvelopedData,encContentInfo),	  SEC_PKCS7EncryptedContentInfoTemplate },    { 0 }};static const SEC_ASN1Template SEC_PointerToPKCS7EnvelopedDataTemplate[] = {    { SEC_ASN1_POINTER, 0, SEC_PKCS7EnvelopedDataTemplate }};static const SEC_ASN1Template SEC_PKCS7SignedAndEnvelopedDataTemplate[] = {    { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,	  0, NULL, sizeof(SEC_PKCS7SignedAndEnvelopedData) },    { SEC_ASN1_INTEGER,	  offsetof(SEC_PKCS7SignedAndEnvelopedData,version) },    { SEC_ASN1_SET_OF,	  offsetof(SEC_PKCS7SignedAndEnvelopedData,recipientInfos),	  SEC_PKCS7RecipientInfoTemplate },    { SEC_ASN1_SET_OF,	  offsetof(SEC_PKCS7SignedAndEnvelopedData,digestAlgorithms),	  SECOID_AlgorithmIDTemplate },    { SEC_ASN1_INLINE,	  offsetof(SEC_PKCS7SignedAndEnvelopedData,encContentInfo),	  SEC_PKCS7EncryptedContentInfoTemplate },    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,	  offsetof(SEC_PKCS7SignedAndEnvelopedData,rawCerts),	  SEC_SetOfAnyTemplate },    { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,	  offsetof(SEC_PKCS7SignedAndEnvelopedData,crls),	  CERT_SetOfSignedCrlTemplate },    { SEC_ASN1_SET_OF,	  offsetof(SEC_PKCS7SignedAndEnvelopedData,signerInfos),	  SEC_PKCS7SignerInfoTemplate },    { 0 }};static const SEC_ASN1TemplateSEC_PointerToPKCS7SignedAndEnvelopedDataTemplate[] = {    { SEC_ASN1_POINTER, 0, SEC_PKCS7SignedAndEnvelopedDataTemplate }};static const SEC_ASN1Template SEC_PKCS7DigestedDataTemplate[] = {    { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,	  0, NULL, sizeof(SEC_PKCS7DigestedData) },    { SEC_ASN1_INTEGER,	  offsetof(SEC_PKCS7DigestedData,version) },    { SEC_ASN1_INLINE,	  offsetof(SEC_PKCS7DigestedData,digestAlg),	  SECOID_AlgorithmIDTemplate },    { SEC_ASN1_INLINE,	  offsetof(SEC_PKCS7DigestedData,contentInfo),	  sec_PKCS7ContentInfoTemplate },    { SEC_ASN1_OCTET_STRING,	  offsetof(SEC_PKCS7DigestedData,digest) },    { 0 }};static const SEC_ASN1Template SEC_PointerToPKCS7DigestedDataTemplate[] = {    { SEC_ASN1_POINTER, 0, SEC_PKCS7DigestedDataTemplate }};static const SEC_ASN1Template SEC_PKCS7EncryptedDataTemplate[] = {    { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,	  0, NULL, sizeof(SEC_PKCS7EncryptedData) },    { SEC_ASN1_INTEGER,	  offsetof(SEC_PKCS7EncryptedData,version) },    { SEC_ASN1_INLINE,	  offsetof(SEC_PKCS7EncryptedData,encContentInfo),	  SEC_PKCS7EncryptedContentInfoTemplate },    { 0 }};static const SEC_ASN1Template SEC_PointerToPKCS7EncryptedDataTemplate[] = {    { SEC_ASN1_POINTER, 0, SEC_PKCS7EncryptedDataTemplate }};const SEC_ASN1Template SEC_SMIMEKEAParamTemplateSkipjack[] = {	{ SEC_ASN1_SEQUENCE,	  0, NULL, sizeof(SEC_PKCS7SMIMEKEAParameters) },	{ SEC_ASN1_OCTET_STRING /* | SEC_ASN1_OPTIONAL */,	  offsetof(SEC_PKCS7SMIMEKEAParameters,originatorKEAKey) },	{ SEC_ASN1_OCTET_STRING,	  offsetof(SEC_PKCS7SMIMEKEAParameters,originatorRA) },	{ 0 }};const SEC_ASN1Template SEC_SMIMEKEAParamTemplateNoSkipjack[] = {	{ SEC_ASN1_SEQUENCE,	  0, NULL, sizeof(SEC_PKCS7SMIMEKEAParameters) },	{ SEC_ASN1_OCTET_STRING /* | SEC_ASN1_OPTIONAL */,	  offsetof(SEC_PKCS7SMIMEKEAParameters,originatorKEAKey) },	{ SEC_ASN1_OCTET_STRING,	  offsetof(SEC_PKCS7SMIMEKEAParameters,originatorRA) },	{ SEC_ASN1_OCTET_STRING  | SEC_ASN1_OPTIONAL ,	  offsetof(SEC_PKCS7SMIMEKEAParameters,nonSkipjackIV) },	{ 0 }};const SEC_ASN1Template SEC_SMIMEKEAParamTemplateAllParams[] = {	{ SEC_ASN1_SEQUENCE,	  0, NULL, sizeof(SEC_PKCS7SMIMEKEAParameters) },	{ SEC_ASN1_OCTET_STRING /* | SEC_ASN1_OPTIONAL */,	  offsetof(SEC_PKCS7SMIMEKEAParameters,originatorKEAKey) },	{ SEC_ASN1_OCTET_STRING,	  offsetof(SEC_PKCS7SMIMEKEAParameters,originatorRA) },	{ SEC_ASN1_OCTET_STRING  | SEC_ASN1_OPTIONAL ,	  offsetof(SEC_PKCS7SMIMEKEAParameters,nonSkipjackIV) },	{ SEC_ASN1_OCTET_STRING  | SEC_ASN1_OPTIONAL ,	  offsetof(SEC_PKCS7SMIMEKEAParameters,bulkKeySize) },	{ 0 }};const SEC_ASN1Template*sec_pkcs7_get_kea_template(SECKEATemplateSelector whichTemplate){	const SEC_ASN1Template *returnVal = NULL;	switch(whichTemplate)	{	case SECKEAUsesNonSkipjack:		returnVal = SEC_SMIMEKEAParamTemplateNoSkipjack;		break;	case SECKEAUsesSkipjack:		returnVal = SEC_SMIMEKEAParamTemplateSkipjack;		break;	case SECKEAUsesNonSkipjackWithPaddedEncKey:	default:		returnVal = SEC_SMIMEKEAParamTemplateAllParams;		break;	}	return returnVal;}	static const SEC_ASN1Template *sec_pkcs7_choose_content_template(void *src_or_dest, PRBool encoding){    const SEC_ASN1Template *theTemplate;    SEC_PKCS7ContentInfo *cinfo;    SECOidTag kind;    PORT_Assert (src_or_dest != NULL);    if (src_or_dest == NULL)	return NULL;    cinfo = (SEC_PKCS7ContentInfo*)src_or_dest;    kind = SEC_PKCS7ContentType (cinfo);    switch (kind) {      default:	theTemplate = SEC_PointerToAnyTemplate;	break;      case SEC_OID_PKCS7_DATA:	theTemplate = SEC_PointerToOctetStringTemplate;	break;      case SEC_OID_PKCS7_SIGNED_DATA:	theTemplate = SEC_PointerToPKCS7SignedDataTemplate;	break;      case SEC_OID_PKCS7_ENVELOPED_DATA:	theTemplate = SEC_PointerToPKCS7EnvelopedDataTemplate;	break;      case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:	theTemplate = SEC_PointerToPKCS7SignedAndEnvelopedDataTemplate;	break;      case SEC_OID_PKCS7_DIGESTED_DATA:	theTemplate = SEC_PointerToPKCS7DigestedDataTemplate;	break;      case SEC_OID_PKCS7_ENCRYPTED_DATA:	theTemplate = SEC_PointerToPKCS7EncryptedDataTemplate;	break;    }    return theTemplate;}/* * End of templates.  Do not add stuff after this; put new code * up above the start of the template definitions. */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?