diff options
Diffstat (limited to 'nss/lib/pkcs7')
-rw-r--r-- | nss/lib/pkcs7/certread.c | 575 | ||||
-rw-r--r-- | nss/lib/pkcs7/exports.gyp | 33 | ||||
-rw-r--r-- | nss/lib/pkcs7/p7common.c | 765 | ||||
-rw-r--r-- | nss/lib/pkcs7/p7create.c | 1048 | ||||
-rw-r--r-- | nss/lib/pkcs7/p7decode.c | 2119 | ||||
-rw-r--r-- | nss/lib/pkcs7/p7encode.c | 1324 | ||||
-rw-r--r-- | nss/lib/pkcs7/p7local.c | 1164 | ||||
-rw-r--r-- | nss/lib/pkcs7/p7local.h | 70 | ||||
-rw-r--r-- | nss/lib/pkcs7/pkcs7.gyp | 29 | ||||
-rw-r--r-- | nss/lib/pkcs7/pkcs7t.h | 106 | ||||
-rw-r--r-- | nss/lib/pkcs7/secmime.c | 752 | ||||
-rw-r--r-- | nss/lib/pkcs7/secmime.h | 23 | ||||
-rw-r--r-- | nss/lib/pkcs7/secpkcs7.h | 242 |
13 files changed, 4074 insertions, 4176 deletions
diff --git a/nss/lib/pkcs7/certread.c b/nss/lib/pkcs7/certread.c index 88812c7..2d692f1 100644 --- a/nss/lib/pkcs7/certread.c +++ b/nss/lib/pkcs7/certread.c @@ -17,7 +17,7 @@ typedef struct ContentInfoStr ContentInfo; typedef struct DegenerateSignedDataStr DegenerateSignedData; struct ContentInfoStr { - SECOidTag contentTypeTag; /* local; not part of encoding */ + SECOidTag contentTypeTag; /* local; not part of encoding */ SECItem contentType; union { SECItem *data; @@ -37,43 +37,42 @@ struct DegenerateSignedDataStr { static const SEC_ASN1Template * choose_content_template(void *src_or_dest, PRBool encoding); -static const SEC_ASN1TemplateChooserPtr template_chooser - = choose_content_template; +static const SEC_ASN1TemplateChooserPtr template_chooser = choose_content_template; static const SEC_ASN1Template ContentInfoTemplate[] = { { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(ContentInfo) }, + 0, NULL, sizeof(ContentInfo) }, { SEC_ASN1_OBJECT_ID, - offsetof(ContentInfo,contentType) }, + offsetof(ContentInfo, contentType) }, { SEC_ASN1_OPTIONAL | SEC_ASN1_DYNAMIC | - SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(ContentInfo,content), - &template_chooser }, + SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, + offsetof(ContentInfo, content), + &template_chooser }, { 0 } }; static const SEC_ASN1Template DegenerateSignedDataTemplate[] = { { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(DegenerateSignedData) }, + 0, NULL, sizeof(DegenerateSignedData) }, { SEC_ASN1_INTEGER, - offsetof(DegenerateSignedData,version) }, + offsetof(DegenerateSignedData, version) }, { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, - offsetof(DegenerateSignedData,digestAlgorithms), - SEC_ASN1_SUB(SEC_AnyTemplate) }, + offsetof(DegenerateSignedData, digestAlgorithms), + SEC_ASN1_SUB(SEC_AnyTemplate) }, { SEC_ASN1_INLINE, - offsetof(DegenerateSignedData,contentInfo), - ContentInfoTemplate }, + offsetof(DegenerateSignedData, contentInfo), + ContentInfoTemplate }, { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | - SEC_ASN1_XTRN | 0, - offsetof(DegenerateSignedData,certificates), - SEC_ASN1_SUB(SEC_SetOfAnyTemplate) }, + SEC_ASN1_XTRN | 0, + offsetof(DegenerateSignedData, certificates), + SEC_ASN1_SUB(SEC_SetOfAnyTemplate) }, { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | - SEC_ASN1_XTRN | 1, - offsetof(DegenerateSignedData,crls), - SEC_ASN1_SUB(SEC_SetOfAnyTemplate) }, + SEC_ASN1_XTRN | 1, + offsetof(DegenerateSignedData, crls), + SEC_ASN1_SUB(SEC_SetOfAnyTemplate) }, { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, - offsetof(DegenerateSignedData,signerInfos), - SEC_ASN1_SUB(SEC_AnyTemplate) }, + offsetof(DegenerateSignedData, signerInfos), + SEC_ASN1_SUB(SEC_AnyTemplate) }, { 0 } }; @@ -100,18 +99,18 @@ choose_content_template(void *src_or_dest, PRBool encoding) if (src_or_dest == NULL) return NULL; - cinfo = (ContentInfo*)src_or_dest; + cinfo = (ContentInfo *)src_or_dest; kind = GetContentTypeTag(cinfo); switch (kind) { - default: - theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate); - break; - case SEC_OID_PKCS7_DATA: - theTemplate = SEC_ASN1_GET(SEC_PointerToOctetStringTemplate); - break; - case SEC_OID_PKCS7_SIGNED_DATA: - theTemplate = PointerToDegenerateSignedDataTemplate; - break; + default: + theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate); + break; + case SEC_OID_PKCS7_DATA: + theTemplate = SEC_ASN1_GET(SEC_PointerToOctetStringTemplate); + break; + case SEC_OID_PKCS7_SIGNED_DATA: + theTemplate = PointerToDegenerateSignedDataTemplate; + break; } return theTemplate; } @@ -120,50 +119,45 @@ static SECStatus SEC_ReadPKCS7Certs(SECItem *pkcs7Item, CERTImportCertificateFunc f, void *arg) { ContentInfo contentInfo; - SECStatus rv; + SECStatus rv = SECFailure; SECItem **certs; int count; PLArenaPool *arena; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - return SECFailure; + if (arena == NULL) { + return rv; } PORT_Memset(&contentInfo, 0, sizeof(contentInfo)); - rv = SEC_ASN1DecodeItem(arena, &contentInfo, ContentInfoTemplate, - pkcs7Item); - if ( rv != SECSuccess ) { - goto loser; + if (SEC_ASN1DecodeItem(arena, &contentInfo, ContentInfoTemplate, + pkcs7Item) != SECSuccess) { + goto done; } - if ( GetContentTypeTag(&contentInfo) != SEC_OID_PKCS7_SIGNED_DATA ) { - goto loser; + if (GetContentTypeTag(&contentInfo) != SEC_OID_PKCS7_SIGNED_DATA) { + goto done; } + rv = SECSuccess; + certs = contentInfo.content.signedData->certificates; - if ( certs ) { - count = 0; - - while ( *certs ) { - count++; - certs++; - } - rv = (* f)(arg, contentInfo.content.signedData->certificates, count); + if (certs) { + count = 0; + + while (*certs) { + count++; + certs++; + } + rv = (*f)(arg, contentInfo.content.signedData->certificates, count); } - - rv = SECSuccess; - - goto done; -loser: - rv = SECFailure; - + done: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); + if (arena) { + PORT_FreeArena(arena, PR_FALSE); } - return(rv); + return rv; } const SEC_ASN1Template SEC_CertSequenceTemplate[] = { @@ -173,7 +167,7 @@ const SEC_ASN1Template SEC_CertSequenceTemplate[] = { static SECStatus SEC_ReadCertSequence(SECItem *certsItem, CERTImportCertificateFunc f, void *arg) { - SECStatus rv; + SECStatus rv = SECFailure; SECItem **certs; int count; SECItem **rawCerts = NULL; @@ -181,51 +175,44 @@ SEC_ReadCertSequence(SECItem *certsItem, CERTImportCertificateFunc f, void *arg) ContentInfo contentInfo; arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if ( arena == NULL ) { - return SECFailure; + if (arena == NULL) { + return rv; } PORT_Memset(&contentInfo, 0, sizeof(contentInfo)); - rv = SEC_ASN1DecodeItem(arena, &contentInfo, ContentInfoTemplate, - certsItem); - if ( rv != SECSuccess ) { - goto loser; + if (SEC_ASN1DecodeItem(arena, &contentInfo, ContentInfoTemplate, + certsItem) != SECSuccess) { + goto done; } - if ( GetContentTypeTag(&contentInfo) != SEC_OID_NS_TYPE_CERT_SEQUENCE ) { - goto loser; + if (GetContentTypeTag(&contentInfo) != SEC_OID_NS_TYPE_CERT_SEQUENCE) { + goto done; } - rv = SEC_QuickDERDecodeItem(arena, &rawCerts, SEC_CertSequenceTemplate, - contentInfo.content.data); - - if (rv != SECSuccess) { - goto loser; + if (SEC_QuickDERDecodeItem(arena, &rawCerts, SEC_CertSequenceTemplate, + contentInfo.content.data) != SECSuccess) { + goto done; } + rv = SECSuccess; + certs = rawCerts; - if ( certs ) { - count = 0; - - while ( *certs ) { - count++; - certs++; - } - rv = (* f)(arg, rawCerts, count); + if (certs) { + count = 0; + + while (*certs) { + count++; + certs++; + } + rv = (*f)(arg, rawCerts, count); } - - rv = SECSuccess; - - goto done; -loser: - rv = SECFailure; - + done: - if ( arena ) { - PORT_FreeArena(arena, PR_FALSE); + if (arena) { + PORT_FreeArena(arena, PR_FALSE); } - - return(rv); + + return rv; } CERTCertificate * @@ -237,18 +224,18 @@ CERT_ConvertAndDecodeCertificate(char *certstr) rv = ATOB_ConvertAsciiToItem(&der, certstr); if (rv != SECSuccess) - return NULL; + return NULL; - cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), + cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &der, NULL, PR_FALSE, PR_TRUE); PORT_Free(der.data); return cert; } -static const char NS_CERT_HEADER[] = "-----BEGIN CERTIFICATE-----"; +static const char NS_CERT_HEADER[] = "-----BEGIN CERTIFICATE-----"; static const char NS_CERT_TRAILER[] = "-----END CERTIFICATE-----"; -#define NS_CERT_HEADER_LEN ((sizeof NS_CERT_HEADER) - 1) +#define NS_CERT_HEADER_LEN ((sizeof NS_CERT_HEADER) - 1) #define NS_CERT_TRAILER_LEN ((sizeof NS_CERT_TRAILER) - 1) /* @@ -256,18 +243,18 @@ static const char NS_CERT_TRAILER[] = "-----END CERTIFICATE-----"; */ SECStatus CERT_DecodeCertPackage(char *certbuf, - int certlen, - CERTImportCertificateFunc f, - void *arg) + int certlen, + CERTImportCertificateFunc f, + void *arg) { unsigned char *cp; unsigned char *bincert = NULL; - char * ascCert = NULL; - SECStatus rv; - - if ( certbuf == NULL ) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return(SECFailure); + char *ascCert = NULL; + SECStatus rv; + + if (certbuf == NULL) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return (SECFailure); } /* * Make sure certlen is long enough to handle the longest possible @@ -282,220 +269,219 @@ CERT_DecodeCertPackage(char *certbuf, * bytes. */ if (certlen < 17) { - PORT_SetError(SEC_ERROR_INPUT_LEN); - return(SECFailure); + PORT_SetError(SEC_ERROR_INPUT_LEN); + return (SECFailure); } - + cp = (unsigned char *)certbuf; /* is a DER encoded certificate of some type? */ - if ( ( *cp & 0x1f ) == SEC_ASN1_SEQUENCE ) { - SECItem certitem; - SECItem *pcertitem = &certitem; - int seqLen, seqLenLen; - - cp++; - - if ( *cp & 0x80) { - /* Multibyte length */ - seqLenLen = cp[0] & 0x7f; - - switch (seqLenLen) { - case 4: - seqLen = ((unsigned long)cp[1]<<24) | - ((unsigned long)cp[2]<<16) | (cp[3]<<8) | cp[4]; - break; - case 3: - seqLen = ((unsigned long)cp[1]<<16) | (cp[2]<<8) | cp[3]; - break; - case 2: - seqLen = (cp[1]<<8) | cp[2]; - break; - case 1: - seqLen = cp[1]; - break; - case 0: - /* indefinite length */ - seqLen = 0; - break; - default: - goto notder; - } - cp += ( seqLenLen + 1 ); - - } else { - seqLenLen = 0; - seqLen = *cp; - cp++; - } - - /* check entire length if definite length */ - if ( seqLen || seqLenLen ) { - if ( certlen != ( seqLen + seqLenLen + 2 ) ) { - if (certlen > ( seqLen + seqLenLen + 2 )) - PORT_SetError(SEC_ERROR_EXTRA_INPUT); - else - PORT_SetError(SEC_ERROR_INPUT_LEN); - goto notder; - } - } - - /* check the type oid */ - if ( cp[0] == SEC_ASN1_OBJECT_ID ) { - SECOidData *oiddata; - SECItem oiditem; - /* XXX - assume DER encoding of OID len!! */ - oiditem.len = cp[1]; - /* if we add an oid below that is longer than 9 bytes, then we - * need to change the certlen check at the top of the function - * to prevent a buffer overflow - */ - if ( oiditem.len > 9 ) { - PORT_SetError(SEC_ERROR_UNRECOGNIZED_OID); - return(SECFailure); - } - oiditem.data = (unsigned char *)&cp[2]; - oiddata = SECOID_FindOID(&oiditem); - if ( oiddata == NULL ) { - return(SECFailure); - } - - certitem.data = (unsigned char*)certbuf; - certitem.len = certlen; - - switch ( oiddata->offset ) { - case SEC_OID_PKCS7_SIGNED_DATA: - /* oid: 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02 */ - return(SEC_ReadPKCS7Certs(&certitem, f, arg)); - break; - case SEC_OID_NS_TYPE_CERT_SEQUENCE: - /* oid: 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x02, 0x05 */ - return(SEC_ReadCertSequence(&certitem, f, arg)); - break; - default: - break; - } - - } else { - /* it had better be a certificate by now!! */ - certitem.data = (unsigned char*)certbuf; - certitem.len = certlen; - - rv = (* f)(arg, &pcertitem, 1); - return(rv); - } + if ((*cp & 0x1f) == SEC_ASN1_SEQUENCE) { + SECItem certitem; + SECItem *pcertitem = &certitem; + PRUint64 seqLen, seqLenLen; + + cp++; + + if (*cp & 0x80) { + /* Multibyte length */ + seqLenLen = cp[0] & 0x7f; + + switch (seqLenLen) { + case 4: + seqLen = ((unsigned long)cp[1] << 24) | + ((unsigned long)cp[2] << 16) | (cp[3] << 8) | cp[4]; + break; + case 3: + seqLen = ((unsigned long)cp[1] << 16) | (cp[2] << 8) | cp[3]; + break; + case 2: + seqLen = (cp[1] << 8) | cp[2]; + break; + case 1: + seqLen = cp[1]; + break; + case 0: + /* indefinite length */ + seqLen = 0; + break; + default: + goto notder; + } + cp += (seqLenLen + 1); + + } else { + seqLenLen = 0; + seqLen = *cp; + cp++; + } + + /* check entire length if definite length */ + if (seqLen || seqLenLen) { + if (certlen != (seqLen + seqLenLen + 2L)) { + if (certlen > (seqLen + seqLenLen + 2L)) + PORT_SetError(SEC_ERROR_EXTRA_INPUT); + else + PORT_SetError(SEC_ERROR_INPUT_LEN); + goto notder; + } + } + + /* check the type oid */ + if (cp[0] == SEC_ASN1_OBJECT_ID) { + SECOidData *oiddata; + SECItem oiditem; + /* XXX - assume DER encoding of OID len!! */ + oiditem.len = cp[1]; + /* if we add an oid below that is longer than 9 bytes, then we + * need to change the certlen check at the top of the function + * to prevent a buffer overflow + */ + if (oiditem.len > 9) { + PORT_SetError(SEC_ERROR_UNRECOGNIZED_OID); + return (SECFailure); + } + oiditem.data = (unsigned char *)&cp[2]; + oiddata = SECOID_FindOID(&oiditem); + if (oiddata == NULL) { + return (SECFailure); + } + + certitem.data = (unsigned char *)certbuf; + certitem.len = certlen; + + switch (oiddata->offset) { + case SEC_OID_PKCS7_SIGNED_DATA: + /* oid: 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02 */ + return (SEC_ReadPKCS7Certs(&certitem, f, arg)); + break; + case SEC_OID_NS_TYPE_CERT_SEQUENCE: + /* oid: 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x02, 0x05 */ + return (SEC_ReadCertSequence(&certitem, f, arg)); + break; + default: + break; + } + + } else { + /* it had better be a certificate by now!! */ + certitem.data = (unsigned char *)certbuf; + certitem.len = certlen; + + rv = (*f)(arg, &pcertitem, 1); + return (rv); + } } - /* now look for a netscape base64 ascii encoded cert */ -notder: - { - unsigned char *certbegin = NULL; - unsigned char *certend = NULL; - char *pc; +/* now look for a netscape base64 ascii encoded cert */ +notder : { + unsigned char *certbegin = NULL; + unsigned char *certend = NULL; + char *pc; int cl; /* Convert the ASCII data into a nul-terminated string */ ascCert = (char *)PORT_Alloc(certlen + 1); if (!ascCert) { rv = SECFailure; - goto loser; + goto loser; } PORT_Memcpy(ascCert, certbuf, certlen); ascCert[certlen] = '\0'; - pc = PORT_Strchr(ascCert, '\n'); /* find an EOL */ - if (!pc) { /* maybe this is a MAC file */ - pc = ascCert; - while (*pc && NULL != (pc = PORT_Strchr(pc, '\r'))) { - *pc++ = '\n'; - } + pc = PORT_Strchr(ascCert, '\n'); /* find an EOL */ + if (!pc) { /* maybe this is a MAC file */ + pc = ascCert; + while (*pc && NULL != (pc = PORT_Strchr(pc, '\r'))) { + *pc++ = '\n'; + } } cp = (unsigned char *)ascCert; cl = certlen; /* find the beginning marker */ - while ( cl > NS_CERT_HEADER_LEN ) { - int found = 0; - if ( !PORT_Strncasecmp((char *)cp, NS_CERT_HEADER, - NS_CERT_HEADER_LEN) ) { - cl -= NS_CERT_HEADER_LEN; - cp += NS_CERT_HEADER_LEN; - found = 1; - } - - /* skip to next eol */ - while ( cl && ( *cp != '\n' )) { - cp++; - cl--; - } - - /* skip all blank lines */ - while ( cl && ( *cp == '\n' || *cp == '\r' )) { - cp++; - cl--; - } - if (cl && found) { - certbegin = cp; - break; - } + while (cl > NS_CERT_HEADER_LEN) { + int found = 0; + if (!PORT_Strncasecmp((char *)cp, NS_CERT_HEADER, + NS_CERT_HEADER_LEN)) { + cl -= NS_CERT_HEADER_LEN; + cp += NS_CERT_HEADER_LEN; + found = 1; + } + + /* skip to next eol */ + while (cl && (*cp != '\n')) { + cp++; + cl--; + } + + /* skip all blank lines */ + while (cl && (*cp == '\n' || *cp == '\r')) { + cp++; + cl--; + } + if (cl && found) { + certbegin = cp; + break; + } } - if ( certbegin ) { - /* find the ending marker */ - while ( cl >= NS_CERT_TRAILER_LEN ) { - if ( !PORT_Strncasecmp((char *)cp, NS_CERT_TRAILER, - NS_CERT_TRAILER_LEN) ) { - certend = cp; - break; - } - - /* skip to next eol */ - while ( cl && ( *cp != '\n' )) { - cp++; - cl--; - } - - /* skip all blank lines */ - while ( cl && ( *cp == '\n' || *cp == '\r' )) { - cp++; - cl--; - } - } + if (certbegin) { + /* find the ending marker */ + while (cl >= NS_CERT_TRAILER_LEN) { + if (!PORT_Strncasecmp((char *)cp, NS_CERT_TRAILER, + NS_CERT_TRAILER_LEN)) { + certend = cp; + break; + } + + /* skip to next eol */ + while (cl && (*cp != '\n')) { + cp++; + cl--; + } + + /* skip all blank lines */ + while (cl && (*cp == '\n' || *cp == '\r')) { + cp++; + cl--; + } + } } - if ( certbegin && certend ) { - unsigned int binLen; + if (certbegin && certend) { + unsigned int binLen; - *certend = 0; - /* convert to binary */ - bincert = ATOB_AsciiToData((char *)certbegin, &binLen); - if (!bincert) { - rv = SECFailure; - goto loser; - } + *certend = 0; + /* convert to binary */ + bincert = ATOB_AsciiToData((char *)certbegin, &binLen); + if (!bincert) { + rv = SECFailure; + goto loser; + } + + /* now recurse to decode the binary */ + rv = CERT_DecodeCertPackage((char *)bincert, binLen, f, arg); - /* now recurse to decode the binary */ - rv = CERT_DecodeCertPackage((char *)bincert, binLen, f, arg); - } else { - PORT_SetError(SEC_ERROR_BAD_DER); - rv = SECFailure; + PORT_SetError(SEC_ERROR_BAD_DER); + rv = SECFailure; } - } +} loser: - if ( bincert ) { - PORT_Free(bincert); + if (bincert) { + PORT_Free(bincert); } - if ( ascCert ) { - PORT_Free(ascCert); + if (ascCert) { + PORT_Free(ascCert); } - return(rv); + return (rv); } typedef struct { @@ -508,15 +494,14 @@ collect_certs(void *arg, SECItem **certs, int numcerts) { SECStatus rv; collect_args *collectArgs; - + collectArgs = (collect_args *)arg; - + rv = SECITEM_CopyItem(collectArgs->arena, &collectArgs->cert, *certs); - return(rv); + return (rv); } - /* * read an old style ascii or binary certificate */ @@ -526,18 +511,18 @@ CERT_DecodeCertFromPackage(char *certbuf, int certlen) collect_args collectArgs; SECStatus rv; CERTCertificate *cert = NULL; - + collectArgs.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - + rv = CERT_DecodeCertPackage(certbuf, certlen, collect_certs, - (void *)&collectArgs); - if ( rv == SECSuccess ) { - cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), - &collectArgs.cert, NULL, - PR_FALSE, PR_TRUE); + (void *)&collectArgs); + if (rv == SECSuccess) { + cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), + &collectArgs.cert, NULL, + PR_FALSE, PR_TRUE); } - + PORT_FreeArena(collectArgs.arena, PR_FALSE); - - return(cert); + + return (cert); } diff --git a/nss/lib/pkcs7/exports.gyp b/nss/lib/pkcs7/exports.gyp new file mode 100644 index 0000000..e5c9f09 --- /dev/null +++ b/nss/lib/pkcs7/exports.gyp @@ -0,0 +1,33 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +{ + 'includes': [ + '../../coreconf/config.gypi' + ], + 'targets': [ + { + 'target_name': 'lib_pkcs7_exports', + 'type': 'none', + 'copies': [ + { + 'files': [ + 'pkcs7t.h', + 'secmime.h', + 'secpkcs7.h' + ], + 'destination': '<(nss_public_dist_dir)/<(module)' + }, + { + 'files': [ + 'p7local.h' + ], + 'destination': '<(nss_private_dist_dir)/<(module)' + } + ] + } + ], + 'variables': { + 'module': 'nss' + } +} diff --git a/nss/lib/pkcs7/p7common.c b/nss/lib/pkcs7/p7common.c index 10015ce..8a6ac03 100644 --- a/nss/lib/pkcs7/p7common.c +++ b/nss/lib/pkcs7/p7common.c @@ -19,18 +19,17 @@ * and return the inner content type. */ SECOidTag -SEC_PKCS7ContentType (SEC_PKCS7ContentInfo *cinfo) +SEC_PKCS7ContentType(SEC_PKCS7ContentInfo *cinfo) { if (cinfo->contentTypeTag == NULL) - cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType)); + cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType)); if (cinfo->contentTypeTag == NULL) - return SEC_OID_UNKNOWN; + return SEC_OID_UNKNOWN; return cinfo->contentTypeTag->offset; } - /* * Destroy a PKCS7 contentInfo and all of its sub-pieces. */ @@ -43,105 +42,98 @@ SEC_PKCS7DestroyContentInfo(SEC_PKCS7ContentInfo *cinfo) SEC_PKCS7SignerInfo **signerinfos; SEC_PKCS7RecipientInfo **recipientinfos; - PORT_Assert (cinfo->refCount > 0); + PORT_Assert(cinfo->refCount > 0); if (cinfo->refCount <= 0) - return; + return; cinfo->refCount--; if (cinfo->refCount > 0) - return; + return; certs = NULL; certlists = NULL; recipientinfos = NULL; signerinfos = NULL; - kind = SEC_PKCS7ContentType (cinfo); + kind = SEC_PKCS7ContentType(cinfo); switch (kind) { - case SEC_OID_PKCS7_ENVELOPED_DATA: - { - SEC_PKCS7EnvelopedData *edp; - - edp = cinfo->content.envelopedData; - if (edp != NULL) { - recipientinfos = edp->recipientInfos; - } - } - break; - case SEC_OID_PKCS7_SIGNED_DATA: - { - SEC_PKCS7SignedData *sdp; - - sdp = cinfo->content.signedData; - if (sdp != NULL) { - certs = sdp->certs; - certlists = sdp->certLists; - signerinfos = sdp->signerInfos; - } - } - break; - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - { - SEC_PKCS7SignedAndEnvelopedData *saedp; - - saedp = cinfo->content.signedAndEnvelopedData; - if (saedp != NULL) { - certs = saedp->certs; - certlists = saedp->certLists; - recipientinfos = saedp->recipientInfos; - signerinfos = saedp->signerInfos; - if (saedp->sigKey != NULL) - PK11_FreeSymKey (saedp->sigKey); - } - } - break; - default: - /* XXX Anything else that needs to be "manually" freed/destroyed? */ - break; + case SEC_OID_PKCS7_ENVELOPED_DATA: { + SEC_PKCS7EnvelopedData *edp; + + edp = cinfo->content.envelopedData; + if (edp != NULL) { + recipientinfos = edp->recipientInfos; + } + } break; + case SEC_OID_PKCS7_SIGNED_DATA: { + SEC_PKCS7SignedData *sdp; + + sdp = cinfo->content.signedData; + if (sdp != NULL) { + certs = sdp->certs; + certlists = sdp->certLists; + signerinfos = sdp->signerInfos; + } + } break; + case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: { + SEC_PKCS7SignedAndEnvelopedData *saedp; + + saedp = cinfo->content.signedAndEnvelopedData; + if (saedp != NULL) { + certs = saedp->certs; + certlists = saedp->certLists; + recipientinfos = saedp->recipientInfos; + signerinfos = saedp->signerInfos; + if (saedp->sigKey != NULL) + PK11_FreeSymKey(saedp->sigKey); + } + } break; + default: + /* XXX Anything else that needs to be "manually" freed/destroyed? */ + break; } if (certs != NULL) { - CERTCertificate *cert; + CERTCertificate *cert; - while ((cert = *certs++) != NULL) { - CERT_DestroyCertificate (cert); - } + while ((cert = *certs++) != NULL) { + CERT_DestroyCertificate(cert); + } } if (certlists != NULL) { - CERTCertificateList *certlist; + CERTCertificateList *certlist; - while ((certlist = *certlists++) != NULL) { - CERT_DestroyCertificateList (certlist); - } + while ((certlist = *certlists++) != NULL) { + CERT_DestroyCertificateList(certlist); + } } if (recipientinfos != NULL) { - SEC_PKCS7RecipientInfo *ri; + SEC_PKCS7RecipientInfo *ri; - while ((ri = *recipientinfos++) != NULL) { - if (ri->cert != NULL) - CERT_DestroyCertificate (ri->cert); - } + while ((ri = *recipientinfos++) != NULL) { + if (ri->cert != NULL) + CERT_DestroyCertificate(ri->cert); + } } if (signerinfos != NULL) { - SEC_PKCS7SignerInfo *si; - - while ((si = *signerinfos++) != NULL) { - if (si->cert != NULL) - CERT_DestroyCertificate (si->cert); - if (si->certList != NULL) - CERT_DestroyCertificateList (si->certList); - } + SEC_PKCS7SignerInfo *si; + + while ((si = *signerinfos++) != NULL) { + if (si->cert != NULL) + CERT_DestroyCertificate(si->cert); + if (si->certList != NULL) + CERT_DestroyCertificateList(si->certList); + } } if (cinfo->poolp != NULL) { - PORT_FreeArena (cinfo->poolp, PR_FALSE); /* XXX clear it? */ + PORT_FreeArena(cinfo->poolp, PR_FALSE); /* XXX clear it? */ } } - /* * Return a copy of the given contentInfo. The copy may be virtual * or may be real -- either way, the result needs to be passed to @@ -151,30 +143,29 @@ SEC_PKCS7ContentInfo * SEC_PKCS7CopyContentInfo(SEC_PKCS7ContentInfo *cinfo) { if (cinfo == NULL) - return NULL; + return NULL; - PORT_Assert (cinfo->refCount > 0); + PORT_Assert(cinfo->refCount > 0); if (cinfo->created) { - /* - * Want to do a real copy of these; otherwise subsequent - * changes made to either copy are likely to be a surprise. - * XXX I suspect that this will not actually be called for yet, - * which is why the assert, so to notice if it is... - */ - PORT_Assert (0); - /* - * XXX Create a new pool here, and copy everything from - * within. For cert stuff, need to call the appropriate - * copy functions, etc. - */ + /* + * Want to do a real copy of these; otherwise subsequent + * changes made to either copy are likely to be a surprise. + * XXX I suspect that this will not actually be called for yet, + * which is why the assert, so to notice if it is... + */ + PORT_Assert(0); + /* + * XXX Create a new pool here, and copy everything from + * within. For cert stuff, need to call the appropriate + * copy functions, etc. + */ } cinfo->refCount++; return cinfo; } - /* * Return a pointer to the actual content. In the case of those types * which are encrypted, this returns the *plain* content. @@ -185,64 +176,58 @@ SEC_PKCS7GetContent(SEC_PKCS7ContentInfo *cinfo) { SECOidTag kind; - kind = SEC_PKCS7ContentType (cinfo); + kind = SEC_PKCS7ContentType(cinfo); switch (kind) { - case SEC_OID_PKCS7_DATA: - return cinfo->content.data; - case SEC_OID_PKCS7_DIGESTED_DATA: - { - SEC_PKCS7DigestedData *digd; - - digd = cinfo->content.digestedData; - if (digd == NULL) - break; - return SEC_PKCS7GetContent (&(digd->contentInfo)); - } - case SEC_OID_PKCS7_ENCRYPTED_DATA: - { - SEC_PKCS7EncryptedData *encd; - - encd = cinfo->content.encryptedData; - if (encd == NULL) - break; - return &(encd->encContentInfo.plainContent); - } - case SEC_OID_PKCS7_ENVELOPED_DATA: - { - SEC_PKCS7EnvelopedData *envd; - - envd = cinfo->content.envelopedData; - if (envd == NULL) - break; - return &(envd->encContentInfo.plainContent); - } - case SEC_OID_PKCS7_SIGNED_DATA: - { - SEC_PKCS7SignedData *sigd; - - sigd = cinfo->content.signedData; - if (sigd == NULL) - break; - return SEC_PKCS7GetContent (&(sigd->contentInfo)); - } - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - { - SEC_PKCS7SignedAndEnvelopedData *saed; - - saed = cinfo->content.signedAndEnvelopedData; - if (saed == NULL) - break; - return &(saed->encContentInfo.plainContent); - } - default: - PORT_Assert(0); - break; + case SEC_OID_PKCS7_DATA: + return cinfo->content.data; + case SEC_OID_PKCS7_DIGESTED_DATA: { + SEC_PKCS7DigestedData *digd; + + digd = cinfo->content.digestedData; + if (digd == NULL) + break; + return SEC_PKCS7GetContent(&(digd->contentInfo)); + } + case SEC_OID_PKCS7_ENCRYPTED_DATA: { + SEC_PKCS7EncryptedData *encd; + + encd = cinfo->content.encryptedData; + if (encd == NULL) + break; + return &(encd->encContentInfo.plainContent); + } + case SEC_OID_PKCS7_ENVELOPED_DATA: { + SEC_PKCS7EnvelopedData *envd; + + envd = cinfo->content.envelopedData; + if (envd == NULL) + break; + return &(envd->encContentInfo.plainContent); + } + case SEC_OID_PKCS7_SIGNED_DATA: { + SEC_PKCS7SignedData *sigd; + + sigd = cinfo->content.signedData; + if (sigd == NULL) + break; + return SEC_PKCS7GetContent(&(sigd->contentInfo)); + } + case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: { + SEC_PKCS7SignedAndEnvelopedData *saed; + + saed = cinfo->content.signedAndEnvelopedData; + if (saed == NULL) + break; + return &(saed->encContentInfo.plainContent); + } + default: + PORT_Assert(0); + break; } return NULL; } - /* * XXX Fix the placement and formatting of the * following routines (i.e. make them consistent with the rest of @@ -250,35 +235,34 @@ SEC_PKCS7GetContent(SEC_PKCS7ContentInfo *cinfo) * they all need a formatting/style rehaul) */ -/* retrieve the algorithm identifier for encrypted data. +/* retrieve the algorithm identifier for encrypted data. * the identifier returned is a copy of the algorithm identifier * in the content info and needs to be freed after being used. * * cinfo is the content info for which to retrieve the * encryption algorithm. * - * if the content info is not encrypted data or an error + * if the content info is not encrypted data or an error * occurs NULL is returned. */ SECAlgorithmID * SEC_PKCS7GetEncryptionAlgorithm(SEC_PKCS7ContentInfo *cinfo) { - SECAlgorithmID *alg = 0; - switch (SEC_PKCS7ContentType(cinfo)) - { - case SEC_OID_PKCS7_ENCRYPTED_DATA: - alg = &cinfo->content.encryptedData->encContentInfo.contentEncAlg; - break; - case SEC_OID_PKCS7_ENVELOPED_DATA: - alg = &cinfo->content.envelopedData->encContentInfo.contentEncAlg; - break; - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - alg = &cinfo->content.signedAndEnvelopedData - ->encContentInfo.contentEncAlg; - break; - default: - alg = 0; - break; + SECAlgorithmID *alg = 0; + switch (SEC_PKCS7ContentType(cinfo)) { + case SEC_OID_PKCS7_ENCRYPTED_DATA: + alg = &cinfo->content.encryptedData->encContentInfo.contentEncAlg; + break; + case SEC_OID_PKCS7_ENVELOPED_DATA: + alg = &cinfo->content.envelopedData->encContentInfo.contentEncAlg; + break; + case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: + alg = &cinfo->content.signedAndEnvelopedData + ->encContentInfo.contentEncAlg; + break; + default: + alg = 0; + break; } return alg; @@ -287,20 +271,20 @@ SEC_PKCS7GetEncryptionAlgorithm(SEC_PKCS7ContentInfo *cinfo) /* set the content of the content info. For data content infos, * the data is set. For encrytped content infos, the plainContent * is set, and is expected to be encrypted later. - * + * * cinfo is the content info where the data will be set * * buf is a buffer of the data to set * * len is the length of the data being set. * - * in the event of an error, SECFailure is returned. SECSuccess + * in the event of an error, SECFailure is returned. SECSuccess * indicates the content was successfully set. */ -SECStatus +SECStatus SEC_PKCS7SetContent(SEC_PKCS7ContentInfo *cinfo, - const char *buf, - unsigned long len) + const char *buf, + unsigned long len) { SECOidTag cinfo_type; SECStatus rv; @@ -314,76 +298,75 @@ SEC_PKCS7SetContent(SEC_PKCS7ContentInfo *cinfo, cinfo_type = SEC_PKCS7ContentType(cinfo); /* set inner content */ - switch(cinfo_type) - { - case SEC_OID_PKCS7_SIGNED_DATA: - if(content.len > 0) { - /* we "leak" the old content here, but as it's all in the pool */ - /* it does not really matter */ - - /* create content item if necessary */ - if (cinfo->content.signedData->contentInfo.content.data == NULL) - cinfo->content.signedData->contentInfo.content.data = SECITEM_AllocItem(cinfo->poolp, NULL, 0); - rv = SECITEM_CopyItem(cinfo->poolp, - cinfo->content.signedData->contentInfo.content.data, - &content); - } else { - cinfo->content.signedData->contentInfo.content.data->data = NULL; - cinfo->content.signedData->contentInfo.content.data->len = 0; - rv = SECSuccess; - } - if(rv == SECFailure) - goto loser; - - break; - case SEC_OID_PKCS7_ENCRYPTED_DATA: - /* XXX this forces the inner content type to be "data" */ - /* do we really want to override without asking or reason? */ - contentTypeTag = SECOID_FindOIDByTag(SEC_OID_PKCS7_DATA); - if(contentTypeTag == NULL) - goto loser; - rv = SECITEM_CopyItem(cinfo->poolp, - &(cinfo->content.encryptedData->encContentInfo.contentType), - &(contentTypeTag->oid)); - if(rv == SECFailure) - goto loser; - if(content.len > 0) { - rv = SECITEM_CopyItem(cinfo->poolp, - &(cinfo->content.encryptedData->encContentInfo.plainContent), - &content); - } else { - cinfo->content.encryptedData->encContentInfo.plainContent.data = NULL; - cinfo->content.encryptedData->encContentInfo.encContent.data = NULL; - cinfo->content.encryptedData->encContentInfo.plainContent.len = 0; - cinfo->content.encryptedData->encContentInfo.encContent.len = 0; - rv = SECSuccess; - } - if(rv == SECFailure) - goto loser; - break; - case SEC_OID_PKCS7_DATA: - cinfo->content.data = (SECItem *)PORT_ArenaZAlloc(cinfo->poolp, - sizeof(SECItem)); - if(cinfo->content.data == NULL) - goto loser; - if(content.len > 0) { - rv = SECITEM_CopyItem(cinfo->poolp, - cinfo->content.data, &content); - } else { - /* handle case with NULL content */ - rv = SECSuccess; - } - if(rv == SECFailure) - goto loser; - break; - default: - goto loser; + switch (cinfo_type) { + case SEC_OID_PKCS7_SIGNED_DATA: + if (content.len > 0) { + /* we "leak" the old content here, but as it's all in the pool */ + /* it does not really matter */ + + /* create content item if necessary */ + if (cinfo->content.signedData->contentInfo.content.data == NULL) + cinfo->content.signedData->contentInfo.content.data = SECITEM_AllocItem(cinfo->poolp, NULL, 0); + rv = SECITEM_CopyItem(cinfo->poolp, + cinfo->content.signedData->contentInfo.content.data, + &content); + } else { + cinfo->content.signedData->contentInfo.content.data->data = NULL; + cinfo->content.signedData->contentInfo.content.data->len = 0; + rv = SECSuccess; + } + if (rv == SECFailure) + goto loser; + + break; + case SEC_OID_PKCS7_ENCRYPTED_DATA: + /* XXX this forces the inner content type to be "data" */ + /* do we really want to override without asking or reason? */ + contentTypeTag = SECOID_FindOIDByTag(SEC_OID_PKCS7_DATA); + if (contentTypeTag == NULL) + goto loser; + rv = SECITEM_CopyItem(cinfo->poolp, + &(cinfo->content.encryptedData->encContentInfo.contentType), + &(contentTypeTag->oid)); + if (rv == SECFailure) + goto loser; + if (content.len > 0) { + rv = SECITEM_CopyItem(cinfo->poolp, + &(cinfo->content.encryptedData->encContentInfo.plainContent), + &content); + } else { + cinfo->content.encryptedData->encContentInfo.plainContent.data = NULL; + cinfo->content.encryptedData->encContentInfo.encContent.data = NULL; + cinfo->content.encryptedData->encContentInfo.plainContent.len = 0; + cinfo->content.encryptedData->encContentInfo.encContent.len = 0; + rv = SECSuccess; + } + if (rv == SECFailure) + goto loser; + break; + case SEC_OID_PKCS7_DATA: + cinfo->content.data = (SECItem *)PORT_ArenaZAlloc(cinfo->poolp, + sizeof(SECItem)); + if (cinfo->content.data == NULL) + goto loser; + if (content.len > 0) { + rv = SECITEM_CopyItem(cinfo->poolp, + cinfo->content.data, &content); + } else { + /* handle case with NULL content */ + rv = SECSuccess; + } + if (rv == SECFailure) + goto loser; + break; + default: + goto loser; } return SECSuccess; loser: - + return SECFailure; } @@ -397,146 +380,145 @@ loser: * algorithm is a password based encryption algorithm, the * key is actually a password which will be processed per * PKCS #5. - * + * * in the event of an error, SECFailure is returned. SECSuccess * indicates a success. */ -SECStatus +SECStatus SEC_PKCS7EncryptContents(PLArenaPool *poolp, - SEC_PKCS7ContentInfo *cinfo, - SECItem *key, - void *wincx) + SEC_PKCS7ContentInfo *cinfo, + SECItem *key, + void *wincx) { - SECAlgorithmID *algid = NULL; - SECItem * src; - SECItem * dest; - SECItem * blocked_data = NULL; - void * mark; - void * cx; - PK11SymKey * eKey = NULL; - PK11SlotInfo * slot = NULL; + SECAlgorithmID *algid = NULL; + SECItem *src; + SECItem *dest; + SECItem *blocked_data = NULL; + void *mark; + void *cx; + PK11SymKey *eKey = NULL; + PK11SlotInfo *slot = NULL; CK_MECHANISM_TYPE cryptoMechType; - int bs; - SECStatus rv = SECFailure; - SECItem *c_param = NULL; + int bs; + SECStatus rv = SECFailure; + SECItem *c_param = NULL; - if((cinfo == NULL) || (key == NULL)) - return SECFailure; + if ((cinfo == NULL) || (key == NULL)) + return SECFailure; - if(SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_ENCRYPTED_DATA) - return SECFailure; + if (SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_ENCRYPTED_DATA) + return SECFailure; - algid = SEC_PKCS7GetEncryptionAlgorithm(cinfo); - if(algid == NULL) - return SECFailure; + algid = SEC_PKCS7GetEncryptionAlgorithm(cinfo); + if (algid == NULL) + return SECFailure; - if(poolp == NULL) - poolp = cinfo->poolp; + if (poolp == NULL) + poolp = cinfo->poolp; mark = PORT_ArenaMark(poolp); - + src = &cinfo->content.encryptedData->encContentInfo.plainContent; dest = &cinfo->content.encryptedData->encContentInfo.encContent; - dest->data = (unsigned char*)PORT_ArenaZAlloc(poolp, (src->len + 64)); + dest->data = (unsigned char *)PORT_ArenaZAlloc(poolp, (src->len + 64)); dest->len = (src->len + 64); - if(dest->data == NULL) { - rv = SECFailure; - goto loser; + if (dest->data == NULL) { + rv = SECFailure; + goto loser; } slot = PK11_GetInternalKeySlot(); - if(slot == NULL) { - rv = SECFailure; - goto loser; + if (slot == NULL) { + rv = SECFailure; + goto loser; } eKey = PK11_PBEKeyGen(slot, algid, key, PR_FALSE, wincx); - if(eKey == NULL) { - rv = SECFailure; - goto loser; + if (eKey == NULL) { + rv = SECFailure; + goto loser; } - + cryptoMechType = PK11_GetPBECryptoMechanism(algid, &c_param, key); if (cryptoMechType == CKM_INVALID_MECHANISM) { - rv = SECFailure; - goto loser; + rv = SECFailure; + goto loser; } /* block according to PKCS 8 */ bs = PK11_GetBlockSize(cryptoMechType, c_param); rv = SECSuccess; - if(bs) { - char pad_char; - pad_char = (char)(bs - (src->len % bs)); - if(src->len % bs) { - rv = SECSuccess; - blocked_data = PK11_BlockData(src, bs); - if(blocked_data) { - PORT_Memset((blocked_data->data + blocked_data->len - - (int)pad_char), - pad_char, (int)pad_char); - } else { - rv = SECFailure; - goto loser; - } - } else { - blocked_data = SECITEM_DupItem(src); - if(blocked_data) { - blocked_data->data = (unsigned char*)PORT_Realloc( - blocked_data->data, - blocked_data->len + bs); - if(blocked_data->data) { - blocked_data->len += bs; - PORT_Memset((blocked_data->data + src->len), (char)bs, bs); - } else { - rv = SECFailure; - goto loser; - } - } else { - rv = SECFailure; - goto loser; - } - } + if (bs) { + char pad_char; + pad_char = (char)(bs - (src->len % bs)); + if (src->len % bs) { + rv = SECSuccess; + blocked_data = PK11_BlockData(src, bs); + if (blocked_data) { + PORT_Memset((blocked_data->data + blocked_data->len - (int)pad_char), + pad_char, (int)pad_char); + } else { + rv = SECFailure; + goto loser; + } + } else { + blocked_data = SECITEM_DupItem(src); + if (blocked_data) { + blocked_data->data = (unsigned char *)PORT_Realloc( + blocked_data->data, + blocked_data->len + bs); + if (blocked_data->data) { + blocked_data->len += bs; + PORT_Memset((blocked_data->data + src->len), (char)bs, bs); + } else { + rv = SECFailure; + goto loser; + } + } else { + rv = SECFailure; + goto loser; + } + } } else { - blocked_data = SECITEM_DupItem(src); - if(!blocked_data) { - rv = SECFailure; - goto loser; - } + blocked_data = SECITEM_DupItem(src); + if (!blocked_data) { + rv = SECFailure; + goto loser; + } } cx = PK11_CreateContextBySymKey(cryptoMechType, CKA_ENCRYPT, - eKey, c_param); - if(cx == NULL) { - rv = SECFailure; - goto loser; + eKey, c_param); + if (cx == NULL) { + rv = SECFailure; + goto loser; } - rv = PK11_CipherOp((PK11Context*)cx, dest->data, (int *)(&dest->len), - (int)(src->len + 64), blocked_data->data, - (int)blocked_data->len); - PK11_DestroyContext((PK11Context*)cx, PR_TRUE); + rv = PK11_CipherOp((PK11Context *)cx, dest->data, (int *)(&dest->len), + (int)(src->len + 64), blocked_data->data, + (int)blocked_data->len); + PK11_DestroyContext((PK11Context *)cx, PR_TRUE); loser: /* let success fall through */ - if(blocked_data != NULL) - SECITEM_ZfreeItem(blocked_data, PR_TRUE); + if (blocked_data != NULL) + SECITEM_ZfreeItem(blocked_data, PR_TRUE); - if(rv == SECFailure) - PORT_ArenaRelease(poolp, mark); - else - PORT_ArenaUnmark(poolp, mark); + if (rv == SECFailure) + PORT_ArenaRelease(poolp, mark); + else + PORT_ArenaUnmark(poolp, mark); + + if (eKey != NULL) + PK11_FreeSymKey(eKey); - if(eKey != NULL) - PK11_FreeSymKey(eKey); + if (slot != NULL) + PK11_FreeSlot(slot); - if(slot != NULL) - PK11_FreeSlot(slot); + if (c_param != NULL) + SECITEM_ZfreeItem(c_param, PR_TRUE); - if(c_param != NULL) - SECITEM_ZfreeItem(c_param, PR_TRUE); - return rv; } @@ -550,15 +532,15 @@ loser: * algorithm is a password based encryption algorithm, the * key is actually a password which will be processed per * PKCS #5. - * + * * in the event of an error, SECFailure is returned. SECSuccess * indicates a success. */ -SECStatus +SECStatus SEC_PKCS7DecryptContents(PLArenaPool *poolp, - SEC_PKCS7ContentInfo *cinfo, - SECItem *key, - void *wincx) + SEC_PKCS7ContentInfo *cinfo, + SECItem *key, + void *wincx) { SECAlgorithmID *algid = NULL; SECStatus rv = SECFailure; @@ -572,113 +554,110 @@ SEC_PKCS7DecryptContents(PLArenaPool *poolp, SECItem *c_param = NULL; int bs; - if((cinfo == NULL) || (key == NULL)) - return SECFailure; + if ((cinfo == NULL) || (key == NULL)) + return SECFailure; - if(SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_ENCRYPTED_DATA) - return SECFailure; + if (SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_ENCRYPTED_DATA) + return SECFailure; - algid = SEC_PKCS7GetEncryptionAlgorithm(cinfo); - if(algid == NULL) - return SECFailure; + algid = SEC_PKCS7GetEncryptionAlgorithm(cinfo); + if (algid == NULL) + return SECFailure; - if(poolp == NULL) - poolp = cinfo->poolp; + if (poolp == NULL) + poolp = cinfo->poolp; mark = PORT_ArenaMark(poolp); - + src = &cinfo->content.encryptedData->encContentInfo.encContent; dest = &cinfo->content.encryptedData->encContentInfo.plainContent; - dest->data = (unsigned char*)PORT_ArenaZAlloc(poolp, (src->len + 64)); + dest->data = (unsigned char *)PORT_ArenaZAlloc(poolp, (src->len + 64)); dest->len = (src->len + 64); - if(dest->data == NULL) { - rv = SECFailure; - goto loser; + if (dest->data == NULL) { + rv = SECFailure; + goto loser; } slot = PK11_GetInternalKeySlot(); - if(slot == NULL) { - rv = SECFailure; - goto loser; + if (slot == NULL) { + rv = SECFailure; + goto loser; } eKey = PK11_PBEKeyGen(slot, algid, key, PR_FALSE, wincx); - if(eKey == NULL) { - rv = SECFailure; - goto loser; + if (eKey == NULL) { + rv = SECFailure; + goto loser; } - + cryptoMechType = PK11_GetPBECryptoMechanism(algid, &c_param, key); if (cryptoMechType == CKM_INVALID_MECHANISM) { - rv = SECFailure; - goto loser; + rv = SECFailure; + goto loser; } cx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT, - eKey, c_param); - if(cx == NULL) { - rv = SECFailure; - goto loser; + eKey, c_param); + if (cx == NULL) { + rv = SECFailure; + goto loser; } - rv = PK11_CipherOp((PK11Context*)cx, dest->data, (int *)(&dest->len), - (int)(src->len + 64), src->data, (int)src->len); + rv = PK11_CipherOp((PK11Context *)cx, dest->data, (int *)(&dest->len), + (int)(src->len + 64), src->data, (int)src->len); PK11_DestroyContext((PK11Context *)cx, PR_TRUE); bs = PK11_GetBlockSize(cryptoMechType, c_param); - if(bs) { - /* check for proper badding in block algorithms. this assumes - * RC2 cbc or a DES cbc variant. and the padding is thus defined - */ - if(((int)dest->data[dest->len-1] <= bs) && - ((int)dest->data[dest->len-1] > 0)) { - dest->len -= (int)dest->data[dest->len-1]; - } else { - rv = SECFailure; - /* set an error ? */ - } - } + if (bs) { + /* check for proper badding in block algorithms. this assumes + * RC2 cbc or a DES cbc variant. and the padding is thus defined + */ + if (((int)dest->data[dest->len - 1] <= bs) && + ((int)dest->data[dest->len - 1] > 0)) { + dest->len -= (int)dest->data[dest->len - 1]; + } else { + rv = SECFailure; + /* set an error ? */ + } + } loser: /* let success fall through */ - if(rv == SECFailure) - PORT_ArenaRelease(poolp, mark); + if (rv == SECFailure) + PORT_ArenaRelease(poolp, mark); else - PORT_ArenaUnmark(poolp, mark); + PORT_ArenaUnmark(poolp, mark); + + if (eKey != NULL) + PK11_FreeSymKey(eKey); - if(eKey != NULL) - PK11_FreeSymKey(eKey); + if (slot != NULL) + PK11_FreeSlot(slot); - if(slot != NULL) - PK11_FreeSlot(slot); + if (c_param != NULL) + SECITEM_ZfreeItem(c_param, PR_TRUE); - if(c_param != NULL) - SECITEM_ZfreeItem(c_param, PR_TRUE); - return rv; } SECItem ** SEC_PKCS7GetCertificateList(SEC_PKCS7ContentInfo *cinfo) { - switch(SEC_PKCS7ContentType(cinfo)) - { - case SEC_OID_PKCS7_SIGNED_DATA: - return cinfo->content.signedData->rawCerts; - break; - default: - return NULL; - break; + switch (SEC_PKCS7ContentType(cinfo)) { + case SEC_OID_PKCS7_SIGNED_DATA: + return cinfo->content.signedData->rawCerts; + break; + default: + return NULL; + break; } } - int SEC_PKCS7GetKeyLength(SEC_PKCS7ContentInfo *cinfo) { - if (cinfo->contentTypeTag->offset == SEC_OID_PKCS7_ENVELOPED_DATA) - return cinfo->content.envelopedData->encContentInfo.keysize; - else - return 0; + if (cinfo->contentTypeTag->offset == SEC_OID_PKCS7_ENVELOPED_DATA) + return cinfo->content.envelopedData->encContentInfo.keysize; + else + return 0; } - diff --git a/nss/lib/pkcs7/p7create.c b/nss/lib/pkcs7/p7create.c index 983b7b5..fcf0cad 100644 --- a/nss/lib/pkcs7/p7create.c +++ b/nss/lib/pkcs7/p7create.c @@ -21,106 +21,104 @@ const int NSS_PBE_DEFAULT_ITERATION_COUNT = 2000; /* used in p12e.c too */ static SECStatus -sec_pkcs7_init_content_info (SEC_PKCS7ContentInfo *cinfo, PLArenaPool *poolp, - SECOidTag kind, PRBool detached) +sec_pkcs7_init_content_info(SEC_PKCS7ContentInfo *cinfo, PLArenaPool *poolp, + SECOidTag kind, PRBool detached) { void *thing; int version; SECItem *versionp; SECStatus rv; - PORT_Assert (cinfo != NULL && poolp != NULL); + PORT_Assert(cinfo != NULL && poolp != NULL); if (cinfo == NULL || poolp == NULL) - return SECFailure; + return SECFailure; - cinfo->contentTypeTag = SECOID_FindOIDByTag (kind); - PORT_Assert (cinfo->contentTypeTag - && cinfo->contentTypeTag->offset == kind); + cinfo->contentTypeTag = SECOID_FindOIDByTag(kind); + PORT_Assert(cinfo->contentTypeTag && cinfo->contentTypeTag->offset == kind); - rv = SECITEM_CopyItem (poolp, &(cinfo->contentType), - &(cinfo->contentTypeTag->oid)); + rv = SECITEM_CopyItem(poolp, &(cinfo->contentType), + &(cinfo->contentTypeTag->oid)); if (rv != SECSuccess) - return rv; + return rv; if (detached) - return SECSuccess; + return SECSuccess; switch (kind) { - default: - case SEC_OID_PKCS7_DATA: - thing = PORT_ArenaZAlloc (poolp, sizeof(SECItem)); - cinfo->content.data = (SECItem*)thing; - versionp = NULL; - version = -1; - break; - case SEC_OID_PKCS7_DIGESTED_DATA: - thing = PORT_ArenaZAlloc (poolp, sizeof(SEC_PKCS7DigestedData)); - cinfo->content.digestedData = (SEC_PKCS7DigestedData*)thing; - versionp = &(cinfo->content.digestedData->version); - version = SEC_PKCS7_DIGESTED_DATA_VERSION; - break; - case SEC_OID_PKCS7_ENCRYPTED_DATA: - thing = PORT_ArenaZAlloc (poolp, sizeof(SEC_PKCS7EncryptedData)); - cinfo->content.encryptedData = (SEC_PKCS7EncryptedData*)thing; - versionp = &(cinfo->content.encryptedData->version); - version = SEC_PKCS7_ENCRYPTED_DATA_VERSION; - break; - case SEC_OID_PKCS7_ENVELOPED_DATA: - thing = PORT_ArenaZAlloc (poolp, sizeof(SEC_PKCS7EnvelopedData)); - cinfo->content.envelopedData = - (SEC_PKCS7EnvelopedData*)thing; - versionp = &(cinfo->content.envelopedData->version); - version = SEC_PKCS7_ENVELOPED_DATA_VERSION; - break; - case SEC_OID_PKCS7_SIGNED_DATA: - thing = PORT_ArenaZAlloc (poolp, sizeof(SEC_PKCS7SignedData)); - cinfo->content.signedData = - (SEC_PKCS7SignedData*)thing; - versionp = &(cinfo->content.signedData->version); - version = SEC_PKCS7_SIGNED_DATA_VERSION; - break; - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - thing = PORT_ArenaZAlloc(poolp,sizeof(SEC_PKCS7SignedAndEnvelopedData)); - cinfo->content.signedAndEnvelopedData = - (SEC_PKCS7SignedAndEnvelopedData*)thing; - versionp = &(cinfo->content.signedAndEnvelopedData->version); - version = SEC_PKCS7_SIGNED_AND_ENVELOPED_DATA_VERSION; - break; + default: + case SEC_OID_PKCS7_DATA: + thing = PORT_ArenaZAlloc(poolp, sizeof(SECItem)); + cinfo->content.data = (SECItem *)thing; + versionp = NULL; + version = -1; + break; + case SEC_OID_PKCS7_DIGESTED_DATA: + thing = PORT_ArenaZAlloc(poolp, sizeof(SEC_PKCS7DigestedData)); + cinfo->content.digestedData = (SEC_PKCS7DigestedData *)thing; + versionp = &(cinfo->content.digestedData->version); + version = SEC_PKCS7_DIGESTED_DATA_VERSION; + break; + case SEC_OID_PKCS7_ENCRYPTED_DATA: + thing = PORT_ArenaZAlloc(poolp, sizeof(SEC_PKCS7EncryptedData)); + cinfo->content.encryptedData = (SEC_PKCS7EncryptedData *)thing; + versionp = &(cinfo->content.encryptedData->version); + version = SEC_PKCS7_ENCRYPTED_DATA_VERSION; + break; + case SEC_OID_PKCS7_ENVELOPED_DATA: + thing = PORT_ArenaZAlloc(poolp, sizeof(SEC_PKCS7EnvelopedData)); + cinfo->content.envelopedData = + (SEC_PKCS7EnvelopedData *)thing; + versionp = &(cinfo->content.envelopedData->version); + version = SEC_PKCS7_ENVELOPED_DATA_VERSION; + break; + case SEC_OID_PKCS7_SIGNED_DATA: + thing = PORT_ArenaZAlloc(poolp, sizeof(SEC_PKCS7SignedData)); + cinfo->content.signedData = + (SEC_PKCS7SignedData *)thing; + versionp = &(cinfo->content.signedData->version); + version = SEC_PKCS7_SIGNED_DATA_VERSION; + break; + case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: + thing = PORT_ArenaZAlloc(poolp, sizeof(SEC_PKCS7SignedAndEnvelopedData)); + cinfo->content.signedAndEnvelopedData = + (SEC_PKCS7SignedAndEnvelopedData *)thing; + versionp = &(cinfo->content.signedAndEnvelopedData->version); + version = SEC_PKCS7_SIGNED_AND_ENVELOPED_DATA_VERSION; + break; } if (thing == NULL) - return SECFailure; + return SECFailure; if (versionp != NULL) { - SECItem *dummy; + SECItem *dummy; - PORT_Assert (version >= 0); - dummy = SEC_ASN1EncodeInteger (poolp, versionp, version); - if (dummy == NULL) - return SECFailure; - PORT_Assert (dummy == versionp); + PORT_Assert(version >= 0); + dummy = SEC_ASN1EncodeInteger(poolp, versionp, version); + if (dummy == NULL) + return SECFailure; + PORT_Assert(dummy == versionp); } return SECSuccess; } - static SEC_PKCS7ContentInfo * -sec_pkcs7_create_content_info (SECOidTag kind, PRBool detached, - SECKEYGetPasswordKey pwfn, void *pwfn_arg) +sec_pkcs7_create_content_info(SECOidTag kind, PRBool detached, + SECKEYGetPasswordKey pwfn, void *pwfn_arg) { SEC_PKCS7ContentInfo *cinfo; PLArenaPool *poolp; SECStatus rv; - poolp = PORT_NewArena (1024); /* XXX what is right value? */ + poolp = PORT_NewArena(1024); /* XXX what is right value? */ if (poolp == NULL) - return NULL; + return NULL; - cinfo = (SEC_PKCS7ContentInfo*)PORT_ArenaZAlloc (poolp, sizeof(*cinfo)); + cinfo = (SEC_PKCS7ContentInfo *)PORT_ArenaZAlloc(poolp, sizeof(*cinfo)); if (cinfo == NULL) { - PORT_FreeArena (poolp, PR_FALSE); - return NULL; + PORT_FreeArena(poolp, PR_FALSE); + return NULL; } cinfo->poolp = poolp; @@ -129,16 +127,15 @@ sec_pkcs7_create_content_info (SECOidTag kind, PRBool detached, cinfo->created = PR_TRUE; cinfo->refCount = 1; - rv = sec_pkcs7_init_content_info (cinfo, poolp, kind, detached); + rv = sec_pkcs7_init_content_info(cinfo, poolp, kind, detached); if (rv != SECSuccess) { - PORT_FreeArena (poolp, PR_FALSE); - return NULL; + PORT_FreeArena(poolp, PR_FALSE); + return NULL; } return cinfo; } - /* * Add a signer to a PKCS7 thing, verifying the signature cert first. * Any error returns SECFailure. @@ -147,45 +144,41 @@ sec_pkcs7_create_content_info (SECOidTag kind, PRBool detached, * to add a second one -- this needs to be fixed. */ static SECStatus -sec_pkcs7_add_signer (SEC_PKCS7ContentInfo *cinfo, - CERTCertificate * cert, - SECCertUsage certusage, - CERTCertDBHandle * certdb, - SECOidTag digestalgtag, - SECItem * digestdata) +sec_pkcs7_add_signer(SEC_PKCS7ContentInfo *cinfo, + CERTCertificate *cert, + SECCertUsage certusage, + CERTCertDBHandle *certdb, + SECOidTag digestalgtag, + SECItem *digestdata) { SEC_PKCS7SignerInfo *signerinfo, **signerinfos, ***signerinfosp; - SECAlgorithmID *digestalg, **digestalgs, ***digestalgsp; - SECItem *digest, **digests, ***digestsp; - SECItem * dummy; - void * mark; - SECStatus rv; - SECOidTag kind; - - kind = SEC_PKCS7ContentType (cinfo); + SECAlgorithmID *digestalg, **digestalgs, ***digestalgsp; + SECItem *digest, **digests, ***digestsp; + SECItem *dummy; + void *mark; + SECStatus rv; + SECOidTag kind; + + kind = SEC_PKCS7ContentType(cinfo); switch (kind) { - case SEC_OID_PKCS7_SIGNED_DATA: - { - SEC_PKCS7SignedData *sdp; - - sdp = cinfo->content.signedData; - digestalgsp = &(sdp->digestAlgorithms); - digestsp = &(sdp->digests); - signerinfosp = &(sdp->signerInfos); - } - break; - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - { - SEC_PKCS7SignedAndEnvelopedData *saedp; - - saedp = cinfo->content.signedAndEnvelopedData; - digestalgsp = &(saedp->digestAlgorithms); - digestsp = &(saedp->digests); - signerinfosp = &(saedp->signerInfos); - } - break; - default: - return SECFailure; /* XXX set an error? */ + case SEC_OID_PKCS7_SIGNED_DATA: { + SEC_PKCS7SignedData *sdp; + + sdp = cinfo->content.signedData; + digestalgsp = &(sdp->digestAlgorithms); + digestsp = &(sdp->digests); + signerinfosp = &(sdp->signerInfos); + } break; + case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: { + SEC_PKCS7SignedAndEnvelopedData *saedp; + + saedp = cinfo->content.signedAndEnvelopedData; + digestalgsp = &(saedp->digestAlgorithms); + digestsp = &(saedp->digests); + signerinfosp = &(saedp->signerInfos); + } break; + default: + return SECFailure; /* XXX set an error? */ } /* @@ -193,16 +186,15 @@ sec_pkcs7_add_signer (SEC_PKCS7ContentInfo *cinfo, * a NULL database. */ if (certdb == NULL) { - certdb = CERT_GetDefaultCertDB(); - if (certdb == NULL) - return SECFailure; /* XXX set an error? */ + certdb = CERT_GetDefaultCertDB(); + if (certdb == NULL) + return SECFailure; /* XXX set an error? */ } - if (CERT_VerifyCert (certdb, cert, PR_TRUE, certusage, PR_Now(), - cinfo->pwfn_arg, NULL) != SECSuccess) - { - /* XXX Did CERT_VerifyCert set an error? */ - return SECFailure; + if (CERT_VerifyCert(certdb, cert, PR_TRUE, certusage, PR_Now(), + cinfo->pwfn_arg, NULL) != SECSuccess) { + /* XXX Did CERT_VerifyCert set an error? */ + return SECFailure; } /* @@ -210,45 +202,44 @@ sec_pkcs7_add_signer (SEC_PKCS7ContentInfo *cinfo, * This is not what we really want -- we want to allow this * and *add* the new signer. */ - PORT_Assert (*signerinfosp == NULL - && *digestalgsp == NULL && *digestsp == NULL); + PORT_Assert(*signerinfosp == NULL && *digestalgsp == NULL && *digestsp == NULL); if (*signerinfosp != NULL || *digestalgsp != NULL || *digestsp != NULL) - return SECFailure; + return SECFailure; - mark = PORT_ArenaMark (cinfo->poolp); + mark = PORT_ArenaMark(cinfo->poolp); - signerinfo = (SEC_PKCS7SignerInfo*)PORT_ArenaZAlloc (cinfo->poolp, - sizeof(SEC_PKCS7SignerInfo)); + signerinfo = (SEC_PKCS7SignerInfo *)PORT_ArenaZAlloc(cinfo->poolp, + sizeof(SEC_PKCS7SignerInfo)); if (signerinfo == NULL) { - PORT_ArenaRelease (cinfo->poolp, mark); - return SECFailure; + PORT_ArenaRelease(cinfo->poolp, mark); + return SECFailure; } - dummy = SEC_ASN1EncodeInteger (cinfo->poolp, &signerinfo->version, - SEC_PKCS7_SIGNER_INFO_VERSION); + dummy = SEC_ASN1EncodeInteger(cinfo->poolp, &signerinfo->version, + SEC_PKCS7_SIGNER_INFO_VERSION); if (dummy == NULL) { - PORT_ArenaRelease (cinfo->poolp, mark); - return SECFailure; + PORT_ArenaRelease(cinfo->poolp, mark); + return SECFailure; } - PORT_Assert (dummy == &signerinfo->version); + PORT_Assert(dummy == &signerinfo->version); - signerinfo->cert = CERT_DupCertificate (cert); + signerinfo->cert = CERT_DupCertificate(cert); if (signerinfo->cert == NULL) { - PORT_ArenaRelease (cinfo->poolp, mark); - return SECFailure; + PORT_ArenaRelease(cinfo->poolp, mark); + return SECFailure; } - signerinfo->issuerAndSN = CERT_GetCertIssuerAndSN (cinfo->poolp, cert); + signerinfo->issuerAndSN = CERT_GetCertIssuerAndSN(cinfo->poolp, cert); if (signerinfo->issuerAndSN == NULL) { - PORT_ArenaRelease (cinfo->poolp, mark); - return SECFailure; + PORT_ArenaRelease(cinfo->poolp, mark); + return SECFailure; } - rv = SECOID_SetAlgorithmID (cinfo->poolp, &signerinfo->digestAlg, - digestalgtag, NULL); + rv = SECOID_SetAlgorithmID(cinfo->poolp, &signerinfo->digestAlg, + digestalgtag, NULL); if (rv != SECSuccess) { - PORT_ArenaRelease (cinfo->poolp, mark); - return SECFailure; + PORT_ArenaRelease(cinfo->poolp, mark); + return SECFailure; } /* @@ -265,46 +256,46 @@ sec_pkcs7_add_signer (SEC_PKCS7ContentInfo *cinfo, * should be *added* to the set already found. */ - signerinfos = (SEC_PKCS7SignerInfo**)PORT_ArenaAlloc (cinfo->poolp, - 2 * sizeof(SEC_PKCS7SignerInfo *)); + signerinfos = (SEC_PKCS7SignerInfo **)PORT_ArenaAlloc(cinfo->poolp, + 2 * sizeof(SEC_PKCS7SignerInfo *)); if (signerinfos == NULL) { - PORT_ArenaRelease (cinfo->poolp, mark); - return SECFailure; + PORT_ArenaRelease(cinfo->poolp, mark); + return SECFailure; } signerinfos[0] = signerinfo; signerinfos[1] = NULL; - digestalg = PORT_ArenaZAlloc (cinfo->poolp, sizeof(SECAlgorithmID)); - digestalgs = PORT_ArenaAlloc (cinfo->poolp, 2 * sizeof(SECAlgorithmID *)); + digestalg = PORT_ArenaZAlloc(cinfo->poolp, sizeof(SECAlgorithmID)); + digestalgs = PORT_ArenaAlloc(cinfo->poolp, 2 * sizeof(SECAlgorithmID *)); if (digestalg == NULL || digestalgs == NULL) { - PORT_ArenaRelease (cinfo->poolp, mark); - return SECFailure; + PORT_ArenaRelease(cinfo->poolp, mark); + return SECFailure; } - rv = SECOID_SetAlgorithmID (cinfo->poolp, digestalg, digestalgtag, NULL); + rv = SECOID_SetAlgorithmID(cinfo->poolp, digestalg, digestalgtag, NULL); if (rv != SECSuccess) { - PORT_ArenaRelease (cinfo->poolp, mark); - return SECFailure; + PORT_ArenaRelease(cinfo->poolp, mark); + return SECFailure; } digestalgs[0] = digestalg; digestalgs[1] = NULL; if (digestdata != NULL) { - digest = (SECItem*)PORT_ArenaAlloc (cinfo->poolp, sizeof(SECItem)); - digests = (SECItem**)PORT_ArenaAlloc (cinfo->poolp, - 2 * sizeof(SECItem *)); - if (digest == NULL || digests == NULL) { - PORT_ArenaRelease (cinfo->poolp, mark); - return SECFailure; - } - rv = SECITEM_CopyItem (cinfo->poolp, digest, digestdata); - if (rv != SECSuccess) { - PORT_ArenaRelease (cinfo->poolp, mark); - return SECFailure; - } - digests[0] = digest; - digests[1] = NULL; + digest = (SECItem *)PORT_ArenaAlloc(cinfo->poolp, sizeof(SECItem)); + digests = (SECItem **)PORT_ArenaAlloc(cinfo->poolp, + 2 * sizeof(SECItem *)); + if (digest == NULL || digests == NULL) { + PORT_ArenaRelease(cinfo->poolp, mark); + return SECFailure; + } + rv = SECITEM_CopyItem(cinfo->poolp, digest, digestdata); + if (rv != SECSuccess) { + PORT_ArenaRelease(cinfo->poolp, mark); + return SECFailure; + } + digests[0] = digest; + digests[1] = NULL; } else { - digests = NULL; + digests = NULL; } *signerinfosp = signerinfos; @@ -315,40 +306,38 @@ sec_pkcs7_add_signer (SEC_PKCS7ContentInfo *cinfo, return SECSuccess; } - /* * Helper function for creating an empty signedData. */ static SEC_PKCS7ContentInfo * -sec_pkcs7_create_signed_data (SECKEYGetPasswordKey pwfn, void *pwfn_arg) +sec_pkcs7_create_signed_data(SECKEYGetPasswordKey pwfn, void *pwfn_arg) { SEC_PKCS7ContentInfo *cinfo; SEC_PKCS7SignedData *sigd; SECStatus rv; - cinfo = sec_pkcs7_create_content_info (SEC_OID_PKCS7_SIGNED_DATA, PR_FALSE, - pwfn, pwfn_arg); + cinfo = sec_pkcs7_create_content_info(SEC_OID_PKCS7_SIGNED_DATA, PR_FALSE, + pwfn, pwfn_arg); if (cinfo == NULL) - return NULL; + return NULL; sigd = cinfo->content.signedData; - PORT_Assert (sigd != NULL); + PORT_Assert(sigd != NULL); /* * XXX Might we want to allow content types other than data? * If so, via what interface? */ - rv = sec_pkcs7_init_content_info (&(sigd->contentInfo), cinfo->poolp, - SEC_OID_PKCS7_DATA, PR_TRUE); + rv = sec_pkcs7_init_content_info(&(sigd->contentInfo), cinfo->poolp, + SEC_OID_PKCS7_DATA, PR_TRUE); if (rv != SECSuccess) { - SEC_PKCS7DestroyContentInfo (cinfo); - return NULL; + SEC_PKCS7DestroyContentInfo(cinfo); + return NULL; } return cinfo; } - /* * Start a PKCS7 signing context. * @@ -378,70 +367,69 @@ sec_pkcs7_create_signed_data (SECKEYGetPasswordKey pwfn, void *pwfn_arg) * (Retrieve specific errors via PORT_GetError()/XP_GetError().) */ SEC_PKCS7ContentInfo * -SEC_PKCS7CreateSignedData (CERTCertificate *cert, - SECCertUsage certusage, - CERTCertDBHandle *certdb, - SECOidTag digestalg, - SECItem *digest, - SECKEYGetPasswordKey pwfn, void *pwfn_arg) +SEC_PKCS7CreateSignedData(CERTCertificate *cert, + SECCertUsage certusage, + CERTCertDBHandle *certdb, + SECOidTag digestalg, + SECItem *digest, + SECKEYGetPasswordKey pwfn, void *pwfn_arg) { SEC_PKCS7ContentInfo *cinfo; SECStatus rv; - cinfo = sec_pkcs7_create_signed_data (pwfn, pwfn_arg); + cinfo = sec_pkcs7_create_signed_data(pwfn, pwfn_arg); if (cinfo == NULL) - return NULL; + return NULL; - rv = sec_pkcs7_add_signer (cinfo, cert, certusage, certdb, - digestalg, digest); + rv = sec_pkcs7_add_signer(cinfo, cert, certusage, certdb, + digestalg, digest); if (rv != SECSuccess) { - SEC_PKCS7DestroyContentInfo (cinfo); - return NULL; + SEC_PKCS7DestroyContentInfo(cinfo); + return NULL; } return cinfo; } - static SEC_PKCS7Attribute * -sec_pkcs7_create_attribute (PLArenaPool *poolp, SECOidTag oidtag, - SECItem *value, PRBool encoded) +sec_pkcs7_create_attribute(PLArenaPool *poolp, SECOidTag oidtag, + SECItem *value, PRBool encoded) { SEC_PKCS7Attribute *attr; SECItem **values; void *mark; - PORT_Assert (poolp != NULL); - mark = PORT_ArenaMark (poolp); + PORT_Assert(poolp != NULL); + mark = PORT_ArenaMark(poolp); - attr = (SEC_PKCS7Attribute*)PORT_ArenaAlloc (poolp, - sizeof(SEC_PKCS7Attribute)); + attr = (SEC_PKCS7Attribute *)PORT_ArenaAlloc(poolp, + sizeof(SEC_PKCS7Attribute)); if (attr == NULL) - goto loser; + goto loser; - attr->typeTag = SECOID_FindOIDByTag (oidtag); + attr->typeTag = SECOID_FindOIDByTag(oidtag); if (attr->typeTag == NULL) - goto loser; + goto loser; - if (SECITEM_CopyItem (poolp, &(attr->type), - &(attr->typeTag->oid)) != SECSuccess) - goto loser; + if (SECITEM_CopyItem(poolp, &(attr->type), + &(attr->typeTag->oid)) != SECSuccess) + goto loser; - values = (SECItem**)PORT_ArenaAlloc (poolp, 2 * sizeof(SECItem *)); + values = (SECItem **)PORT_ArenaAlloc(poolp, 2 * sizeof(SECItem *)); if (values == NULL) - goto loser; + goto loser; if (value != NULL) { - SECItem *copy; + SECItem *copy; - copy = (SECItem*)PORT_ArenaAlloc (poolp, sizeof(SECItem)); - if (copy == NULL) - goto loser; + copy = (SECItem *)PORT_ArenaAlloc(poolp, sizeof(SECItem)); + if (copy == NULL) + goto loser; - if (SECITEM_CopyItem (poolp, copy, value) != SECSuccess) - goto loser; + if (SECITEM_CopyItem(poolp, copy, value) != SECSuccess) + goto loser; - value = copy; + value = copy; } values[0] = value; @@ -449,62 +437,61 @@ sec_pkcs7_create_attribute (PLArenaPool *poolp, SECOidTag oidtag, attr->values = values; attr->encoded = encoded; - PORT_ArenaUnmark (poolp, mark); + PORT_ArenaUnmark(poolp, mark); return attr; loser: - PORT_Assert (mark != NULL); - PORT_ArenaRelease (poolp, mark); + PORT_Assert(mark != NULL); + PORT_ArenaRelease(poolp, mark); return NULL; } - static SECStatus -sec_pkcs7_add_attribute (SEC_PKCS7ContentInfo *cinfo, - SEC_PKCS7Attribute ***attrsp, - SEC_PKCS7Attribute *attr) +sec_pkcs7_add_attribute(SEC_PKCS7ContentInfo *cinfo, + SEC_PKCS7Attribute ***attrsp, + SEC_PKCS7Attribute *attr) { SEC_PKCS7Attribute **attrs; SECItem *ct_value; void *mark; - PORT_Assert (SEC_PKCS7ContentType (cinfo) == SEC_OID_PKCS7_SIGNED_DATA); - if (SEC_PKCS7ContentType (cinfo) != SEC_OID_PKCS7_SIGNED_DATA) - return SECFailure; + PORT_Assert(SEC_PKCS7ContentType(cinfo) == SEC_OID_PKCS7_SIGNED_DATA); + if (SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_SIGNED_DATA) + return SECFailure; attrs = *attrsp; if (attrs != NULL) { - int count; + int count; - /* + /* * We already have some attributes, and just need to add this * new one. */ - /* + /* * We should already have the *required* attributes, which were * created/added at the same time the first attribute was added. */ - PORT_Assert (sec_PKCS7FindAttribute (attrs, - SEC_OID_PKCS9_CONTENT_TYPE, - PR_FALSE) != NULL); - PORT_Assert (sec_PKCS7FindAttribute (attrs, - SEC_OID_PKCS9_MESSAGE_DIGEST, - PR_FALSE) != NULL); - - for (count = 0; attrs[count] != NULL; count++) - ; - attrs = (SEC_PKCS7Attribute**)PORT_ArenaGrow (cinfo->poolp, attrs, - (count + 1) * sizeof(SEC_PKCS7Attribute *), - (count + 2) * sizeof(SEC_PKCS7Attribute *)); - if (attrs == NULL) - return SECFailure; - - attrs[count] = attr; - attrs[count+1] = NULL; - *attrsp = attrs; - - return SECSuccess; + PORT_Assert(sec_PKCS7FindAttribute(attrs, + SEC_OID_PKCS9_CONTENT_TYPE, + PR_FALSE) != NULL); + PORT_Assert(sec_PKCS7FindAttribute(attrs, + SEC_OID_PKCS9_MESSAGE_DIGEST, + PR_FALSE) != NULL); + + for (count = 0; attrs[count] != NULL; count++) + ; + attrs = (SEC_PKCS7Attribute **)PORT_ArenaGrow(cinfo->poolp, attrs, + (count + 1) * sizeof(SEC_PKCS7Attribute *), + (count + 2) * sizeof(SEC_PKCS7Attribute *)); + if (attrs == NULL) + return SECFailure; + + attrs[count] = attr; + attrs[count + 1] = NULL; + *attrsp = attrs; + + return SECSuccess; } /* @@ -517,43 +504,42 @@ sec_pkcs7_add_attribute (SEC_PKCS7ContentInfo *cinfo, * There are 2 required attributes, plus the one our caller wants * to add, plus we always end with a NULL one. Thus, four slots. */ - attrs = (SEC_PKCS7Attribute**)PORT_ArenaAlloc (cinfo->poolp, - 4 * sizeof(SEC_PKCS7Attribute *)); + attrs = (SEC_PKCS7Attribute **)PORT_ArenaAlloc(cinfo->poolp, + 4 * sizeof(SEC_PKCS7Attribute *)); if (attrs == NULL) - return SECFailure; + return SECFailure; - mark = PORT_ArenaMark (cinfo->poolp); + mark = PORT_ArenaMark(cinfo->poolp); /* * First required attribute is the content type of the data * being signed. */ ct_value = &(cinfo->content.signedData->contentInfo.contentType); - attrs[0] = sec_pkcs7_create_attribute (cinfo->poolp, - SEC_OID_PKCS9_CONTENT_TYPE, - ct_value, PR_FALSE); + attrs[0] = sec_pkcs7_create_attribute(cinfo->poolp, + SEC_OID_PKCS9_CONTENT_TYPE, + ct_value, PR_FALSE); /* * Second required attribute is the message digest of the data * being signed; we leave the value NULL for now (just create * the place for it to go), and the encoder will fill it in later. */ - attrs[1] = sec_pkcs7_create_attribute (cinfo->poolp, - SEC_OID_PKCS9_MESSAGE_DIGEST, - NULL, PR_FALSE); + attrs[1] = sec_pkcs7_create_attribute(cinfo->poolp, + SEC_OID_PKCS9_MESSAGE_DIGEST, + NULL, PR_FALSE); if (attrs[0] == NULL || attrs[1] == NULL) { - PORT_ArenaRelease (cinfo->poolp, mark); - return SECFailure; + PORT_ArenaRelease(cinfo->poolp, mark); + return SECFailure; } attrs[2] = attr; attrs[3] = NULL; *attrsp = attrs; - PORT_ArenaUnmark (cinfo->poolp, mark); + PORT_ArenaUnmark(cinfo->poolp, mark); return SECSuccess; } - /* * Add the signing time to the authenticated (i.e. signed) attributes * of "cinfo". This is expected to be included in outgoing signed @@ -571,7 +557,7 @@ sec_pkcs7_add_attribute (SEC_PKCS7ContentInfo *cinfo, * if it is not. */ SECStatus -SEC_PKCS7AddSigningTime (SEC_PKCS7ContentInfo *cinfo) +SEC_PKCS7AddSigningTime(SEC_PKCS7ContentInfo *cinfo) { SEC_PKCS7SignerInfo **signerinfos; SEC_PKCS7Attribute *attr; @@ -579,48 +565,47 @@ SEC_PKCS7AddSigningTime (SEC_PKCS7ContentInfo *cinfo) SECStatus rv; int si; - PORT_Assert (SEC_PKCS7ContentType (cinfo) == SEC_OID_PKCS7_SIGNED_DATA); - if (SEC_PKCS7ContentType (cinfo) != SEC_OID_PKCS7_SIGNED_DATA) - return SECFailure; + PORT_Assert(SEC_PKCS7ContentType(cinfo) == SEC_OID_PKCS7_SIGNED_DATA); + if (SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_SIGNED_DATA) + return SECFailure; signerinfos = cinfo->content.signedData->signerInfos; /* There has to be a signer, or it makes no sense. */ if (signerinfos == NULL || signerinfos[0] == NULL) - return SECFailure; + return SECFailure; rv = DER_EncodeTimeChoice(NULL, &stime, PR_Now()); if (rv != SECSuccess) - return rv; + return rv; - attr = sec_pkcs7_create_attribute (cinfo->poolp, - SEC_OID_PKCS9_SIGNING_TIME, - &stime, PR_FALSE); - SECITEM_FreeItem (&stime, PR_FALSE); + attr = sec_pkcs7_create_attribute(cinfo->poolp, + SEC_OID_PKCS9_SIGNING_TIME, + &stime, PR_FALSE); + SECITEM_FreeItem(&stime, PR_FALSE); if (attr == NULL) - return SECFailure; + return SECFailure; rv = SECSuccess; for (si = 0; signerinfos[si] != NULL; si++) { - SEC_PKCS7Attribute *oattr; - - oattr = sec_PKCS7FindAttribute (signerinfos[si]->authAttr, - SEC_OID_PKCS9_SIGNING_TIME, PR_FALSE); - PORT_Assert (oattr == NULL); - if (oattr != NULL) - continue; /* XXX or would it be better to replace it? */ - - rv = sec_pkcs7_add_attribute (cinfo, &(signerinfos[si]->authAttr), - attr); - if (rv != SECSuccess) - break; /* could try to continue, but may as well give up now */ + SEC_PKCS7Attribute *oattr; + + oattr = sec_PKCS7FindAttribute(signerinfos[si]->authAttr, + SEC_OID_PKCS9_SIGNING_TIME, PR_FALSE); + PORT_Assert(oattr == NULL); + if (oattr != NULL) + continue; /* XXX or would it be better to replace it? */ + + rv = sec_pkcs7_add_attribute(cinfo, &(signerinfos[si]->authAttr), + attr); + if (rv != SECSuccess) + break; /* could try to continue, but may as well give up now */ } return rv; } - /* * Add the specified attribute to the authenticated (i.e. signed) attributes * of "cinfo" -- "oidtag" describes the attribute and "value" is the @@ -640,16 +625,16 @@ SEC_PKCS7AddSigningTime (SEC_PKCS7ContentInfo *cinfo) * if it is not. */ SECStatus -SEC_PKCS7AddSignedAttribute (SEC_PKCS7ContentInfo *cinfo, - SECOidTag oidtag, - SECItem *value) +SEC_PKCS7AddSignedAttribute(SEC_PKCS7ContentInfo *cinfo, + SECOidTag oidtag, + SECItem *value) { SEC_PKCS7SignerInfo **signerinfos; SEC_PKCS7Attribute *attr; - PORT_Assert (SEC_PKCS7ContentType (cinfo) == SEC_OID_PKCS7_SIGNED_DATA); - if (SEC_PKCS7ContentType (cinfo) != SEC_OID_PKCS7_SIGNED_DATA) - return SECFailure; + PORT_Assert(SEC_PKCS7ContentType(cinfo) == SEC_OID_PKCS7_SIGNED_DATA); + if (SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_SIGNED_DATA) + return SECFailure; signerinfos = cinfo->content.signedData->signerInfos; @@ -657,15 +642,14 @@ SEC_PKCS7AddSignedAttribute (SEC_PKCS7ContentInfo *cinfo, * No signature or more than one means no deal. */ if (signerinfos == NULL || signerinfos[0] == NULL || signerinfos[1] != NULL) - return SECFailure; + return SECFailure; - attr = sec_pkcs7_create_attribute (cinfo->poolp, oidtag, value, PR_TRUE); + attr = sec_pkcs7_create_attribute(cinfo->poolp, oidtag, value, PR_TRUE); if (attr == NULL) - return SECFailure; + return SECFailure; - return sec_pkcs7_add_attribute (cinfo, &(signerinfos[0]->authAttr), attr); + return sec_pkcs7_add_attribute(cinfo, &(signerinfos[0]->authAttr), attr); } - /* * Mark that the signer certificates and their issuing chain should @@ -679,115 +663,110 @@ SEC_PKCS7AddSignedAttribute (SEC_PKCS7ContentInfo *cinfo, * SECFailure will be returned if it is not. */ SECStatus -SEC_PKCS7IncludeCertChain (SEC_PKCS7ContentInfo *cinfo, - CERTCertDBHandle *certdb) +SEC_PKCS7IncludeCertChain(SEC_PKCS7ContentInfo *cinfo, + CERTCertDBHandle *certdb) { SECOidTag kind; SEC_PKCS7SignerInfo *signerinfo, **signerinfos; - kind = SEC_PKCS7ContentType (cinfo); + kind = SEC_PKCS7ContentType(cinfo); switch (kind) { - case SEC_OID_PKCS7_SIGNED_DATA: - signerinfos = cinfo->content.signedData->signerInfos; - break; - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - signerinfos = cinfo->content.signedAndEnvelopedData->signerInfos; - break; - default: - return SECFailure; /* XXX set an error? */ + case SEC_OID_PKCS7_SIGNED_DATA: + signerinfos = cinfo->content.signedData->signerInfos; + break; + case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: + signerinfos = cinfo->content.signedAndEnvelopedData->signerInfos; + break; + default: + return SECFailure; /* XXX set an error? */ } - if (signerinfos == NULL) /* no signer, no certs? */ - return SECFailure; /* XXX set an error? */ + if (signerinfos == NULL) /* no signer, no certs? */ + return SECFailure; /* XXX set an error? */ if (certdb == NULL) { - certdb = CERT_GetDefaultCertDB(); - if (certdb == NULL) { - PORT_SetError (SEC_ERROR_BAD_DATABASE); - return SECFailure; - } + certdb = CERT_GetDefaultCertDB(); + if (certdb == NULL) { + PORT_SetError(SEC_ERROR_BAD_DATABASE); + return SECFailure; + } } /* XXX Should it be an error if we find no signerinfo or no certs? */ while ((signerinfo = *signerinfos++) != NULL) { - if (signerinfo->cert != NULL) - /* get the cert chain. don't send the root to avoid contamination + if (signerinfo->cert != NULL) + /* get the cert chain. don't send the root to avoid contamination * of old clients with a new root that they don't trust */ - signerinfo->certList = CERT_CertChainFromCert (signerinfo->cert, - certUsageEmailSigner, - PR_FALSE); + signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, + certUsageEmailSigner, + PR_FALSE); } return SECSuccess; } - /* * Helper function to add a certificate chain for inclusion in the * bag of certificates in a signedData. */ static SECStatus -sec_pkcs7_add_cert_chain (SEC_PKCS7ContentInfo *cinfo, - CERTCertificate *cert, - CERTCertDBHandle *certdb) +sec_pkcs7_add_cert_chain(SEC_PKCS7ContentInfo *cinfo, + CERTCertificate *cert, + CERTCertDBHandle *certdb) { SECOidTag kind; CERTCertificateList *certlist, **certlists, ***certlistsp; int count; - kind = SEC_PKCS7ContentType (cinfo); + kind = SEC_PKCS7ContentType(cinfo); switch (kind) { - case SEC_OID_PKCS7_SIGNED_DATA: - { - SEC_PKCS7SignedData *sdp; - - sdp = cinfo->content.signedData; - certlistsp = &(sdp->certLists); - } - break; - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - { - SEC_PKCS7SignedAndEnvelopedData *saedp; - - saedp = cinfo->content.signedAndEnvelopedData; - certlistsp = &(saedp->certLists); - } - break; - default: - return SECFailure; /* XXX set an error? */ + case SEC_OID_PKCS7_SIGNED_DATA: { + SEC_PKCS7SignedData *sdp; + + sdp = cinfo->content.signedData; + certlistsp = &(sdp->certLists); + } break; + case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: { + SEC_PKCS7SignedAndEnvelopedData *saedp; + + saedp = cinfo->content.signedAndEnvelopedData; + certlistsp = &(saedp->certLists); + } break; + default: + return SECFailure; /* XXX set an error? */ } if (certdb == NULL) { - certdb = CERT_GetDefaultCertDB(); - if (certdb == NULL) { - PORT_SetError (SEC_ERROR_BAD_DATABASE); - return SECFailure; - } + certdb = CERT_GetDefaultCertDB(); + if (certdb == NULL) { + PORT_SetError(SEC_ERROR_BAD_DATABASE); + return SECFailure; + } } - certlist = CERT_CertChainFromCert (cert, certUsageEmailSigner, PR_FALSE); + certlist = CERT_CertChainFromCert(cert, certUsageEmailSigner, PR_FALSE); if (certlist == NULL) - return SECFailure; + return SECFailure; certlists = *certlistsp; if (certlists == NULL) { - count = 0; - certlists = (CERTCertificateList**)PORT_ArenaAlloc (cinfo->poolp, - 2 * sizeof(CERTCertificateList *)); + count = 0; + certlists = (CERTCertificateList **)PORT_ArenaAlloc(cinfo->poolp, + 2 * sizeof(CERTCertificateList *)); } else { - for (count = 0; certlists[count] != NULL; count++) - ; - PORT_Assert (count); /* should be at least one already */ - certlists = (CERTCertificateList**)PORT_ArenaGrow (cinfo->poolp, - certlists, - (count + 1) * sizeof(CERTCertificateList *), - (count + 2) * sizeof(CERTCertificateList *)); + for (count = 0; certlists[count] != NULL; count++) + ; + PORT_Assert(count); /* should be at least one already */ + certlists = (CERTCertificateList **)PORT_ArenaGrow(cinfo->poolp, + certlists, + (count + 1) * sizeof(CERTCertificateList *), + (count + 2) * sizeof(CERTCertificateList *)); } if (certlists == NULL) { - CERT_DestroyCertificateList (certlist); - return SECFailure; + CERT_DestroyCertificateList(certlist); + return SECFailure; } certlists[count] = certlist; @@ -798,62 +777,57 @@ sec_pkcs7_add_cert_chain (SEC_PKCS7ContentInfo *cinfo, return SECSuccess; } - /* * Helper function to add a certificate for inclusion in the bag of * certificates in a signedData. */ static SECStatus -sec_pkcs7_add_certificate (SEC_PKCS7ContentInfo *cinfo, - CERTCertificate *cert) +sec_pkcs7_add_certificate(SEC_PKCS7ContentInfo *cinfo, + CERTCertificate *cert) { SECOidTag kind; CERTCertificate **certs, ***certsp; int count; - kind = SEC_PKCS7ContentType (cinfo); + kind = SEC_PKCS7ContentType(cinfo); switch (kind) { - case SEC_OID_PKCS7_SIGNED_DATA: - { - SEC_PKCS7SignedData *sdp; - - sdp = cinfo->content.signedData; - certsp = &(sdp->certs); - } - break; - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - { - SEC_PKCS7SignedAndEnvelopedData *saedp; - - saedp = cinfo->content.signedAndEnvelopedData; - certsp = &(saedp->certs); - } - break; - default: - return SECFailure; /* XXX set an error? */ + case SEC_OID_PKCS7_SIGNED_DATA: { + SEC_PKCS7SignedData *sdp; + + sdp = cinfo->content.signedData; + certsp = &(sdp->certs); + } break; + case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: { + SEC_PKCS7SignedAndEnvelopedData *saedp; + + saedp = cinfo->content.signedAndEnvelopedData; + certsp = &(saedp->certs); + } break; + default: + return SECFailure; /* XXX set an error? */ } - cert = CERT_DupCertificate (cert); + cert = CERT_DupCertificate(cert); if (cert == NULL) - return SECFailure; + return SECFailure; certs = *certsp; if (certs == NULL) { - count = 0; - certs = (CERTCertificate**)PORT_ArenaAlloc (cinfo->poolp, - 2 * sizeof(CERTCertificate *)); + count = 0; + certs = (CERTCertificate **)PORT_ArenaAlloc(cinfo->poolp, + 2 * sizeof(CERTCertificate *)); } else { - for (count = 0; certs[count] != NULL; count++) - ; - PORT_Assert (count); /* should be at least one already */ - certs = (CERTCertificate**)PORT_ArenaGrow (cinfo->poolp, certs, - (count + 1) * sizeof(CERTCertificate *), - (count + 2) * sizeof(CERTCertificate *)); + for (count = 0; certs[count] != NULL; count++) + ; + PORT_Assert(count); /* should be at least one already */ + certs = (CERTCertificate **)PORT_ArenaGrow(cinfo->poolp, certs, + (count + 1) * sizeof(CERTCertificate *), + (count + 2) * sizeof(CERTCertificate *)); } if (certs == NULL) { - CERT_DestroyCertificate (cert); - return SECFailure; + CERT_DestroyCertificate(cert); + return SECFailure; } certs[count] = cert; @@ -864,7 +838,6 @@ sec_pkcs7_add_certificate (SEC_PKCS7ContentInfo *cinfo, return SECSuccess; } - /* * Create a PKCS7 certs-only container. * @@ -883,31 +856,30 @@ sec_pkcs7_add_certificate (SEC_PKCS7ContentInfo *cinfo, * (Retrieve specific errors via PORT_GetError()/XP_GetError().) */ SEC_PKCS7ContentInfo * -SEC_PKCS7CreateCertsOnly (CERTCertificate *cert, - PRBool include_chain, - CERTCertDBHandle *certdb) +SEC_PKCS7CreateCertsOnly(CERTCertificate *cert, + PRBool include_chain, + CERTCertDBHandle *certdb) { SEC_PKCS7ContentInfo *cinfo; SECStatus rv; - cinfo = sec_pkcs7_create_signed_data (NULL, NULL); + cinfo = sec_pkcs7_create_signed_data(NULL, NULL); if (cinfo == NULL) - return NULL; + return NULL; if (include_chain) - rv = sec_pkcs7_add_cert_chain (cinfo, cert, certdb); + rv = sec_pkcs7_add_cert_chain(cinfo, cert, certdb); else - rv = sec_pkcs7_add_certificate (cinfo, cert); + rv = sec_pkcs7_add_certificate(cinfo, cert); if (rv != SECSuccess) { - SEC_PKCS7DestroyContentInfo (cinfo); - return NULL; + SEC_PKCS7DestroyContentInfo(cinfo); + return NULL; } return cinfo; } - /* * Add "cert" and its entire chain to the set of certs included in "cinfo". * @@ -918,21 +890,19 @@ SEC_PKCS7CreateCertsOnly (CERTCertificate *cert, * SECFailure will be returned if it is not. */ SECStatus -SEC_PKCS7AddCertChain (SEC_PKCS7ContentInfo *cinfo, - CERTCertificate *cert, - CERTCertDBHandle *certdb) +SEC_PKCS7AddCertChain(SEC_PKCS7ContentInfo *cinfo, + CERTCertificate *cert, + CERTCertDBHandle *certdb) { SECOidTag kind; - kind = SEC_PKCS7ContentType (cinfo); - if (kind != SEC_OID_PKCS7_SIGNED_DATA - && kind != SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA) - return SECFailure; /* XXX set an error? */ + kind = SEC_PKCS7ContentType(cinfo); + if (kind != SEC_OID_PKCS7_SIGNED_DATA && kind != SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA) + return SECFailure; /* XXX set an error? */ - return sec_pkcs7_add_cert_chain (cinfo, cert, certdb); + return sec_pkcs7_add_cert_chain(cinfo, cert, certdb); } - /* * Add "cert" to the set of certs included in "cinfo". * @@ -940,30 +910,28 @@ SEC_PKCS7AddCertChain (SEC_PKCS7ContentInfo *cinfo, * SECFailure will be returned if it is not. */ SECStatus -SEC_PKCS7AddCertificate (SEC_PKCS7ContentInfo *cinfo, CERTCertificate *cert) +SEC_PKCS7AddCertificate(SEC_PKCS7ContentInfo *cinfo, CERTCertificate *cert) { SECOidTag kind; - kind = SEC_PKCS7ContentType (cinfo); - if (kind != SEC_OID_PKCS7_SIGNED_DATA - && kind != SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA) - return SECFailure; /* XXX set an error? */ + kind = SEC_PKCS7ContentType(cinfo); + if (kind != SEC_OID_PKCS7_SIGNED_DATA && kind != SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA) + return SECFailure; /* XXX set an error? */ - return sec_pkcs7_add_certificate (cinfo, cert); + return sec_pkcs7_add_certificate(cinfo, cert); } - static SECStatus -sec_pkcs7_init_encrypted_content_info (SEC_PKCS7EncryptedContentInfo *enccinfo, - PLArenaPool *poolp, - SECOidTag kind, PRBool detached, - SECOidTag encalg, int keysize) +sec_pkcs7_init_encrypted_content_info(SEC_PKCS7EncryptedContentInfo *enccinfo, + PLArenaPool *poolp, + SECOidTag kind, PRBool detached, + SECOidTag encalg, int keysize) { SECStatus rv; - PORT_Assert (enccinfo != NULL && poolp != NULL); + PORT_Assert(enccinfo != NULL && poolp != NULL); if (enccinfo == NULL || poolp == NULL) - return SECFailure; + return SECFailure; /* * XXX Some day we may want to allow for other kinds. That needs @@ -972,16 +940,15 @@ sec_pkcs7_init_encrypted_content_info (SEC_PKCS7EncryptedContentInfo *enccinfo, * They are responsible for creating the inner type and encoding, * if it is other than DATA. */ - PORT_Assert (kind == SEC_OID_PKCS7_DATA); + PORT_Assert(kind == SEC_OID_PKCS7_DATA); - enccinfo->contentTypeTag = SECOID_FindOIDByTag (kind); - PORT_Assert (enccinfo->contentTypeTag - && enccinfo->contentTypeTag->offset == kind); + enccinfo->contentTypeTag = SECOID_FindOIDByTag(kind); + PORT_Assert(enccinfo->contentTypeTag && enccinfo->contentTypeTag->offset == kind); - rv = SECITEM_CopyItem (poolp, &(enccinfo->contentType), - &(enccinfo->contentTypeTag->oid)); + rv = SECITEM_CopyItem(poolp, &(enccinfo->contentType), + &(enccinfo->contentTypeTag->oid)); if (rv != SECSuccess) - return rv; + return rv; /* Save keysize and algorithm for later. */ enccinfo->keysize = keysize; @@ -990,16 +957,15 @@ sec_pkcs7_init_encrypted_content_info (SEC_PKCS7EncryptedContentInfo *enccinfo, return SECSuccess; } - /* * Add a recipient to a PKCS7 thing, verifying their cert first. * Any error returns SECFailure. */ static SECStatus -sec_pkcs7_add_recipient (SEC_PKCS7ContentInfo *cinfo, - CERTCertificate *cert, - SECCertUsage certusage, - CERTCertDBHandle *certdb) +sec_pkcs7_add_recipient(SEC_PKCS7ContentInfo *cinfo, + CERTCertificate *cert, + SECCertUsage certusage, + CERTCertDBHandle *certdb) { SECOidTag kind; SEC_PKCS7RecipientInfo *recipientinfo, **recipientinfos, ***recipientinfosp; @@ -1007,26 +973,22 @@ sec_pkcs7_add_recipient (SEC_PKCS7ContentInfo *cinfo, void *mark; int count; - kind = SEC_PKCS7ContentType (cinfo); + kind = SEC_PKCS7ContentType(cinfo); switch (kind) { - case SEC_OID_PKCS7_ENVELOPED_DATA: - { - SEC_PKCS7EnvelopedData *edp; - - edp = cinfo->content.envelopedData; - recipientinfosp = &(edp->recipientInfos); - } - break; - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - { - SEC_PKCS7SignedAndEnvelopedData *saedp; - - saedp = cinfo->content.signedAndEnvelopedData; - recipientinfosp = &(saedp->recipientInfos); - } - break; - default: - return SECFailure; /* XXX set an error? */ + case SEC_OID_PKCS7_ENVELOPED_DATA: { + SEC_PKCS7EnvelopedData *edp; + + edp = cinfo->content.envelopedData; + recipientinfosp = &(edp->recipientInfos); + } break; + case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: { + SEC_PKCS7SignedAndEnvelopedData *saedp; + + saedp = cinfo->content.signedAndEnvelopedData; + recipientinfosp = &(saedp->recipientInfos); + } break; + default: + return SECFailure; /* XXX set an error? */ } /* @@ -1034,45 +996,44 @@ sec_pkcs7_add_recipient (SEC_PKCS7ContentInfo *cinfo, * a NULL database. */ if (certdb == NULL) { - certdb = CERT_GetDefaultCertDB(); - if (certdb == NULL) - return SECFailure; /* XXX set an error? */ + certdb = CERT_GetDefaultCertDB(); + if (certdb == NULL) + return SECFailure; /* XXX set an error? */ } - if (CERT_VerifyCert (certdb, cert, PR_TRUE, certusage, PR_Now(), - cinfo->pwfn_arg, NULL) != SECSuccess) - { - /* XXX Did CERT_VerifyCert set an error? */ - return SECFailure; + if (CERT_VerifyCert(certdb, cert, PR_TRUE, certusage, PR_Now(), + cinfo->pwfn_arg, NULL) != SECSuccess) { + /* XXX Did CERT_VerifyCert set an error? */ + return SECFailure; } - mark = PORT_ArenaMark (cinfo->poolp); + mark = PORT_ArenaMark(cinfo->poolp); - recipientinfo = (SEC_PKCS7RecipientInfo*)PORT_ArenaZAlloc (cinfo->poolp, - sizeof(SEC_PKCS7RecipientInfo)); + recipientinfo = (SEC_PKCS7RecipientInfo *)PORT_ArenaZAlloc(cinfo->poolp, + sizeof(SEC_PKCS7RecipientInfo)); if (recipientinfo == NULL) { - PORT_ArenaRelease (cinfo->poolp, mark); - return SECFailure; + PORT_ArenaRelease(cinfo->poolp, mark); + return SECFailure; } - dummy = SEC_ASN1EncodeInteger (cinfo->poolp, &recipientinfo->version, - SEC_PKCS7_RECIPIENT_INFO_VERSION); + dummy = SEC_ASN1EncodeInteger(cinfo->poolp, &recipientinfo->version, + SEC_PKCS7_RECIPIENT_INFO_VERSION); if (dummy == NULL) { - PORT_ArenaRelease (cinfo->poolp, mark); - return SECFailure; + PORT_ArenaRelease(cinfo->poolp, mark); + return SECFailure; } - PORT_Assert (dummy == &recipientinfo->version); + PORT_Assert(dummy == &recipientinfo->version); - recipientinfo->cert = CERT_DupCertificate (cert); + recipientinfo->cert = CERT_DupCertificate(cert); if (recipientinfo->cert == NULL) { - PORT_ArenaRelease (cinfo->poolp, mark); - return SECFailure; + PORT_ArenaRelease(cinfo->poolp, mark); + return SECFailure; } - recipientinfo->issuerAndSN = CERT_GetCertIssuerAndSN (cinfo->poolp, cert); + recipientinfo->issuerAndSN = CERT_GetCertIssuerAndSN(cinfo->poolp, cert); if (recipientinfo->issuerAndSN == NULL) { - PORT_ArenaRelease (cinfo->poolp, mark); - return SECFailure; + PORT_ArenaRelease(cinfo->poolp, mark); + return SECFailure; } /* @@ -1084,23 +1045,23 @@ sec_pkcs7_add_recipient (SEC_PKCS7ContentInfo *cinfo, */ recipientinfos = *recipientinfosp; if (recipientinfos == NULL) { - count = 0; - recipientinfos = (SEC_PKCS7RecipientInfo **)PORT_ArenaAlloc ( - cinfo->poolp, - 2 * sizeof(SEC_PKCS7RecipientInfo *)); + count = 0; + recipientinfos = (SEC_PKCS7RecipientInfo **)PORT_ArenaAlloc( + cinfo->poolp, + 2 * sizeof(SEC_PKCS7RecipientInfo *)); } else { - for (count = 0; recipientinfos[count] != NULL; count++) - ; - PORT_Assert (count); /* should be at least one already */ - recipientinfos = (SEC_PKCS7RecipientInfo **)PORT_ArenaGrow ( - cinfo->poolp, recipientinfos, - (count + 1) * sizeof(SEC_PKCS7RecipientInfo *), - (count + 2) * sizeof(SEC_PKCS7RecipientInfo *)); + for (count = 0; recipientinfos[count] != NULL; count++) + ; + PORT_Assert(count); /* should be at least one already */ + recipientinfos = (SEC_PKCS7RecipientInfo **)PORT_ArenaGrow( + cinfo->poolp, recipientinfos, + (count + 1) * sizeof(SEC_PKCS7RecipientInfo *), + (count + 2) * sizeof(SEC_PKCS7RecipientInfo *)); } if (recipientinfos == NULL) { - PORT_ArenaRelease (cinfo->poolp, mark); - return SECFailure; + PORT_ArenaRelease(cinfo->poolp, mark); + return SECFailure; } recipientinfos[count] = recipientinfo; @@ -1108,11 +1069,10 @@ sec_pkcs7_add_recipient (SEC_PKCS7ContentInfo *cinfo, *recipientinfosp = recipientinfos; - PORT_ArenaUnmark (cinfo->poolp, mark); + PORT_ArenaUnmark(cinfo->poolp, mark); return SECSuccess; } - /* * Start a PKCS7 enveloping context. * @@ -1140,42 +1100,42 @@ sec_pkcs7_add_recipient (SEC_PKCS7ContentInfo *cinfo, * (Retrieve specific errors via PORT_GetError()/XP_GetError().) */ extern SEC_PKCS7ContentInfo * -SEC_PKCS7CreateEnvelopedData (CERTCertificate *cert, - SECCertUsage certusage, - CERTCertDBHandle *certdb, - SECOidTag encalg, - int keysize, - SECKEYGetPasswordKey pwfn, void *pwfn_arg) +SEC_PKCS7CreateEnvelopedData(CERTCertificate *cert, + SECCertUsage certusage, + CERTCertDBHandle *certdb, + SECOidTag encalg, + int keysize, + SECKEYGetPasswordKey pwfn, void *pwfn_arg) { SEC_PKCS7ContentInfo *cinfo; SEC_PKCS7EnvelopedData *envd; SECStatus rv; - cinfo = sec_pkcs7_create_content_info (SEC_OID_PKCS7_ENVELOPED_DATA, - PR_FALSE, pwfn, pwfn_arg); + cinfo = sec_pkcs7_create_content_info(SEC_OID_PKCS7_ENVELOPED_DATA, + PR_FALSE, pwfn, pwfn_arg); if (cinfo == NULL) - return NULL; + return NULL; - rv = sec_pkcs7_add_recipient (cinfo, cert, certusage, certdb); + rv = sec_pkcs7_add_recipient(cinfo, cert, certusage, certdb); if (rv != SECSuccess) { - SEC_PKCS7DestroyContentInfo (cinfo); - return NULL; + SEC_PKCS7DestroyContentInfo(cinfo); + return NULL; } envd = cinfo->content.envelopedData; - PORT_Assert (envd != NULL); + PORT_Assert(envd != NULL); /* * XXX Might we want to allow content types other than data? * If so, via what interface? */ - rv = sec_pkcs7_init_encrypted_content_info (&(envd->encContentInfo), - cinfo->poolp, - SEC_OID_PKCS7_DATA, PR_FALSE, - encalg, keysize); + rv = sec_pkcs7_init_encrypted_content_info(&(envd->encContentInfo), + cinfo->poolp, + SEC_OID_PKCS7_DATA, PR_FALSE, + encalg, keysize); if (rv != SECSuccess) { - SEC_PKCS7DestroyContentInfo (cinfo); - return NULL; + SEC_PKCS7DestroyContentInfo(cinfo); + return NULL; } /* XXX Anything more to do here? */ @@ -1183,7 +1143,6 @@ SEC_PKCS7CreateEnvelopedData (CERTCertificate *cert, return cinfo; } - /* * Add another recipient to an encrypted message. * @@ -1202,15 +1161,14 @@ SEC_PKCS7CreateEnvelopedData (CERTCertificate *cert, * It can be NULL if a default database is available (like in the client). */ SECStatus -SEC_PKCS7AddRecipient (SEC_PKCS7ContentInfo *cinfo, - CERTCertificate *cert, - SECCertUsage certusage, - CERTCertDBHandle *certdb) +SEC_PKCS7AddRecipient(SEC_PKCS7ContentInfo *cinfo, + CERTCertificate *cert, + SECCertUsage certusage, + CERTCertDBHandle *certdb) { - return sec_pkcs7_add_recipient (cinfo, cert, certusage, certdb); + return sec_pkcs7_add_recipient(cinfo, cert, certusage, certdb); } - /* * Create an empty PKCS7 data content info. * @@ -1218,13 +1176,12 @@ SEC_PKCS7AddRecipient (SEC_PKCS7ContentInfo *cinfo, * (Retrieve specific errors via PORT_GetError()/XP_GetError().) */ SEC_PKCS7ContentInfo * -SEC_PKCS7CreateData (void) +SEC_PKCS7CreateData(void) { - return sec_pkcs7_create_content_info (SEC_OID_PKCS7_DATA, PR_FALSE, - NULL, NULL); + return sec_pkcs7_create_content_info(SEC_OID_PKCS7_DATA, PR_FALSE, + NULL, NULL); } - /* * Create an empty PKCS7 encrypted content info. * @@ -1234,24 +1191,24 @@ SEC_PKCS7CreateData (void) * (Retrieve specific errors via PORT_GetError()/XP_GetError().) */ SEC_PKCS7ContentInfo * -SEC_PKCS7CreateEncryptedData (SECOidTag algorithm, int keysize, - SECKEYGetPasswordKey pwfn, void *pwfn_arg) +SEC_PKCS7CreateEncryptedData(SECOidTag algorithm, int keysize, + SECKEYGetPasswordKey pwfn, void *pwfn_arg) { SEC_PKCS7ContentInfo *cinfo; SECAlgorithmID *algid; SEC_PKCS7EncryptedData *enc_data; SECStatus rv; - cinfo = sec_pkcs7_create_content_info (SEC_OID_PKCS7_ENCRYPTED_DATA, - PR_FALSE, pwfn, pwfn_arg); + cinfo = sec_pkcs7_create_content_info(SEC_OID_PKCS7_ENCRYPTED_DATA, + PR_FALSE, pwfn, pwfn_arg); if (cinfo == NULL) - return NULL; + return NULL; enc_data = cinfo->content.encryptedData; algid = &(enc_data->encContentInfo.contentEncAlg); if (!SEC_PKCS5IsAlgorithmPBEAlgTag(algorithm)) { - rv = SECOID_SetAlgorithmID (cinfo->poolp, algid, algorithm, NULL); + rv = SECOID_SetAlgorithmID(cinfo->poolp, algid, algorithm, NULL); } else { /* Assume password-based-encryption. * Note: we can't generate pkcs5v2 from this interface. @@ -1260,32 +1217,31 @@ SEC_PKCS7CreateEncryptedData (SECOidTag algorithm, int keysize, * NSS_CMSEncryptedData_Create accepts non-PBE oids as regular * CMS encrypted data, so we can't tell SEC_PKCS7CreateEncryptedtedData * to create pkcs5v2 PBEs */ - SECAlgorithmID *pbe_algid; - pbe_algid = PK11_CreatePBEAlgorithmID(algorithm, + SECAlgorithmID *pbe_algid; + pbe_algid = PK11_CreatePBEAlgorithmID(algorithm, NSS_PBE_DEFAULT_ITERATION_COUNT, NULL); - if (pbe_algid == NULL) { - rv = SECFailure; - } else { - rv = SECOID_CopyAlgorithmID (cinfo->poolp, algid, pbe_algid); - SECOID_DestroyAlgorithmID (pbe_algid, PR_TRUE); - } + if (pbe_algid == NULL) { + rv = SECFailure; + } else { + rv = SECOID_CopyAlgorithmID(cinfo->poolp, algid, pbe_algid); + SECOID_DestroyAlgorithmID(pbe_algid, PR_TRUE); + } } if (rv != SECSuccess) { - SEC_PKCS7DestroyContentInfo (cinfo); - return NULL; + SEC_PKCS7DestroyContentInfo(cinfo); + return NULL; } - rv = sec_pkcs7_init_encrypted_content_info (&(enc_data->encContentInfo), - cinfo->poolp, - SEC_OID_PKCS7_DATA, PR_FALSE, - algorithm, keysize); + rv = sec_pkcs7_init_encrypted_content_info(&(enc_data->encContentInfo), + cinfo->poolp, + SEC_OID_PKCS7_DATA, PR_FALSE, + algorithm, keysize); if (rv != SECSuccess) { - SEC_PKCS7DestroyContentInfo (cinfo); - return NULL; + SEC_PKCS7DestroyContentInfo(cinfo); + return NULL; } return cinfo; } - diff --git a/nss/lib/pkcs7/p7decode.c b/nss/lib/pkcs7/p7decode.c index 7a52d82..658c61e 100644 --- a/nss/lib/pkcs7/p7decode.c +++ b/nss/lib/pkcs7/p7decode.c @@ -9,11 +9,11 @@ #include "p7local.h" #include "cert.h" - /* XXX do not want to have to include */ -#include "certdb.h" /* certdb.h -- the trust stuff needed by */ - /* the add certificate code needs to get */ - /* rewritten/abstracted and then this */ - /* include should be removed! */ +/* XXX do not want to have to include */ +#include "certdb.h" /* certdb.h -- the trust stuff needed by */ + /* the add certificate code needs to get */ + /* rewritten/abstracted and then this */ + /* include should be removed! */ /*#include "cdbhdl.h" */ #include "cryptohi.h" #include "key.h" @@ -23,7 +23,7 @@ #include "pk11func.h" #include "prtime.h" #include "secerr.h" -#include "sechash.h" /* for HASH_GetHashObject() */ +#include "sechash.h" /* for HASH_GetHashObject() */ #include "secder.h" #include "secpkcs5.h" @@ -60,10 +60,10 @@ struct SEC_PKCS7DecoderContextStr { * corresponding to the given worker. */ static void -sec_pkcs7_decoder_work_data (SEC_PKCS7DecoderContext *p7dcx, - struct sec_pkcs7_decoder_worker *worker, - const unsigned char *data, unsigned long len, - PRBool final) +sec_pkcs7_decoder_work_data(SEC_PKCS7DecoderContext *p7dcx, + struct sec_pkcs7_decoder_worker *worker, + const unsigned char *data, unsigned long len, + PRBool final) { unsigned char *buf = NULL; SECStatus rv; @@ -76,7 +76,7 @@ sec_pkcs7_decoder_work_data (SEC_PKCS7DecoderContext *p7dcx, * proves they do it right. But it could find a bug in future * modifications/development, that is why it is here.) */ - PORT_Assert ((data != NULL && len) || final); + PORT_Assert((data != NULL && len) || final); /* * Decrypt this chunk. @@ -87,100 +87,99 @@ sec_pkcs7_decoder_work_data (SEC_PKCS7DecoderContext *p7dcx, * sending the data back and they want to know that. */ if (worker->decryptobj != NULL) { - /* XXX the following lengths should all be longs? */ - unsigned int inlen; /* length of data being decrypted */ - unsigned int outlen; /* length of decrypted data */ - unsigned int buflen; /* length available for decrypted data */ - SECItem *plain; - - inlen = len; - buflen = sec_PKCS7DecryptLength (worker->decryptobj, inlen, final); - if (buflen == 0) { - if (inlen == 0) /* no input and no output */ - return; - /* - * No output is expected, but the input data may be buffered - * so we still have to call Decrypt. - */ - rv = sec_PKCS7Decrypt (worker->decryptobj, NULL, NULL, 0, - data, inlen, final); - if (rv != SECSuccess) { - p7dcx->error = PORT_GetError(); - return; /* XXX indicate error? */ - } - return; - } - - if (p7dcx->cb != NULL) { - buf = (unsigned char *) PORT_Alloc (buflen); - plain = NULL; - } else { - unsigned long oldlen; - - /* - * XXX This assumes one level of content only. - * See comment above about nested content types. - * XXX Also, it should work for signedAndEnvelopedData, too! - */ - plain = &(p7dcx->cinfo-> - content.envelopedData->encContentInfo.plainContent); - - oldlen = plain->len; - if (oldlen == 0) { - buf = (unsigned char*)PORT_ArenaAlloc (p7dcx->cinfo->poolp, - buflen); - } else { - buf = (unsigned char*)PORT_ArenaGrow (p7dcx->cinfo->poolp, - plain->data, - oldlen, oldlen + buflen); - if (buf != NULL) - buf += oldlen; - } - plain->data = buf; - } - if (buf == NULL) { - p7dcx->error = SEC_ERROR_NO_MEMORY; - return; /* XXX indicate error? */ - } - rv = sec_PKCS7Decrypt (worker->decryptobj, buf, &outlen, buflen, - data, inlen, final); - if (rv != SECSuccess) { - p7dcx->error = PORT_GetError(); - return; /* XXX indicate error? */ - } - if (plain != NULL) { - PORT_Assert (final || outlen == buflen); - plain->len += outlen; - } - data = buf; - len = outlen; + /* XXX the following lengths should all be longs? */ + unsigned int inlen; /* length of data being decrypted */ + unsigned int outlen; /* length of decrypted data */ + unsigned int buflen; /* length available for decrypted data */ + SECItem *plain; + + inlen = len; + buflen = sec_PKCS7DecryptLength(worker->decryptobj, inlen, final); + if (buflen == 0) { + if (inlen == 0) /* no input and no output */ + return; + /* + * No output is expected, but the input data may be buffered + * so we still have to call Decrypt. + */ + rv = sec_PKCS7Decrypt(worker->decryptobj, NULL, NULL, 0, + data, inlen, final); + if (rv != SECSuccess) { + p7dcx->error = PORT_GetError(); + return; /* XXX indicate error? */ + } + return; + } + + if (p7dcx->cb != NULL) { + buf = (unsigned char *)PORT_Alloc(buflen); + plain = NULL; + } else { + unsigned long oldlen; + + /* + * XXX This assumes one level of content only. + * See comment above about nested content types. + * XXX Also, it should work for signedAndEnvelopedData, too! + */ + plain = &(p7dcx->cinfo->content.envelopedData->encContentInfo.plainContent); + + oldlen = plain->len; + if (oldlen == 0) { + buf = (unsigned char *)PORT_ArenaAlloc(p7dcx->cinfo->poolp, + buflen); + } else { + buf = (unsigned char *)PORT_ArenaGrow(p7dcx->cinfo->poolp, + plain->data, + oldlen, oldlen + buflen); + if (buf != NULL) + buf += oldlen; + } + plain->data = buf; + } + if (buf == NULL) { + p7dcx->error = SEC_ERROR_NO_MEMORY; + return; /* XXX indicate error? */ + } + rv = sec_PKCS7Decrypt(worker->decryptobj, buf, &outlen, buflen, + data, inlen, final); + if (rv != SECSuccess) { + p7dcx->error = PORT_GetError(); + return; /* XXX indicate error? */ + } + if (plain != NULL) { + PORT_Assert(final || outlen == buflen); + plain->len += outlen; + } + data = buf; + len = outlen; } /* * Update the running digests. */ if (len) { - for (i = 0; i < worker->digcnt; i++) { - (* worker->digobjs[i]->update) (worker->digcxs[i], data, len); - } + for (i = 0; i < worker->digcnt; i++) { + (*worker->digobjs[i]->update)(worker->digcxs[i], data, len); + } } /* * Pass back the contents bytes, and free the temporary buffer. */ if (p7dcx->cb != NULL) { - if (len) - (* p7dcx->cb) (p7dcx->cb_arg, (const char *)data, len); - if (worker->decryptobj != NULL) { - PORT_Assert (buf != NULL); - PORT_Free (buf); - } + if (len) + (*p7dcx->cb)(p7dcx->cb_arg, (const char *)data, len); + if (worker->decryptobj != NULL) { + PORT_Assert(buf != NULL); + PORT_Free(buf); + } } } static void -sec_pkcs7_decoder_filter (void *arg, const char *data, unsigned long len, - int depth, SEC_ASN1EncodingPart data_kind) +sec_pkcs7_decoder_filter(void *arg, const char *data, unsigned long len, + int depth, SEC_ASN1EncodingPart data_kind) { SEC_PKCS7DecoderContext *p7dcx; struct sec_pkcs7_decoder_worker *worker; @@ -193,17 +192,17 @@ sec_pkcs7_decoder_filter (void *arg, const char *data, unsigned long len, * smarter based on depth and data_kind. */ if (data_kind != SEC_ASN1_Contents) - return; + return; /* * The ASN.1 decoder should not even call us with a length of 0. * Just being paranoid. */ - PORT_Assert (len); + PORT_Assert(len); if (len == 0) - return; + return; - p7dcx = (SEC_PKCS7DecoderContext*)arg; + p7dcx = (SEC_PKCS7DecoderContext *)arg; /* * Handling nested contents would mean that there is a chain @@ -214,11 +213,10 @@ sec_pkcs7_decoder_filter (void *arg, const char *data, unsigned long len, worker->saw_contents = PR_TRUE; - sec_pkcs7_decoder_work_data (p7dcx, worker, - (const unsigned char *) data, len, PR_FALSE); + sec_pkcs7_decoder_work_data(p7dcx, worker, + (const unsigned char *)data, len, PR_FALSE); } - /* * Create digest contexts for each algorithm in "digestalgs". * No algorithms is not an error, we just do not do anything. @@ -227,35 +225,35 @@ sec_pkcs7_decoder_filter (void *arg, const char *data, unsigned long len, * should just give up altogether. */ static SECStatus -sec_pkcs7_decoder_start_digests (SEC_PKCS7DecoderContext *p7dcx, int depth, - SECAlgorithmID **digestalgs) +sec_pkcs7_decoder_start_digests(SEC_PKCS7DecoderContext *p7dcx, int depth, + SECAlgorithmID **digestalgs) { int i, digcnt; if (digestalgs == NULL) - return SECSuccess; + return SECSuccess; /* * Count the algorithms. */ digcnt = 0; while (digestalgs[digcnt] != NULL) - digcnt++; + digcnt++; /* * No algorithms means no work to do. * Just act as if there were no algorithms specified. */ if (digcnt == 0) - return SECSuccess; + return SECSuccess; - p7dcx->worker.digcxs = (void**)PORT_ArenaAlloc (p7dcx->tmp_poolp, - digcnt * sizeof (void *)); - p7dcx->worker.digobjs = (const SECHashObject**)PORT_ArenaAlloc (p7dcx->tmp_poolp, - digcnt * sizeof (SECHashObject *)); + p7dcx->worker.digcxs = (void **)PORT_ArenaAlloc(p7dcx->tmp_poolp, + digcnt * sizeof(void *)); + p7dcx->worker.digobjs = (const SECHashObject **)PORT_ArenaAlloc(p7dcx->tmp_poolp, + digcnt * sizeof(SECHashObject *)); if (p7dcx->worker.digcxs == NULL || p7dcx->worker.digobjs == NULL) { - p7dcx->error = SEC_ERROR_NO_MEMORY; - return SECFailure; + p7dcx->error = SEC_ERROR_NO_MEMORY; + return SECFailure; } p7dcx->worker.depth = depth; @@ -265,49 +263,48 @@ sec_pkcs7_decoder_start_digests (SEC_PKCS7DecoderContext *p7dcx, int depth, * Create a digest context for each algorithm. */ for (i = 0; i < digcnt; i++) { - SECAlgorithmID * algid = digestalgs[i]; - SECOidTag oidTag = SECOID_FindOIDTag(&(algid->algorithm)); - const SECHashObject *digobj = HASH_GetHashObjectByOidTag(oidTag); - void *digcx; - - /* - * Skip any algorithm we do not even recognize; obviously, - * this could be a problem, but if it is critical then the - * result will just be that the signature does not verify. - * We do not necessarily want to error out here, because - * the particular algorithm may not actually be important, - * but we cannot know that until later. - */ - if (digobj == NULL) { - p7dcx->worker.digcnt--; - continue; - } - - digcx = (* digobj->create)(); - if (digcx != NULL) { - (* digobj->begin) (digcx); - p7dcx->worker.digobjs[p7dcx->worker.digcnt] = digobj; - p7dcx->worker.digcxs[p7dcx->worker.digcnt] = digcx; - p7dcx->worker.digcnt++; - } + SECAlgorithmID *algid = digestalgs[i]; + SECOidTag oidTag = SECOID_FindOIDTag(&(algid->algorithm)); + const SECHashObject *digobj = HASH_GetHashObjectByOidTag(oidTag); + void *digcx; + + /* + * Skip any algorithm we do not even recognize; obviously, + * this could be a problem, but if it is critical then the + * result will just be that the signature does not verify. + * We do not necessarily want to error out here, because + * the particular algorithm may not actually be important, + * but we cannot know that until later. + */ + if (digobj == NULL) { + p7dcx->worker.digcnt--; + continue; + } + + digcx = (*digobj->create)(); + if (digcx != NULL) { + (*digobj->begin)(digcx); + p7dcx->worker.digobjs[p7dcx->worker.digcnt] = digobj; + p7dcx->worker.digcxs[p7dcx->worker.digcnt] = digcx; + p7dcx->worker.digcnt++; + } } if (p7dcx->worker.digcnt != 0) - SEC_ASN1DecoderSetFilterProc (p7dcx->dcx, - sec_pkcs7_decoder_filter, - p7dcx, - (PRBool)(p7dcx->cb != NULL)); + SEC_ASN1DecoderSetFilterProc(p7dcx->dcx, + sec_pkcs7_decoder_filter, + p7dcx, + (PRBool)(p7dcx->cb != NULL)); return SECSuccess; } - /* * Close out all of the digest contexts, storing the results in "digestsp". */ static SECStatus -sec_pkcs7_decoder_finish_digests (SEC_PKCS7DecoderContext *p7dcx, - PLArenaPool *poolp, - SECItem ***digestsp) +sec_pkcs7_decoder_finish_digests(SEC_PKCS7DecoderContext *p7dcx, + PLArenaPool *poolp, + SECItem ***digestsp) { struct sec_pkcs7_decoder_worker *worker; const SECHashObject *digobj; @@ -327,14 +324,14 @@ sec_pkcs7_decoder_finish_digests (SEC_PKCS7DecoderContext *p7dcx, * If no digests, then we have nothing to do. */ if (worker->digcnt == 0) - return SECSuccess; + return SECSuccess; /* * No matter what happens after this, we want to stop filtering. * XXX If we handle nested contents, we only want to stop filtering * if we are finishing off the *last* worker. */ - SEC_ASN1DecoderClearFilterProc (p7dcx->dcx); + SEC_ASN1DecoderClearFilterProc(p7dcx->dcx); /* * If we ended up with no contents, just destroy each @@ -342,50 +339,50 @@ sec_pkcs7_decoder_finish_digests (SEC_PKCS7DecoderContext *p7dcx, * confusing, because their presence would imply some content * was digested. */ - if (! worker->saw_contents) { - for (i = 0; i < worker->digcnt; i++) { - digcx = worker->digcxs[i]; - digobj = worker->digobjs[i]; - (* digobj->destroy) (digcx, PR_TRUE); - } - return SECSuccess; + if (!worker->saw_contents) { + for (i = 0; i < worker->digcnt; i++) { + digcx = worker->digcxs[i]; + digobj = worker->digobjs[i]; + (*digobj->destroy)(digcx, PR_TRUE); + } + return SECSuccess; } - mark = PORT_ArenaMark (poolp); + mark = PORT_ArenaMark(poolp); /* * Close out each digest context, saving digest away. */ - digests = - (SECItem**)PORT_ArenaAlloc (poolp,(worker->digcnt+1)*sizeof(SECItem *)); - digest = (SECItem*)PORT_ArenaAlloc (poolp, worker->digcnt*sizeof(SECItem)); + digests = + (SECItem **)PORT_ArenaAlloc(poolp, (worker->digcnt + 1) * sizeof(SECItem *)); + digest = (SECItem *)PORT_ArenaAlloc(poolp, worker->digcnt * sizeof(SECItem)); if (digests == NULL || digest == NULL) { - p7dcx->error = PORT_GetError(); - PORT_ArenaRelease (poolp, mark); - return SECFailure; + p7dcx->error = PORT_GetError(); + PORT_ArenaRelease(poolp, mark); + return SECFailure; } for (i = 0; i < worker->digcnt; i++, digest++) { - digcx = worker->digcxs[i]; - digobj = worker->digobjs[i]; + digcx = worker->digcxs[i]; + digobj = worker->digobjs[i]; - digest->data = (unsigned char*)PORT_ArenaAlloc (poolp, digobj->length); - if (digest->data == NULL) { - p7dcx->error = PORT_GetError(); - PORT_ArenaRelease (poolp, mark); - return SECFailure; - } + digest->data = (unsigned char *)PORT_ArenaAlloc(poolp, digobj->length); + if (digest->data == NULL) { + p7dcx->error = PORT_GetError(); + PORT_ArenaRelease(poolp, mark); + return SECFailure; + } - digest->len = digobj->length; - (* digobj->end) (digcx, digest->data, &(digest->len), digest->len); - (* digobj->destroy) (digcx, PR_TRUE); + digest->len = digobj->length; + (*digobj->end)(digcx, digest->data, &(digest->len), digest->len); + (*digobj->destroy)(digcx, PR_TRUE); - digests[i] = digest; + digests[i] = digest; } digests[i] = NULL; *digestsp = digests; - PORT_ArenaUnmark (poolp, mark); + PORT_ArenaUnmark(poolp, mark); return SECSuccess; } @@ -395,9 +392,9 @@ sec_pkcs7_decoder_finish_digests (SEC_PKCS7DecoderContext *p7dcx, */ static PK11SymKey * -sec_pkcs7_decoder_get_recipient_key (SEC_PKCS7DecoderContext *p7dcx, - SEC_PKCS7RecipientInfo **recipientinfos, - SEC_PKCS7EncryptedContentInfo *enccinfo) +sec_pkcs7_decoder_get_recipient_key(SEC_PKCS7DecoderContext *p7dcx, + SEC_PKCS7RecipientInfo **recipientinfos, + SEC_PKCS7EncryptedContentInfo *enccinfo) { SEC_PKCS7RecipientInfo *ri; CERTCertificate *cert = NULL; @@ -407,53 +404,53 @@ sec_pkcs7_decoder_get_recipient_key (SEC_PKCS7DecoderContext *p7dcx, PK11SlotInfo *slot = NULL; if (recipientinfos == NULL || recipientinfos[0] == NULL) { - p7dcx->error = SEC_ERROR_NOT_A_RECIPIENT; - goto no_key_found; + p7dcx->error = SEC_ERROR_NOT_A_RECIPIENT; + goto no_key_found; } - cert = PK11_FindCertAndKeyByRecipientList(&slot,recipientinfos,&ri, - &privkey, p7dcx->pwfn_arg); + cert = PK11_FindCertAndKeyByRecipientList(&slot, recipientinfos, &ri, + &privkey, p7dcx->pwfn_arg); if (cert == NULL) { - p7dcx->error = SEC_ERROR_NOT_A_RECIPIENT; - goto no_key_found; + p7dcx->error = SEC_ERROR_NOT_A_RECIPIENT; + goto no_key_found; } - ri->cert = cert; /* so we can find it later */ + ri->cert = cert; /* so we can find it later */ PORT_Assert(privkey != NULL); keyalgtag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm)); - encalgtag = SECOID_GetAlgorithmTag (&(ri->keyEncAlg)); + encalgtag = SECOID_GetAlgorithmTag(&(ri->keyEncAlg)); if (keyalgtag != encalgtag) { - p7dcx->error = SEC_ERROR_PKCS7_KEYALG_MISMATCH; - goto no_key_found; + p7dcx->error = SEC_ERROR_PKCS7_KEYALG_MISMATCH; + goto no_key_found; } - bulkalgtag = SECOID_GetAlgorithmTag (&(enccinfo->contentEncAlg)); + bulkalgtag = SECOID_GetAlgorithmTag(&(enccinfo->contentEncAlg)); switch (encalgtag) { - case SEC_OID_PKCS1_RSA_ENCRYPTION: - bulkkey = PK11_PubUnwrapSymKey (privkey, &ri->encKey, - PK11_AlgtagToMechanism (bulkalgtag), - CKA_DECRYPT, 0); - if (bulkkey == NULL) { - p7dcx->error = PORT_GetError(); - PORT_SetError(0); - goto no_key_found; - } - break; - default: - p7dcx->error = SEC_ERROR_UNSUPPORTED_KEYALG; - break; + case SEC_OID_PKCS1_RSA_ENCRYPTION: + bulkkey = PK11_PubUnwrapSymKey(privkey, &ri->encKey, + PK11_AlgtagToMechanism(bulkalgtag), + CKA_DECRYPT, 0); + if (bulkkey == NULL) { + p7dcx->error = PORT_GetError(); + PORT_SetError(0); + goto no_key_found; + } + break; + default: + p7dcx->error = SEC_ERROR_UNSUPPORTED_KEYALG; + break; } no_key_found: if (privkey != NULL) - SECKEY_DestroyPrivateKey (privkey); + SECKEY_DestroyPrivateKey(privkey); if (slot != NULL) - PK11_FreeSlot(slot); + PK11_FreeSlot(slot); return bulkkey; } - + /* * XXX The following comment is old -- the function used to only handle * EnvelopedData or SignedAndEnvelopedData but now handles EncryptedData @@ -469,16 +466,16 @@ no_key_found: * The encryption key and related information can be found in "enccinfo". */ static SECStatus -sec_pkcs7_decoder_start_decrypt (SEC_PKCS7DecoderContext *p7dcx, int depth, - SEC_PKCS7RecipientInfo **recipientinfos, - SEC_PKCS7EncryptedContentInfo *enccinfo, - PK11SymKey **copy_key_for_signature) +sec_pkcs7_decoder_start_decrypt(SEC_PKCS7DecoderContext *p7dcx, int depth, + SEC_PKCS7RecipientInfo **recipientinfos, + SEC_PKCS7EncryptedContentInfo *enccinfo, + PK11SymKey **copy_key_for_signature) { PK11SymKey *bulkkey = NULL; sec_PKCS7CipherObject *decryptobj; /* - * If a callback is supplied to retrieve the encryption key, + * If a callback is supplied to retrieve the encryption key, * for instance, for Encrypted Content infos, then retrieve * the bulkkey from the callback. Otherwise, assume that * we are processing Enveloped or SignedAndEnveloped data @@ -487,41 +484,41 @@ sec_pkcs7_decoder_start_decrypt (SEC_PKCS7DecoderContext *p7dcx, int depth, * XXX Put an assert here? */ if (SEC_PKCS7ContentType(p7dcx->cinfo) == SEC_OID_PKCS7_ENCRYPTED_DATA) { - if (p7dcx->dkcb != NULL) { - bulkkey = (*p7dcx->dkcb)(p7dcx->dkcb_arg, - &(enccinfo->contentEncAlg)); - } - enccinfo->keysize = 0; + if (p7dcx->dkcb != NULL) { + bulkkey = (*p7dcx->dkcb)(p7dcx->dkcb_arg, + &(enccinfo->contentEncAlg)); + } + enccinfo->keysize = 0; } else { - bulkkey = sec_pkcs7_decoder_get_recipient_key (p7dcx, recipientinfos, - enccinfo); - if (bulkkey == NULL) goto no_decryption; - enccinfo->keysize = PK11_GetKeyStrength(bulkkey, - &(enccinfo->contentEncAlg)); - + bulkkey = sec_pkcs7_decoder_get_recipient_key(p7dcx, recipientinfos, + enccinfo); + if (bulkkey == NULL) + goto no_decryption; + enccinfo->keysize = PK11_GetKeyStrength(bulkkey, + &(enccinfo->contentEncAlg)); } /* * XXX I think following should set error in p7dcx and clear set error * (as used to be done here, or as is done in get_receipient_key above. */ - if(bulkkey == NULL) { - goto no_decryption; + if (bulkkey == NULL) { + goto no_decryption; } - - /* + + /* * We want to make sure decryption is allowed. This is done via * a callback specified in SEC_PKCS7DecoderStart(). */ if (p7dcx->decrypt_allowed_cb) { - if ((*p7dcx->decrypt_allowed_cb) (&(enccinfo->contentEncAlg), - bulkkey) == PR_FALSE) { - p7dcx->error = SEC_ERROR_DECRYPTION_DISALLOWED; - goto no_decryption; - } + if ((*p7dcx->decrypt_allowed_cb)(&(enccinfo->contentEncAlg), + bulkkey) == PR_FALSE) { + p7dcx->error = SEC_ERROR_DECRYPTION_DISALLOWED; + goto no_decryption; + } } else { - p7dcx->error = SEC_ERROR_DECRYPTION_DISALLOWED; - goto no_decryption; + p7dcx->error = SEC_ERROR_DECRYPTION_DISALLOWED; + goto no_decryption; } /* @@ -531,31 +528,31 @@ sec_pkcs7_decoder_start_decrypt (SEC_PKCS7DecoderContext *p7dcx, int depth, * RSA operation), copy it for later signature verification to use. */ if (copy_key_for_signature != NULL) - *copy_key_for_signature = PK11_ReferenceSymKey (bulkkey); + *copy_key_for_signature = PK11_ReferenceSymKey(bulkkey); /* * Now we have the bulk encryption key (in bulkkey) and the * the algorithm (in enccinfo->contentEncAlg). Using those, * create a decryption context. */ - decryptobj = sec_PKCS7CreateDecryptObject (bulkkey, - &(enccinfo->contentEncAlg)); + decryptobj = sec_PKCS7CreateDecryptObject(bulkkey, + &(enccinfo->contentEncAlg)); /* * We are done with (this) bulkkey now. */ - PK11_FreeSymKey (bulkkey); + PK11_FreeSymKey(bulkkey); if (decryptobj == NULL) { - p7dcx->error = PORT_GetError(); - PORT_SetError(0); - goto no_decryption; + p7dcx->error = PORT_GetError(); + PORT_SetError(0); + goto no_decryption; } - SEC_ASN1DecoderSetFilterProc (p7dcx->dcx, - sec_pkcs7_decoder_filter, - p7dcx, - (PRBool)(p7dcx->cb != NULL)); + SEC_ASN1DecoderSetFilterProc(p7dcx->dcx, + sec_pkcs7_decoder_filter, + p7dcx, + (PRBool)(p7dcx->cb != NULL)); p7dcx->worker.depth = depth; p7dcx->worker.decryptobj = decryptobj; @@ -575,16 +572,15 @@ no_decryption: * maybe it is not important that the decryption failed. */ if (p7dcx->cb != NULL) - return SECFailure; + return SECFailure; else - return SECSuccess; /* Let the decoding continue. */ + return SECSuccess; /* Let the decoding continue. */ } - static SECStatus -sec_pkcs7_decoder_finish_decrypt (SEC_PKCS7DecoderContext *p7dcx, - PLArenaPool *poolp, - SEC_PKCS7EncryptedContentInfo *enccinfo) +sec_pkcs7_decoder_finish_decrypt(SEC_PKCS7DecoderContext *p7dcx, + PLArenaPool *poolp, + SEC_PKCS7EncryptedContentInfo *enccinfo) { struct sec_pkcs7_decoder_worker *worker; @@ -599,32 +595,31 @@ sec_pkcs7_decoder_finish_decrypt (SEC_PKCS7DecoderContext *p7dcx, * If no decryption context, then we have nothing to do. */ if (worker->decryptobj == NULL) - return SECSuccess; + return SECSuccess; /* * No matter what happens after this, we want to stop filtering. * XXX If we handle nested contents, we only want to stop filtering * if we are finishing off the *last* worker. */ - SEC_ASN1DecoderClearFilterProc (p7dcx->dcx); + SEC_ASN1DecoderClearFilterProc(p7dcx->dcx); /* * Handle the last block. */ - sec_pkcs7_decoder_work_data (p7dcx, worker, NULL, 0, PR_TRUE); + sec_pkcs7_decoder_work_data(p7dcx, worker, NULL, 0, PR_TRUE); /* * All done, destroy it. */ - sec_PKCS7DestroyDecryptObject (worker->decryptobj); + sec_PKCS7DestroyDecryptObject(worker->decryptobj); worker->decryptobj = NULL; return SECSuccess; } - static void -sec_pkcs7_decoder_notify (void *arg, PRBool before, void *dest, int depth) +sec_pkcs7_decoder_notify(void *arg, PRBool before, void *dest, int depth) { SEC_PKCS7DecoderContext *p7dcx; SEC_PKCS7ContentInfo *cinfo; @@ -643,331 +638,342 @@ sec_pkcs7_decoder_notify (void *arg, PRBool before, void *dest, int depth) * causes a warning on the mac; to avoid that, we do it the long way.) */ if (before) - after = PR_FALSE; + after = PR_FALSE; else - after = PR_TRUE; + after = PR_TRUE; + + p7dcx = (SEC_PKCS7DecoderContext *)arg; + if (!p7dcx) { + return; + } - p7dcx = (SEC_PKCS7DecoderContext*)arg; cinfo = p7dcx->cinfo; + if (!cinfo) { + return; + } + if (cinfo->contentTypeTag == NULL) { - if (after && dest == &(cinfo->contentType)) - cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType)); - return; + if (after && dest == &(cinfo->contentType)) + cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType)); + return; } switch (cinfo->contentTypeTag->offset) { - case SEC_OID_PKCS7_SIGNED_DATA: - sigd = cinfo->content.signedData; - if (sigd == NULL) - break; - - if (sigd->contentInfo.contentTypeTag == NULL) { - if (after && dest == &(sigd->contentInfo.contentType)) - sigd->contentInfo.contentTypeTag = - SECOID_FindOID(&(sigd->contentInfo.contentType)); - break; - } - - /* - * We only set up a filtering digest if the content is - * plain DATA; anything else needs more work because a - * second pass is required to produce a DER encoding from - * an input that can be BER encoded. (This is a requirement - * of PKCS7 that is unfortunate, but there you have it.) - * - * XXX Also, since we stop here if this is not DATA, the - * inner content is not getting processed at all. Someday - * we may want to fix that. - */ - if (sigd->contentInfo.contentTypeTag->offset != SEC_OID_PKCS7_DATA) { - /* XXX Set an error in p7dcx->error */ - SEC_ASN1DecoderClearNotifyProc (p7dcx->dcx); - break; - } - - /* - * Just before the content, we want to set up a digest context - * for each digest algorithm listed, and start a filter which - * will run all of the contents bytes through that digest. - */ - if (before && dest == &(sigd->contentInfo.content)) { - rv = sec_pkcs7_decoder_start_digests (p7dcx, depth, - sigd->digestAlgorithms); - if (rv != SECSuccess) - SEC_ASN1DecoderClearNotifyProc (p7dcx->dcx); - - break; - } - - /* - * XXX To handle nested types, here is where we would want - * to check for inner boundaries that need handling. - */ - - /* - * Are we done? - */ - if (after && dest == &(sigd->contentInfo.content)) { - /* - * Close out the digest contexts. We ignore any error - * because we are stopping anyway; the error status left - * behind in p7dcx will be seen by outer functions. - */ - (void) sec_pkcs7_decoder_finish_digests (p7dcx, cinfo->poolp, - &(sigd->digests)); - - /* - * XXX To handle nested contents, we would need to remove - * the worker from the chain (and free it). - */ - - /* - * Stop notify. - */ - SEC_ASN1DecoderClearNotifyProc (p7dcx->dcx); - } - break; - - case SEC_OID_PKCS7_ENVELOPED_DATA: - envd = cinfo->content.envelopedData; - if (envd == NULL) - break; - - if (envd->encContentInfo.contentTypeTag == NULL) { - if (after && dest == &(envd->encContentInfo.contentType)) - envd->encContentInfo.contentTypeTag = - SECOID_FindOID(&(envd->encContentInfo.contentType)); - break; - } - - /* - * Just before the content, we want to set up a decryption - * context, and start a filter which will run all of the - * contents bytes through it to determine the plain content. - */ - if (before && dest == &(envd->encContentInfo.encContent)) { - rv = sec_pkcs7_decoder_start_decrypt (p7dcx, depth, - envd->recipientInfos, - &(envd->encContentInfo), - NULL); - if (rv != SECSuccess) - SEC_ASN1DecoderClearNotifyProc (p7dcx->dcx); - - break; - } - - /* - * Are we done? - */ - if (after && dest == &(envd->encContentInfo.encContent)) { - /* - * Close out the decryption context. We ignore any error - * because we are stopping anyway; the error status left - * behind in p7dcx will be seen by outer functions. - */ - (void) sec_pkcs7_decoder_finish_decrypt (p7dcx, cinfo->poolp, - &(envd->encContentInfo)); - - /* - * XXX To handle nested contents, we would need to remove - * the worker from the chain (and free it). - */ - - /* - * Stop notify. - */ - SEC_ASN1DecoderClearNotifyProc (p7dcx->dcx); - } - break; - - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - saed = cinfo->content.signedAndEnvelopedData; - if (saed == NULL) - break; - - if (saed->encContentInfo.contentTypeTag == NULL) { - if (after && dest == &(saed->encContentInfo.contentType)) - saed->encContentInfo.contentTypeTag = - SECOID_FindOID(&(saed->encContentInfo.contentType)); - break; - } - - /* - * Just before the content, we want to set up a decryption - * context *and* digest contexts, and start a filter which - * will run all of the contents bytes through both. - */ - if (before && dest == &(saed->encContentInfo.encContent)) { - rv = sec_pkcs7_decoder_start_decrypt (p7dcx, depth, - saed->recipientInfos, - &(saed->encContentInfo), - &(saed->sigKey)); - if (rv == SECSuccess) - rv = sec_pkcs7_decoder_start_digests (p7dcx, depth, - saed->digestAlgorithms); - if (rv != SECSuccess) - SEC_ASN1DecoderClearNotifyProc (p7dcx->dcx); - - break; - } - - /* - * Are we done? - */ - if (after && dest == &(saed->encContentInfo.encContent)) { - /* - * Close out the decryption and digests contexts. - * We ignore any errors because we are stopping anyway; - * the error status left behind in p7dcx will be seen by - * outer functions. - * - * Note that the decrypt stuff must be called first; - * it may have a last buffer to do which in turn has - * to be added to the digest. - */ - (void) sec_pkcs7_decoder_finish_decrypt (p7dcx, cinfo->poolp, - &(saed->encContentInfo)); - (void) sec_pkcs7_decoder_finish_digests (p7dcx, cinfo->poolp, - &(saed->digests)); - - /* - * XXX To handle nested contents, we would need to remove - * the worker from the chain (and free it). - */ - - /* - * Stop notify. - */ - SEC_ASN1DecoderClearNotifyProc (p7dcx->dcx); - } - break; - - case SEC_OID_PKCS7_DIGESTED_DATA: - digd = cinfo->content.digestedData; - - /* - * XXX Want to do the digest or not? Maybe future enhancement... - */ - if (before && dest == &(digd->contentInfo.content.data)) { - SEC_ASN1DecoderSetFilterProc (p7dcx->dcx, sec_pkcs7_decoder_filter, - p7dcx, - (PRBool)(p7dcx->cb != NULL)); - break; - } - - /* - * Are we done? - */ - if (after && dest == &(digd->contentInfo.content.data)) { - SEC_ASN1DecoderClearFilterProc (p7dcx->dcx); - } - break; - - case SEC_OID_PKCS7_ENCRYPTED_DATA: - encd = cinfo->content.encryptedData; - - /* - * XXX If the decryption key callback is set, we want to start - * the decryption. If the callback is not set, we will treat the - * content as plain data, since we do not have the key. - * - * Is this the proper thing to do? - */ - if (before && dest == &(encd->encContentInfo.encContent)) { - /* - * Start the encryption process if the decryption key callback - * is present. Otherwise, treat the content like plain data. - */ - rv = SECSuccess; - if (p7dcx->dkcb != NULL) { - rv = sec_pkcs7_decoder_start_decrypt (p7dcx, depth, NULL, - &(encd->encContentInfo), - NULL); - } - - if (rv != SECSuccess) - SEC_ASN1DecoderClearNotifyProc (p7dcx->dcx); - - break; - } - - /* - * Are we done? - */ - if (after && dest == &(encd->encContentInfo.encContent)) { - /* - * Close out the decryption context. We ignore any error - * because we are stopping anyway; the error status left - * behind in p7dcx will be seen by outer functions. - */ - (void) sec_pkcs7_decoder_finish_decrypt (p7dcx, cinfo->poolp, - &(encd->encContentInfo)); - - /* - * Stop notify. - */ - SEC_ASN1DecoderClearNotifyProc (p7dcx->dcx); - } - break; - - case SEC_OID_PKCS7_DATA: - /* - * If a output callback has been specified, we want to set the filter - * to call the callback. This is taken care of in - * sec_pkcs7_decoder_start_decrypt() or - * sec_pkcs7_decoder_start_digests() for the other content types. - */ - - if (before && dest == &(cinfo->content.data)) { - - /* - * Set the filter proc up. - */ - SEC_ASN1DecoderSetFilterProc (p7dcx->dcx, - sec_pkcs7_decoder_filter, - p7dcx, - (PRBool)(p7dcx->cb != NULL)); - break; - } - - if (after && dest == &(cinfo->content.data)) { - /* - * Time to clean up after ourself, stop the Notify and Filter - * procedures. - */ - SEC_ASN1DecoderClearNotifyProc (p7dcx->dcx); - SEC_ASN1DecoderClearFilterProc (p7dcx->dcx); - } - break; - - default: - SEC_ASN1DecoderClearNotifyProc (p7dcx->dcx); - break; + case SEC_OID_PKCS7_SIGNED_DATA: + sigd = cinfo->content.signedData; + if (sigd == NULL) + break; + + if (sigd->contentInfo.contentTypeTag == NULL) { + if (after && dest == &(sigd->contentInfo.contentType)) + sigd->contentInfo.contentTypeTag = + SECOID_FindOID(&(sigd->contentInfo.contentType)); + break; + } + + /* + * We only set up a filtering digest if the content is + * plain DATA; anything else needs more work because a + * second pass is required to produce a DER encoding from + * an input that can be BER encoded. (This is a requirement + * of PKCS7 that is unfortunate, but there you have it.) + * + * XXX Also, since we stop here if this is not DATA, the + * inner content is not getting processed at all. Someday + * we may want to fix that. + */ + if (sigd->contentInfo.contentTypeTag->offset != SEC_OID_PKCS7_DATA) { + /* XXX Set an error in p7dcx->error */ + SEC_ASN1DecoderClearNotifyProc(p7dcx->dcx); + break; + } + + /* + * Just before the content, we want to set up a digest context + * for each digest algorithm listed, and start a filter which + * will run all of the contents bytes through that digest. + */ + if (before && dest == &(sigd->contentInfo.content)) { + rv = sec_pkcs7_decoder_start_digests(p7dcx, depth, + sigd->digestAlgorithms); + if (rv != SECSuccess) + SEC_ASN1DecoderClearNotifyProc(p7dcx->dcx); + + break; + } + + /* + * XXX To handle nested types, here is where we would want + * to check for inner boundaries that need handling. + */ + + /* + * Are we done? + */ + if (after && dest == &(sigd->contentInfo.content)) { + /* + * Close out the digest contexts. We ignore any error + * because we are stopping anyway; the error status left + * behind in p7dcx will be seen by outer functions. + */ + (void)sec_pkcs7_decoder_finish_digests(p7dcx, cinfo->poolp, + &(sigd->digests)); + + /* + * XXX To handle nested contents, we would need to remove + * the worker from the chain (and free it). + */ + + /* + * Stop notify. + */ + SEC_ASN1DecoderClearNotifyProc(p7dcx->dcx); + } + break; + + case SEC_OID_PKCS7_ENVELOPED_DATA: + envd = cinfo->content.envelopedData; + if (envd == NULL) + break; + + if (envd->encContentInfo.contentTypeTag == NULL) { + if (after && dest == &(envd->encContentInfo.contentType)) + envd->encContentInfo.contentTypeTag = + SECOID_FindOID(&(envd->encContentInfo.contentType)); + break; + } + + /* + * Just before the content, we want to set up a decryption + * context, and start a filter which will run all of the + * contents bytes through it to determine the plain content. + */ + if (before && dest == &(envd->encContentInfo.encContent)) { + rv = sec_pkcs7_decoder_start_decrypt(p7dcx, depth, + envd->recipientInfos, + &(envd->encContentInfo), + NULL); + if (rv != SECSuccess) + SEC_ASN1DecoderClearNotifyProc(p7dcx->dcx); + + break; + } + + /* + * Are we done? + */ + if (after && dest == &(envd->encContentInfo.encContent)) { + /* + * Close out the decryption context. We ignore any error + * because we are stopping anyway; the error status left + * behind in p7dcx will be seen by outer functions. + */ + (void)sec_pkcs7_decoder_finish_decrypt(p7dcx, cinfo->poolp, + &(envd->encContentInfo)); + + /* + * XXX To handle nested contents, we would need to remove + * the worker from the chain (and free it). + */ + + /* + * Stop notify. + */ + SEC_ASN1DecoderClearNotifyProc(p7dcx->dcx); + } + break; + + case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: + saed = cinfo->content.signedAndEnvelopedData; + if (saed == NULL) + break; + + if (saed->encContentInfo.contentTypeTag == NULL) { + if (after && dest == &(saed->encContentInfo.contentType)) + saed->encContentInfo.contentTypeTag = + SECOID_FindOID(&(saed->encContentInfo.contentType)); + break; + } + + /* + * Just before the content, we want to set up a decryption + * context *and* digest contexts, and start a filter which + * will run all of the contents bytes through both. + */ + if (before && dest == &(saed->encContentInfo.encContent)) { + rv = sec_pkcs7_decoder_start_decrypt(p7dcx, depth, + saed->recipientInfos, + &(saed->encContentInfo), + &(saed->sigKey)); + if (rv == SECSuccess) + rv = sec_pkcs7_decoder_start_digests(p7dcx, depth, + saed->digestAlgorithms); + if (rv != SECSuccess) + SEC_ASN1DecoderClearNotifyProc(p7dcx->dcx); + + break; + } + + /* + * Are we done? + */ + if (after && dest == &(saed->encContentInfo.encContent)) { + /* + * Close out the decryption and digests contexts. + * We ignore any errors because we are stopping anyway; + * the error status left behind in p7dcx will be seen by + * outer functions. + * + * Note that the decrypt stuff must be called first; + * it may have a last buffer to do which in turn has + * to be added to the digest. + */ + (void)sec_pkcs7_decoder_finish_decrypt(p7dcx, cinfo->poolp, + &(saed->encContentInfo)); + (void)sec_pkcs7_decoder_finish_digests(p7dcx, cinfo->poolp, + &(saed->digests)); + + /* + * XXX To handle nested contents, we would need to remove + * the worker from the chain (and free it). + */ + + /* + * Stop notify. + */ + SEC_ASN1DecoderClearNotifyProc(p7dcx->dcx); + } + break; + + case SEC_OID_PKCS7_DIGESTED_DATA: + digd = cinfo->content.digestedData; + + /* + * XXX Want to do the digest or not? Maybe future enhancement... + */ + if (before && dest == &(digd->contentInfo.content.data)) { + SEC_ASN1DecoderSetFilterProc(p7dcx->dcx, sec_pkcs7_decoder_filter, + p7dcx, + (PRBool)(p7dcx->cb != NULL)); + break; + } + + /* + * Are we done? + */ + if (after && dest == &(digd->contentInfo.content.data)) { + SEC_ASN1DecoderClearFilterProc(p7dcx->dcx); + } + break; + + case SEC_OID_PKCS7_ENCRYPTED_DATA: + encd = cinfo->content.encryptedData; + + if (!encd) { + break; + } + + /* + * XXX If the decryption key callback is set, we want to start + * the decryption. If the callback is not set, we will treat the + * content as plain data, since we do not have the key. + * + * Is this the proper thing to do? + */ + if (before && dest == &(encd->encContentInfo.encContent)) { + /* + * Start the encryption process if the decryption key callback + * is present. Otherwise, treat the content like plain data. + */ + rv = SECSuccess; + if (p7dcx->dkcb != NULL) { + rv = sec_pkcs7_decoder_start_decrypt(p7dcx, depth, NULL, + &(encd->encContentInfo), + NULL); + } + + if (rv != SECSuccess) + SEC_ASN1DecoderClearNotifyProc(p7dcx->dcx); + + break; + } + + /* + * Are we done? + */ + if (after && dest == &(encd->encContentInfo.encContent)) { + /* + * Close out the decryption context. We ignore any error + * because we are stopping anyway; the error status left + * behind in p7dcx will be seen by outer functions. + */ + (void)sec_pkcs7_decoder_finish_decrypt(p7dcx, cinfo->poolp, + &(encd->encContentInfo)); + + /* + * Stop notify. + */ + SEC_ASN1DecoderClearNotifyProc(p7dcx->dcx); + } + break; + + case SEC_OID_PKCS7_DATA: + /* + * If a output callback has been specified, we want to set the filter + * to call the callback. This is taken care of in + * sec_pkcs7_decoder_start_decrypt() or + * sec_pkcs7_decoder_start_digests() for the other content types. + */ + + if (before && dest == &(cinfo->content.data)) { + + /* + * Set the filter proc up. + */ + SEC_ASN1DecoderSetFilterProc(p7dcx->dcx, + sec_pkcs7_decoder_filter, + p7dcx, + (PRBool)(p7dcx->cb != NULL)); + break; + } + + if (after && dest == &(cinfo->content.data)) { + /* + * Time to clean up after ourself, stop the Notify and Filter + * procedures. + */ + SEC_ASN1DecoderClearNotifyProc(p7dcx->dcx); + SEC_ASN1DecoderClearFilterProc(p7dcx->dcx); + } + break; + + default: + SEC_ASN1DecoderClearNotifyProc(p7dcx->dcx); + break; } } - SEC_PKCS7DecoderContext * SEC_PKCS7DecoderStart(SEC_PKCS7DecoderContentCallback cb, void *cb_arg, - SECKEYGetPasswordKey pwfn, void *pwfn_arg, - SEC_PKCS7GetDecryptKeyCallback decrypt_key_cb, - void *decrypt_key_cb_arg, - SEC_PKCS7DecryptionAllowedCallback decrypt_allowed_cb) + SECKEYGetPasswordKey pwfn, void *pwfn_arg, + SEC_PKCS7GetDecryptKeyCallback decrypt_key_cb, + void *decrypt_key_cb_arg, + SEC_PKCS7DecryptionAllowedCallback decrypt_allowed_cb) { SEC_PKCS7DecoderContext *p7dcx; SEC_ASN1DecoderContext *dcx; SEC_PKCS7ContentInfo *cinfo; PLArenaPool *poolp; - poolp = PORT_NewArena (1024); /* XXX what is right value? */ + poolp = PORT_NewArena(1024); /* XXX what is right value? */ if (poolp == NULL) - return NULL; + return NULL; - cinfo = (SEC_PKCS7ContentInfo*)PORT_ArenaZAlloc (poolp, sizeof(*cinfo)); + cinfo = (SEC_PKCS7ContentInfo *)PORT_ArenaZAlloc(poolp, sizeof(*cinfo)); if (cinfo == NULL) { - PORT_FreeArena (poolp, PR_FALSE); - return NULL; + PORT_FreeArena(poolp, PR_FALSE); + return NULL; } cinfo->poolp = poolp; @@ -976,29 +982,29 @@ SEC_PKCS7DecoderStart(SEC_PKCS7DecoderContentCallback cb, void *cb_arg, cinfo->created = PR_FALSE; cinfo->refCount = 1; - p7dcx = - (SEC_PKCS7DecoderContext*)PORT_ZAlloc (sizeof(SEC_PKCS7DecoderContext)); + p7dcx = + (SEC_PKCS7DecoderContext *)PORT_ZAlloc(sizeof(SEC_PKCS7DecoderContext)); if (p7dcx == NULL) { - PORT_FreeArena (poolp, PR_FALSE); - return NULL; + PORT_FreeArena(poolp, PR_FALSE); + return NULL; } - p7dcx->tmp_poolp = PORT_NewArena (1024); /* XXX what is right value? */ + p7dcx->tmp_poolp = PORT_NewArena(1024); /* XXX what is right value? */ if (p7dcx->tmp_poolp == NULL) { - PORT_Free (p7dcx); - PORT_FreeArena (poolp, PR_FALSE); - return NULL; + PORT_Free(p7dcx); + PORT_FreeArena(poolp, PR_FALSE); + return NULL; } - dcx = SEC_ASN1DecoderStart (poolp, cinfo, sec_PKCS7ContentInfoTemplate); + dcx = SEC_ASN1DecoderStart(poolp, cinfo, sec_PKCS7ContentInfoTemplate); if (dcx == NULL) { - PORT_FreeArena (p7dcx->tmp_poolp, PR_FALSE); - PORT_Free (p7dcx); - PORT_FreeArena (poolp, PR_FALSE); - return NULL; + PORT_FreeArena(p7dcx->tmp_poolp, PR_FALSE); + PORT_Free(p7dcx); + PORT_FreeArena(poolp, PR_FALSE); + return NULL; } - SEC_ASN1DecoderSetNotifyProc (dcx, sec_pkcs7_decoder_notify, p7dcx); + SEC_ASN1DecoderSetNotifyProc(dcx, sec_pkcs7_decoder_notify, p7dcx); p7dcx->dcx = dcx; p7dcx->cinfo = cinfo; @@ -1013,7 +1019,6 @@ SEC_PKCS7DecoderStart(SEC_PKCS7DecoderContentCallback cb, void *cb_arg, return p7dcx; } - /* * Do the next chunk of PKCS7 decoding. If there is a problem, set * an error and return a failure status. Note that in the case of @@ -1024,37 +1029,36 @@ SEC_PKCS7DecoderStart(SEC_PKCS7DecoderContentCallback cb, void *cb_arg, */ SECStatus SEC_PKCS7DecoderUpdate(SEC_PKCS7DecoderContext *p7dcx, - const char *buf, unsigned long len) + const char *buf, unsigned long len) { - if (p7dcx->cinfo != NULL && p7dcx->dcx != NULL) { - PORT_Assert (p7dcx->error == 0); - if (p7dcx->error == 0) { - if (SEC_ASN1DecoderUpdate (p7dcx->dcx, buf, len) != SECSuccess) { - p7dcx->error = PORT_GetError(); - PORT_Assert (p7dcx->error); - if (p7dcx->error == 0) - p7dcx->error = -1; - } - } + if (p7dcx->cinfo != NULL && p7dcx->dcx != NULL) { + PORT_Assert(p7dcx->error == 0); + if (p7dcx->error == 0) { + if (SEC_ASN1DecoderUpdate(p7dcx->dcx, buf, len) != SECSuccess) { + p7dcx->error = PORT_GetError(); + PORT_Assert(p7dcx->error); + if (p7dcx->error == 0) + p7dcx->error = -1; + } + } } if (p7dcx->error) { - if (p7dcx->dcx != NULL) { - (void) SEC_ASN1DecoderFinish (p7dcx->dcx); - p7dcx->dcx = NULL; - } - if (p7dcx->cinfo != NULL) { - SEC_PKCS7DestroyContentInfo (p7dcx->cinfo); - p7dcx->cinfo = NULL; - } - PORT_SetError (p7dcx->error); - return SECFailure; + if (p7dcx->dcx != NULL) { + (void)SEC_ASN1DecoderFinish(p7dcx->dcx); + p7dcx->dcx = NULL; + } + if (p7dcx->cinfo != NULL) { + SEC_PKCS7DestroyContentInfo(p7dcx->cinfo); + p7dcx->cinfo = NULL; + } + PORT_SetError(p7dcx->error); + return SECFailure; } return SECSuccess; } - SEC_PKCS7ContentInfo * SEC_PKCS7DecoderFinish(SEC_PKCS7DecoderContext *p7dcx) { @@ -1062,38 +1066,37 @@ SEC_PKCS7DecoderFinish(SEC_PKCS7DecoderContext *p7dcx) cinfo = p7dcx->cinfo; if (p7dcx->dcx != NULL) { - if (SEC_ASN1DecoderFinish (p7dcx->dcx) != SECSuccess) { - SEC_PKCS7DestroyContentInfo (cinfo); - cinfo = NULL; - } + if (SEC_ASN1DecoderFinish(p7dcx->dcx) != SECSuccess) { + SEC_PKCS7DestroyContentInfo(cinfo); + cinfo = NULL; + } } /* free any NSS data structures */ if (p7dcx->worker.decryptobj) { - sec_PKCS7DestroyDecryptObject (p7dcx->worker.decryptobj); + sec_PKCS7DestroyDecryptObject(p7dcx->worker.decryptobj); } - PORT_FreeArena (p7dcx->tmp_poolp, PR_FALSE); - PORT_Free (p7dcx); + PORT_FreeArena(p7dcx->tmp_poolp, PR_FALSE); + PORT_Free(p7dcx); return cinfo; } - SEC_PKCS7ContentInfo * SEC_PKCS7DecodeItem(SECItem *p7item, - SEC_PKCS7DecoderContentCallback cb, void *cb_arg, - SECKEYGetPasswordKey pwfn, void *pwfn_arg, - SEC_PKCS7GetDecryptKeyCallback decrypt_key_cb, - void *decrypt_key_cb_arg, - SEC_PKCS7DecryptionAllowedCallback decrypt_allowed_cb) + SEC_PKCS7DecoderContentCallback cb, void *cb_arg, + SECKEYGetPasswordKey pwfn, void *pwfn_arg, + SEC_PKCS7GetDecryptKeyCallback decrypt_key_cb, + void *decrypt_key_cb_arg, + SEC_PKCS7DecryptionAllowedCallback decrypt_allowed_cb) { SEC_PKCS7DecoderContext *p7dcx; p7dcx = SEC_PKCS7DecoderStart(cb, cb_arg, pwfn, pwfn_arg, decrypt_key_cb, - decrypt_key_cb_arg, decrypt_allowed_cb); + decrypt_key_cb_arg, decrypt_allowed_cb); if (!p7dcx) { /* error code is set */ return NULL; } - (void) SEC_PKCS7DecoderUpdate(p7dcx, (char *) p7item->data, p7item->len); + (void)SEC_PKCS7DecoderUpdate(p7dcx, (char *)p7item->data, p7item->len); return SEC_PKCS7DecoderFinish(p7dcx); } @@ -1107,7 +1110,6 @@ SEC_PKCS7DecoderAbort(SEC_PKCS7DecoderContext *p7dcx, int error) SEC_ASN1DecoderAbort(p7dcx->dcx, error); } - /* * If the thing contains any certs or crls return true; false otherwise. */ @@ -1118,90 +1120,87 @@ SEC_PKCS7ContainsCertsOrCrls(SEC_PKCS7ContentInfo *cinfo) SECItem **certs; CERTSignedCrl **crls; - kind = SEC_PKCS7ContentType (cinfo); + kind = SEC_PKCS7ContentType(cinfo); switch (kind) { - default: - case SEC_OID_PKCS7_DATA: - case SEC_OID_PKCS7_DIGESTED_DATA: - case SEC_OID_PKCS7_ENVELOPED_DATA: - case SEC_OID_PKCS7_ENCRYPTED_DATA: - return PR_FALSE; - case SEC_OID_PKCS7_SIGNED_DATA: - certs = cinfo->content.signedData->rawCerts; - crls = cinfo->content.signedData->crls; - break; - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - certs = cinfo->content.signedAndEnvelopedData->rawCerts; - crls = cinfo->content.signedAndEnvelopedData->crls; - break; + default: + case SEC_OID_PKCS7_DATA: + case SEC_OID_PKCS7_DIGESTED_DATA: + case SEC_OID_PKCS7_ENVELOPED_DATA: + case SEC_OID_PKCS7_ENCRYPTED_DATA: + return PR_FALSE; + case SEC_OID_PKCS7_SIGNED_DATA: + certs = cinfo->content.signedData->rawCerts; + crls = cinfo->content.signedData->crls; + break; + case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: + certs = cinfo->content.signedAndEnvelopedData->rawCerts; + crls = cinfo->content.signedAndEnvelopedData->crls; + break; } /* * I know this could be collapsed, but I was in a mood to be explicit. */ if (certs != NULL && certs[0] != NULL) - return PR_TRUE; + return PR_TRUE; else if (crls != NULL && crls[0] != NULL) - return PR_TRUE; + return PR_TRUE; else - return PR_FALSE; + return PR_FALSE; } /* return the content length...could use GetContent, however we - * need the encrypted content length + * need the encrypted content length */ PRBool SEC_PKCS7IsContentEmpty(SEC_PKCS7ContentInfo *cinfo, unsigned int minLen) { SECItem *item = NULL; - if(cinfo == NULL) { - return PR_TRUE; + if (cinfo == NULL) { + return PR_TRUE; } - switch(SEC_PKCS7ContentType(cinfo)) - { - case SEC_OID_PKCS7_DATA: - item = cinfo->content.data; - break; - case SEC_OID_PKCS7_ENCRYPTED_DATA: - item = &cinfo->content.encryptedData->encContentInfo.encContent; - break; - default: - /* add other types */ - return PR_FALSE; + switch (SEC_PKCS7ContentType(cinfo)) { + case SEC_OID_PKCS7_DATA: + item = cinfo->content.data; + break; + case SEC_OID_PKCS7_ENCRYPTED_DATA: + item = &cinfo->content.encryptedData->encContentInfo.encContent; + break; + default: + /* add other types */ + return PR_FALSE; } - if(!item) { - return PR_TRUE; - } else if(item->len <= minLen) { - return PR_TRUE; + if (!item) { + return PR_TRUE; + } else if (item->len <= minLen) { + return PR_TRUE; } return PR_FALSE; } - PRBool SEC_PKCS7ContentIsEncrypted(SEC_PKCS7ContentInfo *cinfo) { SECOidTag kind; - kind = SEC_PKCS7ContentType (cinfo); + kind = SEC_PKCS7ContentType(cinfo); switch (kind) { - default: - case SEC_OID_PKCS7_DATA: - case SEC_OID_PKCS7_DIGESTED_DATA: - case SEC_OID_PKCS7_SIGNED_DATA: - return PR_FALSE; - case SEC_OID_PKCS7_ENCRYPTED_DATA: - case SEC_OID_PKCS7_ENVELOPED_DATA: - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - return PR_TRUE; + default: + case SEC_OID_PKCS7_DATA: + case SEC_OID_PKCS7_DIGESTED_DATA: + case SEC_OID_PKCS7_SIGNED_DATA: + return PR_FALSE; + case SEC_OID_PKCS7_ENCRYPTED_DATA: + case SEC_OID_PKCS7_ENVELOPED_DATA: + case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: + return PR_TRUE; } } - /* * If the PKCS7 content has a signature (not just *could* have a signature) * return true; false otherwise. This can/should be called before calling @@ -1216,20 +1215,20 @@ SEC_PKCS7ContentIsSigned(SEC_PKCS7ContentInfo *cinfo) SECOidTag kind; SEC_PKCS7SignerInfo **signerinfos; - kind = SEC_PKCS7ContentType (cinfo); + kind = SEC_PKCS7ContentType(cinfo); switch (kind) { - default: - case SEC_OID_PKCS7_DATA: - case SEC_OID_PKCS7_DIGESTED_DATA: - case SEC_OID_PKCS7_ENVELOPED_DATA: - case SEC_OID_PKCS7_ENCRYPTED_DATA: - return PR_FALSE; - case SEC_OID_PKCS7_SIGNED_DATA: - signerinfos = cinfo->content.signedData->signerInfos; - break; - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - signerinfos = cinfo->content.signedAndEnvelopedData->signerInfos; - break; + default: + case SEC_OID_PKCS7_DATA: + case SEC_OID_PKCS7_DIGESTED_DATA: + case SEC_OID_PKCS7_ENVELOPED_DATA: + case SEC_OID_PKCS7_ENCRYPTED_DATA: + return PR_FALSE; + case SEC_OID_PKCS7_SIGNED_DATA: + signerinfos = cinfo->content.signedData->signerInfos; + break; + case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: + signerinfos = cinfo->content.signedAndEnvelopedData->signerInfos; + break; } /* @@ -1237,27 +1236,26 @@ SEC_PKCS7ContentIsSigned(SEC_PKCS7ContentInfo *cinfo) * more complicated before I am finished, so... */ if (signerinfos != NULL && signerinfos[0] != NULL) - return PR_TRUE; + return PR_TRUE; else - return PR_FALSE; + return PR_FALSE; } - /* * sec_pkcs7_verify_signature * - * Look at a PKCS7 contentInfo and check if the signature is good. - * The digest was either calculated earlier (and is stored in the - * contentInfo itself) or is passed in via "detached_digest". + * Look at a PKCS7 contentInfo and check if the signature is good. + * The digest was either calculated earlier (and is stored in the + * contentInfo itself) or is passed in via "detached_digest". * - * The verification checks that the signing cert is valid and trusted - * for the purpose specified by "certusage" at - * - "*atTime" if "atTime" is not null, or - * - the signing time if the signing time is available in "cinfo", or - * - the current time (as returned by PR_Now). + * The verification checks that the signing cert is valid and trusted + * for the purpose specified by "certusage" at + * - "*atTime" if "atTime" is not null, or + * - the signing time if the signing time is available in "cinfo", or + * - the current time (as returned by PR_Now). * - * In addition, if "keepcerts" is true, add any new certificates found - * into our local database. + * In addition, if "keepcerts" is true, add any new certificates found + * into our local database. * * XXX Each place which returns PR_FALSE should be sure to have a good * error set for inspection by the caller. Alternatively, we could create @@ -1280,11 +1278,11 @@ SEC_PKCS7ContentIsSigned(SEC_PKCS7ContentInfo *cinfo) */ static PRBool sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo, - SECCertUsage certusage, - const SECItem *detached_digest, - HASH_HashType digest_type, - PRBool keepcerts, - const PRTime *atTime) + SECCertUsage certusage, + const SECItem *detached_digest, + HASH_HashType digest_type, + PRBool keepcerts, + const PRTime *atTime) { SECAlgorithmID **digestalgs, *bulkid; const SECItem *digest; @@ -1293,8 +1291,8 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo, SEC_PKCS7SignerInfo **signerinfos, *signerinfo; CERTCertificate *cert, **certs; PRBool goodsig; - CERTCertDBHandle *certdb, *defaultdb; - SECOidTag encTag,digestTag; + CERTCertDBHandle *certdb, *defaultdb; + SECOidTag encTag, digestTag; HASH_HashType found_type; int i, certcount; SECKEYPublicKey *publickey; @@ -1316,54 +1314,50 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo, defaultdb = CERT_GetDefaultCertDB(); publickey = NULL; - if (! SEC_PKCS7ContentIsSigned(cinfo)) { - PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE); - goto done; + if (!SEC_PKCS7ContentIsSigned(cinfo)) { + PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE); + goto done; } - PORT_Assert (cinfo->contentTypeTag != NULL); + PORT_Assert(cinfo->contentTypeTag != NULL); switch (cinfo->contentTypeTag->offset) { - default: - case SEC_OID_PKCS7_DATA: - case SEC_OID_PKCS7_DIGESTED_DATA: - case SEC_OID_PKCS7_ENVELOPED_DATA: - case SEC_OID_PKCS7_ENCRYPTED_DATA: - /* Could only get here if SEC_PKCS7ContentIsSigned is broken. */ - PORT_Assert (0); - case SEC_OID_PKCS7_SIGNED_DATA: - { - SEC_PKCS7SignedData *sdp; - - sdp = cinfo->content.signedData; - digestalgs = sdp->digestAlgorithms; - digests = sdp->digests; - rawcerts = sdp->rawCerts; - signerinfos = sdp->signerInfos; - content_type = &(sdp->contentInfo.contentType); - sigkey = NULL; - bulkid = NULL; - } - break; - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - { - SEC_PKCS7SignedAndEnvelopedData *saedp; - - saedp = cinfo->content.signedAndEnvelopedData; - digestalgs = saedp->digestAlgorithms; - digests = saedp->digests; - rawcerts = saedp->rawCerts; - signerinfos = saedp->signerInfos; - content_type = &(saedp->encContentInfo.contentType); - sigkey = saedp->sigKey; - bulkid = &(saedp->encContentInfo.contentEncAlg); - } - break; + default: + case SEC_OID_PKCS7_DATA: + case SEC_OID_PKCS7_DIGESTED_DATA: + case SEC_OID_PKCS7_ENVELOPED_DATA: + case SEC_OID_PKCS7_ENCRYPTED_DATA: + /* Could only get here if SEC_PKCS7ContentIsSigned is broken. */ + PORT_Assert(0); + case SEC_OID_PKCS7_SIGNED_DATA: { + SEC_PKCS7SignedData *sdp; + + sdp = cinfo->content.signedData; + digestalgs = sdp->digestAlgorithms; + digests = sdp->digests; + rawcerts = sdp->rawCerts; + signerinfos = sdp->signerInfos; + content_type = &(sdp->contentInfo.contentType); + sigkey = NULL; + bulkid = NULL; + } break; + case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: { + SEC_PKCS7SignedAndEnvelopedData *saedp; + + saedp = cinfo->content.signedAndEnvelopedData; + digestalgs = saedp->digestAlgorithms; + digests = saedp->digests; + rawcerts = saedp->rawCerts; + signerinfos = saedp->signerInfos; + content_type = &(saedp->encContentInfo.contentType); + sigkey = saedp->sigKey; + bulkid = &(saedp->encContentInfo.contentEncAlg); + } break; } if ((signerinfos == NULL) || (signerinfos[0] == NULL)) { - PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE); - goto done; + PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE); + goto done; } /* @@ -1371,8 +1365,8 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo, * but what should be the semantics here (like, return value)? */ if (signerinfos[1] != NULL) { - PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE); - goto done; + PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE); + goto done; } signerinfo = signerinfos[0]; @@ -1385,14 +1379,14 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo, */ certdb = defaultdb; if (certdb == NULL) { - goto done; + goto done; } certcount = 0; if (rawcerts != NULL) { - for (; rawcerts[certcount] != NULL; certcount++) { - /* just counting */ - } + for (; rawcerts[certcount] != NULL; certcount++) { + /* just counting */ + } } /* @@ -1400,9 +1394,9 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo, * needs to be destroyed. */ rv = CERT_ImportCerts(certdb, certusage, certcount, rawcerts, &certs, - keepcerts, PR_FALSE, NULL); - if ( rv != SECSuccess ) { - goto done; + keepcerts, PR_FALSE, NULL); + if (rv != SECSuccess) { + goto done; } /* @@ -1413,7 +1407,7 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo, */ cert = CERT_FindCertByIssuerAndSN(certdb, signerinfo->issuerAndSN); if (cert == NULL) { - goto done; + goto done; } signerinfo->cert = cert; @@ -1423,10 +1417,10 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo, * both on the cert verification and for importing the sender * email profile. */ - encoded_stime = SEC_PKCS7GetSigningTime (cinfo); + encoded_stime = SEC_PKCS7GetSigningTime(cinfo); if (encoded_stime != NULL) { - if (DER_DecodeTimeChoice (&stime, encoded_stime) != SECSuccess) - encoded_stime = NULL; /* conversion failed, so pretend none */ + if (DER_DecodeTimeChoice(&stime, encoded_stime) != SECSuccess) + encoded_stime = NULL; /* conversion failed, so pretend none */ } /* @@ -1438,29 +1432,28 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo, * maybe make them pass in the current time, always?). */ if (atTime) { - verificationTime = *atTime; + verificationTime = *atTime; } else if (encoded_stime != NULL) { - verificationTime = stime; + verificationTime = stime; } else { - verificationTime = PR_Now(); + verificationTime = PR_Now(); } - if (CERT_VerifyCert (certdb, cert, PR_TRUE, certusage, verificationTime, - cinfo->pwfn_arg, NULL) != SECSuccess) - { - /* - * XXX Give the user an option to check the signature anyway? - * If we want to do this, need to give a way to leave and display - * some dialog and get the answer and come back through (or do - * the rest of what we do below elsewhere, maybe by putting it - * in a function that we call below and could call from a dialog - * finish handler). - */ - goto savecert; + if (CERT_VerifyCert(certdb, cert, PR_TRUE, certusage, verificationTime, + cinfo->pwfn_arg, NULL) != SECSuccess) { + /* + * XXX Give the user an option to check the signature anyway? + * If we want to do this, need to give a way to leave and display + * some dialog and get the answer and come back through (or do + * the rest of what we do below elsewhere, maybe by putting it + * in a function that we call below and could call from a dialog + * finish handler). + */ + goto savecert; } - publickey = CERT_ExtractPublicKey (cert); + publickey = CERT_ExtractPublicKey(cert); if (publickey == NULL) - goto done; + goto done; /* * XXX No! If digests is empty, see if we can create it now by @@ -1472,9 +1465,8 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo, * stashed in the struct itself or passed in explicitly (as would * be done for detached contents). */ - if ((digests == NULL || digests[0] == NULL) - && (detached_digest == NULL || detached_digest->data == NULL)) - goto done; + if ((digests == NULL || digests[0] == NULL) && (detached_digest == NULL || detached_digest->data == NULL)) + goto done; /* * Find and confirm digest algorithm. @@ -1484,198 +1476,197 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo, /* make sure we understand the digest type first */ found_type = HASH_GetHashTypeByOidTag(digestTag); if ((digestTag == SEC_OID_UNKNOWN) || (found_type == HASH_AlgNULL)) { - PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE); - goto done; + PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE); + goto done; } if (detached_digest != NULL) { - unsigned int hashLen = HASH_ResultLen(found_type); - - if (digest_type != found_type || - detached_digest->len != hashLen) { - PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE); - goto done; - } - digest = detached_digest; + unsigned int hashLen = HASH_ResultLen(found_type); + + if (digest_type != found_type || + detached_digest->len != hashLen) { + PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE); + goto done; + } + digest = detached_digest; } else { - PORT_Assert (digestalgs != NULL && digestalgs[0] != NULL); - if (digestalgs == NULL || digestalgs[0] == NULL) { - PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE); - goto done; - } - - /* - * pick digest matching signerinfo->digestAlg from digests - */ - for (i = 0; digestalgs[i] != NULL; i++) { - if (SECOID_FindOIDTag(&(digestalgs[i]->algorithm)) == digestTag) - break; - } - if (digestalgs[i] == NULL) { - PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE); - goto done; - } - - digest = digests[i]; + PORT_Assert(digestalgs != NULL && digestalgs[0] != NULL); + if (digestalgs == NULL || digestalgs[0] == NULL) { + PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE); + goto done; + } + + /* + * pick digest matching signerinfo->digestAlg from digests + */ + for (i = 0; digestalgs[i] != NULL; i++) { + if (SECOID_FindOIDTag(&(digestalgs[i]->algorithm)) == digestTag) + break; + } + if (digestalgs[i] == NULL) { + PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE); + goto done; + } + + digest = digests[i]; } encTag = SECOID_FindOIDTag(&(signerinfo->digestEncAlg.algorithm)); if (encTag == SEC_OID_UNKNOWN) { - PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE); - goto done; + PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE); + goto done; } if (signerinfo->authAttr != NULL) { - SEC_PKCS7Attribute *attr; - SECItem *value; - SECItem encoded_attrs; - - /* - * We have a sigkey only for signedAndEnvelopedData, which is - * not supposed to have any authenticated attributes. - */ - if (sigkey != NULL) { - PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE); - goto done; - } - - /* - * PKCS #7 says that if there are any authenticated attributes, - * then there must be one for content type which matches the - * content type of the content being signed, and there must - * be one for message digest which matches our message digest. - * So check these things first. - * XXX Might be nice to have a compare-attribute-value function - * which could collapse the following nicely. - */ - attr = sec_PKCS7FindAttribute (signerinfo->authAttr, - SEC_OID_PKCS9_CONTENT_TYPE, PR_TRUE); - value = sec_PKCS7AttributeValue (attr); - if (value == NULL || value->len != content_type->len) { - PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE); - goto done; - } - if (PORT_Memcmp (value->data, content_type->data, value->len) != 0) { - PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE); - goto done; - } - - attr = sec_PKCS7FindAttribute (signerinfo->authAttr, - SEC_OID_PKCS9_MESSAGE_DIGEST, PR_TRUE); - value = sec_PKCS7AttributeValue (attr); - if (value == NULL || value->len != digest->len) { - PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE); - goto done; - } - if (PORT_Memcmp (value->data, digest->data, value->len) != 0) { - PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE); - goto done; - } - - /* - * Okay, we met the constraints of the basic attributes. - * Now check the signature, which is based on a digest of - * the DER-encoded authenticated attributes. So, first we - * encode and then we digest/verify. - */ - encoded_attrs.data = NULL; - encoded_attrs.len = 0; - if (sec_PKCS7EncodeAttributes (NULL, &encoded_attrs, - &(signerinfo->authAttr)) == NULL) - goto done; - - if (encoded_attrs.data == NULL || encoded_attrs.len == 0) { - PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE); - goto done; - } - - goodsig = (PRBool)(VFY_VerifyDataDirect(encoded_attrs.data, - encoded_attrs.len, - publickey, &(signerinfo->encDigest), - encTag, digestTag, NULL, - cinfo->pwfn_arg) == SECSuccess); - PORT_Free (encoded_attrs.data); + SEC_PKCS7Attribute *attr; + SECItem *value; + SECItem encoded_attrs; + + /* + * We have a sigkey only for signedAndEnvelopedData, which is + * not supposed to have any authenticated attributes. + */ + if (sigkey != NULL) { + PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE); + goto done; + } + + /* + * PKCS #7 says that if there are any authenticated attributes, + * then there must be one for content type which matches the + * content type of the content being signed, and there must + * be one for message digest which matches our message digest. + * So check these things first. + * XXX Might be nice to have a compare-attribute-value function + * which could collapse the following nicely. + */ + attr = sec_PKCS7FindAttribute(signerinfo->authAttr, + SEC_OID_PKCS9_CONTENT_TYPE, PR_TRUE); + value = sec_PKCS7AttributeValue(attr); + if (value == NULL || value->len != content_type->len) { + PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE); + goto done; + } + if (PORT_Memcmp(value->data, content_type->data, value->len) != 0) { + PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE); + goto done; + } + + attr = sec_PKCS7FindAttribute(signerinfo->authAttr, + SEC_OID_PKCS9_MESSAGE_DIGEST, PR_TRUE); + value = sec_PKCS7AttributeValue(attr); + if (value == NULL || value->len != digest->len) { + PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE); + goto done; + } + if (PORT_Memcmp(value->data, digest->data, value->len) != 0) { + PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE); + goto done; + } + + /* + * Okay, we met the constraints of the basic attributes. + * Now check the signature, which is based on a digest of + * the DER-encoded authenticated attributes. So, first we + * encode and then we digest/verify. + */ + encoded_attrs.data = NULL; + encoded_attrs.len = 0; + if (sec_PKCS7EncodeAttributes(NULL, &encoded_attrs, + &(signerinfo->authAttr)) == NULL) + goto done; + + if (encoded_attrs.data == NULL || encoded_attrs.len == 0) { + PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE); + goto done; + } + + goodsig = (PRBool)(VFY_VerifyDataDirect(encoded_attrs.data, + encoded_attrs.len, + publickey, &(signerinfo->encDigest), + encTag, digestTag, NULL, + cinfo->pwfn_arg) == SECSuccess); + PORT_Free(encoded_attrs.data); } else { - SECItem *sig; - SECItem holder; - SECStatus rv; - - /* - * No authenticated attributes. - * The signature is based on the plain message digest. - */ - - sig = &(signerinfo->encDigest); - if (sig->len == 0) { /* bad signature */ - PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE); - goto done; - } - - if (sigkey != NULL) { - sec_PKCS7CipherObject *decryptobj; - unsigned int buflen; - - /* - * For signedAndEnvelopedData, we first must decrypt the encrypted - * digest with the bulk encryption key. The result is the normal - * encrypted digest (aka the signature). - */ - decryptobj = sec_PKCS7CreateDecryptObject (sigkey, bulkid); - if (decryptobj == NULL) - goto done; - - buflen = sec_PKCS7DecryptLength (decryptobj, sig->len, PR_TRUE); - PORT_Assert (buflen); - if (buflen == 0) { /* something is wrong */ - sec_PKCS7DestroyDecryptObject (decryptobj); - goto done; - } - - holder.data = (unsigned char*)PORT_Alloc (buflen); - if (holder.data == NULL) { - sec_PKCS7DestroyDecryptObject (decryptobj); - goto done; - } - - rv = sec_PKCS7Decrypt (decryptobj, holder.data, &holder.len, buflen, - sig->data, sig->len, PR_TRUE); - sec_PKCS7DestroyDecryptObject (decryptobj); - if (rv != SECSuccess) { - goto done; - } - - sig = &holder; - } - - goodsig = (PRBool)(VFY_VerifyDigestDirect(digest, publickey, sig, - encTag, digestTag, cinfo->pwfn_arg) - == SECSuccess); - - if (sigkey != NULL) { - PORT_Assert (sig == &holder); - PORT_ZFree (holder.data, holder.len); - } + SECItem *sig; + SECItem holder; + SECStatus rv; + + /* + * No authenticated attributes. + * The signature is based on the plain message digest. + */ + + sig = &(signerinfo->encDigest); + if (sig->len == 0) { /* bad signature */ + PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE); + goto done; + } + + if (sigkey != NULL) { + sec_PKCS7CipherObject *decryptobj; + unsigned int buflen; + + /* + * For signedAndEnvelopedData, we first must decrypt the encrypted + * digest with the bulk encryption key. The result is the normal + * encrypted digest (aka the signature). + */ + decryptobj = sec_PKCS7CreateDecryptObject(sigkey, bulkid); + if (decryptobj == NULL) + goto done; + + buflen = sec_PKCS7DecryptLength(decryptobj, sig->len, PR_TRUE); + PORT_Assert(buflen); + if (buflen == 0) { /* something is wrong */ + sec_PKCS7DestroyDecryptObject(decryptobj); + goto done; + } + + holder.data = (unsigned char *)PORT_Alloc(buflen); + if (holder.data == NULL) { + sec_PKCS7DestroyDecryptObject(decryptobj); + goto done; + } + + rv = sec_PKCS7Decrypt(decryptobj, holder.data, &holder.len, buflen, + sig->data, sig->len, PR_TRUE); + sec_PKCS7DestroyDecryptObject(decryptobj); + if (rv != SECSuccess) { + goto done; + } + + sig = &holder; + } + + goodsig = (PRBool)(VFY_VerifyDigestDirect(digest, publickey, sig, + encTag, digestTag, cinfo->pwfn_arg) == SECSuccess); + + if (sigkey != NULL) { + PORT_Assert(sig == &holder); + PORT_ZFree(holder.data, holder.len); + } } - if (! goodsig) { - /* - * XXX Change the generic error into our specific one, because - * in that case we get a better explanation out of the Security - * Advisor. This is really a bug in our error strings (the - * "generic" error has a lousy/wrong message associated with it - * which assumes the signature verification was done for the - * purposes of checking the issuer signature on a certificate) - * but this is at least an easy workaround and/or in the - * Security Advisor, which specifically checks for the error - * SEC_ERROR_PKCS7_BAD_SIGNATURE and gives more explanation - * in that case but does not similarly check for - * SEC_ERROR_BAD_SIGNATURE. It probably should, but then would - * probably say the wrong thing in the case that it *was* the - * certificate signature check that failed during the cert - * verification done above. Our error handling is really a mess. - */ - if (PORT_GetError() == SEC_ERROR_BAD_SIGNATURE) - PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE); + if (!goodsig) { + /* + * XXX Change the generic error into our specific one, because + * in that case we get a better explanation out of the Security + * Advisor. This is really a bug in our error strings (the + * "generic" error has a lousy/wrong message associated with it + * which assumes the signature verification was done for the + * purposes of checking the issuer signature on a certificate) + * but this is at least an easy workaround and/or in the + * Security Advisor, which specifically checks for the error + * SEC_ERROR_PKCS7_BAD_SIGNATURE and gives more explanation + * in that case but does not similarly check for + * SEC_ERROR_BAD_SIGNATURE. It probably should, but then would + * probably say the wrong thing in the case that it *was* the + * certificate signature check that failed during the cert + * verification done above. Our error handling is really a mess. + */ + if (PORT_GetError() == SEC_ERROR_BAD_SIGNATURE) + PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE); } savecert: @@ -1683,46 +1674,45 @@ savecert: * Only save the smime profile if we are checking an email message and * the cert has an email address in it. */ - if ( cert->emailAddr && cert->emailAddr[0] && - ( ( certusage == certUsageEmailSigner ) || - ( certusage == certUsageEmailRecipient ) ) ) { - SECItem *profile = NULL; - int save_error; - - /* - * Remember the current error set because we do not care about - * anything set by the functions we are about to call. - */ - save_error = PORT_GetError(); - - if (goodsig && (signerinfo->authAttr != NULL)) { - /* - * If the signature is good, then we can save the S/MIME profile, - * if we have one. - */ - SEC_PKCS7Attribute *attr; - - attr = sec_PKCS7FindAttribute (signerinfo->authAttr, - SEC_OID_PKCS9_SMIME_CAPABILITIES, - PR_TRUE); - profile = sec_PKCS7AttributeValue (attr); - } - - rv = CERT_SaveSMimeProfile (cert, profile, encoded_stime); - - /* - * Restore the saved error in case the calls above set a new - * one that we do not actually care about. - */ - PORT_SetError (save_error); - - /* - * XXX Failure is not indicated anywhere -- the signature - * verification itself is unaffected by whether or not the - * profile was successfully saved. - */ + if (cert->emailAddr && cert->emailAddr[0] && + ((certusage == certUsageEmailSigner) || + (certusage == certUsageEmailRecipient))) { + SECItem *profile = NULL; + int save_error; + + /* + * Remember the current error set because we do not care about + * anything set by the functions we are about to call. + */ + save_error = PORT_GetError(); + + if (goodsig && (signerinfo->authAttr != NULL)) { + /* + * If the signature is good, then we can save the S/MIME profile, + * if we have one. + */ + SEC_PKCS7Attribute *attr; + + attr = sec_PKCS7FindAttribute(signerinfo->authAttr, + SEC_OID_PKCS9_SMIME_CAPABILITIES, + PR_TRUE); + profile = sec_PKCS7AttributeValue(attr); + } + + rv = CERT_SaveSMimeProfile(cert, profile, encoded_stime); + + /* + * Restore the saved error in case the calls above set a new + * one that we do not actually care about. + */ + PORT_SetError(save_error); + + /* + * XXX Failure is not indicated anywhere -- the signature + * verification itself is unaffected by whether or not the + * profile was successfully saved. + */ } - done: @@ -1732,52 +1722,52 @@ done: */ if (certs != NULL) - CERT_DestroyCertArray (certs, certcount); + CERT_DestroyCertArray(certs, certcount); if (publickey != NULL) - SECKEY_DestroyPublicKey (publickey); + SECKEY_DestroyPublicKey(publickey); return goodsig; } /* * SEC_PKCS7VerifySignature - * Look at a PKCS7 contentInfo and check if the signature is good. - * The verification checks that the signing cert is valid and trusted - * for the purpose specified by "certusage". + * Look at a PKCS7 contentInfo and check if the signature is good. + * The verification checks that the signing cert is valid and trusted + * for the purpose specified by "certusage". * - * In addition, if "keepcerts" is true, add any new certificates found - * into our local database. + * In addition, if "keepcerts" is true, add any new certificates found + * into our local database. */ PRBool SEC_PKCS7VerifySignature(SEC_PKCS7ContentInfo *cinfo, - SECCertUsage certusage, - PRBool keepcerts) + SECCertUsage certusage, + PRBool keepcerts) { - return sec_pkcs7_verify_signature (cinfo, certusage, - NULL, HASH_AlgNULL, keepcerts, NULL); + return sec_pkcs7_verify_signature(cinfo, certusage, + NULL, HASH_AlgNULL, keepcerts, NULL); } /* * SEC_PKCS7VerifyDetachedSignature - * Look at a PKCS7 contentInfo and check if the signature matches - * a passed-in digest (calculated, supposedly, from detached contents). - * The verification checks that the signing cert is valid and trusted - * for the purpose specified by "certusage". + * Look at a PKCS7 contentInfo and check if the signature matches + * a passed-in digest (calculated, supposedly, from detached contents). + * The verification checks that the signing cert is valid and trusted + * for the purpose specified by "certusage". * - * In addition, if "keepcerts" is true, add any new certificates found - * into our local database. + * In addition, if "keepcerts" is true, add any new certificates found + * into our local database. */ PRBool SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo, - SECCertUsage certusage, - const SECItem *detached_digest, - HASH_HashType digest_type, - PRBool keepcerts) + SECCertUsage certusage, + const SECItem *detached_digest, + HASH_HashType digest_type, + PRBool keepcerts) { - return sec_pkcs7_verify_signature (cinfo, certusage, - detached_digest, digest_type, - keepcerts, NULL); + return sec_pkcs7_verify_signature(cinfo, certusage, + detached_digest, digest_type, + keepcerts, NULL); } /* @@ -1787,20 +1777,20 @@ SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo, * The verification checks that the signing cert is valid and trusted * for the purpose specified by "certusage" at time "atTime". * - * In addition, if "keepcerts" is true, add any new certificates found - * into our local database. + * In addition, if "keepcerts" is true, add any new certificates found + * into our local database. */ PRBool SEC_PKCS7VerifyDetachedSignatureAtTime(SEC_PKCS7ContentInfo *cinfo, - SECCertUsage certusage, - const SECItem *detached_digest, - HASH_HashType digest_type, - PRBool keepcerts, - PRTime atTime) + SECCertUsage certusage, + const SECItem *detached_digest, + HASH_HashType digest_type, + PRBool keepcerts, + PRTime atTime) { - return sec_pkcs7_verify_signature (cinfo, certusage, - detached_digest, digest_type, - keepcerts, &atTime); + return sec_pkcs7_verify_signature(cinfo, certusage, + detached_digest, digest_type, + keepcerts, &atTime); } /* @@ -1822,35 +1812,31 @@ sec_pkcs7_get_signer_cert_info(SEC_PKCS7ContentInfo *cinfo, int selector) CERTCertificate *signercert; char *container; - kind = SEC_PKCS7ContentType (cinfo); + kind = SEC_PKCS7ContentType(cinfo); switch (kind) { - default: - case SEC_OID_PKCS7_DATA: - case SEC_OID_PKCS7_DIGESTED_DATA: - case SEC_OID_PKCS7_ENVELOPED_DATA: - case SEC_OID_PKCS7_ENCRYPTED_DATA: - PORT_Assert (0); - return NULL; - case SEC_OID_PKCS7_SIGNED_DATA: - { - SEC_PKCS7SignedData *sdp; - - sdp = cinfo->content.signedData; - signerinfos = sdp->signerInfos; - } - break; - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - { - SEC_PKCS7SignedAndEnvelopedData *saedp; - - saedp = cinfo->content.signedAndEnvelopedData; - signerinfos = saedp->signerInfos; - } - break; + default: + case SEC_OID_PKCS7_DATA: + case SEC_OID_PKCS7_DIGESTED_DATA: + case SEC_OID_PKCS7_ENVELOPED_DATA: + case SEC_OID_PKCS7_ENCRYPTED_DATA: + PORT_Assert(0); + return NULL; + case SEC_OID_PKCS7_SIGNED_DATA: { + SEC_PKCS7SignedData *sdp; + + sdp = cinfo->content.signedData; + signerinfos = sdp->signerInfos; + } break; + case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: { + SEC_PKCS7SignedAndEnvelopedData *saedp; + + saedp = cinfo->content.signedAndEnvelopedData; + signerinfos = saedp->signerInfos; + } break; } if (signerinfos == NULL || signerinfos[0] == NULL) - return NULL; + return NULL; signercert = signerinfos[0]->cert; @@ -1858,33 +1844,33 @@ sec_pkcs7_get_signer_cert_info(SEC_PKCS7ContentInfo *cinfo, int selector) * No cert there; see if we can find one by calling verify ourselves. */ if (signercert == NULL) { - /* - * The cert usage does not matter in this case, because we do not - * actually care about the verification itself, but we have to pick - * some valid usage to pass in. - */ - (void) sec_pkcs7_verify_signature (cinfo, certUsageEmailSigner, - NULL, HASH_AlgNULL, PR_FALSE, NULL); - signercert = signerinfos[0]->cert; - if (signercert == NULL) - return NULL; + /* + * The cert usage does not matter in this case, because we do not + * actually care about the verification itself, but we have to pick + * some valid usage to pass in. + */ + (void)sec_pkcs7_verify_signature(cinfo, certUsageEmailSigner, + NULL, HASH_AlgNULL, PR_FALSE, NULL); + signercert = signerinfos[0]->cert; + if (signercert == NULL) + return NULL; } switch (selector) { - case sec_common_name: - container = CERT_GetCommonName (&signercert->subject); - break; - case sec_email_address: - if(signercert->emailAddr && signercert->emailAddr[0]) { - container = PORT_Strdup(signercert->emailAddr); - } else { - container = NULL; - } - break; - default: - PORT_Assert (0); - container = NULL; - break; + case sec_common_name: + container = CERT_GetCommonName(&signercert->subject); + break; + case sec_email_address: + if (signercert->emailAddr && signercert->emailAddr[0]) { + container = PORT_Strdup(signercert->emailAddr); + } else { + container = NULL; + } + break; + default: + PORT_Assert(0); + container = NULL; + break; } return container; @@ -1902,7 +1888,6 @@ SEC_PKCS7GetSignerEmailAddress(SEC_PKCS7ContentInfo *cinfo) return sec_pkcs7_get_signer_cert_info(cinfo, sec_email_address); } - /* * Return the signing time, in UTCTime format, of a PKCS7 contentInfo. */ @@ -1912,8 +1897,8 @@ SEC_PKCS7GetSigningTime(SEC_PKCS7ContentInfo *cinfo) SEC_PKCS7SignerInfo **signerinfos; SEC_PKCS7Attribute *attr; - if (SEC_PKCS7ContentType (cinfo) != SEC_OID_PKCS7_SIGNED_DATA) - return NULL; + if (SEC_PKCS7ContentType(cinfo) != SEC_OID_PKCS7_SIGNED_DATA) + return NULL; signerinfos = cinfo->content.signedData->signerInfos; @@ -1921,9 +1906,9 @@ SEC_PKCS7GetSigningTime(SEC_PKCS7ContentInfo *cinfo) * No signature, or more than one, means no deal. */ if (signerinfos == NULL || signerinfos[0] == NULL || signerinfos[1] != NULL) - return NULL; + return NULL; - attr = sec_PKCS7FindAttribute (signerinfos[0]->authAttr, - SEC_OID_PKCS9_SIGNING_TIME, PR_TRUE); - return sec_PKCS7AttributeValue (attr); + attr = sec_PKCS7FindAttribute(signerinfos[0]->authAttr, + SEC_OID_PKCS9_SIGNING_TIME, PR_TRUE); + return sec_PKCS7AttributeValue(attr); } diff --git a/nss/lib/pkcs7/p7encode.c b/nss/lib/pkcs7/p7encode.c index 349bc84..bdbc343 100644 --- a/nss/lib/pkcs7/p7encode.c +++ b/nss/lib/pkcs7/p7encode.c @@ -16,7 +16,7 @@ #include "secitem.h" #include "pk11func.h" #include "secerr.h" -#include "sechash.h" /* for HASH_GetHashObject() */ +#include "sechash.h" /* for HASH_GetHashObject() */ struct sec_pkcs7_encoder_output { SEC_PKCS7EncoderOutputCallback outputfn; @@ -32,7 +32,6 @@ struct SEC_PKCS7EncoderContextStr { void *digestcx; }; - /* * The little output function that the ASN.1 encoder calls to hand * us bytes which we in turn hand back to our caller (via the callback @@ -40,17 +39,17 @@ struct SEC_PKCS7EncoderContextStr { */ static void sec_pkcs7_encoder_out(void *arg, const char *buf, unsigned long len, - int depth, SEC_ASN1EncodingPart data_kind) + int depth, SEC_ASN1EncodingPart data_kind) { struct sec_pkcs7_encoder_output *output; - output = (struct sec_pkcs7_encoder_output*)arg; - output->outputfn (output->outputarg, buf, len); + output = (struct sec_pkcs7_encoder_output *)arg; + output->outputfn(output->outputarg, buf, len); } static sec_PKCS7CipherObject * -sec_pkcs7_encoder_start_encrypt (SEC_PKCS7ContentInfo *cinfo, - PK11SymKey *orig_bulkkey) +sec_pkcs7_encoder_start_encrypt(SEC_PKCS7ContentInfo *cinfo, + PK11SymKey *orig_bulkkey) { SECOidTag kind; sec_PKCS7CipherObject *encryptobj; @@ -58,153 +57,150 @@ sec_pkcs7_encoder_start_encrypt (SEC_PKCS7ContentInfo *cinfo, SEC_PKCS7EncryptedContentInfo *enccinfo; SECKEYPublicKey *publickey = NULL; SECKEYPrivateKey *ourPrivKey = NULL; - PK11SymKey *bulkkey; + PK11SymKey *bulkkey; void *mark; int i; PLArenaPool *arena = NULL; - kind = SEC_PKCS7ContentType (cinfo); + kind = SEC_PKCS7ContentType(cinfo); switch (kind) { - default: - case SEC_OID_PKCS7_DATA: - case SEC_OID_PKCS7_DIGESTED_DATA: - case SEC_OID_PKCS7_SIGNED_DATA: - recipientinfos = NULL; - enccinfo = NULL; - break; - case SEC_OID_PKCS7_ENCRYPTED_DATA: - { - SEC_PKCS7EncryptedData *encdp; - - /* To do EncryptedData we *must* be given a bulk key. */ - PORT_Assert (orig_bulkkey != NULL); - if (orig_bulkkey == NULL) { - /* XXX error? */ - return NULL; - } - - encdp = cinfo->content.encryptedData; - recipientinfos = NULL; - enccinfo = &(encdp->encContentInfo); - } - break; - case SEC_OID_PKCS7_ENVELOPED_DATA: - { - SEC_PKCS7EnvelopedData *envdp; - - envdp = cinfo->content.envelopedData; - recipientinfos = envdp->recipientInfos; - enccinfo = &(envdp->encContentInfo); - } - break; - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - { - SEC_PKCS7SignedAndEnvelopedData *saedp; - - saedp = cinfo->content.signedAndEnvelopedData; - recipientinfos = saedp->recipientInfos; - enccinfo = &(saedp->encContentInfo); - } - break; + default: + case SEC_OID_PKCS7_DATA: + case SEC_OID_PKCS7_DIGESTED_DATA: + case SEC_OID_PKCS7_SIGNED_DATA: + recipientinfos = NULL; + enccinfo = NULL; + break; + case SEC_OID_PKCS7_ENCRYPTED_DATA: { + SEC_PKCS7EncryptedData *encdp; + + /* To do EncryptedData we *must* be given a bulk key. */ + PORT_Assert(orig_bulkkey != NULL); + if (orig_bulkkey == NULL) { + /* XXX error? */ + return NULL; + } + + encdp = cinfo->content.encryptedData; + recipientinfos = NULL; + enccinfo = &(encdp->encContentInfo); + } break; + case SEC_OID_PKCS7_ENVELOPED_DATA: { + SEC_PKCS7EnvelopedData *envdp; + + envdp = cinfo->content.envelopedData; + recipientinfos = envdp->recipientInfos; + enccinfo = &(envdp->encContentInfo); + } break; + case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: { + SEC_PKCS7SignedAndEnvelopedData *saedp; + + saedp = cinfo->content.signedAndEnvelopedData; + recipientinfos = saedp->recipientInfos; + enccinfo = &(saedp->encContentInfo); + } break; } if (enccinfo == NULL) - return NULL; + return NULL; bulkkey = orig_bulkkey; if (bulkkey == NULL) { - CK_MECHANISM_TYPE type = PK11_AlgtagToMechanism(enccinfo->encalg); - PK11SlotInfo *slot; - - - slot = PK11_GetBestSlot(type,cinfo->pwfn_arg); - if (slot == NULL) { - return NULL; - } - bulkkey = PK11_KeyGen(slot,type,NULL, enccinfo->keysize/8, - cinfo->pwfn_arg); - PK11_FreeSlot(slot); - if (bulkkey == NULL) { - return NULL; - } + CK_MECHANISM_TYPE type = PK11_AlgtagToMechanism(enccinfo->encalg); + PK11SlotInfo *slot; + + slot = PK11_GetBestSlot(type, cinfo->pwfn_arg); + if (slot == NULL) { + return NULL; + } + bulkkey = PK11_KeyGen(slot, type, NULL, enccinfo->keysize / 8, + cinfo->pwfn_arg); + PK11_FreeSlot(slot); + if (bulkkey == NULL) { + return NULL; + } } encryptobj = NULL; - mark = PORT_ArenaMark (cinfo->poolp); + mark = PORT_ArenaMark(cinfo->poolp); /* * Encrypt the bulk key with the public key of each recipient. */ for (i = 0; recipientinfos && (ri = recipientinfos[i]) != NULL; i++) { - CERTCertificate *cert; - SECOidTag certalgtag, encalgtag; - SECStatus rv; - int data_len; - SECItem *params = NULL; - - cert = ri->cert; - PORT_Assert (cert != NULL); - if (cert == NULL) - continue; - - /* - * XXX Want an interface that takes a cert and some data and - * fills in an algorithmID and encrypts the data with the public - * key from the cert. Or, give me two interfaces -- one which - * gets the algorithm tag from a cert (I should not have to go - * down into the subjectPublicKeyInfo myself) and another which - * takes a public key and algorithm tag and data and encrypts - * the data. Or something like that. The point is that all - * of the following hardwired RSA stuff should be done elsewhere. - */ - - certalgtag=SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm)); - - switch (certalgtag) { - case SEC_OID_PKCS1_RSA_ENCRYPTION: - encalgtag = certalgtag; - publickey = CERT_ExtractPublicKey (cert); - if (publickey == NULL) goto loser; - - data_len = SECKEY_PublicKeyStrength(publickey); - ri->encKey.data = - (unsigned char*)PORT_ArenaAlloc(cinfo->poolp ,data_len); - ri->encKey.len = data_len; - if (ri->encKey.data == NULL) goto loser; - - rv = PK11_PubWrapSymKey(PK11_AlgtagToMechanism(certalgtag),publickey, - bulkkey,&ri->encKey); - - SECKEY_DestroyPublicKey(publickey); - publickey = NULL; - if (rv != SECSuccess) goto loser; - params = NULL; /* paranoia */ - break; - default: - PORT_SetError (SEC_ERROR_INVALID_ALGORITHM); - goto loser; - } - - rv = SECOID_SetAlgorithmID(cinfo->poolp, &ri->keyEncAlg, encalgtag, - params); - if (rv != SECSuccess) - goto loser; - if (arena) PORT_FreeArena(arena,PR_FALSE); - arena = NULL; + CERTCertificate *cert; + SECOidTag certalgtag, encalgtag; + SECStatus rv; + int data_len; + SECItem *params = NULL; + + cert = ri->cert; + PORT_Assert(cert != NULL); + if (cert == NULL) + continue; + + /* + * XXX Want an interface that takes a cert and some data and + * fills in an algorithmID and encrypts the data with the public + * key from the cert. Or, give me two interfaces -- one which + * gets the algorithm tag from a cert (I should not have to go + * down into the subjectPublicKeyInfo myself) and another which + * takes a public key and algorithm tag and data and encrypts + * the data. Or something like that. The point is that all + * of the following hardwired RSA stuff should be done elsewhere. + */ + + certalgtag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm)); + + switch (certalgtag) { + case SEC_OID_PKCS1_RSA_ENCRYPTION: + encalgtag = certalgtag; + publickey = CERT_ExtractPublicKey(cert); + if (publickey == NULL) + goto loser; + + data_len = SECKEY_PublicKeyStrength(publickey); + ri->encKey.data = + (unsigned char *)PORT_ArenaAlloc(cinfo->poolp, data_len); + ri->encKey.len = data_len; + if (ri->encKey.data == NULL) + goto loser; + + rv = PK11_PubWrapSymKey(PK11_AlgtagToMechanism(certalgtag), publickey, + bulkkey, &ri->encKey); + + SECKEY_DestroyPublicKey(publickey); + publickey = NULL; + if (rv != SECSuccess) + goto loser; + params = NULL; /* paranoia */ + break; + default: + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + goto loser; + } + + rv = SECOID_SetAlgorithmID(cinfo->poolp, &ri->keyEncAlg, encalgtag, + params); + if (rv != SECSuccess) + goto loser; + if (arena) + PORT_FreeArena(arena, PR_FALSE); + arena = NULL; } - encryptobj = sec_PKCS7CreateEncryptObject (cinfo->poolp, bulkkey, - enccinfo->encalg, - &(enccinfo->contentEncAlg)); + encryptobj = sec_PKCS7CreateEncryptObject(cinfo->poolp, bulkkey, + enccinfo->encalg, + &(enccinfo->contentEncAlg)); if (encryptobj != NULL) { - PORT_ArenaUnmark (cinfo->poolp, mark); - mark = NULL; /* good one; do not want to release */ + PORT_ArenaUnmark(cinfo->poolp, mark); + mark = NULL; /* good one; do not want to release */ } - /* fallthru */ +/* fallthru */ loser: if (arena) { - PORT_FreeArena(arena, PR_FALSE); + PORT_FreeArena(arena, PR_FALSE); } if (publickey) { SECKEY_DestroyPublicKey(publickey); @@ -213,18 +209,18 @@ loser: SECKEY_DestroyPrivateKey(ourPrivKey); } if (mark != NULL) { - PORT_ArenaRelease (cinfo->poolp, mark); + PORT_ArenaRelease(cinfo->poolp, mark); } if (orig_bulkkey == NULL) { - if (bulkkey) PK11_FreeSymKey(bulkkey); + if (bulkkey) + PK11_FreeSymKey(bulkkey); } return encryptobj; } - static void -sec_pkcs7_encoder_notify (void *arg, PRBool before, void *dest, int depth) +sec_pkcs7_encoder_notify(void *arg, PRBool before, void *dest, int depth) { SEC_PKCS7EncoderContext *p7ecx; SEC_PKCS7ContentInfo *cinfo; @@ -236,9 +232,9 @@ sec_pkcs7_encoder_notify (void *arg, PRBool before, void *dest, int depth) * not interesting to us. */ if (!before) - return; + return; - p7ecx = (SEC_PKCS7EncoderContext*)arg; + p7ecx = (SEC_PKCS7EncoderContext *)arg; cinfo = p7ecx->cinfo; before_content = PR_FALSE; @@ -251,97 +247,86 @@ sec_pkcs7_encoder_notify (void *arg, PRBool before, void *dest, int depth) * if/when we want to handle fully nested types, this will have * to recurse until reaching the innermost data content. */ - kind = SEC_PKCS7ContentType (cinfo); + kind = SEC_PKCS7ContentType(cinfo); switch (kind) { - default: - case SEC_OID_PKCS7_DATA: - if (dest == &(cinfo->content.data)) - before_content = PR_TRUE; - break; - - case SEC_OID_PKCS7_DIGESTED_DATA: - { - SEC_PKCS7DigestedData *digd; - - digd = cinfo->content.digestedData; - if (digd == NULL) - break; - - if (dest == &(digd->contentInfo.content)) - before_content = PR_TRUE; - } - break; - - case SEC_OID_PKCS7_ENCRYPTED_DATA: - { - SEC_PKCS7EncryptedData *encd; - - encd = cinfo->content.encryptedData; - if (encd == NULL) - break; - - if (dest == &(encd->encContentInfo.encContent)) - before_content = PR_TRUE; - } - break; - - case SEC_OID_PKCS7_ENVELOPED_DATA: - { - SEC_PKCS7EnvelopedData *envd; - - envd = cinfo->content.envelopedData; - if (envd == NULL) - break; - - if (dest == &(envd->encContentInfo.encContent)) - before_content = PR_TRUE; - } - break; - - case SEC_OID_PKCS7_SIGNED_DATA: - { - SEC_PKCS7SignedData *sigd; - - sigd = cinfo->content.signedData; - if (sigd == NULL) - break; - - if (dest == &(sigd->contentInfo.content)) - before_content = PR_TRUE; - } - break; - - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - { - SEC_PKCS7SignedAndEnvelopedData *saed; - - saed = cinfo->content.signedAndEnvelopedData; - if (saed == NULL) - break; - - if (dest == &(saed->encContentInfo.encContent)) - before_content = PR_TRUE; - } - break; + default: + case SEC_OID_PKCS7_DATA: + if (dest == &(cinfo->content.data)) + before_content = PR_TRUE; + break; + + case SEC_OID_PKCS7_DIGESTED_DATA: { + SEC_PKCS7DigestedData *digd; + + digd = cinfo->content.digestedData; + if (digd == NULL) + break; + + if (dest == &(digd->contentInfo.content)) + before_content = PR_TRUE; + } break; + + case SEC_OID_PKCS7_ENCRYPTED_DATA: { + SEC_PKCS7EncryptedData *encd; + + encd = cinfo->content.encryptedData; + if (encd == NULL) + break; + + if (dest == &(encd->encContentInfo.encContent)) + before_content = PR_TRUE; + } break; + + case SEC_OID_PKCS7_ENVELOPED_DATA: { + SEC_PKCS7EnvelopedData *envd; + + envd = cinfo->content.envelopedData; + if (envd == NULL) + break; + + if (dest == &(envd->encContentInfo.encContent)) + before_content = PR_TRUE; + } break; + + case SEC_OID_PKCS7_SIGNED_DATA: { + SEC_PKCS7SignedData *sigd; + + sigd = cinfo->content.signedData; + if (sigd == NULL) + break; + + if (dest == &(sigd->contentInfo.content)) + before_content = PR_TRUE; + } break; + + case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: { + SEC_PKCS7SignedAndEnvelopedData *saed; + + saed = cinfo->content.signedAndEnvelopedData; + if (saed == NULL) + break; + + if (dest == &(saed->encContentInfo.encContent)) + before_content = PR_TRUE; + } break; } if (before_content) { - /* - * This will cause the next SEC_ASN1EncoderUpdate to take the - * contents bytes from the passed-in buffer. - */ - SEC_ASN1EncoderSetTakeFromBuf (p7ecx->ecx); - /* - * And that is all we needed this notify function for. - */ - SEC_ASN1EncoderClearNotifyProc (p7ecx->ecx); + /* + * This will cause the next SEC_ASN1EncoderUpdate to take the + * contents bytes from the passed-in buffer. + */ + SEC_ASN1EncoderSetTakeFromBuf(p7ecx->ecx); + /* + * And that is all we needed this notify function for. + */ + SEC_ASN1EncoderClearNotifyProc(p7ecx->ecx); } } - static SEC_PKCS7EncoderContext * -sec_pkcs7_encoder_start_contexts (SEC_PKCS7ContentInfo *cinfo, - PK11SymKey *bulkkey) +sec_pkcs7_encoder_start_contexts(SEC_PKCS7ContentInfo *cinfo, + PK11SymKey *bulkkey) { SEC_PKCS7EncoderContext *p7ecx; SECOidTag kind; @@ -349,97 +334,96 @@ sec_pkcs7_encoder_start_contexts (SEC_PKCS7ContentInfo *cinfo, SECItem **digests; SECAlgorithmID *digestalg, **digestalgs; - p7ecx = - (SEC_PKCS7EncoderContext*)PORT_ZAlloc (sizeof(SEC_PKCS7EncoderContext)); + p7ecx = + (SEC_PKCS7EncoderContext *)PORT_ZAlloc(sizeof(SEC_PKCS7EncoderContext)); if (p7ecx == NULL) - return NULL; + return NULL; digests = NULL; digestalg = NULL; digestalgs = NULL; encrypt = PR_FALSE; - kind = SEC_PKCS7ContentType (cinfo); + kind = SEC_PKCS7ContentType(cinfo); switch (kind) { - default: - case SEC_OID_PKCS7_DATA: - break; - case SEC_OID_PKCS7_DIGESTED_DATA: - digestalg = &(cinfo->content.digestedData->digestAlg); - break; - case SEC_OID_PKCS7_SIGNED_DATA: - digests = cinfo->content.signedData->digests; - digestalgs = cinfo->content.signedData->digestAlgorithms; - break; - case SEC_OID_PKCS7_ENCRYPTED_DATA: - case SEC_OID_PKCS7_ENVELOPED_DATA: - encrypt = PR_TRUE; - break; - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - digests = cinfo->content.signedAndEnvelopedData->digests; - digestalgs = cinfo->content.signedAndEnvelopedData->digestAlgorithms; - encrypt = PR_TRUE; - break; + default: + case SEC_OID_PKCS7_DATA: + break; + case SEC_OID_PKCS7_DIGESTED_DATA: + digestalg = &(cinfo->content.digestedData->digestAlg); + break; + case SEC_OID_PKCS7_SIGNED_DATA: + digests = cinfo->content.signedData->digests; + digestalgs = cinfo->content.signedData->digestAlgorithms; + break; + case SEC_OID_PKCS7_ENCRYPTED_DATA: + case SEC_OID_PKCS7_ENVELOPED_DATA: + encrypt = PR_TRUE; + break; + case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: + digests = cinfo->content.signedAndEnvelopedData->digests; + digestalgs = cinfo->content.signedAndEnvelopedData->digestAlgorithms; + encrypt = PR_TRUE; + break; } if (encrypt) { - p7ecx->encryptobj = sec_pkcs7_encoder_start_encrypt (cinfo, bulkkey); - if (p7ecx->encryptobj == NULL) { - PORT_Free (p7ecx); - return NULL; - } + p7ecx->encryptobj = sec_pkcs7_encoder_start_encrypt(cinfo, bulkkey); + if (p7ecx->encryptobj == NULL) { + PORT_Free(p7ecx); + return NULL; + } } if (digestalgs != NULL) { - if (digests != NULL) { - /* digests already created (probably for detached data) */ - digestalg = NULL; - } else { - /* - * XXX Some day we should handle multiple digests; for now, - * assume only one will be done. - */ - PORT_Assert (digestalgs[0] != NULL && digestalgs[1] == NULL); - digestalg = digestalgs[0]; - } + if (digests != NULL) { + /* digests already created (probably for detached data) */ + digestalg = NULL; + } else { + /* + * XXX Some day we should handle multiple digests; for now, + * assume only one will be done. + */ + PORT_Assert(digestalgs[0] != NULL && digestalgs[1] == NULL); + digestalg = digestalgs[0]; + } } if (digestalg != NULL) { - SECOidTag oidTag = SECOID_FindOIDTag(&(digestalg->algorithm)); - - p7ecx->digestobj = HASH_GetHashObjectByOidTag(oidTag); - if (p7ecx->digestobj != NULL) { - p7ecx->digestcx = (* p7ecx->digestobj->create) (); - if (p7ecx->digestcx == NULL) - p7ecx->digestobj = NULL; - else - (* p7ecx->digestobj->begin) (p7ecx->digestcx); - } - if (p7ecx->digestobj == NULL) { - if (p7ecx->encryptobj != NULL) - sec_PKCS7DestroyEncryptObject (p7ecx->encryptobj); - PORT_Free (p7ecx); - return NULL; - } + SECOidTag oidTag = SECOID_FindOIDTag(&(digestalg->algorithm)); + + p7ecx->digestobj = HASH_GetHashObjectByOidTag(oidTag); + if (p7ecx->digestobj != NULL) { + p7ecx->digestcx = (*p7ecx->digestobj->create)(); + if (p7ecx->digestcx == NULL) + p7ecx->digestobj = NULL; + else + (*p7ecx->digestobj->begin)(p7ecx->digestcx); + } + if (p7ecx->digestobj == NULL) { + if (p7ecx->encryptobj != NULL) + sec_PKCS7DestroyEncryptObject(p7ecx->encryptobj); + PORT_Free(p7ecx); + return NULL; + } } p7ecx->cinfo = cinfo; return p7ecx; } - SEC_PKCS7EncoderContext * -SEC_PKCS7EncoderStart (SEC_PKCS7ContentInfo *cinfo, - SEC_PKCS7EncoderOutputCallback outputfn, - void *outputarg, - PK11SymKey *bulkkey) +SEC_PKCS7EncoderStart(SEC_PKCS7ContentInfo *cinfo, + SEC_PKCS7EncoderOutputCallback outputfn, + void *outputarg, + PK11SymKey *bulkkey) { SEC_PKCS7EncoderContext *p7ecx; SECStatus rv; - p7ecx = sec_pkcs7_encoder_start_contexts (cinfo, bulkkey); + p7ecx = sec_pkcs7_encoder_start_contexts(cinfo, bulkkey); if (p7ecx == NULL) - return NULL; + return NULL; p7ecx->output.outputfn = outputfn; p7ecx->output.outputarg = outputarg; @@ -447,23 +431,23 @@ SEC_PKCS7EncoderStart (SEC_PKCS7ContentInfo *cinfo, /* * Initialize the BER encoder. */ - p7ecx->ecx = SEC_ASN1EncoderStart (cinfo, sec_PKCS7ContentInfoTemplate, - sec_pkcs7_encoder_out, &(p7ecx->output)); + p7ecx->ecx = SEC_ASN1EncoderStart(cinfo, sec_PKCS7ContentInfoTemplate, + sec_pkcs7_encoder_out, &(p7ecx->output)); if (p7ecx->ecx == NULL) { - PORT_Free (p7ecx); - return NULL; + PORT_Free(p7ecx); + return NULL; } /* * Indicate that we are streaming. We will be streaming until we * get past the contents bytes. */ - SEC_ASN1EncoderSetStreaming (p7ecx->ecx); + SEC_ASN1EncoderSetStreaming(p7ecx->ecx); /* * The notify function will watch for the contents field. */ - SEC_ASN1EncoderSetNotifyProc (p7ecx->ecx, sec_pkcs7_encoder_notify, p7ecx); + SEC_ASN1EncoderSetNotifyProc(p7ecx->ecx, sec_pkcs7_encoder_notify, p7ecx); /* * This will encode everything up to the content bytes. (The notify @@ -471,29 +455,27 @@ SEC_PKCS7EncoderStart (SEC_PKCS7ContentInfo *cinfo, * caller can start passing contents bytes to our Update, which we * will pass along. */ - rv = SEC_ASN1EncoderUpdate (p7ecx->ecx, NULL, 0); + rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0); if (rv != SECSuccess) { - PORT_Free (p7ecx); - return NULL; + PORT_Free(p7ecx); + return NULL; } return p7ecx; } - /* * XXX If/when we support nested contents, this needs to be revised. */ static SECStatus -sec_pkcs7_encoder_work_data (SEC_PKCS7EncoderContext *p7ecx, SECItem *dest, - const unsigned char *data, unsigned long len, - PRBool final) +sec_pkcs7_encoder_work_data(SEC_PKCS7EncoderContext *p7ecx, SECItem *dest, + const unsigned char *data, unsigned long len, + PRBool final) { unsigned char *buf = NULL; SECStatus rv; - - rv = SECSuccess; /* may as well be optimistic */ + rv = SECSuccess; /* may as well be optimistic */ /* * We should really have data to process, or we should be trying @@ -502,154 +484,153 @@ sec_pkcs7_encoder_work_data (SEC_PKCS7EncoderContext *p7ecx, SECItem *dest, * proves they do it right. But it could find a bug in future * modifications/development, that is why it is here.) */ - PORT_Assert ((data != NULL && len) || final); + PORT_Assert((data != NULL && len) || final); /* * Update the running digest. * XXX This needs modification if/when we handle multiple digests. */ if (len && p7ecx->digestobj != NULL) { - (* p7ecx->digestobj->update) (p7ecx->digestcx, data, len); + (*p7ecx->digestobj->update)(p7ecx->digestcx, data, len); } /* * Encrypt this chunk. */ if (p7ecx->encryptobj != NULL) { - /* XXX the following lengths should all be longs? */ - unsigned int inlen; /* length of data being encrypted */ - unsigned int outlen; /* length of encrypted data */ - unsigned int buflen; /* length available for encrypted data */ - - inlen = len; - buflen = sec_PKCS7EncryptLength (p7ecx->encryptobj, inlen, final); - if (buflen == 0) { - /* - * No output is expected, but the input data may be buffered - * so we still have to call Encrypt. - */ - rv = sec_PKCS7Encrypt (p7ecx->encryptobj, NULL, NULL, 0, - data, inlen, final); - if (final) { - len = 0; - goto done; - } - return rv; - } - - if (dest != NULL) - buf = (unsigned char*)PORT_ArenaAlloc(p7ecx->cinfo->poolp, buflen); - else - buf = (unsigned char*)PORT_Alloc (buflen); - - if (buf == NULL) { - rv = SECFailure; - } else { - rv = sec_PKCS7Encrypt (p7ecx->encryptobj, buf, &outlen, buflen, - data, inlen, final); - data = buf; - len = outlen; - } - if (rv != SECSuccess) { - if (final) - goto done; - return rv; - } + /* XXX the following lengths should all be longs? */ + unsigned int inlen; /* length of data being encrypted */ + unsigned int outlen; /* length of encrypted data */ + unsigned int buflen; /* length available for encrypted data */ + + inlen = len; + buflen = sec_PKCS7EncryptLength(p7ecx->encryptobj, inlen, final); + if (buflen == 0) { + /* + * No output is expected, but the input data may be buffered + * so we still have to call Encrypt. + */ + rv = sec_PKCS7Encrypt(p7ecx->encryptobj, NULL, NULL, 0, + data, inlen, final); + if (final) { + len = 0; + goto done; + } + return rv; + } + + if (dest != NULL) + buf = (unsigned char *)PORT_ArenaAlloc(p7ecx->cinfo->poolp, buflen); + else + buf = (unsigned char *)PORT_Alloc(buflen); + + if (buf == NULL) { + rv = SECFailure; + } else { + rv = sec_PKCS7Encrypt(p7ecx->encryptobj, buf, &outlen, buflen, + data, inlen, final); + data = buf; + len = outlen; + } + if (rv != SECSuccess) { + if (final) + goto done; + return rv; + } } if (p7ecx->ecx != NULL) { - /* - * Encode the contents bytes. - */ - if(len) { - rv = SEC_ASN1EncoderUpdate (p7ecx->ecx, (const char *)data, len); - } + /* + * Encode the contents bytes. + */ + if (len) { + rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, (const char *)data, len); + } } done: if (p7ecx->encryptobj != NULL) { - if (final) - sec_PKCS7DestroyEncryptObject (p7ecx->encryptobj); - if (dest != NULL) { - dest->data = buf; - dest->len = len; - } else if (buf != NULL) { - PORT_Free (buf); - } + if (final) + sec_PKCS7DestroyEncryptObject(p7ecx->encryptobj); + if (dest != NULL) { + dest->data = buf; + dest->len = len; + } else if (buf != NULL) { + PORT_Free(buf); + } } if (final && p7ecx->digestobj != NULL) { - SECItem *digest, **digests, ***digestsp; - unsigned char *digdata; - SECOidTag kind; - - kind = SEC_PKCS7ContentType (p7ecx->cinfo); - switch (kind) { - default: - PORT_Assert (0); - return SECFailure; - case SEC_OID_PKCS7_DIGESTED_DATA: - digest = &(p7ecx->cinfo->content.digestedData->digest); - digestsp = NULL; - break; - case SEC_OID_PKCS7_SIGNED_DATA: - digest = NULL; - digestsp = &(p7ecx->cinfo->content.signedData->digests); - break; - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - digest = NULL; - digestsp = &(p7ecx->cinfo->content.signedAndEnvelopedData->digests); - break; - } - - digdata = (unsigned char*)PORT_ArenaAlloc (p7ecx->cinfo->poolp, - p7ecx->digestobj->length); - if (digdata == NULL) - return SECFailure; - - if (digestsp != NULL) { - PORT_Assert (digest == NULL); - - digest = (SECItem*)PORT_ArenaAlloc (p7ecx->cinfo->poolp, - sizeof(SECItem)); - digests = (SECItem**)PORT_ArenaAlloc (p7ecx->cinfo->poolp, - 2 * sizeof(SECItem *)); - if (digests == NULL || digest == NULL) - return SECFailure; - - digests[0] = digest; - digests[1] = NULL; - - *digestsp = digests; - } - - PORT_Assert (digest != NULL); - - digest->data = digdata; - digest->len = p7ecx->digestobj->length; - - (* p7ecx->digestobj->end) (p7ecx->digestcx, digest->data, - &(digest->len), digest->len); - (* p7ecx->digestobj->destroy) (p7ecx->digestcx, PR_TRUE); + SECItem *digest, **digests, ***digestsp; + unsigned char *digdata; + SECOidTag kind; + + kind = SEC_PKCS7ContentType(p7ecx->cinfo); + switch (kind) { + default: + PORT_Assert(0); + return SECFailure; + case SEC_OID_PKCS7_DIGESTED_DATA: + digest = &(p7ecx->cinfo->content.digestedData->digest); + digestsp = NULL; + break; + case SEC_OID_PKCS7_SIGNED_DATA: + digest = NULL; + digestsp = &(p7ecx->cinfo->content.signedData->digests); + break; + case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: + digest = NULL; + digestsp = &(p7ecx->cinfo->content.signedAndEnvelopedData->digests); + break; + } + + digdata = (unsigned char *)PORT_ArenaAlloc(p7ecx->cinfo->poolp, + p7ecx->digestobj->length); + if (digdata == NULL) + return SECFailure; + + if (digestsp != NULL) { + PORT_Assert(digest == NULL); + + digest = (SECItem *)PORT_ArenaAlloc(p7ecx->cinfo->poolp, + sizeof(SECItem)); + digests = (SECItem **)PORT_ArenaAlloc(p7ecx->cinfo->poolp, + 2 * sizeof(SECItem *)); + if (digests == NULL || digest == NULL) + return SECFailure; + + digests[0] = digest; + digests[1] = NULL; + + *digestsp = digests; + } + + PORT_Assert(digest != NULL); + + digest->data = digdata; + digest->len = p7ecx->digestobj->length; + + (*p7ecx->digestobj->end)(p7ecx->digestcx, digest->data, + &(digest->len), digest->len); + (*p7ecx->digestobj->destroy)(p7ecx->digestcx, PR_TRUE); } return rv; } - SECStatus -SEC_PKCS7EncoderUpdate (SEC_PKCS7EncoderContext *p7ecx, - const char *data, unsigned long len) +SEC_PKCS7EncoderUpdate(SEC_PKCS7EncoderContext *p7ecx, + const char *data, unsigned long len) { /* XXX Error handling needs help. Return what? Do "Finish" on failure? */ - return sec_pkcs7_encoder_work_data (p7ecx, NULL, - (const unsigned char *)data, len, - PR_FALSE); + return sec_pkcs7_encoder_work_data(p7ecx, NULL, + (const unsigned char *)data, len, + PR_FALSE); } static SECStatus -sec_pkcs7_encoder_sig_and_certs (SEC_PKCS7ContentInfo *cinfo, - SECKEYGetPasswordKey pwfn, void *pwfnarg) +sec_pkcs7_encoder_sig_and_certs(SEC_PKCS7ContentInfo *cinfo, + SECKEYGetPasswordKey pwfn, void *pwfnarg) { SECOidTag kind; CERTCertificate **certs; @@ -662,206 +643,202 @@ sec_pkcs7_encoder_sig_and_certs (SEC_PKCS7ContentInfo *cinfo, int certcount; int ci, cli, rci, si; - kind = SEC_PKCS7ContentType (cinfo); + kind = SEC_PKCS7ContentType(cinfo); switch (kind) { - default: - case SEC_OID_PKCS7_DATA: - case SEC_OID_PKCS7_DIGESTED_DATA: - case SEC_OID_PKCS7_ENCRYPTED_DATA: - case SEC_OID_PKCS7_ENVELOPED_DATA: - certs = NULL; - certlists = NULL; - digestalgs = NULL; - digests = NULL; - signerinfos = NULL; - rawcertsp = NULL; - break; - case SEC_OID_PKCS7_SIGNED_DATA: - { - SEC_PKCS7SignedData *sdp; - - sdp = cinfo->content.signedData; - certs = sdp->certs; - certlists = sdp->certLists; - digestalgs = sdp->digestAlgorithms; - digests = sdp->digests; - signerinfos = sdp->signerInfos; - rawcertsp = &(sdp->rawCerts); - } - break; - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - { - SEC_PKCS7SignedAndEnvelopedData *saedp; - - saedp = cinfo->content.signedAndEnvelopedData; - certs = saedp->certs; - certlists = saedp->certLists; - digestalgs = saedp->digestAlgorithms; - digests = saedp->digests; - signerinfos = saedp->signerInfos; - rawcertsp = &(saedp->rawCerts); - } - break; + default: + case SEC_OID_PKCS7_DATA: + case SEC_OID_PKCS7_DIGESTED_DATA: + case SEC_OID_PKCS7_ENCRYPTED_DATA: + case SEC_OID_PKCS7_ENVELOPED_DATA: + certs = NULL; + certlists = NULL; + digestalgs = NULL; + digests = NULL; + signerinfos = NULL; + rawcertsp = NULL; + break; + case SEC_OID_PKCS7_SIGNED_DATA: { + SEC_PKCS7SignedData *sdp; + + sdp = cinfo->content.signedData; + certs = sdp->certs; + certlists = sdp->certLists; + digestalgs = sdp->digestAlgorithms; + digests = sdp->digests; + signerinfos = sdp->signerInfos; + rawcertsp = &(sdp->rawCerts); + } break; + case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: { + SEC_PKCS7SignedAndEnvelopedData *saedp; + + saedp = cinfo->content.signedAndEnvelopedData; + certs = saedp->certs; + certlists = saedp->certLists; + digestalgs = saedp->digestAlgorithms; + digests = saedp->digests; + signerinfos = saedp->signerInfos; + rawcertsp = &(saedp->rawCerts); + } break; } if (certs == NULL && certlists == NULL && signerinfos == NULL) - return SECSuccess; /* nothing for us to do! */ + return SECSuccess; /* nothing for us to do! */ poolp = cinfo->poolp; certcount = 0; if (signerinfos != NULL) { - SECOidTag digestalgtag; - int di; - SECStatus rv; - CERTCertificate *cert; - SECKEYPrivateKey *privkey; - SECItem signature; - SECOidTag signalgtag; - - PORT_Assert (digestalgs != NULL && digests != NULL); - - /* - * If one fails, we bail right then. If we want to continue and - * try to do subsequent signatures, this loop, and the departures - * from it, will need to be reworked. - */ - for (si = 0; signerinfos[si] != NULL; si++) { - - signerinfo = signerinfos[si]; - - /* find right digest */ - digestalgtag = SECOID_GetAlgorithmTag (&(signerinfo->digestAlg)); - for (di = 0; digestalgs[di] != NULL; di++) { - /* XXX Should I be comparing more than the tag? */ - if (digestalgtag == SECOID_GetAlgorithmTag (digestalgs[di])) - break; - } - if (digestalgs[di] == NULL) { - /* XXX oops; do what? set an error? */ - return SECFailure; - } - PORT_Assert (digests[di] != NULL); - - cert = signerinfo->cert; - privkey = PK11_FindKeyByAnyCert (cert, pwfnarg); - if (privkey == NULL) - return SECFailure; - - /* - * XXX I think there should be a cert-level interface for this, - * so that I do not have to know about subjectPublicKeyInfo... - */ - signalgtag = SECOID_GetAlgorithmTag (&(cert->subjectPublicKeyInfo.algorithm)); - - if (signerinfo->authAttr != NULL) { - SEC_PKCS7Attribute *attr; - SECItem encoded_attrs; - SECItem *dummy; - SECOidTag algid; - - /* - * First, find and fill in the message digest attribute. - */ - attr = sec_PKCS7FindAttribute (signerinfo->authAttr, - SEC_OID_PKCS9_MESSAGE_DIGEST, - PR_TRUE); - PORT_Assert (attr != NULL); - if (attr == NULL) { - SECKEY_DestroyPrivateKey (privkey); - return SECFailure; - } - - /* - * XXX The second half of the following assertion prevents - * the encoder from being called twice on the same content. - * Either just remove the second half the assertion, or - * change the code to check if the value already there is - * the same as digests[di], whichever seems more right. - */ - PORT_Assert (attr->values != NULL && attr->values[0] == NULL); - attr->values[0] = digests[di]; - - /* - * Before encoding, reorder the attributes so that when they - * are encoded, they will be conforming DER, which is required - * to have a specific order and that is what must be used for - * the hash/signature. We do this here, rather than building - * it into EncodeAttributes, because we do not want to do - * such reordering on incoming messages (which also uses - * EncodeAttributes) or our old signatures (and other "broken" - * implementations) will not verify. So, we want to guarantee - * that we send out good DER encodings of attributes, but not - * to expect to receive them. - */ - rv = sec_PKCS7ReorderAttributes (signerinfo->authAttr); - if (rv != SECSuccess) { - SECKEY_DestroyPrivateKey (privkey); - return SECFailure; - } - - encoded_attrs.data = NULL; - encoded_attrs.len = 0; - dummy = sec_PKCS7EncodeAttributes (NULL, &encoded_attrs, - &(signerinfo->authAttr)); - if (dummy == NULL) { - SECKEY_DestroyPrivateKey (privkey); - return SECFailure; - } - - algid = SEC_GetSignatureAlgorithmOidTag(privkey->keyType, - digestalgtag); - if (algid == SEC_OID_UNKNOWN) { - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - SECKEY_DestroyPrivateKey (privkey); - return SECFailure; - } - rv = SEC_SignData (&signature, - encoded_attrs.data, encoded_attrs.len, - privkey, - algid); - SECITEM_FreeItem (&encoded_attrs, PR_FALSE); - } else { - rv = SGN_Digest (privkey, digestalgtag, &signature, - digests[di]); - } - - SECKEY_DestroyPrivateKey (privkey); - - if (rv != SECSuccess) - return rv; - - rv = SECITEM_CopyItem (poolp, &(signerinfo->encDigest), &signature); - if (rv != SECSuccess) - return rv; - - SECITEM_FreeItem (&signature, PR_FALSE); - - rv = SECOID_SetAlgorithmID (poolp, &(signerinfo->digestEncAlg), - signalgtag, NULL); - if (rv != SECSuccess) - return SECFailure; - - /* - * Count the cert chain for this signer. - */ - if (signerinfo->certList != NULL) - certcount += signerinfo->certList->len; - } + SECOidTag digestalgtag; + int di; + SECStatus rv; + CERTCertificate *cert; + SECKEYPrivateKey *privkey; + SECItem signature; + SECOidTag signalgtag; + + PORT_Assert(digestalgs != NULL && digests != NULL); + + /* + * If one fails, we bail right then. If we want to continue and + * try to do subsequent signatures, this loop, and the departures + * from it, will need to be reworked. + */ + for (si = 0; signerinfos[si] != NULL; si++) { + + signerinfo = signerinfos[si]; + + /* find right digest */ + digestalgtag = SECOID_GetAlgorithmTag(&(signerinfo->digestAlg)); + for (di = 0; digestalgs[di] != NULL; di++) { + /* XXX Should I be comparing more than the tag? */ + if (digestalgtag == SECOID_GetAlgorithmTag(digestalgs[di])) + break; + } + if (digestalgs[di] == NULL) { + /* XXX oops; do what? set an error? */ + return SECFailure; + } + PORT_Assert(digests[di] != NULL); + + cert = signerinfo->cert; + privkey = PK11_FindKeyByAnyCert(cert, pwfnarg); + if (privkey == NULL) + return SECFailure; + + /* + * XXX I think there should be a cert-level interface for this, + * so that I do not have to know about subjectPublicKeyInfo... + */ + signalgtag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm)); + + if (signerinfo->authAttr != NULL) { + SEC_PKCS7Attribute *attr; + SECItem encoded_attrs; + SECItem *dummy; + SECOidTag algid; + + /* + * First, find and fill in the message digest attribute. + */ + attr = sec_PKCS7FindAttribute(signerinfo->authAttr, + SEC_OID_PKCS9_MESSAGE_DIGEST, + PR_TRUE); + PORT_Assert(attr != NULL); + if (attr == NULL) { + SECKEY_DestroyPrivateKey(privkey); + return SECFailure; + } + + /* + * XXX The second half of the following assertion prevents + * the encoder from being called twice on the same content. + * Either just remove the second half the assertion, or + * change the code to check if the value already there is + * the same as digests[di], whichever seems more right. + */ + PORT_Assert(attr->values != NULL && attr->values[0] == NULL); + attr->values[0] = digests[di]; + + /* + * Before encoding, reorder the attributes so that when they + * are encoded, they will be conforming DER, which is required + * to have a specific order and that is what must be used for + * the hash/signature. We do this here, rather than building + * it into EncodeAttributes, because we do not want to do + * such reordering on incoming messages (which also uses + * EncodeAttributes) or our old signatures (and other "broken" + * implementations) will not verify. So, we want to guarantee + * that we send out good DER encodings of attributes, but not + * to expect to receive them. + */ + rv = sec_PKCS7ReorderAttributes(signerinfo->authAttr); + if (rv != SECSuccess) { + SECKEY_DestroyPrivateKey(privkey); + return SECFailure; + } + + encoded_attrs.data = NULL; + encoded_attrs.len = 0; + dummy = sec_PKCS7EncodeAttributes(NULL, &encoded_attrs, + &(signerinfo->authAttr)); + if (dummy == NULL) { + SECKEY_DestroyPrivateKey(privkey); + return SECFailure; + } + + algid = SEC_GetSignatureAlgorithmOidTag(privkey->keyType, + digestalgtag); + if (algid == SEC_OID_UNKNOWN) { + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + SECKEY_DestroyPrivateKey(privkey); + return SECFailure; + } + rv = SEC_SignData(&signature, + encoded_attrs.data, encoded_attrs.len, + privkey, + algid); + SECITEM_FreeItem(&encoded_attrs, PR_FALSE); + } else { + rv = SGN_Digest(privkey, digestalgtag, &signature, + digests[di]); + } + + SECKEY_DestroyPrivateKey(privkey); + + if (rv != SECSuccess) + return rv; + + rv = SECITEM_CopyItem(poolp, &(signerinfo->encDigest), &signature); + if (rv != SECSuccess) + return rv; + + SECITEM_FreeItem(&signature, PR_FALSE); + + rv = SECOID_SetAlgorithmID(poolp, &(signerinfo->digestEncAlg), + signalgtag, NULL); + if (rv != SECSuccess) + return SECFailure; + + /* + * Count the cert chain for this signer. + */ + if (signerinfo->certList != NULL) + certcount += signerinfo->certList->len; + } } if (certs != NULL) { - for (ci = 0; certs[ci] != NULL; ci++) - certcount++; + for (ci = 0; certs[ci] != NULL; ci++) + certcount++; } if (certlists != NULL) { - for (cli = 0; certlists[cli] != NULL; cli++) - certcount += certlists[cli]->len; + for (cli = 0; certlists[cli] != NULL; cli++) + certcount += certlists[cli]->len; } if (certcount == 0) - return SECSuccess; /* signing done; no certs */ + return SECSuccess; /* signing done; no certs */ /* * Combine all of the certs and cert chains into rawcerts. @@ -869,10 +846,10 @@ sec_pkcs7_encoder_sig_and_certs (SEC_PKCS7ContentInfo *cinfo, * but we will allocate anyway to avoid having to do another pass. * (The temporary space saving is not worth it.) */ - rawcerts = (SECItem**)PORT_ArenaAlloc (poolp, - (certcount + 1) * sizeof(SECItem *)); + rawcerts = (SECItem **)PORT_ArenaAlloc(poolp, + (certcount + 1) * sizeof(SECItem *)); if (rawcerts == NULL) - return SECFailure; + return SECFailure; /* * XXX Want to check for duplicates and not add *any* cert that is @@ -882,24 +859,23 @@ sec_pkcs7_encoder_sig_and_certs (SEC_PKCS7ContentInfo *cinfo, */ rci = 0; if (signerinfos != NULL) { - for (si = 0; signerinfos[si] != NULL; si++) { - signerinfo = signerinfos[si]; - for (ci = 0; ci < signerinfo->certList->len; ci++) - rawcerts[rci++] = &(signerinfo->certList->certs[ci]); - } - + for (si = 0; signerinfos[si] != NULL; si++) { + signerinfo = signerinfos[si]; + for (ci = 0; ci < signerinfo->certList->len; ci++) + rawcerts[rci++] = &(signerinfo->certList->certs[ci]); + } } if (certs != NULL) { - for (ci = 0; certs[ci] != NULL; ci++) - rawcerts[rci++] = &(certs[ci]->derCert); + for (ci = 0; certs[ci] != NULL; ci++) + rawcerts[rci++] = &(certs[ci]->derCert); } if (certlists != NULL) { - for (cli = 0; certlists[cli] != NULL; cli++) { - for (ci = 0; ci < certlists[cli]->len; ci++) - rawcerts[rci++] = &(certlists[cli]->certs[ci]); - } + for (cli = 0; certlists[cli] != NULL; cli++) { + for (ci = 0; ci < certlists[cli]->len; ci++) + rawcerts[rci++] = &(certlists[cli]->certs[ci]); + } } rawcerts[rci] = NULL; @@ -908,36 +884,35 @@ sec_pkcs7_encoder_sig_and_certs (SEC_PKCS7ContentInfo *cinfo, return SECSuccess; } - SECStatus -SEC_PKCS7EncoderFinish (SEC_PKCS7EncoderContext *p7ecx, - SECKEYGetPasswordKey pwfn, void *pwfnarg) +SEC_PKCS7EncoderFinish(SEC_PKCS7EncoderContext *p7ecx, + SECKEYGetPasswordKey pwfn, void *pwfnarg) { SECStatus rv; /* * Flush out any remaining data. */ - rv = sec_pkcs7_encoder_work_data (p7ecx, NULL, NULL, 0, PR_TRUE); + rv = sec_pkcs7_encoder_work_data(p7ecx, NULL, NULL, 0, PR_TRUE); /* * Turn off streaming stuff. */ - SEC_ASN1EncoderClearTakeFromBuf (p7ecx->ecx); - SEC_ASN1EncoderClearStreaming (p7ecx->ecx); + SEC_ASN1EncoderClearTakeFromBuf(p7ecx->ecx); + SEC_ASN1EncoderClearStreaming(p7ecx->ecx); if (rv != SECSuccess) - goto loser; + goto loser; - rv = sec_pkcs7_encoder_sig_and_certs (p7ecx->cinfo, pwfn, pwfnarg); + rv = sec_pkcs7_encoder_sig_and_certs(p7ecx->cinfo, pwfn, pwfnarg); if (rv != SECSuccess) - goto loser; + goto loser; - rv = SEC_ASN1EncoderUpdate (p7ecx->ecx, NULL, 0); + rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0); loser: - SEC_ASN1EncoderFinish (p7ecx->ecx); - PORT_Free (p7ecx); + SEC_ASN1EncoderFinish(p7ecx->ecx); + PORT_Free(p7ecx); return rv; } @@ -958,61 +933,60 @@ SEC_PKCS7EncoderAbort(SEC_PKCS7EncoderContext *p7ecx, int error) * the ASN1 template for pkcs7 contentInfo built into their own encodings. */ SECStatus -SEC_PKCS7PrepareForEncode (SEC_PKCS7ContentInfo *cinfo, - PK11SymKey *bulkkey, - SECKEYGetPasswordKey pwfn, - void *pwfnarg) +SEC_PKCS7PrepareForEncode(SEC_PKCS7ContentInfo *cinfo, + PK11SymKey *bulkkey, + SECKEYGetPasswordKey pwfn, + void *pwfnarg) { SEC_PKCS7EncoderContext *p7ecx; SECItem *content, *enc_content; SECStatus rv; - p7ecx = sec_pkcs7_encoder_start_contexts (cinfo, bulkkey); + p7ecx = sec_pkcs7_encoder_start_contexts(cinfo, bulkkey); if (p7ecx == NULL) - return SECFailure; + return SECFailure; - content = SEC_PKCS7GetContent (cinfo); + content = SEC_PKCS7GetContent(cinfo); if (p7ecx->encryptobj != NULL) { - SECOidTag kind; - SEC_PKCS7EncryptedContentInfo *enccinfo; - - kind = SEC_PKCS7ContentType (p7ecx->cinfo); - switch (kind) { - default: - PORT_Assert (0); - rv = SECFailure; - goto loser; - case SEC_OID_PKCS7_ENCRYPTED_DATA: - enccinfo = &(p7ecx->cinfo->content.encryptedData->encContentInfo); - break; - case SEC_OID_PKCS7_ENVELOPED_DATA: - enccinfo = &(p7ecx->cinfo->content.envelopedData->encContentInfo); - break; - case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: - enccinfo = &(p7ecx->cinfo->content.signedAndEnvelopedData->encContentInfo); - break; - } - enc_content = &(enccinfo->encContent); + SECOidTag kind; + SEC_PKCS7EncryptedContentInfo *enccinfo; + + kind = SEC_PKCS7ContentType(p7ecx->cinfo); + switch (kind) { + default: + PORT_Assert(0); + rv = SECFailure; + goto loser; + case SEC_OID_PKCS7_ENCRYPTED_DATA: + enccinfo = &(p7ecx->cinfo->content.encryptedData->encContentInfo); + break; + case SEC_OID_PKCS7_ENVELOPED_DATA: + enccinfo = &(p7ecx->cinfo->content.envelopedData->encContentInfo); + break; + case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: + enccinfo = &(p7ecx->cinfo->content.signedAndEnvelopedData->encContentInfo); + break; + } + enc_content = &(enccinfo->encContent); } else { - enc_content = NULL; + enc_content = NULL; } if (content != NULL && content->data != NULL && content->len) { - rv = sec_pkcs7_encoder_work_data (p7ecx, enc_content, - content->data, content->len, PR_TRUE); - if (rv != SECSuccess) - goto loser; + rv = sec_pkcs7_encoder_work_data(p7ecx, enc_content, + content->data, content->len, PR_TRUE); + if (rv != SECSuccess) + goto loser; } - rv = sec_pkcs7_encoder_sig_and_certs (cinfo, pwfn, pwfnarg); + rv = sec_pkcs7_encoder_sig_and_certs(cinfo, pwfn, pwfnarg); loser: - PORT_Free (p7ecx); + PORT_Free(p7ecx); return rv; } - /* * Encode a PKCS7 object, in one shot. All necessary components * of the object must already be specified. Either the data has @@ -1037,30 +1011,29 @@ loser: * "pwfnarg" is an opaque argument to the above callback. */ SECStatus -SEC_PKCS7Encode (SEC_PKCS7ContentInfo *cinfo, - SEC_PKCS7EncoderOutputCallback outputfn, - void *outputarg, - PK11SymKey *bulkkey, - SECKEYGetPasswordKey pwfn, - void *pwfnarg) +SEC_PKCS7Encode(SEC_PKCS7ContentInfo *cinfo, + SEC_PKCS7EncoderOutputCallback outputfn, + void *outputarg, + PK11SymKey *bulkkey, + SECKEYGetPasswordKey pwfn, + void *pwfnarg) { SECStatus rv; - rv = SEC_PKCS7PrepareForEncode (cinfo, bulkkey, pwfn, pwfnarg); + rv = SEC_PKCS7PrepareForEncode(cinfo, bulkkey, pwfn, pwfnarg); if (rv == SECSuccess) { - struct sec_pkcs7_encoder_output outputcx; + struct sec_pkcs7_encoder_output outputcx; - outputcx.outputfn = outputfn; - outputcx.outputarg = outputarg; + outputcx.outputfn = outputfn; + outputcx.outputarg = outputarg; - rv = SEC_ASN1Encode (cinfo, sec_PKCS7ContentInfoTemplate, - sec_pkcs7_encoder_out, &outputcx); + rv = SEC_ASN1Encode(cinfo, sec_PKCS7ContentInfoTemplate, + sec_pkcs7_encoder_out, &outputcx); } return rv; } - /* * Encode a PKCS7 object, in one shot. All necessary components * of the object must already be specified. Either the data has @@ -1089,19 +1062,18 @@ SEC_PKCS7Encode (SEC_PKCS7ContentInfo *cinfo, * "pwfnarg" is an opaque argument to the above callback. */ SECItem * -SEC_PKCS7EncodeItem (PLArenaPool *pool, - SECItem *dest, - SEC_PKCS7ContentInfo *cinfo, - PK11SymKey *bulkkey, - SECKEYGetPasswordKey pwfn, - void *pwfnarg) +SEC_PKCS7EncodeItem(PLArenaPool *pool, + SECItem *dest, + SEC_PKCS7ContentInfo *cinfo, + PK11SymKey *bulkkey, + SECKEYGetPasswordKey pwfn, + void *pwfnarg) { SECStatus rv; - rv = SEC_PKCS7PrepareForEncode (cinfo, bulkkey, pwfn, pwfnarg); + rv = SEC_PKCS7PrepareForEncode(cinfo, bulkkey, pwfn, pwfnarg); if (rv != SECSuccess) - return NULL; + return NULL; - return SEC_ASN1EncodeItem (pool, dest, cinfo, sec_PKCS7ContentInfoTemplate); + return SEC_ASN1EncodeItem(pool, dest, cinfo, sec_PKCS7ContentInfoTemplate); } - diff --git a/nss/lib/pkcs7/p7local.c b/nss/lib/pkcs7/p7local.c index 5e67a0e..182e385 100644 --- a/nss/lib/pkcs7/p7local.c +++ b/nss/lib/pkcs7/p7local.c @@ -11,7 +11,7 @@ #include "p7local.h" -#include "cryptohi.h" +#include "cryptohi.h" #include "secasn1.h" #include "secoid.h" #include "secitem.h" @@ -24,13 +24,13 @@ * Cipher stuff. */ -typedef SECStatus (*sec_pkcs7_cipher_function) (void *, - unsigned char *, - unsigned *, - unsigned int, - const unsigned char *, - unsigned int); -typedef SECStatus (*sec_pkcs7_cipher_destroy) (void *, PRBool); +typedef SECStatus (*sec_pkcs7_cipher_function)(void *, + unsigned char *, + unsigned *, + unsigned int, + const unsigned char *, + unsigned int); +typedef SECStatus (*sec_pkcs7_cipher_destroy)(void *, PRBool); #define BLOCK_SIZE 4096 @@ -61,10 +61,10 @@ SEC_ASN1_MKSUB(SEC_SetOfAnyTemplate) * * XXX Once both are working, it might be nice to combine this and the * function below (for starting up encryption) into one routine, and just - * have two simple cover functions which call it. + * have two simple cover functions which call it. */ sec_PKCS7CipherObject * -sec_PKCS7CreateDecryptObject (PK11SymKey *key, SECAlgorithmID *algid) +sec_PKCS7CreateDecryptObject(PK11SymKey *key, SECAlgorithmID *algid) { sec_PKCS7CipherObject *result; SECOidTag algtag; @@ -73,53 +73,53 @@ sec_PKCS7CreateDecryptObject (PK11SymKey *key, SECAlgorithmID *algid) PK11SlotInfo *slot; SECItem *param = NULL; - result = (struct sec_pkcs7_cipher_object*) - PORT_ZAlloc (sizeof(struct sec_pkcs7_cipher_object)); + result = (struct sec_pkcs7_cipher_object *) + PORT_ZAlloc(sizeof(struct sec_pkcs7_cipher_object)); if (result == NULL) - return NULL; + return NULL; ciphercx = NULL; - algtag = SECOID_GetAlgorithmTag (algid); + algtag = SECOID_GetAlgorithmTag(algid); if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) { - SECItem *pwitem; - - pwitem = (SECItem *)PK11_GetSymKeyUserData(key); - if (!pwitem) { - PORT_Free(result); - return NULL; - } - - cryptoMechType = PK11_GetPBECryptoMechanism(algid, ¶m, pwitem); - if (cryptoMechType == CKM_INVALID_MECHANISM) { - PORT_Free(result); - SECITEM_FreeItem(param,PR_TRUE); - return NULL; - } + SECItem *pwitem; + + pwitem = (SECItem *)PK11_GetSymKeyUserData(key); + if (!pwitem) { + PORT_Free(result); + return NULL; + } + + cryptoMechType = PK11_GetPBECryptoMechanism(algid, ¶m, pwitem); + if (cryptoMechType == CKM_INVALID_MECHANISM) { + PORT_Free(result); + SECITEM_FreeItem(param, PR_TRUE); + return NULL; + } } else { - cryptoMechType = PK11_AlgtagToMechanism(algtag); - param = PK11_ParamFromAlgid(algid); - if (param == NULL) { - PORT_Free(result); - return NULL; - } + cryptoMechType = PK11_AlgtagToMechanism(algtag); + param = PK11_ParamFromAlgid(algid); + if (param == NULL) { + PORT_Free(result); + return NULL; + } } result->pad_size = PK11_GetBlockSize(cryptoMechType, param); slot = PK11_GetSlotFromKey(key); result->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : result->pad_size; PK11_FreeSlot(slot); - ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT, - key, param); - SECITEM_FreeItem(param,PR_TRUE); + ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT, + key, param); + SECITEM_FreeItem(param, PR_TRUE); if (ciphercx == NULL) { - PORT_Free (result); - return NULL; + PORT_Free(result); + return NULL; } result->cx = ciphercx; - result->doit = (sec_pkcs7_cipher_function) PK11_CipherOp; - result->destroy = (sec_pkcs7_cipher_destroy) PK11_DestroyContext; + result->doit = (sec_pkcs7_cipher_function)PK11_CipherOp; + result->destroy = (sec_pkcs7_cipher_destroy)PK11_DestroyContext; result->encrypt = PR_FALSE; result->pending_count = 0; @@ -137,11 +137,11 @@ sec_PKCS7CreateDecryptObject (PK11SymKey *key, SECAlgorithmID *algid) * * XXX Once both are working, it might be nice to combine this and the * function above (for starting up decryption) into one routine, and just - * have two simple cover functions which call it. + * have two simple cover functions which call it. */ sec_PKCS7CipherObject * -sec_PKCS7CreateEncryptObject (PLArenaPool *poolp, PK11SymKey *key, - SECOidTag algtag, SECAlgorithmID *algid) +sec_PKCS7CreateEncryptObject(PLArenaPool *poolp, PK11SymKey *key, + SECOidTag algtag, SECAlgorithmID *algid) { sec_PKCS7CipherObject *result; void *ciphercx; @@ -151,47 +151,47 @@ sec_PKCS7CreateEncryptObject (PLArenaPool *poolp, PK11SymKey *key, SECItem *param = NULL; PRBool needToEncodeAlgid = PR_FALSE; - result = (struct sec_pkcs7_cipher_object*) - PORT_ZAlloc (sizeof(struct sec_pkcs7_cipher_object)); + result = (struct sec_pkcs7_cipher_object *) + PORT_ZAlloc(sizeof(struct sec_pkcs7_cipher_object)); if (result == NULL) - return NULL; + return NULL; ciphercx = NULL; if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) { - SECItem *pwitem; - - pwitem = (SECItem *)PK11_GetSymKeyUserData(key); - if (!pwitem) { - PORT_Free(result); - return NULL; - } - - cryptoMechType = PK11_GetPBECryptoMechanism(algid, ¶m, pwitem); - if (cryptoMechType == CKM_INVALID_MECHANISM) { - PORT_Free(result); - SECITEM_FreeItem(param,PR_TRUE); - return NULL; - } + SECItem *pwitem; + + pwitem = (SECItem *)PK11_GetSymKeyUserData(key); + if (!pwitem) { + PORT_Free(result); + return NULL; + } + + cryptoMechType = PK11_GetPBECryptoMechanism(algid, ¶m, pwitem); + if (cryptoMechType == CKM_INVALID_MECHANISM) { + PORT_Free(result); + SECITEM_FreeItem(param, PR_TRUE); + return NULL; + } } else { - cryptoMechType = PK11_AlgtagToMechanism(algtag); - param = PK11_GenerateNewParam(cryptoMechType, key); - if (param == NULL) { - PORT_Free(result); - return NULL; - } - needToEncodeAlgid = PR_TRUE; + cryptoMechType = PK11_AlgtagToMechanism(algtag); + param = PK11_GenerateNewParam(cryptoMechType, key); + if (param == NULL) { + PORT_Free(result); + return NULL; + } + needToEncodeAlgid = PR_TRUE; } - result->pad_size = PK11_GetBlockSize(cryptoMechType,param); + result->pad_size = PK11_GetBlockSize(cryptoMechType, param); slot = PK11_GetSlotFromKey(key); result->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : result->pad_size; PK11_FreeSlot(slot); - ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_ENCRYPT, - key, param); + ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_ENCRYPT, + key, param); if (ciphercx == NULL) { - PORT_Free (result); - SECITEM_FreeItem(param,PR_TRUE); - return NULL; + PORT_Free(result); + SECITEM_FreeItem(param, PR_TRUE); + return NULL; } /* @@ -200,63 +200,60 @@ sec_PKCS7CreateEncryptObject (PLArenaPool *poolp, PK11SymKey *key, * Don't move it from here. */ if (needToEncodeAlgid) { - rv = PK11_ParamToAlgid(algtag,param,poolp,algid); - if(rv != SECSuccess) { - PORT_Free (result); - SECITEM_FreeItem(param,PR_TRUE); - PK11_DestroyContext(ciphercx, PR_TRUE); - return NULL; - } + rv = PK11_ParamToAlgid(algtag, param, poolp, algid); + if (rv != SECSuccess) { + PORT_Free(result); + SECITEM_FreeItem(param, PR_TRUE); + PK11_DestroyContext(ciphercx, PR_TRUE); + return NULL; + } } - SECITEM_FreeItem(param,PR_TRUE); + SECITEM_FreeItem(param, PR_TRUE); result->cx = ciphercx; - result->doit = (sec_pkcs7_cipher_function) PK11_CipherOp; - result->destroy = (sec_pkcs7_cipher_destroy) PK11_DestroyContext; + result->doit = (sec_pkcs7_cipher_function)PK11_CipherOp; + result->destroy = (sec_pkcs7_cipher_destroy)PK11_DestroyContext; result->encrypt = PR_TRUE; result->pending_count = 0; return result; } - /* * Destroy the cipher object. */ static void -sec_pkcs7_destroy_cipher (sec_PKCS7CipherObject *obj) +sec_pkcs7_destroy_cipher(sec_PKCS7CipherObject *obj) { - (* obj->destroy) (obj->cx, PR_TRUE); - PORT_Free (obj); + (*obj->destroy)(obj->cx, PR_TRUE); + PORT_Free(obj); } void -sec_PKCS7DestroyDecryptObject (sec_PKCS7CipherObject *obj) +sec_PKCS7DestroyDecryptObject(sec_PKCS7CipherObject *obj) { - PORT_Assert (obj != NULL); + PORT_Assert(obj != NULL); if (obj == NULL) - return; - PORT_Assert (! obj->encrypt); - sec_pkcs7_destroy_cipher (obj); + return; + PORT_Assert(!obj->encrypt); + sec_pkcs7_destroy_cipher(obj); } void -sec_PKCS7DestroyEncryptObject (sec_PKCS7CipherObject *obj) +sec_PKCS7DestroyEncryptObject(sec_PKCS7CipherObject *obj) { - PORT_Assert (obj != NULL); + PORT_Assert(obj != NULL); if (obj == NULL) - return; - PORT_Assert (obj->encrypt); - sec_pkcs7_destroy_cipher (obj); + return; + PORT_Assert(obj->encrypt); + sec_pkcs7_destroy_cipher(obj); } - /* * XXX I think all of the following lengths should be longs instead * of ints, but our current crypto interface uses ints, so I did too. */ - /* * What will be the output length of the next call to decrypt? * Result can be used to perform memory allocations. Note that the amount @@ -274,12 +271,12 @@ sec_PKCS7DestroyEncryptObject (sec_PKCS7CipherObject *obj) * will be stored. */ unsigned int -sec_PKCS7DecryptLength (sec_PKCS7CipherObject *obj, unsigned int input_len, - PRBool final) +sec_PKCS7DecryptLength(sec_PKCS7CipherObject *obj, unsigned int input_len, + PRBool final) { int blocks, block_size; - PORT_Assert (! obj->encrypt); + PORT_Assert(!obj->encrypt); block_size = obj->block_size; @@ -288,7 +285,7 @@ sec_PKCS7DecryptLength (sec_PKCS7CipherObject *obj, unsigned int input_len, * number of output bytes as we had input bytes. */ if (block_size == 0) - return input_len; + return input_len; /* * On the final call, we will always use up all of the pending @@ -299,7 +296,7 @@ sec_PKCS7DecryptLength (sec_PKCS7CipherObject *obj, unsigned int input_len, * at least 1 byte of padding), but seemed clearer/better to me. */ if (final) - return obj->pending_count + input_len; + return obj->pending_count + input_len; /* * Okay, this amount is exactly what we will output on the @@ -328,13 +325,13 @@ sec_PKCS7DecryptLength (sec_PKCS7CipherObject *obj, unsigned int input_len, * will be stored. */ unsigned int -sec_PKCS7EncryptLength (sec_PKCS7CipherObject *obj, unsigned int input_len, - PRBool final) +sec_PKCS7EncryptLength(sec_PKCS7CipherObject *obj, unsigned int input_len, + PRBool final) { int blocks, block_size; int pad_size; - PORT_Assert (obj->encrypt); + PORT_Assert(obj->encrypt); block_size = obj->block_size; pad_size = obj->pad_size; @@ -344,7 +341,7 @@ sec_PKCS7EncryptLength (sec_PKCS7CipherObject *obj, unsigned int input_len, * number of output bytes as we had input bytes. */ if (block_size == 0) - return input_len; + return input_len; /* * On the final call, we only send out what we need for @@ -353,13 +350,13 @@ sec_PKCS7EncryptLength (sec_PKCS7CipherObject *obj, unsigned int input_len, * will add another full block that is just padding.) */ if (final) { - if (pad_size == 0) { - return obj->pending_count + input_len; - } else { - blocks = (obj->pending_count + input_len) / pad_size; - blocks++; - return blocks*pad_size; - } + if (pad_size == 0) { + return obj->pending_count + input_len; + } else { + blocks = (obj->pending_count + input_len) / pad_size; + blocks++; + return blocks * pad_size; + } } /* @@ -367,11 +364,9 @@ sec_PKCS7EncryptLength (sec_PKCS7CipherObject *obj, unsigned int input_len, */ blocks = (obj->pending_count + input_len) / block_size; - return blocks * block_size; } - /* * Decrypt a given length of input buffer (starting at "input" and * containing "input_len" bytes), placing the decrypted bytes in @@ -391,29 +386,29 @@ sec_PKCS7EncryptLength (sec_PKCS7CipherObject *obj, unsigned int input_len, * the same as the length of the padding, and that all data is padded. * (Even data that starts out with an exact multiple of blocks gets * added to it another block, all of which is padding.) - */ + */ SECStatus -sec_PKCS7Decrypt (sec_PKCS7CipherObject *obj, unsigned char *output, - unsigned int *output_len_p, unsigned int max_output_len, - const unsigned char *input, unsigned int input_len, - PRBool final) +sec_PKCS7Decrypt(sec_PKCS7CipherObject *obj, unsigned char *output, + unsigned int *output_len_p, unsigned int max_output_len, + const unsigned char *input, unsigned int input_len, + PRBool final) { unsigned int blocks, bsize, pcount, padsize; unsigned int max_needed, ifraglen, ofraglen, output_len; unsigned char *pbuf; SECStatus rv; - PORT_Assert (! obj->encrypt); + PORT_Assert(!obj->encrypt); /* * Check that we have enough room for the output. Our caller should * already handle this; failure is really an internal error (i.e. bug). */ - max_needed = sec_PKCS7DecryptLength (obj, input_len, final); - PORT_Assert (max_output_len >= max_needed); + max_needed = sec_PKCS7DecryptLength(obj, input_len, final); + PORT_Assert(max_output_len >= max_needed); if (max_output_len < max_needed) { - /* PORT_SetError (XXX); */ - return SECFailure; + /* PORT_SetError (XXX); */ + return SECFailure; } /* @@ -428,8 +423,8 @@ sec_PKCS7Decrypt (sec_PKCS7CipherObject *obj, unsigned char *output, * cipher function and we are done. */ if (bsize == 0) { - return (* obj->doit) (obj->cx, output, output_len_p, max_output_len, - input, input_len); + return (*obj->doit)(obj->cx, output, output_len_p, max_output_len, + input, input_len); } pcount = obj->pending_count; @@ -438,64 +433,64 @@ sec_PKCS7Decrypt (sec_PKCS7CipherObject *obj, unsigned char *output, output_len = 0; if (pcount) { - /* - * Try to fill in an entire block, starting with the bytes - * we already have saved away. - */ - while (input_len && pcount < bsize) { - pbuf[pcount++] = *input++; - input_len--; - } - /* - * If we have at most a whole block and this is not our last call, - * then we are done for now. (We do not try to decrypt a lone - * single block because we cannot interpret the padding bytes - * until we know we are handling the very last block of all input.) - */ - if (input_len == 0 && !final) { - obj->pending_count = pcount; - if (output_len_p) - *output_len_p = 0; - return SECSuccess; - } - /* - * Given the logic above, we expect to have a full block by now. - * If we do not, there is something wrong, either with our own - * logic or with (length of) the data given to us. - */ - PORT_Assert ((padsize == 0) || (pcount % padsize) == 0); - if ((padsize != 0) && (pcount % padsize) != 0) { - PORT_Assert (final); - PORT_SetError (SEC_ERROR_BAD_DATA); - return SECFailure; - } - /* - * Decrypt the block. - */ - rv = (* obj->doit) (obj->cx, output, &ofraglen, max_output_len, - pbuf, pcount); - if (rv != SECSuccess) - return rv; - - /* - * For now anyway, all of our ciphers have the same number of - * bytes of output as they do input. If this ever becomes untrue, - * then sec_PKCS7DecryptLength needs to be made smarter! - */ - PORT_Assert (ofraglen == pcount); - - /* - * Account for the bytes now in output. - */ - max_output_len -= ofraglen; - output_len += ofraglen; - output += ofraglen; + /* + * Try to fill in an entire block, starting with the bytes + * we already have saved away. + */ + while (input_len && pcount < bsize) { + pbuf[pcount++] = *input++; + input_len--; + } + /* + * If we have at most a whole block and this is not our last call, + * then we are done for now. (We do not try to decrypt a lone + * single block because we cannot interpret the padding bytes + * until we know we are handling the very last block of all input.) + */ + if (input_len == 0 && !final) { + obj->pending_count = pcount; + if (output_len_p) + *output_len_p = 0; + return SECSuccess; + } + /* + * Given the logic above, we expect to have a full block by now. + * If we do not, there is something wrong, either with our own + * logic or with (length of) the data given to us. + */ + PORT_Assert((padsize == 0) || (pcount % padsize) == 0); + if ((padsize != 0) && (pcount % padsize) != 0) { + PORT_Assert(final); + PORT_SetError(SEC_ERROR_BAD_DATA); + return SECFailure; + } + /* + * Decrypt the block. + */ + rv = (*obj->doit)(obj->cx, output, &ofraglen, max_output_len, + pbuf, pcount); + if (rv != SECSuccess) + return rv; + + /* + * For now anyway, all of our ciphers have the same number of + * bytes of output as they do input. If this ever becomes untrue, + * then sec_PKCS7DecryptLength needs to be made smarter! + */ + PORT_Assert(ofraglen == pcount); + + /* + * Account for the bytes now in output. + */ + max_output_len -= ofraglen; + output_len += ofraglen; + output += ofraglen; } /* * If this is our last call, we expect to have an exact number of * blocks left to be decrypted; we will decrypt them all. - * + * * If not our last call, we always save between 1 and bsize bytes * until next time. (We must do this because we cannot be sure * that none of the decrypted bytes are padding bytes until we @@ -506,46 +501,47 @@ sec_PKCS7Decrypt (sec_PKCS7CipherObject *obj, unsigned char *output, * the same way we treat partial block bytes. */ if (final) { - if (padsize) { - blocks = input_len / padsize; - ifraglen = blocks * padsize; - } else ifraglen = input_len; - PORT_Assert (ifraglen == input_len); - - if (ifraglen != input_len) { - PORT_SetError (SEC_ERROR_BAD_DATA); - return SECFailure; - } + if (padsize) { + blocks = input_len / padsize; + ifraglen = blocks * padsize; + } else + ifraglen = input_len; + PORT_Assert(ifraglen == input_len); + + if (ifraglen != input_len) { + PORT_SetError(SEC_ERROR_BAD_DATA); + return SECFailure; + } } else { - blocks = (input_len - 1) / bsize; - ifraglen = blocks * bsize; - PORT_Assert (ifraglen < input_len); + blocks = (input_len - 1) / bsize; + ifraglen = blocks * bsize; + PORT_Assert(ifraglen < input_len); - pcount = input_len - ifraglen; - PORT_Memcpy (pbuf, input + ifraglen, pcount); - obj->pending_count = pcount; + pcount = input_len - ifraglen; + PORT_Memcpy(pbuf, input + ifraglen, pcount); + obj->pending_count = pcount; } if (ifraglen) { - rv = (* obj->doit) (obj->cx, output, &ofraglen, max_output_len, - input, ifraglen); - if (rv != SECSuccess) - return rv; - - /* - * For now anyway, all of our ciphers have the same number of - * bytes of output as they do input. If this ever becomes untrue, - * then sec_PKCS7DecryptLength needs to be made smarter! - */ - PORT_Assert (ifraglen == ofraglen); - if (ifraglen != ofraglen) { - PORT_SetError (SEC_ERROR_BAD_DATA); - return SECFailure; - } - - output_len += ofraglen; + rv = (*obj->doit)(obj->cx, output, &ofraglen, max_output_len, + input, ifraglen); + if (rv != SECSuccess) + return rv; + + /* + * For now anyway, all of our ciphers have the same number of + * bytes of output as they do input. If this ever becomes untrue, + * then sec_PKCS7DecryptLength needs to be made smarter! + */ + PORT_Assert(ifraglen == ofraglen); + if (ifraglen != ofraglen) { + PORT_SetError(SEC_ERROR_BAD_DATA); + return SECFailure; + } + + output_len += ofraglen; } else { - ofraglen = 0; + ofraglen = 0; } /* @@ -553,17 +549,17 @@ sec_PKCS7Decrypt (sec_PKCS7CipherObject *obj, unsigned char *output, * adjusting the output length. */ if (final && (padsize != 0)) { - unsigned int padlen = *(output + ofraglen - 1); - if (padlen == 0 || padlen > padsize) { - PORT_SetError (SEC_ERROR_BAD_DATA); - return SECFailure; - } - output_len -= padlen; + unsigned int padlen = *(output + ofraglen - 1); + if (padlen == 0 || padlen > padsize) { + PORT_SetError(SEC_ERROR_BAD_DATA); + return SECFailure; + } + output_len -= padlen; } - PORT_Assert (output_len_p != NULL || output_len == 0); + PORT_Assert(output_len_p != NULL || output_len == 0); if (output_len_p != NULL) - *output_len_p = output_len; + *output_len_p = output_len; return SECSuccess; } @@ -592,29 +588,29 @@ sec_PKCS7Decrypt (sec_PKCS7CipherObject *obj, unsigned char *output, * tricky parts about padding and filling blocks would be much * harder to read that way, so I left them separate. At least for * now until it is clear that they are right. - */ + */ SECStatus -sec_PKCS7Encrypt (sec_PKCS7CipherObject *obj, unsigned char *output, - unsigned int *output_len_p, unsigned int max_output_len, - const unsigned char *input, unsigned int input_len, - PRBool final) +sec_PKCS7Encrypt(sec_PKCS7CipherObject *obj, unsigned char *output, + unsigned int *output_len_p, unsigned int max_output_len, + const unsigned char *input, unsigned int input_len, + PRBool final) { int blocks, bsize, padlen, pcount, padsize; unsigned int max_needed, ifraglen, ofraglen, output_len; unsigned char *pbuf; SECStatus rv; - PORT_Assert (obj->encrypt); + PORT_Assert(obj->encrypt); /* * Check that we have enough room for the output. Our caller should * already handle this; failure is really an internal error (i.e. bug). */ - max_needed = sec_PKCS7EncryptLength (obj, input_len, final); - PORT_Assert (max_output_len >= max_needed); + max_needed = sec_PKCS7EncryptLength(obj, input_len, final); + PORT_Assert(max_output_len >= max_needed); if (max_output_len < max_needed) { - /* PORT_SetError (XXX); */ - return SECFailure; + /* PORT_SetError (XXX); */ + return SECFailure; } bsize = obj->block_size; @@ -625,8 +621,8 @@ sec_PKCS7Encrypt (sec_PKCS7CipherObject *obj, unsigned char *output, * cipher function and we are done. */ if (bsize == 0) { - return (* obj->doit) (obj->cx, output, output_len_p, max_output_len, - input, input_len); + return (*obj->doit)(obj->cx, output, output_len_p, max_output_len, + input, input_len); } pcount = obj->pending_count; @@ -635,103 +631,107 @@ sec_PKCS7Encrypt (sec_PKCS7CipherObject *obj, unsigned char *output, output_len = 0; if (pcount) { - /* - * Try to fill in an entire block, starting with the bytes - * we already have saved away. - */ - while (input_len && pcount < bsize) { - pbuf[pcount++] = *input++; - input_len--; - } - /* - * If we do not have a full block and we know we will be - * called again, then we are done for now. - */ - if (pcount < bsize && !final) { - obj->pending_count = pcount; - if (output_len_p != NULL) - *output_len_p = 0; - return SECSuccess; - } - /* - * If we have a whole block available, encrypt it. - */ - if ((padsize == 0) || (pcount % padsize) == 0) { - rv = (* obj->doit) (obj->cx, output, &ofraglen, max_output_len, - pbuf, pcount); - if (rv != SECSuccess) - return rv; - - /* - * For now anyway, all of our ciphers have the same number of - * bytes of output as they do input. If this ever becomes untrue, - * then sec_PKCS7EncryptLength needs to be made smarter! - */ - PORT_Assert (ofraglen == pcount); - - /* - * Account for the bytes now in output. - */ - max_output_len -= ofraglen; - output_len += ofraglen; - output += ofraglen; - - pcount = 0; - } + /* + * Try to fill in an entire block, starting with the bytes + * we already have saved away. + */ + while (input_len && pcount < bsize) { + pbuf[pcount++] = *input++; + input_len--; + } + /* + * If we do not have a full block and we know we will be + * called again, then we are done for now. + */ + if (pcount < bsize && !final) { + obj->pending_count = pcount; + if (output_len_p != NULL) + *output_len_p = 0; + return SECSuccess; + } + /* + * If we have a whole block available, encrypt it. + */ + if ((padsize == 0) || (pcount % padsize) == 0) { + rv = (*obj->doit)(obj->cx, output, &ofraglen, max_output_len, + pbuf, pcount); + if (rv != SECSuccess) + return rv; + + /* + * For now anyway, all of our ciphers have the same number of + * bytes of output as they do input. If this ever becomes untrue, + * then sec_PKCS7EncryptLength needs to be made smarter! + */ + PORT_Assert(ofraglen == pcount); + + /* + * Account for the bytes now in output. + */ + max_output_len -= ofraglen; + output_len += ofraglen; + output += ofraglen; + + pcount = 0; + } } if (input_len) { - PORT_Assert (pcount == 0); - - blocks = input_len / bsize; - ifraglen = blocks * bsize; - - if (ifraglen) { - rv = (* obj->doit) (obj->cx, output, &ofraglen, max_output_len, - input, ifraglen); - if (rv != SECSuccess) - return rv; - - /* - * For now anyway, all of our ciphers have the same number of - * bytes of output as they do input. If this ever becomes untrue, - * then sec_PKCS7EncryptLength needs to be made smarter! - */ - PORT_Assert (ifraglen == ofraglen); - - max_output_len -= ofraglen; - output_len += ofraglen; - output += ofraglen; - } - - pcount = input_len - ifraglen; - PORT_Assert (pcount < bsize); - if (pcount) - PORT_Memcpy (pbuf, input + ifraglen, pcount); + PORT_Assert(pcount == 0); + + blocks = input_len / bsize; + ifraglen = blocks * bsize; + + if (ifraglen) { + rv = (*obj->doit)(obj->cx, output, &ofraglen, max_output_len, + input, ifraglen); + if (rv != SECSuccess) + return rv; + + /* + * For now anyway, all of our ciphers have the same number of + * bytes of output as they do input. If this ever becomes untrue, + * then sec_PKCS7EncryptLength needs to be made smarter! + */ + PORT_Assert(ifraglen == ofraglen); + + max_output_len -= ofraglen; + output_len += ofraglen; + output += ofraglen; + } + + pcount = input_len - ifraglen; + PORT_Assert(pcount < bsize); + if (pcount) + PORT_Memcpy(pbuf, input + ifraglen, pcount); } if (final) { - padlen = padsize - (pcount % padsize); - PORT_Memset (pbuf + pcount, padlen, padlen); - rv = (* obj->doit) (obj->cx, output, &ofraglen, max_output_len, - pbuf, pcount+padlen); - if (rv != SECSuccess) - return rv; - - /* - * For now anyway, all of our ciphers have the same number of - * bytes of output as they do input. If this ever becomes untrue, - * then sec_PKCS7EncryptLength needs to be made smarter! - */ - PORT_Assert (ofraglen == (pcount+padlen)); - output_len += ofraglen; + if (padsize) { + padlen = padsize - (pcount % padsize); + PORT_Memset(pbuf + pcount, padlen, padlen); + } else { + padlen = 0; + } + rv = (*obj->doit)(obj->cx, output, &ofraglen, max_output_len, + pbuf, pcount + padlen); + if (rv != SECSuccess) + return rv; + + /* + * For now anyway, all of our ciphers have the same number of + * bytes of output as they do input. If this ever becomes untrue, + * then sec_PKCS7EncryptLength needs to be made smarter! + */ + PORT_Assert(ofraglen == (pcount + padlen)); + output_len += ofraglen; } else { - obj->pending_count = pcount; + obj->pending_count = pcount; } - PORT_Assert (output_len_p != NULL || output_len == 0); + PORT_Assert(output_len_p != NULL || output_len == 0); if (output_len_p != NULL) - *output_len_p = output_len; + *output_len_p = output_len; return SECSuccess; } @@ -741,7 +741,6 @@ sec_PKCS7Encrypt (sec_PKCS7CipherObject *obj, unsigned char *output, * ------------------------------------------------------------------- */ - /* * ------------------------------------------------------------------- * XXX The following Attribute stuff really belongs elsewhere. @@ -760,46 +759,41 @@ sec_PKCS7Encrypt (sec_PKCS7CipherObject *obj, unsigned char *output, * that first-found behavior? It was like that when I found it...) */ SEC_PKCS7Attribute * -sec_PKCS7FindAttribute (SEC_PKCS7Attribute **attrs, SECOidTag oidtag, - PRBool only) +sec_PKCS7FindAttribute(SEC_PKCS7Attribute **attrs, SECOidTag oidtag, + PRBool only) { SECOidData *oid; SEC_PKCS7Attribute *attr1, *attr2; if (attrs == NULL) - return NULL; + return NULL; oid = SECOID_FindOIDByTag(oidtag); if (oid == NULL) - return NULL; + return NULL; while ((attr1 = *attrs++) != NULL) { - if (attr1->type.len == oid->oid.len && PORT_Memcmp (attr1->type.data, - oid->oid.data, - oid->oid.len) == 0) - break; + if (attr1->type.len == oid->oid.len && PORT_Memcmp(attr1->type.data, oid->oid.data, oid->oid.len) == 0) + break; } if (attr1 == NULL) - return NULL; + return NULL; if (!only) - return attr1; + return attr1; while ((attr2 = *attrs++) != NULL) { - if (attr2->type.len == oid->oid.len && PORT_Memcmp (attr2->type.data, - oid->oid.data, - oid->oid.len) == 0) - break; + if (attr2->type.len == oid->oid.len && PORT_Memcmp(attr2->type.data, oid->oid.data, oid->oid.len) == 0) + break; } if (attr2 != NULL) - return NULL; + return NULL; return attr1; } - /* * Return the single attribute value, doing some sanity checking first: * - Multiple values are *not* expected. @@ -811,15 +805,15 @@ sec_PKCS7AttributeValue(SEC_PKCS7Attribute *attr) SECItem *value; if (attr == NULL) - return NULL; + return NULL; value = attr->values[0]; if (value == NULL || value->data == NULL || value->len == 0) - return NULL; + return NULL; if (attr->values[1] != NULL) - return NULL; + return NULL; return value; } @@ -833,82 +827,81 @@ sec_attr_choose_attr_value_template(void *src_or_dest, PRBool encoding) SECOidData *oiddata; PRBool encoded; - PORT_Assert (src_or_dest != NULL); + PORT_Assert(src_or_dest != NULL); if (src_or_dest == NULL) - return NULL; + return NULL; - attribute = (SEC_PKCS7Attribute*)src_or_dest; + attribute = (SEC_PKCS7Attribute *)src_or_dest; if (encoding && attribute->encoded) - return SEC_ASN1_GET(SEC_AnyTemplate); + return SEC_ASN1_GET(SEC_AnyTemplate); oiddata = attribute->typeTag; if (oiddata == NULL) { - oiddata = SECOID_FindOID(&attribute->type); - attribute->typeTag = oiddata; + oiddata = SECOID_FindOID(&attribute->type); + attribute->typeTag = oiddata; } if (oiddata == NULL) { - encoded = PR_TRUE; - theTemplate = SEC_ASN1_GET(SEC_AnyTemplate); + encoded = PR_TRUE; + theTemplate = SEC_ASN1_GET(SEC_AnyTemplate); } else { - switch (oiddata->offset) { - default: - encoded = PR_TRUE; - theTemplate = SEC_ASN1_GET(SEC_AnyTemplate); - break; - case SEC_OID_PKCS9_EMAIL_ADDRESS: - case SEC_OID_RFC1274_MAIL: - case SEC_OID_PKCS9_UNSTRUCTURED_NAME: - encoded = PR_FALSE; - theTemplate = SEC_ASN1_GET(SEC_IA5StringTemplate); - break; - case SEC_OID_PKCS9_CONTENT_TYPE: - encoded = PR_FALSE; - theTemplate = SEC_ASN1_GET(SEC_ObjectIDTemplate); - break; - case SEC_OID_PKCS9_MESSAGE_DIGEST: - encoded = PR_FALSE; - theTemplate = SEC_ASN1_GET(SEC_OctetStringTemplate); - break; - case SEC_OID_PKCS9_SIGNING_TIME: - encoded = PR_FALSE; - theTemplate = SEC_ASN1_GET(CERT_TimeChoiceTemplate); - break; - /* XXX Want other types here, too */ - } + switch (oiddata->offset) { + default: + encoded = PR_TRUE; + theTemplate = SEC_ASN1_GET(SEC_AnyTemplate); + break; + case SEC_OID_PKCS9_EMAIL_ADDRESS: + case SEC_OID_RFC1274_MAIL: + case SEC_OID_PKCS9_UNSTRUCTURED_NAME: + encoded = PR_FALSE; + theTemplate = SEC_ASN1_GET(SEC_IA5StringTemplate); + break; + case SEC_OID_PKCS9_CONTENT_TYPE: + encoded = PR_FALSE; + theTemplate = SEC_ASN1_GET(SEC_ObjectIDTemplate); + break; + case SEC_OID_PKCS9_MESSAGE_DIGEST: + encoded = PR_FALSE; + theTemplate = SEC_ASN1_GET(SEC_OctetStringTemplate); + break; + case SEC_OID_PKCS9_SIGNING_TIME: + encoded = PR_FALSE; + theTemplate = SEC_ASN1_GET(CERT_TimeChoiceTemplate); + break; + /* XXX Want other types here, too */ + } } if (encoding) { - /* - * If we are encoding and we think we have an already-encoded value, - * then the code which initialized this attribute should have set - * the "encoded" property to true (and we would have returned early, - * up above). No devastating error, but that code should be fixed. - * (It could indicate that the resulting encoded bytes are wrong.) - */ - PORT_Assert (!encoded); + /* + * If we are encoding and we think we have an already-encoded value, + * then the code which initialized this attribute should have set + * the "encoded" property to true (and we would have returned early, + * up above). No devastating error, but that code should be fixed. + * (It could indicate that the resulting encoded bytes are wrong.) + */ + PORT_Assert(!encoded); } else { - /* - * We are decoding; record whether the resulting value is - * still encoded or not. - */ - attribute->encoded = encoded; + /* + * We are decoding; record whether the resulting value is + * still encoded or not. + */ + attribute->encoded = encoded; } return theTemplate; } -static const SEC_ASN1TemplateChooserPtr sec_attr_chooser - = sec_attr_choose_attr_value_template; +static const SEC_ASN1TemplateChooserPtr 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) }, + 0, NULL, sizeof(SEC_PKCS7Attribute) }, { SEC_ASN1_OBJECT_ID, - offsetof(SEC_PKCS7Attribute,type) }, + offsetof(SEC_PKCS7Attribute, type) }, { SEC_ASN1_DYNAMIC | SEC_ASN1_SET_OF, - offsetof(SEC_PKCS7Attribute,values), - &sec_attr_chooser }, + offsetof(SEC_PKCS7Attribute, values), + &sec_attr_chooser }, { 0 } }; @@ -924,10 +917,10 @@ static const SEC_ASN1Template sec_pkcs7_set_of_attribute_template[] = { * do the reordering.) */ SECItem * -sec_PKCS7EncodeAttributes (PLArenaPool *poolp, SECItem *dest, void *src) +sec_PKCS7EncodeAttributes(PLArenaPool *poolp, SECItem *dest, void *src) { - return SEC_ASN1EncodeItem (poolp, dest, src, - sec_pkcs7_set_of_attribute_template); + return SEC_ASN1EncodeItem(poolp, dest, src, + sec_pkcs7_set_of_attribute_template); } /* @@ -936,7 +929,7 @@ sec_PKCS7EncodeAttributes (PLArenaPool *poolp, SECItem *dest, void *src) * if reordering is necessary it will be done in place (in attrs). */ SECStatus -sec_PKCS7ReorderAttributes (SEC_PKCS7Attribute **attrs) +sec_PKCS7ReorderAttributes(SEC_PKCS7Attribute **attrs) { PLArenaPool *poolp; int num_attrs, i, pass, besti; @@ -948,56 +941,56 @@ sec_PKCS7ReorderAttributes (SEC_PKCS7Attribute **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); + PORT_Assert(attrs != NULL); if (attrs == NULL) - return SECSuccess; + return SECSuccess; /* * Count how many attributes we are dealing with here. */ num_attrs = 0; while (attrs[num_attrs] != NULL) - num_attrs++; + 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); + PORT_Assert(num_attrs); if (num_attrs == 0 || num_attrs == 1) - return SECSuccess; + 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? */ + poolp = PORT_NewArena(1024); /* XXX what is right value? */ if (poolp == NULL) - return SECFailure; /* no memory; nothing we can do... */ + 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 *)); + 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; + 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; - } + 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; + } } /* @@ -1006,60 +999,60 @@ sec_PKCS7ReorderAttributes (SEC_PKCS7Attribute **attrs) * 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; + /* + * 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; } /* @@ -1067,9 +1060,9 @@ sec_PKCS7ReorderAttributes (SEC_PKCS7Attribute **attrs) * copy them back into the attrs array we started with. */ for (i = 0; i < num_attrs; i++) - attrs[i] = new_attrs[i]; + attrs[i] = new_attrs[i]; - PORT_FreeArena (poolp, PR_FALSE); + PORT_FreeArena(poolp, PR_FALSE); return SECSuccess; } @@ -1078,7 +1071,6 @@ sec_PKCS7ReorderAttributes (SEC_PKCS7Attribute **attrs) * ------------------------------------------------------------------- */ - /* * Templates and stuff. Keep these at the end of the file. */ @@ -1087,18 +1079,16 @@ sec_PKCS7ReorderAttributes (SEC_PKCS7Attribute **attrs) static const SEC_ASN1Template * sec_pkcs7_choose_content_template(void *src_or_dest, PRBool encoding); -static const SEC_ASN1TemplateChooserPtr sec_pkcs7_chooser - = sec_pkcs7_choose_content_template; +static const SEC_ASN1TemplateChooserPtr 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) }, + 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 }, + 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 } }; @@ -1106,51 +1096,51 @@ const SEC_ASN1Template sec_PKCS7ContentInfoTemplate[] = { static const SEC_ASN1Template SEC_PKCS7SignerInfoTemplate[] = { { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(SEC_PKCS7SignerInfo) }, + 0, NULL, sizeof(SEC_PKCS7SignerInfo) }, { SEC_ASN1_INTEGER, - offsetof(SEC_PKCS7SignerInfo,version) }, + offsetof(SEC_PKCS7SignerInfo, version) }, { SEC_ASN1_POINTER | SEC_ASN1_XTRN, - offsetof(SEC_PKCS7SignerInfo,issuerAndSN), - SEC_ASN1_SUB(CERT_IssuerAndSNTemplate) }, + offsetof(SEC_PKCS7SignerInfo, issuerAndSN), + SEC_ASN1_SUB(CERT_IssuerAndSNTemplate) }, { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(SEC_PKCS7SignerInfo,digestAlg), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, + offsetof(SEC_PKCS7SignerInfo, digestAlg), + SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, - offsetof(SEC_PKCS7SignerInfo,authAttr), - sec_pkcs7_set_of_attribute_template }, + offsetof(SEC_PKCS7SignerInfo, authAttr), + sec_pkcs7_set_of_attribute_template }, { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(SEC_PKCS7SignerInfo,digestEncAlg), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, + offsetof(SEC_PKCS7SignerInfo, digestEncAlg), + SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, { SEC_ASN1_OCTET_STRING, - offsetof(SEC_PKCS7SignerInfo,encDigest) }, + 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 }, + 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) }, + 0, NULL, sizeof(SEC_PKCS7SignedData) }, { SEC_ASN1_INTEGER, - offsetof(SEC_PKCS7SignedData,version) }, + offsetof(SEC_PKCS7SignedData, version) }, { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, - offsetof(SEC_PKCS7SignedData,digestAlgorithms), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, + offsetof(SEC_PKCS7SignedData, digestAlgorithms), + SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, { SEC_ASN1_INLINE, - offsetof(SEC_PKCS7SignedData,contentInfo), - sec_PKCS7ContentInfoTemplate }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | - SEC_ASN1_XTRN | 0, - offsetof(SEC_PKCS7SignedData,rawCerts), - SEC_ASN1_SUB(SEC_SetOfAnyTemplate) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | - SEC_ASN1_XTRN | 1, - offsetof(SEC_PKCS7SignedData,crls), - SEC_ASN1_SUB(CERT_SetOfSignedCrlTemplate) }, + offsetof(SEC_PKCS7SignedData, contentInfo), + sec_PKCS7ContentInfoTemplate }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | + SEC_ASN1_XTRN | 0, + offsetof(SEC_PKCS7SignedData, rawCerts), + SEC_ASN1_SUB(SEC_SetOfAnyTemplate) }, + { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | + SEC_ASN1_XTRN | 1, + offsetof(SEC_PKCS7SignedData, crls), + SEC_ASN1_SUB(CERT_SetOfSignedCrlTemplate) }, { SEC_ASN1_SET_OF, - offsetof(SEC_PKCS7SignedData,signerInfos), - SEC_PKCS7SignerInfoTemplate }, + offsetof(SEC_PKCS7SignedData, signerInfos), + SEC_PKCS7SignerInfoTemplate }, { 0 } }; @@ -1160,46 +1150,46 @@ static const SEC_ASN1Template SEC_PointerToPKCS7SignedDataTemplate[] = { static const SEC_ASN1Template SEC_PKCS7RecipientInfoTemplate[] = { { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(SEC_PKCS7RecipientInfo) }, + 0, NULL, sizeof(SEC_PKCS7RecipientInfo) }, { SEC_ASN1_INTEGER, - offsetof(SEC_PKCS7RecipientInfo,version) }, + offsetof(SEC_PKCS7RecipientInfo, version) }, { SEC_ASN1_POINTER | SEC_ASN1_XTRN, - offsetof(SEC_PKCS7RecipientInfo,issuerAndSN), - SEC_ASN1_SUB(CERT_IssuerAndSNTemplate) }, + offsetof(SEC_PKCS7RecipientInfo, issuerAndSN), + SEC_ASN1_SUB(CERT_IssuerAndSNTemplate) }, { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(SEC_PKCS7RecipientInfo,keyEncAlg), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, + offsetof(SEC_PKCS7RecipientInfo, keyEncAlg), + SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, { SEC_ASN1_OCTET_STRING, - offsetof(SEC_PKCS7RecipientInfo,encKey) }, + offsetof(SEC_PKCS7RecipientInfo, encKey) }, { 0 } }; static const SEC_ASN1Template SEC_PKCS7EncryptedContentInfoTemplate[] = { { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM, - 0, NULL, sizeof(SEC_PKCS7EncryptedContentInfo) }, + 0, NULL, sizeof(SEC_PKCS7EncryptedContentInfo) }, { SEC_ASN1_OBJECT_ID, - offsetof(SEC_PKCS7EncryptedContentInfo,contentType) }, + offsetof(SEC_PKCS7EncryptedContentInfo, contentType) }, { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(SEC_PKCS7EncryptedContentInfo,contentEncAlg), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, + offsetof(SEC_PKCS7EncryptedContentInfo, contentEncAlg), + SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, { SEC_ASN1_OPTIONAL | SEC_ASN1_MAY_STREAM | SEC_ASN1_CONTEXT_SPECIFIC | - SEC_ASN1_XTRN | 0, - offsetof(SEC_PKCS7EncryptedContentInfo,encContent), - SEC_ASN1_SUB(SEC_OctetStringTemplate) }, + SEC_ASN1_XTRN | 0, + offsetof(SEC_PKCS7EncryptedContentInfo, encContent), + SEC_ASN1_SUB(SEC_OctetStringTemplate) }, { 0 } }; static const SEC_ASN1Template SEC_PKCS7EnvelopedDataTemplate[] = { { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM, - 0, NULL, sizeof(SEC_PKCS7EnvelopedData) }, + 0, NULL, sizeof(SEC_PKCS7EnvelopedData) }, { SEC_ASN1_INTEGER, - offsetof(SEC_PKCS7EnvelopedData,version) }, + offsetof(SEC_PKCS7EnvelopedData, version) }, { SEC_ASN1_SET_OF, - offsetof(SEC_PKCS7EnvelopedData,recipientInfos), - SEC_PKCS7RecipientInfoTemplate }, + offsetof(SEC_PKCS7EnvelopedData, recipientInfos), + SEC_PKCS7RecipientInfoTemplate }, { SEC_ASN1_INLINE, - offsetof(SEC_PKCS7EnvelopedData,encContentInfo), - SEC_PKCS7EncryptedContentInfoTemplate }, + offsetof(SEC_PKCS7EnvelopedData, encContentInfo), + SEC_PKCS7EncryptedContentInfoTemplate }, { 0 } }; @@ -1209,50 +1199,50 @@ static const SEC_ASN1Template SEC_PointerToPKCS7EnvelopedDataTemplate[] = { static const SEC_ASN1Template SEC_PKCS7SignedAndEnvelopedDataTemplate[] = { { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM, - 0, NULL, sizeof(SEC_PKCS7SignedAndEnvelopedData) }, + 0, NULL, sizeof(SEC_PKCS7SignedAndEnvelopedData) }, { SEC_ASN1_INTEGER, - offsetof(SEC_PKCS7SignedAndEnvelopedData,version) }, + offsetof(SEC_PKCS7SignedAndEnvelopedData, version) }, { SEC_ASN1_SET_OF, - offsetof(SEC_PKCS7SignedAndEnvelopedData,recipientInfos), - SEC_PKCS7RecipientInfoTemplate }, + offsetof(SEC_PKCS7SignedAndEnvelopedData, recipientInfos), + SEC_PKCS7RecipientInfoTemplate }, { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, - offsetof(SEC_PKCS7SignedAndEnvelopedData,digestAlgorithms), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, + offsetof(SEC_PKCS7SignedAndEnvelopedData, digestAlgorithms), + SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, { SEC_ASN1_INLINE, - offsetof(SEC_PKCS7SignedAndEnvelopedData,encContentInfo), - SEC_PKCS7EncryptedContentInfoTemplate }, + offsetof(SEC_PKCS7SignedAndEnvelopedData, encContentInfo), + SEC_PKCS7EncryptedContentInfoTemplate }, { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | - SEC_ASN1_XTRN | 0, - offsetof(SEC_PKCS7SignedAndEnvelopedData,rawCerts), - SEC_ASN1_SUB(SEC_SetOfAnyTemplate) }, + SEC_ASN1_XTRN | 0, + offsetof(SEC_PKCS7SignedAndEnvelopedData, rawCerts), + SEC_ASN1_SUB(SEC_SetOfAnyTemplate) }, { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | - SEC_ASN1_XTRN | 1, - offsetof(SEC_PKCS7SignedAndEnvelopedData,crls), - SEC_ASN1_SUB(CERT_SetOfSignedCrlTemplate) }, + SEC_ASN1_XTRN | 1, + offsetof(SEC_PKCS7SignedAndEnvelopedData, crls), + SEC_ASN1_SUB(CERT_SetOfSignedCrlTemplate) }, { SEC_ASN1_SET_OF, - offsetof(SEC_PKCS7SignedAndEnvelopedData,signerInfos), - SEC_PKCS7SignerInfoTemplate }, + offsetof(SEC_PKCS7SignedAndEnvelopedData, signerInfos), + SEC_PKCS7SignerInfoTemplate }, { 0 } }; static const SEC_ASN1Template -SEC_PointerToPKCS7SignedAndEnvelopedDataTemplate[] = { - { SEC_ASN1_POINTER, 0, SEC_PKCS7SignedAndEnvelopedDataTemplate } -}; + SEC_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) }, + 0, NULL, sizeof(SEC_PKCS7DigestedData) }, { SEC_ASN1_INTEGER, - offsetof(SEC_PKCS7DigestedData,version) }, + offsetof(SEC_PKCS7DigestedData, version) }, { SEC_ASN1_INLINE | SEC_ASN1_XTRN, - offsetof(SEC_PKCS7DigestedData,digestAlg), - SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, + offsetof(SEC_PKCS7DigestedData, digestAlg), + SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, { SEC_ASN1_INLINE, - offsetof(SEC_PKCS7DigestedData,contentInfo), - sec_PKCS7ContentInfoTemplate }, + offsetof(SEC_PKCS7DigestedData, contentInfo), + sec_PKCS7ContentInfoTemplate }, { SEC_ASN1_OCTET_STRING, - offsetof(SEC_PKCS7DigestedData,digest) }, + offsetof(SEC_PKCS7DigestedData, digest) }, { 0 } }; @@ -1262,12 +1252,12 @@ static const SEC_ASN1Template SEC_PointerToPKCS7DigestedDataTemplate[] = { static const SEC_ASN1Template SEC_PKCS7EncryptedDataTemplate[] = { { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM, - 0, NULL, sizeof(SEC_PKCS7EncryptedData) }, + 0, NULL, sizeof(SEC_PKCS7EncryptedData) }, { SEC_ASN1_INTEGER, - offsetof(SEC_PKCS7EncryptedData,version) }, + offsetof(SEC_PKCS7EncryptedData, version) }, { SEC_ASN1_INLINE, - offsetof(SEC_PKCS7EncryptedData,encContentInfo), - SEC_PKCS7EncryptedContentInfoTemplate }, + offsetof(SEC_PKCS7EncryptedData, encContentInfo), + SEC_PKCS7EncryptedContentInfoTemplate }, { 0 } }; @@ -1282,34 +1272,34 @@ sec_pkcs7_choose_content_template(void *src_or_dest, PRBool encoding) SEC_PKCS7ContentInfo *cinfo; SECOidTag kind; - PORT_Assert (src_or_dest != NULL); + PORT_Assert(src_or_dest != NULL); if (src_or_dest == NULL) - return NULL; + return NULL; - cinfo = (SEC_PKCS7ContentInfo*)src_or_dest; - kind = SEC_PKCS7ContentType (cinfo); + cinfo = (SEC_PKCS7ContentInfo *)src_or_dest; + kind = SEC_PKCS7ContentType(cinfo); switch (kind) { - default: - theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate); - break; - case SEC_OID_PKCS7_DATA: - theTemplate = SEC_ASN1_GET(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; + default: + theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate); + break; + case SEC_OID_PKCS7_DATA: + theTemplate = SEC_ASN1_GET(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; } diff --git a/nss/lib/pkcs7/p7local.h b/nss/lib/pkcs7/p7local.h index a9b7887..ad37c3a 100644 --- a/nss/lib/pkcs7/p7local.h +++ b/nss/lib/pkcs7/p7local.h @@ -25,7 +25,6 @@ extern const SEC_ASN1Template sec_PKCS7ContentInfoTemplate[]; /* opaque objects */ typedef struct sec_pkcs7_cipher_object sec_PKCS7CipherObject; - /************************************************************************/ SEC_BEGIN_PROTOS @@ -36,49 +35,48 @@ SEC_BEGIN_PROTOS * just return the first one found. (XXX Does anybody really want * that first-found behavior? It was like that when I found it...) */ -extern SEC_PKCS7Attribute *sec_PKCS7FindAttribute (SEC_PKCS7Attribute **attrs, - SECOidTag oidtag, - PRBool only); +extern SEC_PKCS7Attribute *sec_PKCS7FindAttribute(SEC_PKCS7Attribute **attrs, + SECOidTag oidtag, + PRBool only); /* * Return the single attribute value, doing some sanity checking first: * - Multiple values are *not* expected. * - Empty values are *not* expected. */ -extern SECItem *sec_PKCS7AttributeValue (SEC_PKCS7Attribute *attr); +extern SECItem *sec_PKCS7AttributeValue(SEC_PKCS7Attribute *attr); /* * Encode a set of attributes (found in "src"). */ -extern SECItem *sec_PKCS7EncodeAttributes (PLArenaPool *poolp, - SECItem *dest, void *src); +extern SECItem *sec_PKCS7EncodeAttributes(PLArenaPool *poolp, + SECItem *dest, void *src); /* * 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). */ -extern SECStatus sec_PKCS7ReorderAttributes (SEC_PKCS7Attribute **attrs); - +extern SECStatus sec_PKCS7ReorderAttributes(SEC_PKCS7Attribute **attrs); /* * Create a context for decrypting, based on the given key and algorithm. */ extern sec_PKCS7CipherObject * -sec_PKCS7CreateDecryptObject (PK11SymKey *key, SECAlgorithmID *algid); +sec_PKCS7CreateDecryptObject(PK11SymKey *key, SECAlgorithmID *algid); /* * Create a context for encrypting, based on the given key and algorithm, * and fill in the algorithm id. */ extern sec_PKCS7CipherObject * -sec_PKCS7CreateEncryptObject (PLArenaPool *poolp, PK11SymKey *key, - SECOidTag algtag, SECAlgorithmID *algid); +sec_PKCS7CreateEncryptObject(PLArenaPool *poolp, PK11SymKey *key, + SECOidTag algtag, SECAlgorithmID *algid); /* * Destroy the given decryption or encryption object. */ -extern void sec_PKCS7DestroyDecryptObject (sec_PKCS7CipherObject *obj); -extern void sec_PKCS7DestroyEncryptObject (sec_PKCS7CipherObject *obj); +extern void sec_PKCS7DestroyDecryptObject(sec_PKCS7CipherObject *obj); +extern void sec_PKCS7DestroyEncryptObject(sec_PKCS7CipherObject *obj); /* * What will be the output length of the next call to encrypt/decrypt? @@ -96,12 +94,12 @@ extern void sec_PKCS7DestroyEncryptObject (sec_PKCS7CipherObject *obj); * passed in to the subsequent cipher operation, as no output bytes * will be stored. */ -extern unsigned int sec_PKCS7DecryptLength (sec_PKCS7CipherObject *obj, - unsigned int input_len, - PRBool final); -extern unsigned int sec_PKCS7EncryptLength (sec_PKCS7CipherObject *obj, - unsigned int input_len, - PRBool final); +extern unsigned int sec_PKCS7DecryptLength(sec_PKCS7CipherObject *obj, + unsigned int input_len, + PRBool final); +extern unsigned int sec_PKCS7EncryptLength(sec_PKCS7CipherObject *obj, + unsigned int input_len, + PRBool final); /* * Decrypt a given length of input buffer (starting at "input" and @@ -109,14 +107,14 @@ extern unsigned int sec_PKCS7EncryptLength (sec_PKCS7CipherObject *obj, * "output" and storing the output length in "*output_len_p". * "obj" is the return value from sec_PKCS7CreateDecryptObject. * When "final" is true, this is the last of the data to be decrypted. - */ -extern SECStatus sec_PKCS7Decrypt (sec_PKCS7CipherObject *obj, - unsigned char *output, - unsigned int *output_len_p, - unsigned int max_output_len, - const unsigned char *input, - unsigned int input_len, - PRBool final); + */ +extern SECStatus sec_PKCS7Decrypt(sec_PKCS7CipherObject *obj, + unsigned char *output, + unsigned int *output_len_p, + unsigned int max_output_len, + const unsigned char *input, + unsigned int input_len, + PRBool final); /* * Encrypt a given length of input buffer (starting at "input" and @@ -124,14 +122,14 @@ extern SECStatus sec_PKCS7Decrypt (sec_PKCS7CipherObject *obj, * "output" and storing the output length in "*output_len_p". * "obj" is the return value from sec_PKCS7CreateEncryptObject. * When "final" is true, this is the last of the data to be encrypted. - */ -extern SECStatus sec_PKCS7Encrypt (sec_PKCS7CipherObject *obj, - unsigned char *output, - unsigned int *output_len_p, - unsigned int max_output_len, - const unsigned char *input, - unsigned int input_len, - PRBool final); + */ +extern SECStatus sec_PKCS7Encrypt(sec_PKCS7CipherObject *obj, + unsigned char *output, + unsigned int *output_len_p, + unsigned int max_output_len, + const unsigned char *input, + unsigned int input_len, + PRBool final); /************************************************************************/ SEC_END_PROTOS diff --git a/nss/lib/pkcs7/pkcs7.gyp b/nss/lib/pkcs7/pkcs7.gyp new file mode 100644 index 0000000..8a73a29 --- /dev/null +++ b/nss/lib/pkcs7/pkcs7.gyp @@ -0,0 +1,29 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +{ + 'includes': [ + '../../coreconf/config.gypi' + ], + 'targets': [ + { + 'target_name': 'pkcs7', + 'type': 'static_library', + 'sources': [ + 'certread.c', + 'p7common.c', + 'p7create.c', + 'p7decode.c', + 'p7encode.c', + 'p7local.c', + 'secmime.c' + ], + 'dependencies': [ + '<(DEPTH)/exports.gyp:nss_exports' + ] + } + ], + 'variables': { + 'module': 'nss' + } +}
\ No newline at end of file diff --git a/nss/lib/pkcs7/pkcs7t.h b/nss/lib/pkcs7/pkcs7t.h index d01b1ea..4ef8902 100644 --- a/nss/lib/pkcs7/pkcs7t.h +++ b/nss/lib/pkcs7/pkcs7t.h @@ -23,7 +23,6 @@ typedef struct SEC_PKCS7EncoderContextStr SEC_PKCS7EncoderContext; /* legacy defines that haven't been active for years */ typedef void *(*SECKEYGetPasswordKey)(void *arg, void *handle); - /* Non-opaque objects. NOTE, though: I want them to be treated as * opaque as much as possible. If I could hide them completely, * I would. (I tried, but ran into trouble that was taking me too @@ -59,7 +58,7 @@ typedef struct SEC_PKCS7SignedDataStr SEC_PKCS7SignedData; typedef struct SEC_PKCS7EncryptedContentInfoStr SEC_PKCS7EncryptedContentInfo; typedef struct SEC_PKCS7EnvelopedDataStr SEC_PKCS7EnvelopedData; typedef struct SEC_PKCS7SignedAndEnvelopedDataStr - SEC_PKCS7SignedAndEnvelopedData; + SEC_PKCS7SignedAndEnvelopedData; typedef struct SEC_PKCS7SignerInfoStr SEC_PKCS7SignerInfo; typedef struct SEC_PKCS7RecipientInfoStr SEC_PKCS7RecipientInfo; typedef struct SEC_PKCS7DigestedDataStr SEC_PKCS7DigestedData; @@ -73,20 +72,20 @@ typedef struct SEC_PKCS7EncryptedDataStr SEC_PKCS7EncryptedData; typedef struct SEC_PKCS7AttributeStr SEC_PKCS7Attribute; struct SEC_PKCS7ContentInfoStr { - PLArenaPool *poolp; /* local; not part of encoding */ - PRBool created; /* local; not part of encoding */ - int refCount; /* local; not part of encoding */ - SECOidData *contentTypeTag; /* local; not part of encoding */ - SECKEYGetPasswordKey pwfn; /* local; not part of encoding */ - void *pwfn_arg; /* local; not part of encoding */ + PLArenaPool *poolp; /* local; not part of encoding */ + PRBool created; /* local; not part of encoding */ + int refCount; /* local; not part of encoding */ + SECOidData *contentTypeTag; /* local; not part of encoding */ + SECKEYGetPasswordKey pwfn; /* local; not part of encoding */ + void *pwfn_arg; /* local; not part of encoding */ SECItem contentType; union { - SECItem *data; - SEC_PKCS7DigestedData *digestedData; - SEC_PKCS7EncryptedData *encryptedData; - SEC_PKCS7EnvelopedData *envelopedData; - SEC_PKCS7SignedData *signedData; - SEC_PKCS7SignedAndEnvelopedData *signedAndEnvelopedData; + SECItem *data; + SEC_PKCS7DigestedData *digestedData; + SEC_PKCS7EncryptedData *encryptedData; + SEC_PKCS7EnvelopedData *envelopedData; + SEC_PKCS7SignedData *signedData; + SEC_PKCS7SignedAndEnvelopedData *signedAndEnvelopedData; } content; }; @@ -97,25 +96,25 @@ struct SEC_PKCS7SignedDataStr { SECItem **rawCerts; CERTSignedCrl **crls; SEC_PKCS7SignerInfo **signerInfos; - SECItem **digests; /* local; not part of encoding */ - CERTCertificate **certs; /* local; not part of encoding */ - CERTCertificateList **certLists; /* local; not part of encoding */ + SECItem **digests; /* local; not part of encoding */ + CERTCertificate **certs; /* local; not part of encoding */ + CERTCertificateList **certLists; /* local; not part of encoding */ }; -#define SEC_PKCS7_SIGNED_DATA_VERSION 1 /* what we *create* */ +#define SEC_PKCS7_SIGNED_DATA_VERSION 1 /* what we *create* */ struct SEC_PKCS7EncryptedContentInfoStr { - SECOidData *contentTypeTag; /* local; not part of encoding */ + SECOidData *contentTypeTag; /* local; not part of encoding */ SECItem contentType; SECAlgorithmID contentEncAlg; SECItem encContent; - SECItem plainContent; /* local; not part of encoding */ - /* bytes not encrypted, but encoded */ - int keysize; /* local; not part of encoding */ - /* size of bulk encryption key - * (only used by creation code) */ - SECOidTag encalg; /* local; not part of encoding */ - /* oid tag of encryption algorithm - * (only used by creation code) */ + SECItem plainContent; /* local; not part of encoding */ + /* bytes not encrypted, but encoded */ + int keysize; /* local; not part of encoding */ + /* size of bulk encryption key + * (only used by creation code) */ + SECOidTag encalg; /* local; not part of encoding */ + /* oid tag of encryption algorithm + * (only used by creation code) */ }; struct SEC_PKCS7EnvelopedDataStr { @@ -123,7 +122,7 @@ struct SEC_PKCS7EnvelopedDataStr { SEC_PKCS7RecipientInfo **recipientInfos; SEC_PKCS7EncryptedContentInfo encContentInfo; }; -#define SEC_PKCS7_ENVELOPED_DATA_VERSION 0 /* what we *create* */ +#define SEC_PKCS7_ENVELOPED_DATA_VERSION 0 /* what we *create* */ struct SEC_PKCS7SignedAndEnvelopedDataStr { SECItem version; @@ -133,12 +132,12 @@ struct SEC_PKCS7SignedAndEnvelopedDataStr { SECItem **rawCerts; CERTSignedCrl **crls; SEC_PKCS7SignerInfo **signerInfos; - SECItem **digests; /* local; not part of encoding */ - CERTCertificate **certs; /* local; not part of encoding */ - CERTCertificateList **certLists; /* local; not part of encoding */ - PK11SymKey *sigKey; /* local; not part of encoding */ + SECItem **digests; /* local; not part of encoding */ + CERTCertificate **certs; /* local; not part of encoding */ + CERTCertificateList **certLists; /* local; not part of encoding */ + PK11SymKey *sigKey; /* local; not part of encoding */ }; -#define SEC_PKCS7_SIGNED_AND_ENVELOPED_DATA_VERSION 1 /* what we *create* */ +#define SEC_PKCS7_SIGNED_AND_ENVELOPED_DATA_VERSION 1 /* what we *create* */ struct SEC_PKCS7SignerInfoStr { SECItem version; @@ -148,19 +147,19 @@ struct SEC_PKCS7SignerInfoStr { SECAlgorithmID digestEncAlg; SECItem encDigest; SEC_PKCS7Attribute **unAuthAttr; - CERTCertificate *cert; /* local; not part of encoding */ - CERTCertificateList *certList; /* local; not part of encoding */ + CERTCertificate *cert; /* local; not part of encoding */ + CERTCertificateList *certList; /* local; not part of encoding */ }; -#define SEC_PKCS7_SIGNER_INFO_VERSION 1 /* what we *create* */ +#define SEC_PKCS7_SIGNER_INFO_VERSION 1 /* what we *create* */ struct SEC_PKCS7RecipientInfoStr { SECItem version; CERTIssuerAndSN *issuerAndSN; SECAlgorithmID keyEncAlg; SECItem encKey; - CERTCertificate *cert; /* local; not part of encoding */ + CERTCertificate *cert; /* local; not part of encoding */ }; -#define SEC_PKCS7_RECIPIENT_INFO_VERSION 0 /* what we *create* */ +#define SEC_PKCS7_RECIPIENT_INFO_VERSION 0 /* what we *create* */ struct SEC_PKCS7DigestedDataStr { SECItem version; @@ -168,13 +167,13 @@ struct SEC_PKCS7DigestedDataStr { SEC_PKCS7ContentInfo contentInfo; SECItem digest; }; -#define SEC_PKCS7_DIGESTED_DATA_VERSION 0 /* what we *create* */ +#define SEC_PKCS7_DIGESTED_DATA_VERSION 0 /* what we *create* */ struct SEC_PKCS7EncryptedDataStr { SECItem version; SEC_PKCS7EncryptedContentInfo encContentInfo; }; -#define SEC_PKCS7_ENCRYPTED_DATA_VERSION 0 /* what we *create* */ +#define SEC_PKCS7_ENCRYPTED_DATA_VERSION 0 /* what we *create* */ /* * See comment above about this type not really belonging to PKCS7. @@ -182,10 +181,10 @@ struct SEC_PKCS7EncryptedDataStr { struct SEC_PKCS7AttributeStr { /* The following fields make up an encoded Attribute: */ SECItem type; - SECItem **values; /* data may or may not be encoded */ + SECItem **values; /* data may or may not be encoded */ /* The following fields are not part of an encoded Attribute: */ SECOidData *typeTag; - PRBool encoded; /* when true, values are encoded */ + PRBool encoded; /* when true, values are encoded */ }; /* @@ -196,9 +195,9 @@ struct SEC_PKCS7AttributeStr { * XXX Should just combine this with SEC_PKCS7EncoderContentCallback type * and use a simpler, common name. */ -typedef void (* SEC_PKCS7DecoderContentCallback)(void *arg, - const char *buf, - unsigned long len); +typedef void (*SEC_PKCS7DecoderContentCallback)(void *arg, + const char *buf, + unsigned long len); /* * Type of function passed to SEC_PKCS7Encode or SEC_PKCS7EncoderStart. @@ -207,10 +206,9 @@ typedef void (* SEC_PKCS7DecoderContentCallback)(void *arg, * XXX Should just combine this with SEC_PKCS7DecoderContentCallback type * and use a simpler, common name. */ -typedef void (* SEC_PKCS7EncoderOutputCallback)(void *arg, - const char *buf, - unsigned long len); - +typedef void (*SEC_PKCS7EncoderOutputCallback)(void *arg, + const char *buf, + unsigned long len); /* * Type of function passed to SEC_PKCS7Decode or SEC_PKCS7DecoderStart @@ -218,10 +216,10 @@ typedef void (* SEC_PKCS7EncoderOutputCallback)(void *arg, * used for EncryptedData content info's which do not have a key available * in a certificate, etc. */ -typedef PK11SymKey * (* SEC_PKCS7GetDecryptKeyCallback)(void *arg, - SECAlgorithmID *algid); +typedef PK11SymKey *(*SEC_PKCS7GetDecryptKeyCallback)(void *arg, + SECAlgorithmID *algid); -/* +/* * Type of function passed to SEC_PKCS7Decode or SEC_PKCS7DecoderStart. * This function in intended to be used to verify that decrypting a * particular crypto algorithm is allowed. Content types which do not @@ -229,7 +227,7 @@ typedef PK11SymKey * (* SEC_PKCS7GetDecryptKeyCallback)(void *arg, * is not specified for content types which require decryption, the * decryption will be disallowed. */ -typedef PRBool (* SEC_PKCS7DecryptionAllowedCallback)(SECAlgorithmID *algid, - PK11SymKey *bulkkey); +typedef PRBool (*SEC_PKCS7DecryptionAllowedCallback)(SECAlgorithmID *algid, + PK11SymKey *bulkkey); #endif /* _PKCS7T_H_ */ diff --git a/nss/lib/pkcs7/secmime.c b/nss/lib/pkcs7/secmime.c index 12a1e20..ca1046a 100644 --- a/nss/lib/pkcs7/secmime.c +++ b/nss/lib/pkcs7/secmime.c @@ -10,7 +10,7 @@ #include "secmime.h" #include "secoid.h" #include "pk11func.h" -#include "ciferfam.h" /* for CIPHER_FAMILY symbols */ +#include "ciferfam.h" /* for CIPHER_FAMILY symbols */ #include "secasn1.h" #include "secitem.h" #include "cert.h" @@ -27,12 +27,12 @@ typedef struct smime_cipher_map_struct { * These are macros because I think some subsequent parameters, * like those for RC5, will want to use them, too, separately. */ -#define SMIME_DER_INTVAL_16 SEC_ASN1_INTEGER, 0x01, 0x10 -#define SMIME_DER_INTVAL_40 SEC_ASN1_INTEGER, 0x01, 0x28 -#define SMIME_DER_INTVAL_64 SEC_ASN1_INTEGER, 0x01, 0x40 -#define SMIME_DER_INTVAL_128 SEC_ASN1_INTEGER, 0x02, 0x00, 0x80 +#define SMIME_DER_INTVAL_16 SEC_ASN1_INTEGER, 0x01, 0x10 +#define SMIME_DER_INTVAL_40 SEC_ASN1_INTEGER, 0x01, 0x28 +#define SMIME_DER_INTVAL_64 SEC_ASN1_INTEGER, 0x01, 0x40 +#define SMIME_DER_INTVAL_128 SEC_ASN1_INTEGER, 0x02, 0x00, 0x80 -#ifdef SMIME_DOES_RC5 /* will be needed; quiet unused warning for now */ +#ifdef SMIME_DOES_RC5 /* will be needed; quiet unused warning for now */ static unsigned char smime_int16[] = { SMIME_DER_INTVAL_16 }; #endif static unsigned char smime_int40[] = { SMIME_DER_INTVAL_40 }; @@ -44,24 +44,23 @@ static SECItem smime_rc2p64 = { siBuffer, smime_int64, sizeof(smime_int64) }; static SECItem smime_rc2p128 = { siBuffer, smime_int128, sizeof(smime_int128) }; static smime_cipher_map smime_cipher_maps[] = { - { SMIME_RC2_CBC_40, SEC_OID_RC2_CBC, &smime_rc2p40 }, - { SMIME_RC2_CBC_64, SEC_OID_RC2_CBC, &smime_rc2p64 }, - { SMIME_RC2_CBC_128, SEC_OID_RC2_CBC, &smime_rc2p128 }, + { SMIME_RC2_CBC_40, SEC_OID_RC2_CBC, &smime_rc2p40 }, + { SMIME_RC2_CBC_64, SEC_OID_RC2_CBC, &smime_rc2p64 }, + { SMIME_RC2_CBC_128, SEC_OID_RC2_CBC, &smime_rc2p128 }, #ifdef SMIME_DOES_RC5 - { SMIME_RC5PAD_64_16_40, SEC_OID_RC5_CBC_PAD, &smime_rc5p40 }, - { SMIME_RC5PAD_64_16_64, SEC_OID_RC5_CBC_PAD, &smime_rc5p64 }, - { SMIME_RC5PAD_64_16_128, SEC_OID_RC5_CBC_PAD, &smime_rc5p128 }, + { SMIME_RC5PAD_64_16_40, SEC_OID_RC5_CBC_PAD, &smime_rc5p40 }, + { SMIME_RC5PAD_64_16_64, SEC_OID_RC5_CBC_PAD, &smime_rc5p64 }, + { SMIME_RC5PAD_64_16_128, SEC_OID_RC5_CBC_PAD, &smime_rc5p128 }, #endif - { SMIME_DES_CBC_56, SEC_OID_DES_CBC, NULL }, - { SMIME_DES_EDE3_168, SEC_OID_DES_EDE3_CBC, NULL } + { SMIME_DES_CBC_56, SEC_OID_DES_CBC, NULL }, + { SMIME_DES_EDE3_168, SEC_OID_DES_EDE3_CBC, NULL } }; /* * Note, the following value really just needs to be an upper bound * on the ciphers. */ -static const int smime_symmetric_count = sizeof(smime_cipher_maps) - / sizeof(smime_cipher_map); +static const int smime_symmetric_count = sizeof(smime_cipher_maps) / sizeof(smime_cipher_map); static unsigned long *smime_prefs, *smime_newprefs; static int smime_current_pref_index = 0; @@ -70,119 +69,114 @@ static PRBool smime_prefs_changed = PR_TRUE; static unsigned long smime_policy_bits = 0; - static int -smime_mapi_by_cipher (unsigned long cipher) +smime_mapi_by_cipher(unsigned long cipher) { int i; for (i = 0; i < smime_symmetric_count; i++) { - if (smime_cipher_maps[i].cipher == cipher) - break; + if (smime_cipher_maps[i].cipher == cipher) + break; } if (i == smime_symmetric_count) - return -1; + return -1; return i; } - /* * this function locally records the user's preference */ -SECStatus +SECStatus SECMIME_EnableCipher(long which, int on) { unsigned long mask; if (smime_newprefs == NULL || smime_prefs_complete) { - /* - * This is either the very first time, or we are starting over. - */ - smime_newprefs = (unsigned long*)PORT_ZAlloc (smime_symmetric_count - * sizeof(*smime_newprefs)); - if (smime_newprefs == NULL) - return SECFailure; - smime_current_pref_index = 0; - smime_prefs_complete = PR_FALSE; + /* + * This is either the very first time, or we are starting over. + */ + smime_newprefs = (unsigned long *)PORT_ZAlloc(smime_symmetric_count * sizeof(*smime_newprefs)); + if (smime_newprefs == NULL) + return SECFailure; + smime_current_pref_index = 0; + smime_prefs_complete = PR_FALSE; } mask = which & CIPHER_FAMILYID_MASK; if (mask == CIPHER_FAMILYID_MASK) { - /* - * This call signifies that all preferences have been set. - * Move "newprefs" over, after checking first whether or - * not the new ones are different from the old ones. - */ - if (smime_prefs != NULL) { - if (PORT_Memcmp (smime_prefs, smime_newprefs, - smime_symmetric_count * sizeof(*smime_prefs)) == 0) - smime_prefs_changed = PR_FALSE; - else - smime_prefs_changed = PR_TRUE; - PORT_Free (smime_prefs); - } - - smime_prefs = smime_newprefs; - smime_prefs_complete = PR_TRUE; - return SECSuccess; + /* + * This call signifies that all preferences have been set. + * Move "newprefs" over, after checking first whether or + * not the new ones are different from the old ones. + */ + if (smime_prefs != NULL) { + if (PORT_Memcmp(smime_prefs, smime_newprefs, + smime_symmetric_count * sizeof(*smime_prefs)) == 0) + smime_prefs_changed = PR_FALSE; + else + smime_prefs_changed = PR_TRUE; + PORT_Free(smime_prefs); + } + + smime_prefs = smime_newprefs; + smime_prefs_complete = PR_TRUE; + return SECSuccess; } - PORT_Assert (mask == CIPHER_FAMILYID_SMIME); + PORT_Assert(mask == CIPHER_FAMILYID_SMIME); if (mask != CIPHER_FAMILYID_SMIME) { - /* XXX set an error! */ - return SECFailure; + /* XXX set an error! */ + return SECFailure; } if (on) { - PORT_Assert (smime_current_pref_index < smime_symmetric_count); - if (smime_current_pref_index >= smime_symmetric_count) { - /* XXX set an error! */ - return SECFailure; - } + PORT_Assert(smime_current_pref_index < smime_symmetric_count); + if (smime_current_pref_index >= smime_symmetric_count) { + /* XXX set an error! */ + return SECFailure; + } - smime_newprefs[smime_current_pref_index++] = which; + smime_newprefs[smime_current_pref_index++] = which; } return SECSuccess; } - /* * this function locally records the export policy */ -SECStatus +SECStatus SECMIME_SetPolicy(long which, int on) { unsigned long mask; - PORT_Assert ((which & CIPHER_FAMILYID_MASK) == CIPHER_FAMILYID_SMIME); + PORT_Assert((which & CIPHER_FAMILYID_MASK) == CIPHER_FAMILYID_SMIME); if ((which & CIPHER_FAMILYID_MASK) != CIPHER_FAMILYID_SMIME) { - /* XXX set an error! */ - return SECFailure; + /* XXX set an error! */ + return SECFailure; } which &= ~CIPHER_FAMILYID_MASK; - PORT_Assert (which < 32); /* bits in the long */ + PORT_Assert(which < 32); /* bits in the long */ if (which >= 32) { - /* XXX set an error! */ - return SECFailure; + /* XXX set an error! */ + return SECFailure; } mask = 1UL << which; if (on) { - smime_policy_bits |= mask; + smime_policy_bits |= mask; } else { - smime_policy_bits &= ~mask; + smime_policy_bits &= ~mask; } return SECSuccess; } - /* * Based on the given algorithm (including its parameters, in some cases!) * and the given key (may or may not be inspected, depending on the @@ -190,77 +184,72 @@ SECMIME_SetPolicy(long which, int on) * and return it. If no match can be made, -1 is returned. */ static long -smime_policy_algorithm (SECAlgorithmID *algid, PK11SymKey *key) +smime_policy_algorithm(SECAlgorithmID *algid, PK11SymKey *key) { SECOidTag algtag; - algtag = SECOID_GetAlgorithmTag (algid); + algtag = SECOID_GetAlgorithmTag(algid); switch (algtag) { - case SEC_OID_RC2_CBC: - { - unsigned int keylen_bits; - - keylen_bits = PK11_GetKeyStrength (key, algid); - switch (keylen_bits) { - case 40: - return SMIME_RC2_CBC_40; - case 64: - return SMIME_RC2_CBC_64; - case 128: - return SMIME_RC2_CBC_128; - default: - break; - } - } - break; - case SEC_OID_DES_CBC: - return SMIME_DES_CBC_56; - case SEC_OID_DES_EDE3_CBC: - return SMIME_DES_EDE3_168; + case SEC_OID_RC2_CBC: { + unsigned int keylen_bits; + + keylen_bits = PK11_GetKeyStrength(key, algid); + switch (keylen_bits) { + case 40: + return SMIME_RC2_CBC_40; + case 64: + return SMIME_RC2_CBC_64; + case 128: + return SMIME_RC2_CBC_128; + default: + break; + } + } break; + case SEC_OID_DES_CBC: + return SMIME_DES_CBC_56; + case SEC_OID_DES_EDE3_CBC: + return SMIME_DES_EDE3_168; #ifdef SMIME_DOES_RC5 - case SEC_OID_RC5_CBC_PAD: - PORT_Assert (0); /* XXX need to pull out parameters and match */ - break; + case SEC_OID_RC5_CBC_PAD: + PORT_Assert(0); /* XXX need to pull out parameters and match */ + break; #endif - default: - break; + default: + break; } return -1; } - static PRBool -smime_cipher_allowed (unsigned long which) +smime_cipher_allowed(unsigned long which) { unsigned long mask; which &= ~CIPHER_FAMILYID_MASK; - PORT_Assert (which < 32); /* bits per long (min) */ + PORT_Assert(which < 32); /* bits per long (min) */ if (which >= 32) - return PR_FALSE; + return PR_FALSE; mask = 1UL << which; if ((mask & smime_policy_bits) == 0) - return PR_FALSE; + return PR_FALSE; return PR_TRUE; } - PRBool SECMIME_DecryptionAllowed(SECAlgorithmID *algid, PK11SymKey *key) { long which; - which = smime_policy_algorithm (algid, key); + which = smime_policy_algorithm(algid, key); if (which < 0) - return PR_FALSE; + return PR_FALSE; - return smime_cipher_allowed ((unsigned long)which); + return smime_cipher_allowed((unsigned long)which); } - /* * Does the current policy allow *any* S/MIME encryption (or decryption)? * @@ -273,93 +262,89 @@ SECMIME_DecryptionAllowed(SECAlgorithmID *algid, PK11SymKey *key) * * It takes no arguments. The return value is a simple boolean: * PR_TRUE means encryption (or decryption) is *possible* - * (but may still fail due to other reasons, like because we cannot - * find all the necessary certs, etc.; PR_TRUE is *not* a guarantee) + * (but may still fail due to other reasons, like because we cannot + * find all the necessary certs, etc.; PR_TRUE is *not* a guarantee) * PR_FALSE means encryption (or decryption) is not permitted * * There are no errors from this routine. */ PRBool -SECMIME_EncryptionPossible (void) +SECMIME_EncryptionPossible(void) { if (smime_policy_bits != 0) - return PR_TRUE; + return PR_TRUE; return PR_FALSE; } - /* * XXX Would like the "parameters" field to be a SECItem *, but the * encoder is having trouble with optional pointers to an ANY. Maybe * once that is fixed, can change this back... */ typedef struct smime_capability_struct { - unsigned long cipher; /* local; not part of encoding */ - SECOidTag capIDTag; /* local; not part of encoding */ + unsigned long cipher; /* local; not part of encoding */ + SECOidTag capIDTag; /* local; not part of encoding */ SECItem capabilityID; SECItem parameters; } smime_capability; static const SEC_ASN1Template smime_capability_template[] = { { SEC_ASN1_SEQUENCE, - 0, NULL, sizeof(smime_capability) }, + 0, NULL, sizeof(smime_capability) }, { SEC_ASN1_OBJECT_ID, - offsetof(smime_capability,capabilityID), }, + offsetof(smime_capability, capabilityID) }, { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY, - offsetof(smime_capability,parameters), }, - { 0, } + offsetof(smime_capability, parameters) }, + { 0 } }; static const SEC_ASN1Template smime_capabilities_template[] = { { SEC_ASN1_SEQUENCE_OF, 0, smime_capability_template } }; - - static void -smime_fill_capability (smime_capability *cap) +smime_fill_capability(smime_capability *cap) { unsigned long cipher; SECOidTag algtag; int i; - algtag = SECOID_FindOIDTag (&(cap->capabilityID)); + algtag = SECOID_FindOIDTag(&(cap->capabilityID)); for (i = 0; i < smime_symmetric_count; i++) { - if (smime_cipher_maps[i].algtag != algtag) - continue; - /* - * XXX If SECITEM_CompareItem allowed NULLs as arguments (comparing - * 2 NULLs as equal and NULL and non-NULL as not equal), we could - * use that here instead of all of the following comparison code. - */ - if (cap->parameters.data != NULL) { - if (smime_cipher_maps[i].parms == NULL) - continue; - if (cap->parameters.len != smime_cipher_maps[i].parms->len) - continue; - if (PORT_Memcmp (cap->parameters.data, - smime_cipher_maps[i].parms->data, - cap->parameters.len) == 0) - break; - } else if (smime_cipher_maps[i].parms == NULL) { - break; - } + if (smime_cipher_maps[i].algtag != algtag) + continue; + /* + * XXX If SECITEM_CompareItem allowed NULLs as arguments (comparing + * 2 NULLs as equal and NULL and non-NULL as not equal), we could + * use that here instead of all of the following comparison code. + */ + if (cap->parameters.data != NULL) { + if (smime_cipher_maps[i].parms == NULL) + continue; + if (cap->parameters.len != smime_cipher_maps[i].parms->len) + continue; + if (PORT_Memcmp(cap->parameters.data, + smime_cipher_maps[i].parms->data, + cap->parameters.len) == 0) + break; + } else if (smime_cipher_maps[i].parms == NULL) { + break; + } } if (i == smime_symmetric_count) - cipher = 0; + cipher = 0; else - cipher = smime_cipher_maps[i].cipher; + cipher = smime_cipher_maps[i].cipher; cap->cipher = cipher; cap->capIDTag = algtag; } - static long -smime_choose_cipher (CERTCertificate *scert, CERTCertificate **rcerts) +smime_choose_cipher(CERTCertificate *scert, CERTCertificate **rcerts) { PLArenaPool *poolp; long chosen_cipher; @@ -369,25 +354,25 @@ smime_choose_cipher (CERTCertificate *scert, CERTCertificate **rcerts) int rcount, mapi, max; if (smime_policy_bits == 0) { - PORT_SetError (SEC_ERROR_BAD_EXPORT_ALGORITHM); - return -1; + PORT_SetError(SEC_ERROR_BAD_EXPORT_ALGORITHM); + return -1; } - chosen_cipher = SMIME_RC2_CBC_40; /* the default, LCD */ + chosen_cipher = SMIME_RC2_CBC_40; /* the default, LCD */ - poolp = PORT_NewArena (1024); /* XXX what is right value? */ + poolp = PORT_NewArena(1024); /* XXX what is right value? */ if (poolp == NULL) - goto done; + goto done; - cipher_abilities = (int*)PORT_ArenaZAlloc (poolp, - smime_symmetric_count * sizeof(int)); + cipher_abilities = (int *)PORT_ArenaZAlloc(poolp, + smime_symmetric_count * sizeof(int)); if (cipher_abilities == NULL) - goto done; + goto done; - cipher_votes = (int*)PORT_ArenaZAlloc (poolp, - smime_symmetric_count * sizeof(int)); + cipher_votes = (int *)PORT_ArenaZAlloc(poolp, + smime_symmetric_count * sizeof(int)); if (cipher_votes == NULL) - goto done; + goto done; /* * XXX Should have a #define somewhere which specifies default @@ -395,127 +380,125 @@ smime_choose_cipher (CERTCertificate *scert, CERTCertificate **rcerts) */ /* Make triple-DES the strong cipher. */ - strong_mapi = smime_mapi_by_cipher (SMIME_DES_EDE3_168); + strong_mapi = smime_mapi_by_cipher(SMIME_DES_EDE3_168); - PORT_Assert (strong_mapi >= 0); + PORT_Assert(strong_mapi >= 0); for (rcount = 0; rcerts[rcount] != NULL; rcount++) { - SECItem *profile; - smime_capability **caps; - int capi, pref; - SECStatus dstat; - - pref = smime_symmetric_count; - profile = CERT_FindSMimeProfile (rcerts[rcount]); - if (profile != NULL && profile->data != NULL && profile->len > 0) { - caps = NULL; - dstat = SEC_QuickDERDecodeItem (poolp, &caps, - smime_capabilities_template, - profile); - if (dstat == SECSuccess && caps != NULL) { - for (capi = 0; caps[capi] != NULL; capi++) { - smime_fill_capability (caps[capi]); - mapi = smime_mapi_by_cipher (caps[capi]->cipher); - if (mapi >= 0) { - cipher_abilities[mapi]++; - cipher_votes[mapi] += pref; - --pref; - } - } - } - } else { - SECKEYPublicKey *key; - unsigned int pklen_bits; - - /* - * XXX This is probably only good for RSA keys. What I would - * really like is a function to just say; Is the public key in - * this cert an export-length key? Then I would not have to - * know things like the value 512, or the kind of key, or what - * a subjectPublicKeyInfo is, etc. - */ - key = CERT_ExtractPublicKey (rcerts[rcount]); - if (key != NULL) { - pklen_bits = SECKEY_PublicKeyStrength (key) * 8; - SECKEY_DestroyPublicKey (key); - - if (pklen_bits > 512) { - cipher_abilities[strong_mapi]++; - cipher_votes[strong_mapi] += pref; - } - } - } - if (profile != NULL) - SECITEM_FreeItem (profile, PR_TRUE); + SECItem *profile; + smime_capability **caps; + int capi, pref; + SECStatus dstat; + + pref = smime_symmetric_count; + profile = CERT_FindSMimeProfile(rcerts[rcount]); + if (profile != NULL && profile->data != NULL && profile->len > 0) { + caps = NULL; + dstat = SEC_QuickDERDecodeItem(poolp, &caps, + smime_capabilities_template, + profile); + if (dstat == SECSuccess && caps != NULL) { + for (capi = 0; caps[capi] != NULL; capi++) { + smime_fill_capability(caps[capi]); + mapi = smime_mapi_by_cipher(caps[capi]->cipher); + if (mapi >= 0) { + cipher_abilities[mapi]++; + cipher_votes[mapi] += pref; + --pref; + } + } + } + } else { + SECKEYPublicKey *key; + unsigned int pklen_bits; + + /* + * XXX This is probably only good for RSA keys. What I would + * really like is a function to just say; Is the public key in + * this cert an export-length key? Then I would not have to + * know things like the value 512, or the kind of key, or what + * a subjectPublicKeyInfo is, etc. + */ + key = CERT_ExtractPublicKey(rcerts[rcount]); + if (key != NULL) { + pklen_bits = SECKEY_PublicKeyStrength(key) * 8; + SECKEY_DestroyPublicKey(key); + + if (pklen_bits > 512) { + cipher_abilities[strong_mapi]++; + cipher_votes[strong_mapi] += pref; + } + } + } + if (profile != NULL) + SECITEM_FreeItem(profile, PR_TRUE); } max = 0; for (mapi = 0; mapi < smime_symmetric_count; mapi++) { - if (cipher_abilities[mapi] != rcount) - continue; - if (! smime_cipher_allowed (smime_cipher_maps[mapi].cipher)) - continue; - if (cipher_votes[mapi] > max) { - chosen_cipher = smime_cipher_maps[mapi].cipher; - max = cipher_votes[mapi]; - } /* XXX else if a tie, let scert break it? */ + if (cipher_abilities[mapi] != rcount) + continue; + if (!smime_cipher_allowed(smime_cipher_maps[mapi].cipher)) + continue; + if (cipher_votes[mapi] > max) { + chosen_cipher = smime_cipher_maps[mapi].cipher; + max = cipher_votes[mapi]; + } /* XXX else if a tie, let scert break it? */ } done: if (poolp != NULL) - PORT_FreeArena (poolp, PR_FALSE); + PORT_FreeArena(poolp, PR_FALSE); return chosen_cipher; } - /* * XXX This is a hack for now to satisfy our current interface. * Eventually, with more parameters needing to be specified, just * looking up the keysize is not going to be sufficient. */ static int -smime_keysize_by_cipher (unsigned long which) +smime_keysize_by_cipher(unsigned long which) { int keysize; switch (which) { - case SMIME_RC2_CBC_40: - keysize = 40; - break; - case SMIME_RC2_CBC_64: - keysize = 64; - break; - case SMIME_RC2_CBC_128: - keysize = 128; - break; + case SMIME_RC2_CBC_40: + keysize = 40; + break; + case SMIME_RC2_CBC_64: + keysize = 64; + break; + case SMIME_RC2_CBC_128: + keysize = 128; + break; #ifdef SMIME_DOES_RC5 - case SMIME_RC5PAD_64_16_40: - case SMIME_RC5PAD_64_16_64: - case SMIME_RC5PAD_64_16_128: - /* XXX See comment above; keysize is not enough... */ - PORT_Assert (0); - PORT_SetError (SEC_ERROR_INVALID_ALGORITHM); - keysize = -1; - break; + case SMIME_RC5PAD_64_16_40: + case SMIME_RC5PAD_64_16_64: + case SMIME_RC5PAD_64_16_128: + /* XXX See comment above; keysize is not enough... */ + PORT_Assert(0); + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); + keysize = -1; + break; #endif - case SMIME_DES_CBC_56: - case SMIME_DES_EDE3_168: - /* - * These are special; since the key size is fixed, we actually - * want to *avoid* specifying a key size. - */ - keysize = 0; - break; - default: - keysize = -1; - break; + case SMIME_DES_CBC_56: + case SMIME_DES_EDE3_168: + /* + * These are special; since the key size is fixed, we actually + * want to *avoid* specifying a key size. + */ + keysize = 0; + break; + default: + keysize = -1; + break; } return keysize; } - /* * Start an S/MIME encrypting context. * @@ -535,10 +518,10 @@ smime_keysize_by_cipher (unsigned long which) */ SEC_PKCS7ContentInfo * SECMIME_CreateEncrypted(CERTCertificate *scert, - CERTCertificate **rcerts, - CERTCertDBHandle *certdb, - SECKEYGetPasswordKey pwfn, - void *pwfn_arg) + CERTCertificate **rcerts, + CERTCertDBHandle *certdb, + SECKEYGetPasswordKey pwfn, + void *pwfn_arg) { SEC_PKCS7ContentInfo *cinfo; long cipher; @@ -546,13 +529,13 @@ SECMIME_CreateEncrypted(CERTCertificate *scert, int keysize; int mapi, rci; - cipher = smime_choose_cipher (scert, rcerts); + cipher = smime_choose_cipher(scert, rcerts); if (cipher < 0) - return NULL; + return NULL; - mapi = smime_mapi_by_cipher (cipher); + mapi = smime_mapi_by_cipher(cipher); if (mapi < 0) - return NULL; + return NULL; /* * XXX This is stretching it -- CreateEnvelopedData should probably @@ -563,36 +546,34 @@ SECMIME_CreateEncrypted(CERTCertificate *scert, * block size). Work this out into a better API! */ encalg = smime_cipher_maps[mapi].algtag; - keysize = smime_keysize_by_cipher (cipher); + keysize = smime_keysize_by_cipher(cipher); if (keysize < 0) - return NULL; + return NULL; - cinfo = SEC_PKCS7CreateEnvelopedData (scert, certUsageEmailRecipient, - certdb, encalg, keysize, - pwfn, pwfn_arg); + cinfo = SEC_PKCS7CreateEnvelopedData(scert, certUsageEmailRecipient, + certdb, encalg, keysize, + pwfn, pwfn_arg); if (cinfo == NULL) - return NULL; + return NULL; for (rci = 0; rcerts[rci] != NULL; rci++) { - if (rcerts[rci] == scert) - continue; - if (SEC_PKCS7AddRecipient (cinfo, rcerts[rci], certUsageEmailRecipient, - NULL) != SECSuccess) { - SEC_PKCS7DestroyContentInfo (cinfo); - return NULL; - } + if (rcerts[rci] == scert) + continue; + if (SEC_PKCS7AddRecipient(cinfo, rcerts[rci], certUsageEmailRecipient, + NULL) != SECSuccess) { + SEC_PKCS7DestroyContentInfo(cinfo); + return NULL; + } } return cinfo; } - static smime_capability **smime_capabilities; static SECItem *smime_encoded_caps; - static SECStatus -smime_init_caps (void) +smime_init_caps(void) { smime_capability *cap; smime_cipher_map *map; @@ -600,141 +581,138 @@ smime_init_caps (void) SECStatus rv; int i; - if (smime_encoded_caps != NULL && (! smime_prefs_changed)) - return SECSuccess; + if (smime_encoded_caps != NULL && (!smime_prefs_changed)) + return SECSuccess; if (smime_encoded_caps != NULL) { - SECITEM_FreeItem (smime_encoded_caps, PR_TRUE); - smime_encoded_caps = NULL; + SECITEM_FreeItem(smime_encoded_caps, PR_TRUE); + smime_encoded_caps = NULL; } if (smime_capabilities == NULL) { - smime_capabilities = (smime_capability**)PORT_ZAlloc ( - (smime_symmetric_count + 1) - * sizeof(smime_capability *)); - if (smime_capabilities == NULL) - return SECFailure; + smime_capabilities = (smime_capability **)PORT_ZAlloc( + (smime_symmetric_count + 1) * sizeof(smime_capability *)); + if (smime_capabilities == NULL) + return SECFailure; } rv = SECFailure; - /* + /* The process of creating the encoded PKCS7 cipher capability list - involves two basic steps: + involves two basic steps: - (a) Convert our internal representation of cipher preferences - (smime_prefs) into an array containing cipher OIDs and - parameter data (smime_capabilities). This step is - performed here. + (a) Convert our internal representation of cipher preferences + (smime_prefs) into an array containing cipher OIDs and + parameter data (smime_capabilities). This step is + performed here. - (b) Encode, using ASN.1, the cipher information in - smime_capabilities, leaving the encoded result in - smime_encoded_caps. + (b) Encode, using ASN.1, the cipher information in + smime_capabilities, leaving the encoded result in + smime_encoded_caps. (In the process of performing (a), Lisa put in some optimizations - which allow us to avoid needlessly re-populating elements in + which allow us to avoid needlessly re-populating elements in smime_capabilities as we walk through smime_prefs.) */ for (i = 0; i < smime_current_pref_index; i++) { - int mapi; - - /* Get the next cipher preference in smime_prefs. */ - mapi = smime_mapi_by_cipher (smime_prefs[i]); - if (mapi < 0) - break; - - /* Find the corresponding entry in the cipher map. */ - PORT_Assert (mapi < smime_symmetric_count); - map = &(smime_cipher_maps[mapi]); - - /* - * Convert the next preference found in smime_prefs into an - * smime_capability. - */ - - cap = smime_capabilities[i]; - if (cap == NULL) { - cap = (smime_capability*)PORT_ZAlloc (sizeof(smime_capability)); - if (cap == NULL) - break; - smime_capabilities[i] = cap; - } else if (cap->cipher == smime_prefs[i]) { - continue; /* no change to this one */ - } - - cap->capIDTag = map->algtag; - oiddata = SECOID_FindOIDByTag (map->algtag); - if (oiddata == NULL) - break; - - if (cap->capabilityID.data != NULL) { - SECITEM_FreeItem (&(cap->capabilityID), PR_FALSE); - cap->capabilityID.data = NULL; - cap->capabilityID.len = 0; - } - - rv = SECITEM_CopyItem (NULL, &(cap->capabilityID), &(oiddata->oid)); - if (rv != SECSuccess) - break; - - if (map->parms == NULL) { - cap->parameters.data = NULL; - cap->parameters.len = 0; - } else { - cap->parameters.data = map->parms->data; - cap->parameters.len = map->parms->len; - } - - cap->cipher = smime_prefs[i]; + int mapi; + + /* Get the next cipher preference in smime_prefs. */ + mapi = smime_mapi_by_cipher(smime_prefs[i]); + if (mapi < 0) + break; + + /* Find the corresponding entry in the cipher map. */ + PORT_Assert(mapi < smime_symmetric_count); + map = &(smime_cipher_maps[mapi]); + + /* + * Convert the next preference found in smime_prefs into an + * smime_capability. + */ + + cap = smime_capabilities[i]; + if (cap == NULL) { + cap = (smime_capability *)PORT_ZAlloc(sizeof(smime_capability)); + if (cap == NULL) + break; + smime_capabilities[i] = cap; + } else if (cap->cipher == smime_prefs[i]) { + continue; /* no change to this one */ + } + + cap->capIDTag = map->algtag; + oiddata = SECOID_FindOIDByTag(map->algtag); + if (oiddata == NULL) + break; + + if (cap->capabilityID.data != NULL) { + SECITEM_FreeItem(&(cap->capabilityID), PR_FALSE); + cap->capabilityID.data = NULL; + cap->capabilityID.len = 0; + } + + rv = SECITEM_CopyItem(NULL, &(cap->capabilityID), &(oiddata->oid)); + if (rv != SECSuccess) + break; + + if (map->parms == NULL) { + cap->parameters.data = NULL; + cap->parameters.len = 0; + } else { + cap->parameters.data = map->parms->data; + cap->parameters.len = map->parms->len; + } + + cap->cipher = smime_prefs[i]; } if (i != smime_current_pref_index) - return rv; + return rv; while (i < smime_symmetric_count) { - cap = smime_capabilities[i]; - if (cap != NULL) { - SECITEM_FreeItem (&(cap->capabilityID), PR_FALSE); - PORT_Free (cap); - } - smime_capabilities[i] = NULL; - i++; + cap = smime_capabilities[i]; + if (cap != NULL) { + SECITEM_FreeItem(&(cap->capabilityID), PR_FALSE); + PORT_Free(cap); + } + smime_capabilities[i] = NULL; + i++; } smime_capabilities[i] = NULL; - smime_encoded_caps = SEC_ASN1EncodeItem (NULL, NULL, &smime_capabilities, - smime_capabilities_template); + smime_encoded_caps = SEC_ASN1EncodeItem(NULL, NULL, &smime_capabilities, + smime_capabilities_template); if (smime_encoded_caps == NULL) - return SECFailure; + return SECFailure; return SECSuccess; } - static SECStatus -smime_add_profile (CERTCertificate *cert, SEC_PKCS7ContentInfo *cinfo) +smime_add_profile(CERTCertificate *cert, SEC_PKCS7ContentInfo *cinfo) { - PORT_Assert (smime_prefs_complete); - if (! smime_prefs_complete) - return SECFailure; + PORT_Assert(smime_prefs_complete); + if (!smime_prefs_complete) + return SECFailure; /* For that matter, if capabilities haven't been initialized yet, do so now. */ if (smime_encoded_caps == NULL || smime_prefs_changed) { - SECStatus rv; + SECStatus rv; - rv = smime_init_caps(); - if (rv != SECSuccess) - return rv; + rv = smime_init_caps(); + if (rv != SECSuccess) + return rv; - PORT_Assert (smime_encoded_caps != NULL); + PORT_Assert(smime_encoded_caps != NULL); } - return SEC_PKCS7AddSignedAttribute (cinfo, SEC_OID_PKCS9_SMIME_CAPABILITIES, - smime_encoded_caps); + return SEC_PKCS7AddSignedAttribute(cinfo, SEC_OID_PKCS9_SMIME_CAPABILITIES, + smime_encoded_caps); } - /* * Start an S/MIME signing context. * @@ -747,7 +725,7 @@ smime_add_profile (CERTCertificate *cert, SEC_PKCS7ContentInfo *cinfo) * * "certdb" is the cert database to use for verifying the cert. * It can be NULL if a default database is available (like in the client). - * + * * "digestalg" names the digest algorithm (e.g. SEC_OID_SHA1). * XXX There should be SECMIME functions for hashing, or the hashing should * be built into this interface, which we would like because we would @@ -766,13 +744,13 @@ smime_add_profile (CERTCertificate *cert, SEC_PKCS7ContentInfo *cinfo) */ SEC_PKCS7ContentInfo * -SECMIME_CreateSigned (CERTCertificate *scert, - CERTCertificate *ecert, - CERTCertDBHandle *certdb, - SECOidTag digestalg, - SECItem *digest, - SECKEYGetPasswordKey pwfn, - void *pwfn_arg) +SECMIME_CreateSigned(CERTCertificate *scert, + CERTCertificate *ecert, + CERTCertDBHandle *certdb, + SECOidTag digestalg, + SECItem *digest, + SECKEYGetPasswordKey pwfn, + void *pwfn_arg) { SEC_PKCS7ContentInfo *cinfo; SECStatus rv; @@ -780,15 +758,15 @@ SECMIME_CreateSigned (CERTCertificate *scert, /* See note in header comment above about digestalg. */ /* Doesn't explain this. PORT_Assert (digestalg == SEC_OID_SHA1); */ - cinfo = SEC_PKCS7CreateSignedData (scert, certUsageEmailSigner, - certdb, digestalg, digest, - pwfn, pwfn_arg); + cinfo = SEC_PKCS7CreateSignedData(scert, certUsageEmailSigner, + certdb, digestalg, digest, + pwfn, pwfn_arg); if (cinfo == NULL) - return NULL; + return NULL; - if (SEC_PKCS7IncludeCertChain (cinfo, NULL) != SECSuccess) { - SEC_PKCS7DestroyContentInfo (cinfo); - return NULL; + if (SEC_PKCS7IncludeCertChain(cinfo, NULL) != SECSuccess) { + SEC_PKCS7DestroyContentInfo(cinfo); + return NULL; } /* if the encryption cert and the signing cert differ, then include @@ -797,26 +775,26 @@ SECMIME_CreateSigned (CERTCertificate *scert, /* it is ok to compare the pointers since we ref count, and the same * cert will always have the same pointer */ - if ( ( ecert != NULL ) && ( ecert != scert ) ) { - rv = SEC_PKCS7AddCertificate(cinfo, ecert); - if ( rv != SECSuccess ) { - SEC_PKCS7DestroyContentInfo (cinfo); - return NULL; - } + if ((ecert != NULL) && (ecert != scert)) { + rv = SEC_PKCS7AddCertificate(cinfo, ecert); + if (rv != SECSuccess) { + SEC_PKCS7DestroyContentInfo(cinfo); + return NULL; + } } /* * Add the signing time. But if it fails for some reason, * may as well not give up altogether -- just assert. */ - rv = SEC_PKCS7AddSigningTime (cinfo); - PORT_Assert (rv == SECSuccess); + rv = SEC_PKCS7AddSigningTime(cinfo); + PORT_Assert(rv == SECSuccess); /* * Add the email profile. Again, if it fails for some reason, * may as well not give up altogether -- just assert. */ - rv = smime_add_profile (ecert, cinfo); - PORT_Assert (rv == SECSuccess); + rv = smime_add_profile(ecert, cinfo); + PORT_Assert(rv == SECSuccess); return cinfo; } diff --git a/nss/lib/pkcs7/secmime.h b/nss/lib/pkcs7/secmime.h index a813d85..683cd8d 100644 --- a/nss/lib/pkcs7/secmime.h +++ b/nss/lib/pkcs7/secmime.h @@ -12,7 +12,6 @@ #include "secpkcs7.h" - /************************************************************************/ SEC_BEGIN_PROTOS @@ -117,10 +116,10 @@ extern PRBool SECMIME_EncryptionPossible(void); * (Retrieve specific errors via PORT_GetError()/XP_GetError().) */ extern SEC_PKCS7ContentInfo *SECMIME_CreateEncrypted(CERTCertificate *scert, - CERTCertificate **rcerts, - CERTCertDBHandle *certdb, - SECKEYGetPasswordKey pwfn, - void *pwfn_arg); + CERTCertificate **rcerts, + CERTCertDBHandle *certdb, + SECKEYGetPasswordKey pwfn, + void *pwfn_arg); /* * Start an S/MIME signing context. @@ -130,7 +129,7 @@ extern SEC_PKCS7ContentInfo *SECMIME_CreateEncrypted(CERTCertificate *scert, * * "certdb" is the cert database to use for verifying the cert. * It can be NULL if a default database is available (like in the client). - * + * * "digestalg" names the digest algorithm. (It should be SEC_OID_SHA1; * XXX There should be SECMIME functions for hashing, or the hashing should * be built into this interface, which we would like because we would @@ -148,12 +147,12 @@ extern SEC_PKCS7ContentInfo *SECMIME_CreateEncrypted(CERTCertificate *scert, * (Retrieve specific errors via PORT_GetError()/XP_GetError().) */ extern SEC_PKCS7ContentInfo *SECMIME_CreateSigned(CERTCertificate *scert, - CERTCertificate *ecert, - CERTCertDBHandle *certdb, - SECOidTag digestalg, - SECItem *digest, - SECKEYGetPasswordKey pwfn, - void *pwfn_arg); + CERTCertificate *ecert, + CERTCertDBHandle *certdb, + SECOidTag digestalg, + SECItem *digest, + SECKEYGetPasswordKey pwfn, + void *pwfn_arg); /************************************************************************/ SEC_END_PROTOS diff --git a/nss/lib/pkcs7/secpkcs7.h b/nss/lib/pkcs7/secpkcs7.h index 22f147a..d95c7d8 100644 --- a/nss/lib/pkcs7/secpkcs7.h +++ b/nss/lib/pkcs7/secpkcs7.h @@ -23,13 +23,13 @@ extern const SEC_ASN1Template sec_PKCS7ContentInfoTemplate[]; SEC_BEGIN_PROTOS /************************************************************************ - * Miscellaneous + * Miscellaneous ************************************************************************/ /* * Returns the content type of the given contentInfo. */ -extern SECOidTag SEC_PKCS7ContentType (SEC_PKCS7ContentInfo *cinfo); +extern SECOidTag SEC_PKCS7ContentType(SEC_PKCS7ContentInfo *cinfo); /* * Destroy a PKCS7 contentInfo and all of its sub-pieces. @@ -49,35 +49,34 @@ SEC_PKCS7CopyContentInfo(SEC_PKCS7ContentInfo *contentInfo); extern SECItem *SEC_PKCS7GetContent(SEC_PKCS7ContentInfo *cinfo); /************************************************************************ - * PKCS7 Decoding, Verification, etc.. + * PKCS7 Decoding, Verification, etc.. ************************************************************************/ extern SEC_PKCS7DecoderContext * SEC_PKCS7DecoderStart(SEC_PKCS7DecoderContentCallback callback, - void *callback_arg, - SECKEYGetPasswordKey pwfn, void *pwfn_arg, - SEC_PKCS7GetDecryptKeyCallback decrypt_key_cb, - void *decrypt_key_cb_arg, - SEC_PKCS7DecryptionAllowedCallback decrypt_allowed_cb); + void *callback_arg, + SECKEYGetPasswordKey pwfn, void *pwfn_arg, + SEC_PKCS7GetDecryptKeyCallback decrypt_key_cb, + void *decrypt_key_cb_arg, + SEC_PKCS7DecryptionAllowedCallback decrypt_allowed_cb); extern SECStatus SEC_PKCS7DecoderUpdate(SEC_PKCS7DecoderContext *p7dcx, - const char *buf, unsigned long len); + const char *buf, unsigned long len); extern SEC_PKCS7ContentInfo * SEC_PKCS7DecoderFinish(SEC_PKCS7DecoderContext *p7dcx); - /* Abort the underlying ASN.1 stream & set an error */ void SEC_PKCS7DecoderAbort(SEC_PKCS7DecoderContext *p7dcx, int error); extern SEC_PKCS7ContentInfo * SEC_PKCS7DecodeItem(SECItem *p7item, - SEC_PKCS7DecoderContentCallback cb, void *cb_arg, - SECKEYGetPasswordKey pwfn, void *pwfn_arg, - SEC_PKCS7GetDecryptKeyCallback decrypt_key_cb, - void *decrypt_key_cb_arg, - SEC_PKCS7DecryptionAllowedCallback decrypt_allowed_cb); + SEC_PKCS7DecoderContentCallback cb, void *cb_arg, + SECKEYGetPasswordKey pwfn, void *pwfn_arg, + SEC_PKCS7GetDecryptKeyCallback decrypt_key_cb, + void *decrypt_key_cb_arg, + SEC_PKCS7DecryptionAllowedCallback decrypt_allowed_cb); extern PRBool SEC_PKCS7ContainsCertsOrCrls(SEC_PKCS7ContentInfo *cinfo); @@ -87,8 +86,8 @@ extern PRBool SEC_PKCS7ContainsCertsOrCrls(SEC_PKCS7ContentInfo *cinfo); * minLen is used to specify a minimum size. if content size <= minLen, * content is assumed empty. */ -extern PRBool -SEC_PKCS7IsContentEmpty(SEC_PKCS7ContentInfo *cinfo, unsigned int minLen); +extern PRBool +SEC_PKCS7IsContentEmpty(SEC_PKCS7ContentInfo *cinfo, unsigned int minLen); extern PRBool SEC_PKCS7ContentIsEncrypted(SEC_PKCS7ContentInfo *cinfo); @@ -104,32 +103,32 @@ extern PRBool SEC_PKCS7ContentIsSigned(SEC_PKCS7ContentInfo *cinfo); /* * SEC_PKCS7VerifySignature - * Look at a PKCS7 contentInfo and check if the signature is good. - * The verification checks that the signing cert is valid and trusted - * for the purpose specified by "certusage". + * Look at a PKCS7 contentInfo and check if the signature is good. + * The verification checks that the signing cert is valid and trusted + * for the purpose specified by "certusage". * - * In addition, if "keepcerts" is true, add any new certificates found - * into our local database. + * In addition, if "keepcerts" is true, add any new certificates found + * into our local database. */ extern PRBool SEC_PKCS7VerifySignature(SEC_PKCS7ContentInfo *cinfo, - SECCertUsage certusage, - PRBool keepcerts); + SECCertUsage certusage, + PRBool keepcerts); /* * SEC_PKCS7VerifyDetachedSignature - * Look at a PKCS7 contentInfo and check if the signature matches - * a passed-in digest (calculated, supposedly, from detached contents). - * The verification checks that the signing cert is valid and trusted - * for the purpose specified by "certusage". + * Look at a PKCS7 contentInfo and check if the signature matches + * a passed-in digest (calculated, supposedly, from detached contents). + * The verification checks that the signing cert is valid and trusted + * for the purpose specified by "certusage". * - * In addition, if "keepcerts" is true, add any new certificates found - * into our local database. + * In addition, if "keepcerts" is true, add any new certificates found + * into our local database. */ extern PRBool SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo, - SECCertUsage certusage, - const SECItem *detached_digest, - HASH_HashType digest_type, - PRBool keepcerts); + SECCertUsage certusage, + const SECItem *detached_digest, + HASH_HashType digest_type, + PRBool keepcerts); /* * SEC_PKCS7VerifyDetachedSignatureAtTime @@ -138,16 +137,16 @@ extern PRBool SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo, * The verification checks that the signing cert is valid and trusted * for the purpose specified by "certusage" at time "atTime". * - * In addition, if "keepcerts" is true, add any new certificates found - * into our local database. + * In addition, if "keepcerts" is true, add any new certificates found + * into our local database. */ extern PRBool SEC_PKCS7VerifyDetachedSignatureAtTime(SEC_PKCS7ContentInfo *cinfo, - SECCertUsage certusage, - const SECItem *detached_digest, - HASH_HashType digest_type, - PRBool keepcerts, - PRTime atTime); + SECCertUsage certusage, + const SECItem *detached_digest, + HASH_HashType digest_type, + PRBool keepcerts, + PRTime atTime); /* * SEC_PKCS7GetSignerCommonName, SEC_PKCS7GetSignerEmailAddress @@ -165,9 +164,8 @@ extern char *SEC_PKCS7GetSignerEmailAddress(SEC_PKCS7ContentInfo *cinfo); */ extern SECItem *SEC_PKCS7GetSigningTime(SEC_PKCS7ContentInfo *cinfo); - /************************************************************************ - * PKCS7 Creation and Encoding. + * PKCS7 Creation and Encoding. ************************************************************************/ /* @@ -184,7 +182,7 @@ extern SECItem *SEC_PKCS7GetSigningTime(SEC_PKCS7ContentInfo *cinfo); * * "certdb" is the cert database to use for verifying the cert. * It can be NULL if a default database is available (like in the client). - * + * * "digestalg" names the digest algorithm (e.g. SEC_OID_SHA1). * * "digest" is the actual digest of the data. It must be provided in @@ -199,12 +197,12 @@ extern SECItem *SEC_PKCS7GetSigningTime(SEC_PKCS7ContentInfo *cinfo); * (Retrieve specific errors via PORT_GetError()/XP_GetError().) */ extern SEC_PKCS7ContentInfo * -SEC_PKCS7CreateSignedData (CERTCertificate *cert, - SECCertUsage certusage, - CERTCertDBHandle *certdb, - SECOidTag digestalg, - SECItem *digest, - SECKEYGetPasswordKey pwfn, void *pwfn_arg); +SEC_PKCS7CreateSignedData(CERTCertificate *cert, + SECCertUsage certusage, + CERTCertDBHandle *certdb, + SECOidTag digestalg, + SECItem *digest, + SECKEYGetPasswordKey pwfn, void *pwfn_arg); /* * Create a PKCS7 certs-only container. @@ -224,9 +222,9 @@ SEC_PKCS7CreateSignedData (CERTCertificate *cert, * (Retrieve specific errors via PORT_GetError()/XP_GetError().) */ extern SEC_PKCS7ContentInfo * -SEC_PKCS7CreateCertsOnly (CERTCertificate *cert, - PRBool include_chain, - CERTCertDBHandle *certdb); +SEC_PKCS7CreateCertsOnly(CERTCertificate *cert, + PRBool include_chain, + CERTCertDBHandle *certdb); /* * Start a PKCS7 enveloping context. @@ -255,12 +253,12 @@ SEC_PKCS7CreateCertsOnly (CERTCertificate *cert, * (Retrieve specific errors via PORT_GetError()/XP_GetError().) */ extern SEC_PKCS7ContentInfo * -SEC_PKCS7CreateEnvelopedData (CERTCertificate *cert, - SECCertUsage certusage, - CERTCertDBHandle *certdb, - SECOidTag encalg, - int keysize, - SECKEYGetPasswordKey pwfn, void *pwfn_arg); +SEC_PKCS7CreateEnvelopedData(CERTCertificate *cert, + SECCertUsage certusage, + CERTCertDBHandle *certdb, + SECOidTag encalg, + int keysize, + SECKEYGetPasswordKey pwfn, void *pwfn_arg); /* * XXX There will be a similar routine for creating signedAndEnvelopedData. @@ -274,19 +272,19 @@ SEC_PKCS7CreateEnvelopedData (CERTCertificate *cert, * An error results in a return value of NULL and an error set. * (Retrieve specific errors via PORT_GetError()/XP_GetError().) */ -extern SEC_PKCS7ContentInfo *SEC_PKCS7CreateData (void); +extern SEC_PKCS7ContentInfo *SEC_PKCS7CreateData(void); /* * Create an empty PKCS7 encrypted content info. * * "algorithm" specifies the bulk encryption algorithm to use. - * + * * An error results in a return value of NULL and an error set. * (Retrieve specific errors via PORT_GetError()/XP_GetError().) */ extern SEC_PKCS7ContentInfo * -SEC_PKCS7CreateEncryptedData (SECOidTag algorithm, int keysize, - SECKEYGetPasswordKey pwfn, void *pwfn_arg); +SEC_PKCS7CreateEncryptedData(SECOidTag algorithm, int keysize, + SECKEYGetPasswordKey pwfn, void *pwfn_arg); /* * All of the following things return SECStatus to signal success or failure. @@ -312,9 +310,9 @@ SEC_PKCS7CreateEncryptedData (SECOidTag algorithm, int keysize, * that is allowed authenticated attributes); SECFailure will be returned * if it is not. */ -extern SECStatus SEC_PKCS7AddSignedAttribute (SEC_PKCS7ContentInfo *cinfo, - SECOidTag oidtag, - SECItem *value); +extern SECStatus SEC_PKCS7AddSignedAttribute(SEC_PKCS7ContentInfo *cinfo, + SECOidTag oidtag, + SECItem *value); /* * Add "cert" and its entire chain to the set of certs included in "cinfo". @@ -325,9 +323,9 @@ extern SECStatus SEC_PKCS7AddSignedAttribute (SEC_PKCS7ContentInfo *cinfo, * "cinfo" should be of type signedData or signedAndEnvelopedData; * SECFailure will be returned if it is not. */ -extern SECStatus SEC_PKCS7AddCertChain (SEC_PKCS7ContentInfo *cinfo, - CERTCertificate *cert, - CERTCertDBHandle *certdb); +extern SECStatus SEC_PKCS7AddCertChain(SEC_PKCS7ContentInfo *cinfo, + CERTCertificate *cert, + CERTCertDBHandle *certdb); /* * Add "cert" to the set of certs included in "cinfo". @@ -335,8 +333,8 @@ extern SECStatus SEC_PKCS7AddCertChain (SEC_PKCS7ContentInfo *cinfo, * "cinfo" should be of type signedData or signedAndEnvelopedData; * SECFailure will be returned if it is not. */ -extern SECStatus SEC_PKCS7AddCertificate (SEC_PKCS7ContentInfo *cinfo, - CERTCertificate *cert); +extern SECStatus SEC_PKCS7AddCertificate(SEC_PKCS7ContentInfo *cinfo, + CERTCertificate *cert); /* * Add another recipient to an encrypted message. @@ -355,10 +353,10 @@ extern SECStatus SEC_PKCS7AddCertificate (SEC_PKCS7ContentInfo *cinfo, * "certdb" is the cert database to use for verifying the cert. * It can be NULL if a default database is available (like in the client). */ -extern SECStatus SEC_PKCS7AddRecipient (SEC_PKCS7ContentInfo *cinfo, - CERTCertificate *cert, - SECCertUsage certusage, - CERTCertDBHandle *certdb); +extern SECStatus SEC_PKCS7AddRecipient(SEC_PKCS7ContentInfo *cinfo, + CERTCertificate *cert, + SECCertUsage certusage, + CERTCertDBHandle *certdb); /* * Add the signing time to the authenticated (i.e. signed) attributes @@ -376,7 +374,7 @@ extern SECStatus SEC_PKCS7AddRecipient (SEC_PKCS7ContentInfo *cinfo, * that is allowed authenticated attributes); SECFailure will be returned * if it is not. */ -extern SECStatus SEC_PKCS7AddSigningTime (SEC_PKCS7ContentInfo *cinfo); +extern SECStatus SEC_PKCS7AddSigningTime(SEC_PKCS7ContentInfo *cinfo); /* * Add the signer's symmetric capabilities to the authenticated @@ -401,9 +399,8 @@ extern SECStatus SEC_PKCS7AddSymmetricCapabilities(SEC_PKCS7ContentInfo *cinfo); * "cinfo" should be of type signedData or signedAndEnvelopedData; * SECFailure will be returned if it is not. */ -extern SECStatus SEC_PKCS7IncludeCertChain (SEC_PKCS7ContentInfo *cinfo, - CERTCertDBHandle *certdb); - +extern SECStatus SEC_PKCS7IncludeCertChain(SEC_PKCS7ContentInfo *cinfo, + CERTCertDBHandle *certdb); /* * Set the content; it will be included and also hashed and/or encrypted @@ -413,8 +410,8 @@ extern SECStatus SEC_PKCS7IncludeCertChain (SEC_PKCS7ContentInfo *cinfo, * * "buf" points to data of length "len"; it will be copied. */ -extern SECStatus SEC_PKCS7SetContent (SEC_PKCS7ContentInfo *cinfo, - const char *buf, unsigned long len); +extern SECStatus SEC_PKCS7SetContent(SEC_PKCS7ContentInfo *cinfo, + const char *buf, unsigned long len); /* * Encode a PKCS7 object, in one shot. All necessary components @@ -439,12 +436,12 @@ extern SECStatus SEC_PKCS7SetContent (SEC_PKCS7ContentInfo *cinfo, * * "pwfnarg" is an opaque argument to the above callback. */ -extern SECStatus SEC_PKCS7Encode (SEC_PKCS7ContentInfo *cinfo, - SEC_PKCS7EncoderOutputCallback outputfn, - void *outputarg, - PK11SymKey *bulkkey, - SECKEYGetPasswordKey pwfn, - void *pwfnarg); +extern SECStatus SEC_PKCS7Encode(SEC_PKCS7ContentInfo *cinfo, + SEC_PKCS7EncoderOutputCallback outputfn, + void *outputarg, + PK11SymKey *bulkkey, + SECKEYGetPasswordKey pwfn, + void *pwfnarg); /* * Encode a PKCS7 object, in one shot. All necessary components @@ -473,12 +470,12 @@ extern SECStatus SEC_PKCS7Encode (SEC_PKCS7ContentInfo *cinfo, * * "pwfnarg" is an opaque argument to the above callback. */ -extern SECItem *SEC_PKCS7EncodeItem (PLArenaPool *pool, - SECItem *dest, - SEC_PKCS7ContentInfo *cinfo, - PK11SymKey *bulkkey, - SECKEYGetPasswordKey pwfn, - void *pwfnarg); +extern SECItem *SEC_PKCS7EncodeItem(PLArenaPool *pool, + SECItem *dest, + SEC_PKCS7ContentInfo *cinfo, + PK11SymKey *bulkkey, + SECKEYGetPasswordKey pwfn, + void *pwfnarg); /* * For those who want to simply point to the pkcs7 contentInfo ASN.1 @@ -486,10 +483,10 @@ extern SECItem *SEC_PKCS7EncodeItem (PLArenaPool *pool, * following function can be used -- after it is called, the entire * PKCS7 contentInfo is ready to be encoded. */ -extern SECStatus SEC_PKCS7PrepareForEncode (SEC_PKCS7ContentInfo *cinfo, - PK11SymKey *bulkkey, - SECKEYGetPasswordKey pwfn, - void *pwfnarg); +extern SECStatus SEC_PKCS7PrepareForEncode(SEC_PKCS7ContentInfo *cinfo, + PK11SymKey *bulkkey, + SECKEYGetPasswordKey pwfn, + void *pwfnarg); /* * Start the process of encoding a PKCS7 object. The first part of @@ -512,17 +509,17 @@ extern SECStatus SEC_PKCS7PrepareForEncode (SEC_PKCS7ContentInfo *cinfo, * Returns an object to be passed to EncoderUpdate and EncoderFinish. */ extern SEC_PKCS7EncoderContext * -SEC_PKCS7EncoderStart (SEC_PKCS7ContentInfo *cinfo, - SEC_PKCS7EncoderOutputCallback outputfn, - void *outputarg, - PK11SymKey *bulkkey); +SEC_PKCS7EncoderStart(SEC_PKCS7ContentInfo *cinfo, + SEC_PKCS7EncoderOutputCallback outputfn, + void *outputarg, + PK11SymKey *bulkkey); /* * Encode more contents, hashing and/or encrypting along the way. */ -extern SECStatus SEC_PKCS7EncoderUpdate (SEC_PKCS7EncoderContext *p7ecx, - const char *buf, - unsigned long len); +extern SECStatus SEC_PKCS7EncoderUpdate(SEC_PKCS7EncoderContext *p7ecx, + const char *buf, + unsigned long len); /* * No more contents; finish the signature creation, if appropriate, @@ -534,9 +531,9 @@ extern SECStatus SEC_PKCS7EncoderUpdate (SEC_PKCS7EncoderContext *p7ecx, * * "pwfnarg" is an opaque argument to the above callback. */ -extern SECStatus SEC_PKCS7EncoderFinish (SEC_PKCS7EncoderContext *p7ecx, - SECKEYGetPasswordKey pwfn, - void *pwfnarg); +extern SECStatus SEC_PKCS7EncoderFinish(SEC_PKCS7EncoderContext *p7ecx, + SECKEYGetPasswordKey pwfn, + void *pwfnarg); /* Abort the underlying ASN.1 stream & set an error */ void SEC_PKCS7EncoderAbort(SEC_PKCS7EncoderContext *p7dcx, int error); @@ -545,9 +542,9 @@ void SEC_PKCS7EncoderAbort(SEC_PKCS7EncoderContext *p7dcx, int error); * for encrypted and enveloped data. The SECAlgorithmID pointer * returned needs to be freed as it is a copy of the algorithm * id in the content info. - */ + */ extern SECAlgorithmID * -SEC_PKCS7GetEncryptionAlgorithm(SEC_PKCS7ContentInfo *cinfo); +SEC_PKCS7GetEncryptionAlgorithm(SEC_PKCS7ContentInfo *cinfo); /* the content of an encrypted data content info is encrypted. * it is assumed that for encrypted data, that the data has already @@ -559,16 +556,16 @@ SEC_PKCS7GetEncryptionAlgorithm(SEC_PKCS7ContentInfo *cinfo); * algorithm is a password based encryption algorithm, the * key is actually a password which will be processed per * PKCS #5. - * + * * in the event of an error, SECFailure is returned. SECSuccess * indicates a success. */ -extern SECStatus +extern SECStatus SEC_PKCS7EncryptContents(PLArenaPool *poolp, - SEC_PKCS7ContentInfo *cinfo, - SECItem *key, - void *wincx); - + SEC_PKCS7ContentInfo *cinfo, + SECItem *key, + void *wincx); + /* the content of an encrypted data content info is decrypted. * it is assumed that for encrypted data, that the data has already * been set and is in the "encContent" field of the content info. @@ -579,19 +576,19 @@ SEC_PKCS7EncryptContents(PLArenaPool *poolp, * algorithm is a password based encryption algorithm, the * key is actually a password which will be processed per * PKCS #5. - * + * * in the event of an error, SECFailure is returned. SECSuccess * indicates a success. */ -extern SECStatus +extern SECStatus SEC_PKCS7DecryptContents(PLArenaPool *poolp, - SEC_PKCS7ContentInfo *cinfo, - SECItem *key, - void *wincx); + SEC_PKCS7ContentInfo *cinfo, + SECItem *key, + void *wincx); /* retrieve the certificate list from the content info. the list * is a pointer to the list in the content info. this should not - * be deleted or freed in any way short of calling + * be deleted or freed in any way short of calling * SEC_PKCS7DestroyContentInfo */ extern SECItem ** @@ -600,9 +597,8 @@ SEC_PKCS7GetCertificateList(SEC_PKCS7ContentInfo *cinfo); /* Returns the key length (in bits) of the algorithm used to encrypt this object. Returns 0 if it's not encrypted, or the key length is irrelevant. */ -extern int +extern int SEC_PKCS7GetKeyLength(SEC_PKCS7ContentInfo *cinfo); - /************************************************************************/ SEC_END_PROTOS |