mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-14 11:40:13 +01:00
213 lines
5.8 KiB
C
213 lines
5.8 KiB
C
|
/* ***** BEGIN LICENSE BLOCK *****
|
||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||
|
*
|
||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||
|
* the License. You may obtain a copy of the License at
|
||
|
* http://www.mozilla.org/MPL/
|
||
|
*
|
||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||
|
* for the specific language governing rights and limitations under the
|
||
|
* License.
|
||
|
*
|
||
|
* The Original Code is the Netscape security libraries.
|
||
|
*
|
||
|
* The Initial Developer of the Original Code is
|
||
|
* Netscape Communications Corporation.
|
||
|
* Portions created by the Initial Developer are Copyright (C) 1994-2000
|
||
|
* the Initial Developer. All Rights Reserved.
|
||
|
*
|
||
|
* Contributor(s):
|
||
|
*
|
||
|
* Alternatively, the contents of this file may be used under the terms of
|
||
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||
|
* of those above. If you wish to allow use of your version of this file only
|
||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||
|
* use your version of this file under the terms of the MPL, indicate your
|
||
|
* decision by deleting the provisions above and replace them with the notice
|
||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||
|
* the provisions above, a recipient may use your version of this file under
|
||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||
|
*
|
||
|
* ***** END LICENSE BLOCK ***** */
|
||
|
/* $Id: secdig.c,v 1.9 2007/11/07 02:37:22 julien.pierre.boogz%sun.com Exp $ */
|
||
|
#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(PRArenaPool *poolp, SECItem *dest, SGNDigestInfo *diginfo)
|
||
|
{
|
||
|
return SEC_ASN1EncodeItem (poolp, dest, diginfo, sgn_DigestInfoTemplate);
|
||
|
}
|
||
|
|
||
|
SGNDigestInfo *
|
||
|
SGN_CreateDigestInfo(SECOidTag algorithm, unsigned char *sig, unsigned len)
|
||
|
{
|
||
|
SGNDigestInfo *di;
|
||
|
SECStatus rv;
|
||
|
PRArenaPool *arena;
|
||
|
SECItem *null_param;
|
||
|
SECItem dummy_value;
|
||
|
|
||
|
switch (algorithm) {
|
||
|
case SEC_OID_MD2:
|
||
|
case SEC_OID_MD5:
|
||
|
case SEC_OID_SHA1:
|
||
|
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)
|
||
|
{
|
||
|
PRArenaPool *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(PRArenaPool *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;
|
||
|
}
|