summaryrefslogtreecommitdiff
path: root/security/nss/lib/crmf/crmfpop.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/crmf/crmfpop.c')
-rw-r--r--security/nss/lib/crmf/crmfpop.c120
1 files changed, 72 insertions, 48 deletions
diff --git a/security/nss/lib/crmf/crmfpop.c b/security/nss/lib/crmf/crmfpop.c
index e105a90a8..06d5f467f 100644
--- a/security/nss/lib/crmf/crmfpop.c
+++ b/security/nss/lib/crmf/crmfpop.c
@@ -94,35 +94,14 @@ CRMF_CertReqMsgSetRAVerifiedPOP(CRMFCertReqMsg *inCertReqMsg)
}
SECOidTag
-crmf_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;
-}
-
-SECOidTag
crmf_get_key_sign_tag(SECKEYPublicKey *inPubKey)
{
- CERTSubjectPublicKeyInfo *spki;
- SECOidTag tag;
-
- spki = SECKEY_CreateSubjectPublicKeyInfo(inPubKey);
- if (spki == NULL) {
- return SEC_OID_UNKNOWN;
+ /* maintain backward compatibility with older
+ * implementations */
+ if (inPubKey->keyType == rsaKey) {
+ return SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
}
- tag = SECOID_GetAlgorithmTag(&spki->algorithm);
- SECKEY_DestroySubjectPublicKeyInfo(spki);
- return crmf_map_keytag_to_signtag(tag);
+ return SEC_GetSignatureAlgorithmOidTag(inPubKey->keyType, SEC_OID_UNKNOWN);
}
SECAlgorithmID*
@@ -206,8 +185,8 @@ crmf_sign_certreq(PRArenaPool *poolp,
SECKEYPrivateKey *inKey,
SECAlgorithmID *inAlgId)
{
- SECItem derCertReq;
- SECItem certReqSig;
+ SECItem derCertReq = { siBuffer, NULL, 0 };
+ SECItem certReqSig = { siBuffer, NULL, 0 };
SECStatus rv = SECSuccess;
rv = crmf_encode_certreq(certReq, &derCertReq);
@@ -282,7 +261,7 @@ CRMF_CertReqMsgSetSignaturePOP(CRMFCertReqMsg *inCertReqMsg,
{
SECAlgorithmID *algID;
PRArenaPool *poolp;
- SECItem derDest = {siBuffer, NULL, 0};
+ SECItem derTemp = {siBuffer, NULL, 0};
void *mark;
SECStatus rv;
CRMFPOPOSigningKeyInput *signKeyInput = NULL;
@@ -325,7 +304,7 @@ CRMF_CertReqMsgSetSignaturePOP(CRMFCertReqMsg *inCertReqMsg,
pop->popChoice.signature.algorithmIdentifier = algID;
inCertReqMsg->pop = pop;
- rv = crmf_init_encoder_callback_arg (&encoderArg, &derDest);
+ rv = crmf_init_encoder_callback_arg (&encoderArg, &derTemp);
if (rv != SECSuccess) {
goto loser;
}
@@ -335,18 +314,18 @@ CRMF_CertReqMsgSetSignaturePOP(CRMFCertReqMsg *inCertReqMsg,
if (rv != SECSuccess) {
goto loser;
}
- rv = SECITEM_CopyItem(poolp, &(inCertReqMsg->derPOP), &derDest);
- PORT_Free (derDest.data);
+ rv = SECITEM_CopyItem(poolp, &(inCertReqMsg->derPOP), &derTemp);
if (rv != SECSuccess) {
goto loser;
}
+ PORT_Free (derTemp.data);
PORT_ArenaUnmark(poolp,mark);
return SECSuccess;
loser:
PORT_ArenaRelease(poolp,mark);
- if (derDest.data != NULL) {
- PORT_Free(derDest.data);
+ if (derTemp.data != NULL) {
+ PORT_Free(derTemp.data);
}
return SECFailure;
}
@@ -379,13 +358,13 @@ crmf_encode_popoprivkey(PRArenaPool *poolp,
const SEC_ASN1Template *privKeyTemplate)
{
struct crmfEncoderArg encoderArg;
- SECItem derDest;
+ SECItem derTemp;
SECStatus rv;
void *mark;
const SEC_ASN1Template *subDerTemplate;
mark = PORT_ArenaMark(poolp);
- rv = crmf_init_encoder_callback_arg(&encoderArg, &derDest);
+ rv = crmf_init_encoder_callback_arg(&encoderArg, &derTemp);
if (rv != SECSuccess) {
goto loser;
}
@@ -399,32 +378,32 @@ crmf_encode_popoprivkey(PRArenaPool *poolp,
if (rv != SECSuccess) {
goto loser;
}
- if (encoderArg.allocatedLen > derDest.len+2) {
- void *dummy = PORT_Realloc(derDest.data, derDest.len+2);
+ if (encoderArg.allocatedLen > derTemp.len+2) {
+ void *dummy = PORT_Realloc(derTemp.data, derTemp.len+2);
if (dummy == NULL) {
goto loser;
}
- derDest.data = dummy;
+ derTemp.data = dummy;
}
- PORT_Memmove(&derDest.data[2], &derDest.data[0], derDest.len);
+ PORT_Memmove(&derTemp.data[2], &derTemp.data[0], derTemp.len);
/* I couldn't figure out how to get the ASN1 encoder to implicitly
* tag an implicitly tagged der blob. So I'm putting in the outter-
* most tag myself. -javi
*/
- derDest.data[0] = (unsigned char)privKeyTemplate->kind;
- derDest.data[1] = (unsigned char)derDest.len;
- derDest.len += 2;
- rv = SECITEM_CopyItem(poolp, &inCertReqMsg->derPOP, &derDest);
+ derTemp.data[0] = (unsigned char)privKeyTemplate->kind;
+ derTemp.data[1] = (unsigned char)derTemp.len;
+ derTemp.len += 2;
+ rv = SECITEM_CopyItem(poolp, &inCertReqMsg->derPOP, &derTemp);
if (rv != SECSuccess) {
goto loser;
}
- PORT_Free(derDest.data);
+ PORT_Free(derTemp.data);
PORT_ArenaUnmark(poolp, mark);
return SECSuccess;
loser:
PORT_ArenaRelease(poolp, mark);
- if (derDest.data) {
- PORT_Free(derDest.data);
+ if (derTemp.data) {
+ PORT_Free(derTemp.data);
}
return SECFailure;
}
@@ -491,6 +470,47 @@ crmf_add_privkey_thismessage(CRMFCertReqMsg *inCertReqMsg, SECItem *encPrivKey,
}
static SECStatus
+crmf_add_privkey_dhmac(CRMFCertReqMsg *inCertReqMsg, SECItem *dhmac,
+ CRMFPOPChoice inChoice)
+{
+ PRArenaPool *poolp;
+ void *mark;
+ CRMFPOPOPrivKey *popoPrivKey;
+ CRMFProofOfPossession *pop;
+ SECStatus rv;
+
+ PORT_Assert(inCertReqMsg != NULL && dhmac != NULL);
+ poolp = inCertReqMsg->poolp;
+ mark = PORT_ArenaMark(poolp);
+ pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession);
+ if (pop == NULL) {
+ goto loser;
+ }
+ pop->popUsed = inChoice;
+ popoPrivKey = &pop->popChoice.keyAgreement;
+
+ rv = SECITEM_CopyItem(poolp, &(popoPrivKey->message.dhMAC),
+ dhmac);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ popoPrivKey->message.dhMAC.len <<= 3;
+ popoPrivKey->messageChoice = crmfDHMAC;
+ inCertReqMsg->pop = pop;
+ rv = crmf_encode_popoprivkey(poolp, inCertReqMsg, popoPrivKey,
+ crmf_get_template_for_privkey(inChoice));
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ PORT_ArenaUnmark(poolp, mark);
+ return SECSuccess;
+
+ loser:
+ PORT_ArenaRelease(poolp, mark);
+ return SECFailure;
+}
+
+static SECStatus
crmf_add_privkey_subseqmessage(CRMFCertReqMsg *inCertReqMsg,
CRMFSubseqMessOptions subsequentMessage,
CRMFPOPChoice inChoice)
@@ -599,7 +619,11 @@ CRMF_CertReqMsgSetKeyAgreementPOP (CRMFCertReqMsg *inCertReqMsg,
crmfKeyAgreement);
break;
case crmfDHMAC:
- /* This case should be added in the future. */
+ /* In this case encPrivKey should be the calculated dhMac
+ * as specified in RFC 2511 */
+ rv = crmf_add_privkey_dhmac(inCertReqMsg, encPrivKey,
+ crmfKeyAgreement);
+ break;
default:
rv = SECFailure;
}