📄 crmfres.c
字号:
SSMCRMFRequest_SetDH(SSMCRMFRequest *crmfReq){ unsigned char keyUsage = KEY_AGREEMENT; crmfReq->m_KeyGenType = dhEx; return SSMCRMFRequest_SetKeyUsageExtension(crmfReq, keyUsage);}SSMStatusSSMCRMFRequest_SetDSASign(SSMCRMFRequest *crmfReq){ unsigned char keyUsage = DIGITAL_SIGNATURE; crmfReq->m_KeyGenType = dsaSign; return SSMCRMFRequest_SetKeyUsageExtension(crmfReq, keyUsage);}SSMStatusSSMCRMFRequest_SetDSANonRepudiation(SSMCRMFRequest *crmfReq){ unsigned char keyUsage = NON_REPUDIATION; crmfReq->m_KeyGenType = dsaNonrepudiation; return SSMCRMFRequest_SetKeyUsageExtension(crmfReq, keyUsage);}SSMStatusSSMCRMFRequest_SetDSASignNonRepudiation(SSMCRMFRequest *crmfReq){ unsigned char keyUsage = DIGITAL_SIGNATURE | NON_REPUDIATION; crmfReq->m_KeyGenType = dsaSignNonrepudiation; return SSMCRMFRequest_SetKeyUsageExtension(crmfReq, keyUsage);}SSMStatusSSMCRMFRequest_SetKeyGenType(SSMCRMFRequest *crmfReq, SSMKeyGenType keyGenType){ SSMStatus rv; if (crmfReq->m_KeyGenType != invalidKeyGen) { return PR_FAILURE; } switch (keyGenType) { case rsaDualUse: rv = SSMCRMFRequest_SetRSADualUse(crmfReq); break; case rsaEnc: rv = SSMCRMFRequest_SetRSAKeyEx(crmfReq); break; case rsaSign: rv = SSMCRMFRequest_SetRSASign(crmfReq); break; case rsaNonrepudiation: rv = SSMCRMFRequest_SetRSANonRepudiation(crmfReq); break; case rsaSignNonrepudiation: rv = SSMCRMFRequest_SetRSASignNonRepudiation(crmfReq); break; case dhEx: rv = SSMCRMFRequest_SetDH(crmfReq); break; case dsaSign: rv = SSMCRMFRequest_SetDSASign(crmfReq); break; case dsaNonrepudiation: rv = SSMCRMFRequest_SetDSANonRepudiation(crmfReq); break; case dsaSignNonrepudiation: rv = SSMCRMFRequest_SetDSASignNonRepudiation(crmfReq); break; default: SSM_DEBUG("Unknown KeyGenType %d\n", keyGenType); rv = PR_FAILURE; break; } return rv;}/* * This function takes an ASCII string in RFC1485 format and converts it * to a CERTName, then sets that names as the subjectName for the request * passed in. */SSMStatusSSMCRMFRequest_SetDN(SSMCRMFRequest *crmfReq, char *data){ SECStatus srv; CERTName *subjectName; if (data == NULL || CRMF_CertRequestIsFieldPresent(crmfReq->m_CRMFRequest, crmfSubject)) { return PR_FAILURE; } subjectName = CERT_AsciiToName(data); if (subjectName == NULL) { return PR_FAILURE; } srv = CRMF_CertRequestSetTemplateField (crmfReq->m_CRMFRequest, crmfSubject, (void*)subjectName); CERT_DestroyName(subjectName); return (srv == SECSuccess) ? PR_SUCCESS : PR_FAILURE;}/* * This function will set the Registration Token Control in * the certificate request passed in. We only allow one registration * token control per request in PSM. */SSMStatusSSMCRMFRequest_SetRegToken(SSMCRMFRequest *crmfReq, char *value){ SECItem src, *derEncoded; SECStatus rv; if (CRMF_CertRequestIsControlPresent(crmfReq->m_CRMFRequest, crmfRegTokenControl)) { return PR_FAILURE; } src.data = (unsigned char*)value; src.len = strlen(value)+1; derEncoded = SEC_ASN1EncodeItem(NULL, NULL, &src, SEC_UTF8StringTemplate); if (derEncoded == NULL) { return PR_FAILURE; } rv = CRMF_CertRequestSetRegTokenControl(crmfReq->m_CRMFRequest, derEncoded); SECITEM_FreeItem(derEncoded, PR_TRUE); if (rv != SECSuccess) { return PR_FAILURE; } return PR_SUCCESS;}/* * This function sets the authenticator control in the certificate request. * The string passed in is an ASCII string. The CRMF libraries encode that * string as a UTF8 string and then include it in the request. PSM will * only allow one Authenticator control per request. */SSMStatusSSMCRMFRequest_SetAuthenticator(SSMCRMFRequest *crmfReq, char *value){ SECItem src, *derEncoded; SECStatus rv; if (CRMF_CertRequestIsControlPresent(crmfReq->m_CRMFRequest, crmfAuthenticatorControl)) { return PR_FAILURE; } src.data = (unsigned char*)value; src.len = strlen(value)+1; derEncoded = SEC_ASN1EncodeItem(NULL, NULL, &src, SEC_UTF8StringTemplate); if (derEncoded == NULL) { return PR_FAILURE; } rv = CRMF_CertRequestSetAuthenticatorControl(crmfReq->m_CRMFRequest, derEncoded); SECITEM_FreeItem(derEncoded, PR_TRUE); if (rv != SECSuccess) { return PR_FAILURE; } return PR_SUCCESS;}SSMStatusSSMCRMFRequest_SetEscrowAuthority(SSMCRMFRequest *crmfReq, CERTCertificate *eaCert){ CRMFEncryptedKey *encrKey = NULL; CRMFPKIArchiveOptions *archOpt = NULL; SSMEscrowWarnParam *warnParam = NULL; SECStatus rv; SECItem derCert = {siBuffer, NULL, 0}; PR_ASSERT(eaCert!= NULL); if (eaCert == NULL || CRMF_CertRequestIsControlPresent(crmfReq->m_CRMFRequest, crmfPKIArchiveOptionsControl)) { return PR_FAILURE; } /* * CRMF_CreatePKIArchiveOptions checks to see if the value passed in, * in this case encrKey, is NULL. So passing in the value without * checking the contents first is OK in this case. Really. */ encrKey = CRMF_CreateEncryptedKeyWithEncryptedValue(crmfReq->m_KeyPair->m_PrivKey, eaCert); archOpt = CRMF_CreatePKIArchiveOptions(crmfEncryptedPrivateKey, (void*)encrKey); if (archOpt == NULL) { goto loser; } rv = CRMF_CertRequestSetPKIArchiveOptions(crmfReq->m_CRMFRequest, archOpt); if (rv != SECSuccess) { goto loser; } CRMF_DestroyEncryptedKey(encrKey); CRMF_DestroyPKIArchiveOptions(archOpt); CERT_DestroyCertificate(eaCert); return PR_SUCCESS; loser: /* Free up all the memory here. */ if (encrKey != NULL) { CRMF_DestroyEncryptedKey(encrKey); } if (archOpt != NULL) { CRMF_DestroyPKIArchiveOptions(archOpt); } return PR_FAILURE;}SSMStatusSSMCRMFRequest_SetAttr(SSMResource *res, SSMAttributeID attrID, SSMAttributeValue *value){ SSMCRMFRequest *crmfReq = (SSMCRMFRequest*)res; SSMStatus rv; SSM_DEBUG("Calling SSMCRMFRequest_SetAttr\n"); switch (attrID) { case SSM_FID_CRMFREQ_KEY_TYPE: SSM_DEBUG("Setting SSMKeyGenType to %d\n", value->u.numeric); if (value->type != SSM_NUMERIC_ATTRIBUTE) { rv = PR_FAILURE; break; } rv = SSMCRMFRequest_SetKeyGenType(crmfReq, (SSMKeyGenType) value->u.numeric); break; case SSM_FID_CRMFREQ_DN: SSM_DEBUG("Setting the DN to %s\n", value->u.string.data); if (value->type != SSM_STRING_ATTRIBUTE) { rv = PR_FAILURE; break; } rv = SSMCRMFRequest_SetDN(crmfReq, (char *) value->u.string.data); break; case SSM_FID_CRMFREQ_REGTOKEN: SSM_DEBUG("Setting the regToken to %s\n", value->u.string.data); if (value->type != SSM_STRING_ATTRIBUTE) { rv = PR_FAILURE; break; } rv = SSMCRMFRequest_SetRegToken(crmfReq, (char *) value->u.string.data); break; case SSM_FID_CRMFREQ_AUTHENTICATOR: SSM_DEBUG("Setting the authenticator to %s\n", value->u.string.data); rv = SSMCRMFRequest_SetAuthenticator(crmfReq, (char *) value->u.string.data); break; default: SSM_DEBUG("Got unknown CRMF Set Attribute request %d\n", attrID); rv = PR_FAILURE; break; } return rv;}/* * This function checks to see if a CRMF request has the PKIArchiveOptions * control already set. */PRBoolSSMCRMFRequest_HasEscrowAuthority(SSMCRMFRequest *currReq){ return CRMF_CertRequestIsControlPresent(currReq->m_CRMFRequest, crmfPKIArchiveOptionsControl);}/* * This function will set the Proof Of Possession (POP) for a request * associated with a key pair intended to do Key Encipherment. Currently * this means encryption only keys. */SSMStatusSSMCRMFRequest_SetKeyEnciphermentPOP(CRMFCertReqMsg *certReqMsg, SSMCRMFRequest *curReq){ SECItem bitString; unsigned char der[2]; SECStatus rv; if (SSMCRMFRequest_HasEscrowAuthority(curReq)) { /* For proof of possession on escrowed keys, we use the * this Message option of POPOPrivKey and include a zero * length bit string in the POP field. This is OK because the encrypted * private key already exists as part of the PKIArchiveOptions * Control and that for all intents and purposes proves that * we do own the private key. */ der[0] = 0x03; /*We've got a bit string */ der[1] = 0x00; /*We've got a 0 length bit string */ bitString.data = der; bitString.len = 2; rv = CRMF_CertReqMsgSetKeyEnciphermentPOP(certReqMsg, crmfThisMessage, crmfNoSubseqMess, &bitString); } else { /* If the encryption key is not being escrowed, then we set the * Proof Of Possession to be a Challenge Response mechanism. */ rv = CRMF_CertReqMsgSetKeyEnciphermentPOP(certReqMsg, crmfSubsequentMessage, crmfChallengeResp, NULL); } return (rv == SECSuccess) ? PR_SUCCESS : PR_FAILURE; }/* * This function sets the Proof Of Possession(POP) for a requests. * All requests except for those associated with encryption only keys * sign the request as their form of POP. Encryption only keys require * extra logic in determining the type of POP to use, that is why encryption * only keys have an extra layer for setting the POP instead of calling into * the CRMF libraries directly from within this function. */SSMStatusSSMCRMFRequest_SetProofOfPossession(CRMFCertReqMsg *certReqMsg, SSMCRMFRequest *curReq){ SSMStatus rv; SECStatus srv; switch (curReq->m_KeyGenType) { case rsaSign: case rsaDualUse: case rsaNonrepudiation: case rsaSignNonrepudiation: case dsaSign: case dsaNonrepudiation: case dsaSignNonrepudiation: srv = CRMF_CertReqMsgSetSignaturePOP(certReqMsg, curReq->m_KeyPair->m_PrivKey, curReq->m_KeyPair->m_PubKey, NULL, NULL, NULL); rv = (srv == SECSuccess) ? PR_SUCCESS : PR_FAILURE; break; case rsaEnc: rv = SSMCRMFRequest_SetKeyEnciphermentPOP(certReqMsg, curReq); break; case dhEx: /* This case may be supported in the future, but for now, we just fall * though to the default case and return an error for diffie-hellman keys. */ default: rv = PR_FAILURE; break; } return rv;}SSMStatusSSM_EncodeCRMFRequests(SSMControlConnection * ctrl,SECItem *msg, char **destDER, SSMPRUint32 *destLen){ PRInt32 i; SSMStatus rv; SECStatus srv; CRMFCertReqMsg **certReqMsgs = NULL; SSMCRMFRequest *curReq; SSMResource *res; SECItem *encodedReq; CRMFCertReqMessages messages; EncodeCRMFReqRequest request; if (CMT_DecodeMessage(EncodeCRMFReqRequestTemplate, &request, (CMTItem*)msg) != CMTSuccess) { goto loser; } certReqMsgs = SSM_ZNEW_ARRAY(CRMFCertReqMsg*, (request.numRequests+1)); for (i=0; i<request.numRequests; i++) { rv = SSMControlConnection_GetResource(ctrl, (SSMResourceID)request.reqIDs[i], &res); if (rv != PR_SUCCESS) { goto loser; } if (!SSM_IsAKindOf(res, SSM_RESTYPE_CRMF_REQUEST)) { rv = PR_FAILURE; goto loser; } curReq = (SSMCRMFRequest*)res; certReqMsgs[i] = CRMF_CreateCertReqMsg(); srv = CRMF_CertReqMsgSetCertRequest(certReqMsgs[i], curReq->m_CRMFRequest); if (srv != SECSuccess) { rv = PR_FAILURE; goto loser; } rv = SSMCRMFRequest_SetProofOfPossession(certReqMsgs[i], curReq); if (rv != PR_SUCCESS) { goto loser; } } /* Now we're ready to encode */ messages.messages = certReqMsgs; encodedReq = SEC_ASN1EncodeItem(NULL, NULL, &messages, CRMFCertReqMessagesTemplate); if (encodedReq == NULL) { rv = PR_FAILURE; goto loser; } *destDER = BTOA_DataToAscii(encodedReq->data, encodedReq->len); *destLen = (*destDER == NULL) ? 0 : strlen(*destDER) + 1; SECITEM_FreeItem(encodedReq, PR_TRUE); rv = (*destDER == NULL) ? PR_FAILURE : PR_SUCCESS; loser: /* Do some massive memory clean-up in here. */ if (certReqMsgs != NULL) { for (i=0; certReqMsgs[i] != NULL; i++){ CRMF_DestroyCertReqMsg(certReqMsgs[i]); } PR_Free(certReqMsgs); } return rv;}voidssm_processcmmfresponse_thread(void *arg){ CMMFResponseArg *inArg = (CMMFResponseArg*)arg; SECItem *msg = inArg->msg; SSMControlConnection *connection = inArg->connection; SECStatus srv; SSMStatus rv; char *base64=NULL; char *nickname=NULL; int numResponses, i; SECItem cmmfDer = {siBuffer, NULL, 0}; PRArenaPool *ourPool = NULL; SECItem *derCerts = NULL; SSMPKCS12CreateArg p12Create; SSMResourceID p12RID; PRBool freeLocalNickname = PR_FALSE; SSMPKCS12Context *p12Cxt = NULL; CERTCertList *caPubs = NULL; CERTCertificate *currCert = NULL; CERTCertificate *dbCert = NULL; CMMFCertRepContent *certRepContent = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -