cmmfchal.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 323 行
C
323 行
/* -*- Mode: C; tab-width: 8 -*-*//* * 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 Netscape are * Copyright (C) 1994-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#include "cmmf.h"#include "cmmfi.h"#include "sechash.h"#include "genname.h"#include "pk11func.h"#include "cert.h"#include "secitem.h"#include "secmod.h"#include "secmodi.h"#include "keyhi.h"static SECStatuscmmf_create_witness_and_challenge(PRArenaPool *poolp, CMMFChallenge *challenge, long inRandom, SECItem *senderDER, SECKEYPublicKey *inPubKey, void *passwdArg){ SECItem *encodedRandNum; SECItem encodedRandStr = {siBuffer, NULL, 0}; SECItem encryptBlock = {siBuffer, NULL, 0}; SECItem *dummy; unsigned char *randHash, *senderHash, *encChal=NULL; unsigned modulusLen = 0; SECStatus rv = SECFailure; CMMFRand randStr= { {siBuffer, NULL, 0}, {siBuffer, NULL, 0}}; PK11SlotInfo *slot; PK11SymKey *symKey = NULL; CK_OBJECT_HANDLE id; CERTSubjectPublicKeyInfo *spki = NULL; encodedRandNum = SEC_ASN1EncodeInteger(poolp, &challenge->randomNumber, inRandom); encodedRandNum = &challenge->randomNumber; randHash = PORT_ArenaNewArray(poolp, unsigned char, SHA1_LENGTH); senderHash = PORT_ArenaNewArray(poolp, unsigned char, SHA1_LENGTH); if (randHash == NULL) { goto loser; } rv = PK11_HashBuf(SEC_OID_SHA1, randHash, encodedRandNum->data, (uint32)encodedRandNum->len); if (rv != SECSuccess) { goto loser; } rv = PK11_HashBuf(SEC_OID_SHA1, senderHash, senderDER->data, (uint32)senderDER->len); if (rv != SECSuccess) { goto loser; } challenge->witness.data = randHash; challenge->witness.len = SHA1_LENGTH; randStr.integer = *encodedRandNum; randStr.senderHash.data = senderHash; randStr.senderHash.len = SHA1_LENGTH; dummy = SEC_ASN1EncodeItem(NULL, &encodedRandStr, &randStr, CMMFRandTemplate); if (dummy != &encodedRandStr) { rv = SECFailure; goto loser; } /* XXXX Now I have to encrypt encodedRandStr and stash it away. */ modulusLen = SECKEY_PublicKeyStrength(inPubKey); encChal = PORT_ArenaNewArray(poolp, unsigned char, modulusLen); if (encChal == NULL) { rv = SECFailure; goto loser; } slot =PK11_GetBestSlot(CKM_RSA_PKCS, passwdArg); if (slot == NULL) { rv = SECFailure; goto loser; } id = PK11_ImportPublicKey(slot, inPubKey, PR_FALSE); /* In order to properly encrypt the data, we import as a symmetric * key, and then wrap that key. That in essence encrypts the data. * This is the method recommended in the PK11 world in order * to prevent threading issues as well as breaking any other semantics * the PK11 libraries depend on. */ symKey = PK11_ImportSymKey(slot, CKM_RSA_PKCS, PK11_OriginGenerated, CKA_VALUE, &encodedRandStr, passwdArg); if (symKey == NULL) { rv = SECFailure; goto loser; } challenge->challenge.data = encChal; challenge->challenge.len = modulusLen; rv = PK11_PubWrapSymKey(CKM_RSA_PKCS, inPubKey, symKey, &challenge->challenge); PK11_FreeSlot(slot); if (rv != SECSuccess) { goto loser; } rv = SECITEM_CopyItem(poolp, &challenge->senderDER, senderDER); crmf_get_public_value(inPubKey, &challenge->key); /* Fall through */ loser: if (spki != NULL) { SECKEY_DestroySubjectPublicKeyInfo(spki); } if (encodedRandStr.data != NULL) { PORT_Free(encodedRandStr.data); } if (encodedRandNum != NULL) { SECITEM_FreeItem(encodedRandNum, PR_TRUE); } if (symKey != NULL) { PK11_FreeSymKey(symKey); } return rv;}static SECStatuscmmf_create_first_challenge(CMMFPOPODecKeyChallContent *challContent, long inRandom, SECItem *senderDER, SECKEYPublicKey *inPubKey, void *passwdArg){ SECOidData *oidData; CMMFChallenge *challenge; SECAlgorithmID *algId; PRArenaPool *poolp; SECStatus rv; oidData = SECOID_FindOIDByTag(SEC_OID_SHA1); if (oidData == NULL) { return SECFailure; } poolp = challContent->poolp; challenge = PORT_ArenaZNew(poolp, CMMFChallenge); if (challenge == NULL) { return SECFailure; } algId = challenge->owf = PORT_ArenaZNew(poolp, SECAlgorithmID); if (algId == NULL) { return SECFailure; } rv = SECITEM_CopyItem(poolp, &algId->algorithm, &oidData->oid); if (rv != SECSuccess) { return SECFailure; } rv = cmmf_create_witness_and_challenge(poolp, challenge, inRandom, senderDER, inPubKey, passwdArg); challContent->challenges[0] = (rv == SECSuccess) ? challenge : NULL; challContent->numChallenges++; return rv ;}CMMFPOPODecKeyChallContent*CMMF_CreatePOPODecKeyChallContent (void){ PRArenaPool *poolp; CMMFPOPODecKeyChallContent *challContent; poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE); if (poolp == NULL) { return NULL; } challContent = PORT_ArenaZNew(poolp, CMMFPOPODecKeyChallContent); if (challContent == NULL) { PORT_FreeArena(poolp, PR_FALSE); return NULL; } challContent->poolp = poolp; return challContent;}SECStatusCMMF_POPODecKeyChallContentSetNextChallenge (CMMFPOPODecKeyChallContent *inDecKeyChall, long inRandom, CERTGeneralName *inSender, SECKEYPublicKey *inPubKey, void *passwdArg){ CMMFChallenge *curChallenge; PRArenaPool *genNamePool = NULL, *poolp; SECStatus rv; SECItem *genNameDER; void *mark; SECItem senderDER = {siBuffer, NULL, 0}; PORT_Assert (inDecKeyChall != NULL && inSender != NULL && inPubKey != NULL); if (inDecKeyChall == NULL || inSender == NULL || inPubKey == NULL) { return SECFailure; } poolp = inDecKeyChall->poolp; mark = PORT_ArenaMark(poolp); genNamePool = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE); genNameDER = cert_EncodeGeneralName(inSender, NULL, genNamePool); if (genNameDER == NULL) { rv = SECFailure; goto loser; } if (inDecKeyChall->challenges == NULL) { inDecKeyChall->challenges = PORT_ArenaZNewArray(poolp, CMMFChallenge*,(CMMF_MAX_CHALLENGES+1)); inDecKeyChall->numAllocated = CMMF_MAX_CHALLENGES; } if (inDecKeyChall->numChallenges >= inDecKeyChall->numAllocated) { rv = SECFailure; goto loser; } if (inDecKeyChall->numChallenges == 0) { rv = cmmf_create_first_challenge(inDecKeyChall, inRandom, genNameDER, inPubKey, passwdArg); } else { curChallenge = PORT_ArenaZNew(poolp, CMMFChallenge); if (curChallenge == NULL) { rv = SECFailure; goto loser; } rv = cmmf_create_witness_and_challenge(poolp, curChallenge, inRandom, genNameDER, inPubKey, passwdArg); if (rv == SECSuccess) { inDecKeyChall->challenges[inDecKeyChall->numChallenges] = curChallenge; inDecKeyChall->numChallenges++; } } if (rv != SECSuccess) { goto loser; } PORT_ArenaUnmark(poolp, mark); PORT_FreeArena(genNamePool, PR_FALSE); return SECSuccess; loser: PORT_ArenaRelease(poolp, mark); if (genNamePool != NULL) { PORT_FreeArena(genNamePool, PR_FALSE); } PORT_Assert(rv != SECSuccess); return rv;}SECStatusCMMF_DestroyPOPODecKeyRespContent(CMMFPOPODecKeyRespContent *inDecKeyResp){ PORT_Assert(inDecKeyResp != NULL); if (inDecKeyResp != NULL && inDecKeyResp->poolp != NULL) { PORT_FreeArena(inDecKeyResp->poolp, PR_FALSE); } return SECSuccess;}int CMMF_POPODecKeyRespContentGetNumResponses(CMMFPOPODecKeyRespContent *inRespCont){ int numResponses = 0; PORT_Assert(inRespCont != NULL); if (inRespCont == NULL) { return 0; } while (inRespCont->responses[numResponses] != NULL) { numResponses ++; } return numResponses;}SECStatusCMMF_POPODecKeyRespContentGetResponse (CMMFPOPODecKeyRespContent *inRespCont, int inIndex, long *inDest){ PORT_Assert(inRespCont != NULL); if (inRespCont == NULL || inIndex < 0 || inIndex >= CMMF_POPODecKeyRespContentGetNumResponses(inRespCont)) { return SECFailure; } *inDest = DER_GetInteger(inRespCont->responses[inIndex]); return (*inDest == -1) ? SECFailure : SECSuccess;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?