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 + -
显示快捷键?