crmfpop.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 605 行 · 第 1/2 页
C
605 行
/* -*- 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 "crmf.h"#include "crmfi.h"#include "secasn1.h"#include "keyhi.h"#include "cryptohi.h"#define CRMF_DEFAULT_ALLOC_SIZE 1024SECStatuscrmf_init_encoder_callback_arg (struct crmfEncoderArg *encoderArg, SECItem *derDest) { derDest->data = PORT_ZNewArray(unsigned char, CRMF_DEFAULT_ALLOC_SIZE); if (derDest->data == NULL) { return SECFailure; } derDest->len = 0; encoderArg->allocatedLen = CRMF_DEFAULT_ALLOC_SIZE; encoderArg->buffer = derDest; return SECSuccess;}/* Caller should release or unmark the pool, instead of doing it here.** But there are NO callers of this function at present...*/SECStatus CRMF_CertReqMsgSetRAVerifiedPOP(CRMFCertReqMsg *inCertReqMsg){ SECItem *dummy; CRMFProofOfPossession *pop; PRArenaPool *poolp; void *mark; PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->pop == NULL); poolp = inCertReqMsg->poolp; mark = PORT_ArenaMark(poolp); if (CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfNoPOPChoice) { return SECFailure; } pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession); if (pop == NULL) { goto loser; } pop->popUsed = crmfRAVerified; pop->popChoice.raVerified.data = NULL; pop->popChoice.raVerified.len = 0; inCertReqMsg->pop = pop; dummy = SEC_ASN1EncodeItem(poolp, &(inCertReqMsg->derPOP), &(pop->popChoice.raVerified), CRMFRAVerifiedTemplate); return SECSuccess; loser: PORT_ArenaRelease(poolp, mark); return SECFailure;}SECOidTagcrmf_map_keytag_to_signtag(SECOidTag inTag){ switch (inTag) { case SEC_OID_PKCS1_RSA_ENCRYPTION: return SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; case SEC_OID_ANSIX9_DSA_SIGNATURE: case SEC_OID_MISSI_KEA_DSS: case SEC_OID_MISSI_DSS: return SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; default: /* Put this in here to kill warnings. */ break; } return inTag;}SECOidTagcrmf_get_key_sign_tag(SECKEYPublicKey *inPubKey){ CERTSubjectPublicKeyInfo *spki; SECOidTag tag; spki = SECKEY_CreateSubjectPublicKeyInfo(inPubKey); if (spki == NULL) { return SEC_OID_UNKNOWN; } tag = SECOID_GetAlgorithmTag(&spki->algorithm); SECKEY_DestroySubjectPublicKeyInfo(spki); return crmf_map_keytag_to_signtag(tag);}SECAlgorithmID*crmf_create_poposignkey_algid(PRArenaPool *poolp, SECKEYPublicKey *inPubKey){ SECAlgorithmID *algID; SECOidTag tag; SECStatus rv; void *mark; mark = PORT_ArenaMark(poolp); algID = PORT_ArenaZNew(poolp, SECAlgorithmID); if (algID == NULL) { goto loser; } tag = crmf_get_key_sign_tag(inPubKey); if (tag == SEC_OID_UNKNOWN) { goto loser; } rv = SECOID_SetAlgorithmID(poolp, algID, tag, NULL); if (rv != SECSuccess) { goto loser; } PORT_ArenaUnmark(poolp, mark); return algID; loser: PORT_ArenaRelease(poolp, mark); return NULL;}static CRMFPOPOSigningKeyInput*crmf_create_poposigningkeyinput(PRArenaPool *poolp, CERTCertificate *inCert, CRMFMACPasswordCallback fn, void *arg){ /* PSM isn't going to do this, so we'll fail here for now.*/ return NULL;}voidcrmf_generic_encoder_callback(void *arg, const char* buf, unsigned long len, int depth, SEC_ASN1EncodingPart data_kind){ struct crmfEncoderArg *encoderArg = (struct crmfEncoderArg*)arg; unsigned char *cursor; if (encoderArg->buffer->len + len > encoderArg->allocatedLen) { int newSize = encoderArg->buffer->len+CRMF_DEFAULT_ALLOC_SIZE; void *dummy = PORT_Realloc(encoderArg->buffer->data, newSize); if (dummy == NULL) { /* I really want to return an error code here */ PORT_Assert(0); return; } encoderArg->buffer->data = dummy; encoderArg->allocatedLen = newSize; } cursor = &(encoderArg->buffer->data[encoderArg->buffer->len]); PORT_Memcpy (cursor, buf, len); encoderArg->buffer->len += len; }static SECStatuscrmf_encode_certreq(CRMFCertRequest *inCertReq, SECItem *derDest){ struct crmfEncoderArg encoderArg; SECStatus rv; rv = crmf_init_encoder_callback_arg (&encoderArg, derDest); if (rv != SECSuccess) { return SECFailure; } return SEC_ASN1Encode(inCertReq, CRMFCertRequestTemplate, crmf_generic_encoder_callback, &encoderArg);}static SECStatuscrmf_sign_certreq(PRArenaPool *poolp, CRMFPOPOSigningKey *crmfSignKey, CRMFCertRequest *certReq, SECKEYPrivateKey *inKey, SECAlgorithmID *inAlgId){ SECItem derCertReq; SECItem certReqSig; SECStatus rv = SECSuccess; rv = crmf_encode_certreq(certReq, &derCertReq); if (rv != SECSuccess) { goto loser; } rv = SEC_SignData(&certReqSig, derCertReq.data, derCertReq.len, inKey,SECOID_GetAlgorithmTag(inAlgId)); if (rv != SECSuccess) { goto loser; } /* Now make it a part of the POPOSigningKey */ rv = SECITEM_CopyItem(poolp, &(crmfSignKey->signature), &certReqSig); /* Convert this length to number of bits */ crmfSignKey->signature.len <<= 3; loser: if (derCertReq.data != NULL) { PORT_Free(derCertReq.data); } if (certReqSig.data != NULL) { PORT_Free(certReqSig.data); } return rv;}static SECStatuscrmf_create_poposignkey(PRArenaPool *poolp, CRMFCertReqMsg *inCertReqMsg, CRMFPOPOSigningKeyInput *signKeyInput, SECKEYPrivateKey *inPrivKey, SECAlgorithmID *inAlgID, CRMFPOPOSigningKey *signKey) { CRMFCertRequest *certReq; void *mark; PRBool useSignKeyInput; SECStatus rv; PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->certReq != NULL); mark = PORT_ArenaMark(poolp); if (signKey == NULL) { goto loser; } certReq = inCertReqMsg->certReq; useSignKeyInput = !(CRMF_DoesRequestHaveField(certReq,crmfSubject) && CRMF_DoesRequestHaveField(certReq,crmfPublicKey)); if (useSignKeyInput) { goto loser; } else { rv = crmf_sign_certreq(poolp, signKey, certReq,inPrivKey, inAlgID); if (rv != SECSuccess) { goto loser; } } PORT_ArenaUnmark(poolp,mark); return SECSuccess; loser: PORT_ArenaRelease(poolp,mark); return SECFailure;}SECStatusCRMF_CertReqMsgSetSignaturePOP(CRMFCertReqMsg *inCertReqMsg, SECKEYPrivateKey *inPrivKey, SECKEYPublicKey *inPubKey, CERTCertificate *inCertForInput, CRMFMACPasswordCallback fn, void *arg){ SECAlgorithmID *algID; PRArenaPool *poolp; SECItem derDest = {siBuffer, NULL, 0}; void *mark; SECStatus rv; CRMFPOPOSigningKeyInput *signKeyInput = NULL; CRMFCertRequest *certReq; CRMFProofOfPossession *pop; struct crmfEncoderArg encoderArg; PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->certReq != NULL && inCertReqMsg->pop == NULL); certReq = inCertReqMsg->certReq; if (CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfNoPOPChoice || !CRMF_DoesRequestHaveField(certReq, crmfPublicKey)) { return SECFailure; } poolp = inCertReqMsg->poolp; mark = PORT_ArenaMark(poolp); algID = crmf_create_poposignkey_algid(poolp, inPubKey); if(!CRMF_DoesRequestHaveField(certReq,crmfSubject)) { signKeyInput = crmf_create_poposigningkeyinput(poolp, inCertForInput, fn, arg);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?