123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- /* 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/. */
- #include "secdig.h"
- #include "secoid.h"
- #include "secasn1.h"
- #include "secerr.h"
- /*
- * XXX Want to have a SGN_DecodeDigestInfo, like:
- * SGNDigestInfo *SGN_DecodeDigestInfo(SECItem *didata);
- * that creates a pool and allocates from it and decodes didata into
- * the newly allocated DigestInfo structure. Then fix secvfy.c (it
- * will no longer need an arena itself) to call this and then call
- * DestroyDigestInfo when it is done, then can remove the old template
- * above and keep our new template static and "hidden".
- */
- /*
- * XXX It might be nice to combine the following two functions (create
- * and encode). I think that is all anybody ever wants to do anyway.
- */
- SECItem *
- SGN_EncodeDigestInfo(PLArenaPool *poolp, SECItem *dest, SGNDigestInfo *diginfo)
- {
- return SEC_ASN1EncodeItem(poolp, dest, diginfo, sgn_DigestInfoTemplate);
- }
- SGNDigestInfo *
- SGN_CreateDigestInfo(SECOidTag algorithm, const unsigned char *sig,
- unsigned len)
- {
- SGNDigestInfo *di;
- SECStatus rv;
- PLArenaPool *arena;
- SECItem *null_param;
- SECItem dummy_value;
- switch (algorithm) {
- case SEC_OID_MD2:
- case SEC_OID_MD5:
- case SEC_OID_SHA1:
- case SEC_OID_SHA224:
- case SEC_OID_SHA256:
- case SEC_OID_SHA384:
- case SEC_OID_SHA512:
- break;
- default:
- PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
- return NULL;
- }
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) {
- return NULL;
- }
- di = (SGNDigestInfo *)PORT_ArenaZAlloc(arena, sizeof(SGNDigestInfo));
- if (di == NULL) {
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
- }
- di->arena = arena;
- /*
- * PKCS #1 specifies that the AlgorithmID must have a NULL parameter
- * (as opposed to no parameter at all).
- */
- dummy_value.data = NULL;
- dummy_value.len = 0;
- null_param = SEC_ASN1EncodeItem(NULL, NULL, &dummy_value, SEC_NullTemplate);
- if (null_param == NULL) {
- goto loser;
- }
- rv = SECOID_SetAlgorithmID(arena, &di->digestAlgorithm, algorithm,
- null_param);
- SECITEM_FreeItem(null_param, PR_TRUE);
- if (rv != SECSuccess) {
- goto loser;
- }
- di->digest.data = (unsigned char *)PORT_ArenaAlloc(arena, len);
- if (di->digest.data == NULL) {
- goto loser;
- }
- di->digest.len = len;
- PORT_Memcpy(di->digest.data, sig, len);
- return di;
- loser:
- SGN_DestroyDigestInfo(di);
- return NULL;
- }
- SGNDigestInfo *
- SGN_DecodeDigestInfo(SECItem *didata)
- {
- PLArenaPool *arena;
- SGNDigestInfo *di;
- SECStatus rv = SECFailure;
- SECItem diCopy = { siBuffer, NULL, 0 };
- arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if (arena == NULL)
- return NULL;
- rv = SECITEM_CopyItem(arena, &diCopy, didata);
- if (rv != SECSuccess) {
- PORT_FreeArena(arena, PR_FALSE);
- return NULL;
- }
- di = (SGNDigestInfo *)PORT_ArenaZAlloc(arena, sizeof(SGNDigestInfo));
- if (di != NULL) {
- di->arena = arena;
- rv = SEC_QuickDERDecodeItem(arena, di, sgn_DigestInfoTemplate, &diCopy);
- }
- if ((di == NULL) || (rv != SECSuccess)) {
- PORT_FreeArena(arena, PR_FALSE);
- di = NULL;
- }
- return di;
- }
- void
- SGN_DestroyDigestInfo(SGNDigestInfo *di)
- {
- if (di && di->arena) {
- PORT_FreeArena(di->arena, PR_FALSE);
- }
- return;
- }
- SECStatus
- SGN_CopyDigestInfo(PLArenaPool *poolp, SGNDigestInfo *a, SGNDigestInfo *b)
- {
- SECStatus rv;
- void *mark;
- if ((poolp == NULL) || (a == NULL) || (b == NULL))
- return SECFailure;
- mark = PORT_ArenaMark(poolp);
- a->arena = poolp;
- rv = SECOID_CopyAlgorithmID(poolp, &a->digestAlgorithm,
- &b->digestAlgorithm);
- if (rv == SECSuccess)
- rv = SECITEM_CopyItem(poolp, &a->digest, &b->digest);
- if (rv != SECSuccess) {
- PORT_ArenaRelease(poolp, mark);
- } else {
- PORT_ArenaUnmark(poolp, mark);
- }
- return rv;
- }
- SECComparison
- SGN_CompareDigestInfo(SGNDigestInfo *a, SGNDigestInfo *b)
- {
- SECComparison rv;
- /* Check signature algorithm's */
- rv = SECOID_CompareAlgorithmID(&a->digestAlgorithm, &b->digestAlgorithm);
- if (rv)
- return rv;
- /* Compare signature block length's */
- rv = SECITEM_CompareItem(&a->digest, &b->digest);
- return rv;
- }
|