security/nss/lib/util/secdig.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     4 #include "secdig.h"
     6 #include "secoid.h"
     7 #include "secasn1.h" 
     8 #include "secerr.h"
    10 /*
    11  * XXX Want to have a SGN_DecodeDigestInfo, like:
    12  *	SGNDigestInfo *SGN_DecodeDigestInfo(SECItem *didata);
    13  * that creates a pool and allocates from it and decodes didata into
    14  * the newly allocated DigestInfo structure.  Then fix secvfy.c (it
    15  * will no longer need an arena itself) to call this and then call
    16  * DestroyDigestInfo when it is done, then can remove the old template
    17  * above and keep our new template static and "hidden".
    18  */
    20 /*
    21  * XXX It might be nice to combine the following two functions (create
    22  * and encode).  I think that is all anybody ever wants to do anyway.
    23  */
    25 SECItem *
    26 SGN_EncodeDigestInfo(PLArenaPool *poolp, SECItem *dest, SGNDigestInfo *diginfo)
    27 {
    28     return SEC_ASN1EncodeItem (poolp, dest, diginfo, sgn_DigestInfoTemplate);
    29 }
    31 SGNDigestInfo *
    32 SGN_CreateDigestInfo(SECOidTag algorithm, const unsigned char *sig,
    33                      unsigned len)
    34 {
    35     SGNDigestInfo *di;
    36     SECStatus rv;
    37     PLArenaPool *arena;
    38     SECItem *null_param;
    39     SECItem dummy_value;
    41     switch (algorithm) {
    42       case SEC_OID_MD2:
    43       case SEC_OID_MD5:
    44       case SEC_OID_SHA1:
    45       case SEC_OID_SHA224:
    46       case SEC_OID_SHA256:
    47       case SEC_OID_SHA384:
    48       case SEC_OID_SHA512:
    49 	break;
    50       default:
    51 	PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
    52 	return NULL;
    53     }
    55     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    56     if (arena == NULL) {
    57 	return NULL;
    58     }
    60     di = (SGNDigestInfo *) PORT_ArenaZAlloc(arena, sizeof(SGNDigestInfo));
    61     if (di == NULL) {
    62 	PORT_FreeArena(arena, PR_FALSE);
    63 	return NULL;
    64     }
    66     di->arena = arena;
    68     /*
    69      * PKCS #1 specifies that the AlgorithmID must have a NULL parameter
    70      * (as opposed to no parameter at all).
    71      */
    72     dummy_value.data = NULL;
    73     dummy_value.len = 0;
    74     null_param = SEC_ASN1EncodeItem(NULL, NULL, &dummy_value, SEC_NullTemplate);
    75     if (null_param == NULL) {
    76 	goto loser;
    77     }
    79     rv = SECOID_SetAlgorithmID(arena, &di->digestAlgorithm, algorithm,
    80 			       null_param);
    82     SECITEM_FreeItem(null_param, PR_TRUE);
    84     if (rv != SECSuccess) {
    85 	goto loser;
    86     }
    88     di->digest.data = (unsigned char *) PORT_ArenaAlloc(arena, len);
    89     if (di->digest.data == NULL) {
    90 	goto loser;
    91     }
    93     di->digest.len = len;
    94     PORT_Memcpy(di->digest.data, sig, len);
    95     return di;
    97   loser:
    98     SGN_DestroyDigestInfo(di);
    99     return NULL;
   100 }
   102 SGNDigestInfo *
   103 SGN_DecodeDigestInfo(SECItem *didata)
   104 {
   105     PLArenaPool *arena;
   106     SGNDigestInfo *di;
   107     SECStatus rv = SECFailure;
   108     SECItem      diCopy   = {siBuffer, NULL, 0};
   110     arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
   111     if(arena == NULL)
   112 	return NULL;
   114     rv = SECITEM_CopyItem(arena, &diCopy, didata);
   115     if (rv != SECSuccess) {
   116 	PORT_FreeArena(arena, PR_FALSE);
   117     	return NULL;
   118     }
   120     di = (SGNDigestInfo *)PORT_ArenaZAlloc(arena, sizeof(SGNDigestInfo));
   121     if (di != NULL) {
   122 	di->arena = arena;
   123 	rv = SEC_QuickDERDecodeItem(arena, di, sgn_DigestInfoTemplate, &diCopy);
   124     }
   126     if ((di == NULL) || (rv != SECSuccess)) {
   127 	PORT_FreeArena(arena, PR_FALSE);
   128 	di = NULL;
   129     }
   131     return di;
   132 }
   134 void
   135 SGN_DestroyDigestInfo(SGNDigestInfo *di)
   136 {
   137     if (di && di->arena) {
   138 	PORT_FreeArena(di->arena, PR_FALSE);
   139     }
   141     return;
   142 }
   144 SECStatus 
   145 SGN_CopyDigestInfo(PLArenaPool *poolp, SGNDigestInfo *a, SGNDigestInfo *b)
   146 {
   147     SECStatus rv;
   148     void *mark;
   150     if((poolp == NULL) || (a == NULL) || (b == NULL))
   151 	return SECFailure;
   153     mark = PORT_ArenaMark(poolp);
   154     a->arena = poolp;
   155     rv = SECOID_CopyAlgorithmID(poolp, &a->digestAlgorithm, 
   156 	&b->digestAlgorithm);
   157     if (rv == SECSuccess)
   158 	rv = SECITEM_CopyItem(poolp, &a->digest, &b->digest);
   160     if (rv != SECSuccess) {
   161 	PORT_ArenaRelease(poolp, mark);
   162     } else {
   163 	PORT_ArenaUnmark(poolp, mark);
   164     }
   166     return rv;
   167 }
   169 SECComparison
   170 SGN_CompareDigestInfo(SGNDigestInfo *a, SGNDigestInfo *b)
   171 {
   172     SECComparison rv;
   174     /* Check signature algorithm's */
   175     rv = SECOID_CompareAlgorithmID(&a->digestAlgorithm, &b->digestAlgorithm);
   176     if (rv) return rv;
   178     /* Compare signature block length's */
   179     rv = SECITEM_CompareItem(&a->digest, &b->digest);
   180     return rv;
   181 }

mercurial