00001
00009 #include "PKIFCMSUtils.h"
00010 #include "PKIFMemoryUtils.h"
00011 #include "private/PrivatePKIFCMSUtils.h"
00012 #include "Attribute.h"
00013 #include "Certificate.h"
00014 #include "KeyUsage.h"
00015 #include "OID.h"
00016 #include "AttrMatch.h"
00017 #include "AlgorithmIdentifier.h"
00018 #include "MessageDigestAttribute.h"
00019 #include "ContentTypeAttribute.h"
00020 #include "SignerInfo.h"
00021 #include "IssuerAndSerialNumber.h"
00022 #include "SubjectKeyIdentifier.h"
00023 #include "SubjectPublicKeyInfo.h"
00024 #include "Name.h"
00025 #include "KEKRecipInfoDetails.h"
00026 #include "CountersignatureAttribute.h"
00027
00028 #include "PKIFCertificateNodeEntry.h"
00029 #include "PathResults.h"
00030 #include "ToolkitUtils.h"
00031 #include "components.h"
00032 #include "PKIFMessageException.h"
00033 #include "PKIFCommonErrors.h"
00034 #include "ASN1Helper.h"
00035 #include "Buffer.h"
00036 #include "OID.h"
00037 #include "IPKIFColleague.h"
00038 #include "IPKIFCryptoKeyAgree.h"
00039 #include "ParallelHash.h"
00040 #include "PKIFCMSMessageMemoryHelper.h"
00041 #include "PKIFFuncStorage.h"
00042 #include "PKIFAlgorithm.h"
00043
00044 #include "PKIX1Algorithms88.h"
00045 #include "CryptographicMessageSyntax2004.h"
00046 #include "ECC-CMS.h"
00047
00048 #include "IPKIFCryptoKeyIDOperations.h"
00049 #include "IPKIFCryptoMisc.h"
00050 #include "IPKIFCryptoRawOperations.h"
00051 #include "IPKIFPathBuild.h"
00052 #include "IPKIFPathValidate.h"
00053 #include "IPKIFHashContext.h"
00054 #include "IPKIFKeyAgreeContext.h"
00055
00056 #include "PKIFCryptoPPUtils.h"
00057
00058 #include "SignedData.h"
00059
00060 #include "PKIFCAPIErrors.h"
00061 #include "PKIFCryptoPPErrors.h"
00062 #include "PKIFNSSErrors.h"
00063 using namespace std;
00064
00078 void PKIFCMS_API keyUsageChecker_Signature(
00080 const CPKIFCertificateNodeEntryPtr& certNode,
00082 CPKIFPathValidationResults& results,
00084 CertificateType type)
00085 {
00086 if(EE == type)
00087 {
00088 CPKIFCertificatePtr curCert = certNode->GetCert();
00089 CPKIFKeyUsagePtr keyUsage = curCert->GetExtension<CPKIFKeyUsage>();
00091 if(keyUsage != (CPKIFKeyUsage*)NULL && (keyUsage->DigitalSignature() || keyUsage->NonRepudiation()))
00092 {
00093 CPKIFX509ExtensionPtr keyUsage2 = keyUsage;
00094 certNode->MarkExtensionAsProcessed(keyUsage2);
00095 }
00096 }
00097 }
00111 void PKIFCMS_API keyUsageChecker_Encryption(
00114 const CPKIFCertificateNodeEntryPtr& certNode,
00116 CPKIFPathValidationResults& results,
00118 CertificateType type)
00119 {
00120 if(EE == type)
00121 {
00122 CPKIFCertificatePtr curCert = certNode->GetCert();
00123 CPKIFKeyUsagePtr keyUsage = curCert->GetExtension<CPKIFKeyUsage>();
00124 if(keyUsage != (CPKIFKeyUsage*)NULL && keyUsage->KeyEncipherment())
00125 {
00126 CPKIFX509ExtensionPtr keyUsage2 = keyUsage;
00127 certNode->MarkExtensionAsProcessed(keyUsage2);
00128 }
00129 }
00130 }
00131
00145 void PKIFCMS_API keyUsageChecker_KeyAgreement(
00148 const CPKIFCertificateNodeEntryPtr& certNode,
00150 CPKIFPathValidationResults& results,
00152 CertificateType type)
00153 {
00154 if(EE == type)
00155 {
00156 CPKIFCertificatePtr curCert = certNode->GetCert();
00157 CPKIFKeyUsagePtr keyUsage = curCert->GetExtension<CPKIFKeyUsage>();
00158 if(keyUsage != (CPKIFKeyUsage*)NULL && keyUsage->KeyAgreement())
00159 {
00160 CPKIFX509ExtensionPtr keyUsage2 = keyUsage;
00161 certNode->MarkExtensionAsProcessed(keyUsage2);
00162 }
00163 }
00164 }
00165 #if 0
00166
00173 void PKIFCMS_API CopyOID(
00175 ASN1OBJID* dest,
00177 ASN1OBJID* src)
00178 {
00179 dest->numids = src->numids;
00180 for(unsigned int ii = 0; ii < src->numids; ++ii)
00181 dest->subid[ii] = src->subid[ii];
00182 }
00183 #endif
00184
00192 CPKIFAlgorithm * GetCACHashAlg(
00194 CACX509V3AlgorithmIdentifier* alg
00195 )
00196 {
00197 if(0 == alg) return 0;
00198
00199 CPKIFOIDPtr algOID(new CPKIFOID(alg->algorithm.subid, alg->algorithm.numids));
00200 CPKIFAlgorithm * pkifAlg = CPKIFAlgorithm::GetAlg(algOID);
00201 if (*(pkifAlg->OID()) != *algOID) {
00202 return 0;
00203 }
00204 return pkifAlg;
00205 }
00213 CPKIFAlgorithm * GetCACSymAlg(
00215 CACX509V3AlgorithmIdentifier* alg
00216 )
00217 {
00218 if(0 == alg) return 0;
00219
00220 CPKIFOIDPtr algOID(new CPKIFOID(alg->algorithm.subid, alg->algorithm.numids));
00221 CPKIFAlgorithm * pkifAlg = CPKIFAlgorithm::GetAlg(algOID);
00222 if (*(pkifAlg->OID()) != *algOID) {
00223 return 0;
00224 }
00225 return pkifAlg;
00226 }
00234 bool ModeRequiresIV(
00236 PKIFCRYPTO::SYMKEY_MODE mode)
00237 {
00238 if(PKIFCRYPTO::ECB == mode)
00239 return false;
00240 else
00241 return true;
00242 }
00243
00244
00245
00246
00247
00248
00258 void EncodeDSASignature(
00260 unsigned char* sig,
00262 int nSigLen,
00264 unsigned char** sigData,
00266 int* numocts)
00267 {
00268 if(NULL == sig || 0 == nSigLen || MAXHASH*2 < nSigLen || NULL == sigData || NULL == numocts || 0 != nSigLen%2)
00269 throw CPKIFMessageException(TOOLKIT_MESSAGE_ASN, COMMON_INVALID_INPUT, "An input to EncodeDSASignature was invalid.");
00270
00271
00272 const int asciiHexHash = (MAXHASH*2) + 5;
00273 char r[asciiHexHash]; memset(r, 0, asciiHexHash); r[0] = '0'; r[1] = 'x';
00274 char s[asciiHexHash]; memset(s, 0, asciiHexHash); s[0] = '0'; s[1] = 'x';
00275
00276
00277 int offset = 2;
00278 if(sig[0] >= (unsigned char)0x80)
00279 {
00280 r[2] = '0'; ++offset;
00281 r[3] = '0'; ++offset;
00282 }
00283 btoa((char*)sig, r+offset, nSigLen/2);
00284
00285 offset = 2;
00286 if(sig[(nSigLen/2)] >= (unsigned char)0x80)
00287 {
00288 s[2] = '0'; ++offset;
00289 s[3] = '0'; ++offset;
00290 }
00291 btoa((char*)sig+(nSigLen/2), s+offset, nSigLen/2);
00292
00293 Dss_Sig_Value dssSigVal;
00294 dssSigVal.r = r;
00295 dssSigVal.s = s;
00296
00297 CACASNWRAPPER_CREATE(Dss_Sig_Value, tmpPDU);
00298 ASN1OpenType* data1 = tmpPDU.Encode(&dssSigVal);
00299
00300 *numocts = data1->numocts;
00301 *sigData = new unsigned char[data1->numocts + 1];
00302 memcpy(*sigData, data1->data, data1->numocts);
00303 delete data1;
00304 }
00312 void AddSignedAttributes(
00314 unsigned char* hashResult,
00316 int nHashResult,
00318 CPKIFOIDPtr& eContentType,
00320 CPKIFAttributeList& sas)
00321 {
00322
00323
00324 if(*g_data == eContentType && sas.empty())
00325 return;
00326
00327
00328
00329 bool foundMD = false, foundCT = false;
00330
00331 AttrMatch attrSearch;
00332 attrSearch.SetRHS(g_messageDigestAttribute);
00333 CPKIFAttributeList::iterator end = sas.end();
00334 if(end != find_if(sas.begin(), sas.end(), attrSearch))
00335 foundMD = true;
00336
00337 attrSearch.SetRHS(g_contentTypeAttribute);
00338 if(end != find_if(sas.begin(), sas.end(), attrSearch))
00339 foundCT = true;
00340
00341 if(!foundMD)
00342 {
00343 CPKIFMessageDigestAttributePtr mdAttr(new CPKIFMessageDigestAttribute());
00344 CPKIFBufferPtr mdBuf(new CPKIFBuffer(hashResult, nHashResult));
00345 mdAttr->SetMessageDigest(mdBuf);
00346 sas.push_back(mdAttr);
00347 }
00348
00349 if(!foundCT)
00350 {
00351 CPKIFContentTypeAttributePtr ctAttr(new CPKIFContentTypeAttribute());
00352 ctAttr->SetContentType(eContentType);
00353 sas.push_back(ctAttr);
00354 }
00355 }
00363 void SetupAttributesInObjectiveStructure(
00365 CPKIFAttributeList& attrs,
00367 DList& objAttrs)
00368 {
00369 objAttrs.count = 0;
00370 objAttrs.head = NULL;
00371 objAttrs.tail = NULL;
00372
00373 DListNode* cur = NULL;
00374 CPKIFAttributeList::iterator sasPos;
00375 CPKIFAttributeList::iterator sasEnd = attrs.end();
00376 for(sasPos = attrs.begin(); sasPos != sasEnd; ++sasPos)
00377 {
00378 CPKIFBufferList bl;
00379 (*sasPos)->GetValues(bl);
00380
00381 if(NULL == cur)
00382 {
00383 NEW_NODE(cur)
00384 }
00385 else
00386 {
00387 NEW_NEXT_AND_ADVANCE(cur)
00388 }
00389
00390 CPKIFBufferList::iterator bufPos;
00391 DListNode* cur2 = NULL;
00392
00393 CACCMSAttribute* attr = new CACCMSAttribute;
00394 CPKIFStringPtr str(new std::string((*sasPos)->GetOID()->ToString()));
00395 ASN1OBJID* tmpOid = ConvertStringToASN1OBJID(str);
00396 CopyOID(&attr->attrType, tmpOid);
00397 if(tmpOid)
00398 delete tmpOid;
00399
00400
00401 DList* attrVals = new DList;
00402 attrVals->count = 0;
00403 attrVals->head = NULL;
00404 attrVals->tail = NULL;
00405
00406 cur->data = attr;
00407 CPKIFBufferList::iterator bufEnd = bl.end();
00408 for(bufPos = bl.begin(); bufPos != bufEnd; ++bufPos)
00409 {
00410 if(NULL == cur2)
00411 {
00412 NEW_NODE(cur2)
00413 }
00414 else
00415 {
00416 NEW_NEXT_AND_ADVANCE(cur2)
00417 }
00418
00419 ASN1OpenType* tmpOT = new ASN1OpenType;
00420 tmpOT->numocts = (*bufPos)->GetLength();
00421 tmpOT->data = new unsigned char[tmpOT->numocts];
00422 memcpy((void*)tmpOT->data, (*bufPos)->GetBuffer(), tmpOT->numocts);
00423 cur2->data = tmpOT;
00424
00425 SET_HEAD_TAIL_INCREMENT((*attrVals), cur2)
00426 }
00427
00428 SET_HEAD_TAIL_INCREMENT(objAttrs, cur)
00429
00430 CACASNWRAPPER_CREATE(CACCMSAttributeValues, avs);
00431 ASN1OpenType* aot = avs.Encode(attrVals);
00432
00433 attr->attrValues.data = new unsigned char[aot->numocts];
00434
00435 memcpy((void *)attr->attrValues.data,aot->data,aot->numocts);
00436 attr->attrValues.numocts = aot->numocts;
00437 delete aot;
00438
00439 DListNode* cur = NULL, *tmp = NULL;
00440 cur = attrVals->head;
00441 while(NULL != cur)
00442 {
00443 ASN1OpenType* tmpOT = (ASN1OpenType*)cur->data;
00444 if(NULL != tmpOT->data)
00445 delete[] tmpOT->data;
00446
00447 delete tmpOT;
00448
00449 tmp = cur->next;
00450 delete cur;
00451 cur = tmp;
00452 }
00453
00454 if(attrVals != NULL)
00455 delete attrVals;
00456
00457
00458
00459 }
00460 }
00471 void GetSignerInfo(
00473 CACCMSSignerInfo* tmpSignerInfo,
00475 CPKIFSignerInfoPtr& siPos,
00477 unsigned char* hashResult,
00479 int nHashResult,
00481 IPKIFMediatorPtr m,
00483 CPKIFOIDPtr& eContentType,
00485 PKIFCRYPTO::HASH_ALG hashAlg,
00487 bool useSKIDIfPresent)
00488 {
00489 IPKIFCryptoKeyIDOperations* cm = m->GetMediator<IPKIFCryptoKeyIDOperations>();
00490 IPKIFCryptoMisc* cMisc = m->GetMediator<IPKIFCryptoMisc>();
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 if(!siPos->Decoded())
00506 {
00507 if(NULL == hashResult || 0 == nHashResult)
00508 throw CPKIFMessageException(TOOLKIT_MESSAGE, COMMON_UNSUPPORTED_ALG, "SignerInfo contains an unsupported hash algorithm or a signer is being added to an object with detached content after encoding.");
00509
00510 CPKIFCertificatePtr cert = siPos->GetCredential()->GetCertificate();
00511 CPKIFSubjectKeyIdentifierPtr skid = cert->GetExtension<CPKIFSubjectKeyIdentifier>();
00512 if(skid != (CPKIFSubjectKeyIdentifier*)NULL && useSKIDIfPresent)
00513 {
00514 tmpSignerInfo->version = CACCMSv3;
00515
00516
00517 tmpSignerInfo->sid.t = 2;
00518 CPKIFBufferPtr skidBuf = skid->KeyIdentifier();
00519 tmpSignerInfo->sid.u.subjectKeyIdentifier = new CACCMSSubjectKeyIdentifier;
00520 tmpSignerInfo->sid.u.subjectKeyIdentifier->numocts = skidBuf->GetLength();
00521 tmpSignerInfo->sid.u.subjectKeyIdentifier->data = new unsigned char[tmpSignerInfo->sid.u.subjectKeyIdentifier->numocts];
00522 memcpy((void*)tmpSignerInfo->sid.u.subjectKeyIdentifier->data, skidBuf->GetBuffer(), tmpSignerInfo->sid.u.subjectKeyIdentifier->numocts);
00523 }
00524 else
00525 {
00526 tmpSignerInfo->version = CACCMSv1;
00527
00528
00529 tmpSignerInfo->sid.t = 1;
00530 tmpSignerInfo->sid.u.issuerAndSerialNumber = new CACCMSIssuerAndSerialNumber;
00531 tmpSignerInfo->sid.u.issuerAndSerialNumber->serialNumber = cert->SerialNumber();
00532
00533 CACASNWRAPPER_CREATE(CACX509V3Name, objPDU);
00534 CACX509V3Name *tmpName = NULL;
00535 CPKIFBufferPtr nameBuf = cert->Issuer()->rawName();
00536 tmpName = objPDU.Decode(nameBuf->GetBuffer(), nameBuf->GetLength());
00537
00538
00539
00540 CopyName(&tmpSignerInfo->sid.u.issuerAndSerialNumber->issuer, *tmpName);
00541
00542 }
00543
00544 tmpSignerInfo->m.signedAttrsPresent = 0;
00545
00546
00547 CPKIFStringPtr str(new std::string(siPos->GetDigestAlg()->oid()->ToString()));
00548 ASN1OBJID* tmpOid = ConvertStringToASN1OBJID(str);
00549 CopyOID(&tmpSignerInfo->digestAlgorithm.algorithm, tmpOid);
00550 if(tmpOid)
00551 delete tmpOid;
00552
00553 tmpSignerInfo->digestAlgorithm.m.parametersPresent = 1;
00554 tmpSignerInfo->digestAlgorithm.parameters.data = nullParams;
00555 tmpSignerInfo->digestAlgorithm.parameters.numocts = 2;
00556
00557 {
00558 CPKIFAttributeList sas;
00559 siPos->GetSignedAttributes(sas);
00560
00561 AddSignedAttributes(hashResult, nHashResult, eContentType, sas);
00562 SetupAttributesInObjectiveStructure(sas, tmpSignerInfo->signedAttrs);
00563
00564 if(!sas.empty())
00565 tmpSignerInfo->m.signedAttrsPresent = 1;
00566 }
00567
00568 unsigned char* signThis = hashResult;
00569 int nSignThisLen = nHashResult;
00570
00571 HashInfo* hi = NULL;
00572 if(tmpSignerInfo->m.signedAttrsPresent)
00573 {
00574
00575
00576 hi = ComputeSignedAttrHash(tmpSignerInfo, cMisc);
00577
00578 signThis = hi->m_hashResult;
00579 nSignThisLen = CPKIFAlgorithm::GetAlg(hi->m_hashAlg)->DigestSize();
00580 }
00581
00582 unsigned char sig[500]; memset(sig, 0, 500);
00583 int nSigLen = 500;
00584 try
00585 {
00586 cm->Sign(*siPos->GetCredential(), signThis, nSignThisLen, sig, &nSigLen, hashAlg);
00587 }
00588 catch(CPKIFException& e)
00589 {
00590 if(NULL != hi)
00591 delete hi;
00592
00593 std::string reason = "Error generating signature using credential named: ";
00594 reason.append(siPos->GetCredential()->Name());
00595
00596 CPKIFMessageException me(TOOLKIT_MESSAGE_ASN, MSG_SIGNATURE_GENERATION_ERROR, reason.c_str());
00597 me.push_info(e);
00598
00599 throw me;
00600 }
00601
00602 if(NULL != hi)
00603 delete hi;
00604
00605 CPKIFStringPtr anotherStr2;
00606 CPKIFAlgorithmIdentifierPtr certAlg = cert->SubjectPublicKeyInfo()->alg();
00607 if(DSA_CLASS == GetAlgClass(certAlg))
00608 {
00609
00610 EncodeDSASignature(sig, nSigLen, (unsigned char**)&tmpSignerInfo->signature.data, (int*)&tmpSignerInfo->signature.numocts);
00611
00612 if(PKIFCRYPTO::SHA1 == hashAlg)
00613 {
00614 CPKIFStringPtr tmpOidSt(new std::string(g_dsaWithSHA1->ToString()));
00615 anotherStr2 = tmpOidSt;
00616 }
00617 }
00618 else if(RSA_CLASS == GetAlgClass(certAlg))
00619 {
00620 tmpSignerInfo->signature.data = new unsigned char[nSigLen];
00621 memcpy((void*)tmpSignerInfo->signature.data, sig, nSigLen);
00622 tmpSignerInfo->signature.numocts = nSigLen;
00623
00624 if(PKIFCRYPTO::MD5 == hashAlg)
00625 {
00626 CPKIFStringPtr tmpOidSt(new std::string(g_md5WithRSAEncryption->ToString()));
00627 anotherStr2 = tmpOidSt;
00628 }
00629 else if(PKIFCRYPTO::SHA1 == hashAlg)
00630 {
00631 CPKIFStringPtr tmpOidSt(new std::string(g_sha1WithRSAEncryption->ToString()));
00632 anotherStr2 = tmpOidSt;
00633 }
00634 else if(PKIFCRYPTO::SHA224 == hashAlg)
00635 {
00636 CPKIFStringPtr tmpOidSt(new std::string(g_sha224WithRSAEncryption->ToString()));
00637 anotherStr2 = tmpOidSt;
00638 }
00639 else if(PKIFCRYPTO::SHA256 == hashAlg)
00640 {
00641 CPKIFStringPtr tmpOidSt(new std::string(g_sha256WithRSAEncryption->ToString()));
00642 anotherStr2 = tmpOidSt;
00643 }
00644 else if(PKIFCRYPTO::SHA384 == hashAlg)
00645 {
00646 CPKIFStringPtr tmpOidSt(new std::string(g_sha384WithRSAEncryption->ToString()));
00647 anotherStr2 = tmpOidSt;
00648 }
00649 else if(PKIFCRYPTO::SHA512 == hashAlg)
00650 {
00651 CPKIFStringPtr tmpOidSt(new std::string(g_sha512WithRSAEncryption->ToString()));
00652 anotherStr2 = tmpOidSt;
00653 }
00654 }
00655 else if(ECDSA_CLASS == GetAlgClass(certAlg))
00656 {
00657 EncodeDSASignature(sig, nSigLen, (unsigned char**)&tmpSignerInfo->signature.data, (int*)&tmpSignerInfo->signature.numocts);
00658 if(PKIFCRYPTO::SHA1 == hashAlg)
00659 {
00660 CPKIFStringPtr tmpOidSt(new std::string(g_ecdsa_sha1->ToString()));
00661 anotherStr2 = tmpOidSt;
00662 }
00663 else if(PKIFCRYPTO::SHA224 == hashAlg)
00664 {
00665 CPKIFStringPtr tmpOidSt(new std::string(g_ecdsa_sha224->ToString()));
00666 anotherStr2 = tmpOidSt;
00667 }
00668 else if(PKIFCRYPTO::SHA256 == hashAlg)
00669 {
00670 CPKIFStringPtr tmpOidSt(new std::string(g_ecdsa_sha256->ToString()));
00671 anotherStr2 = tmpOidSt;
00672 }
00673 else if(PKIFCRYPTO::SHA384 == hashAlg)
00674 {
00675 CPKIFStringPtr tmpOidSt(new std::string(g_ecdsa_sha384->ToString()));
00676 anotherStr2 = tmpOidSt;
00677 }
00678 else if(PKIFCRYPTO::SHA512 == hashAlg)
00679 {
00680 CPKIFStringPtr tmpOidSt(new std::string(g_ecdsa_sha512->ToString()));
00681 anotherStr2 = tmpOidSt;
00682 }
00683 }
00684 else
00685 {
00686 tmpSignerInfo->signature.data = new unsigned char[nSigLen];
00687 memcpy((void*)tmpSignerInfo->signature.data, sig, nSigLen);
00688 tmpSignerInfo->signature.numocts = nSigLen;
00689 }
00690
00691 if(!anotherStr2)
00692 {
00693 CPKIFStringPtr tmpOidSt(new std::string(certAlg->oid()->ToString()));
00694 anotherStr2 = tmpOidSt;
00695 }
00696 ASN1OBJID* anotherTmpOid = ConvertStringToASN1OBJID(anotherStr2);
00697 CopyOID(&tmpSignerInfo->signatureAlgorithm.algorithm, anotherTmpOid);
00698 if(anotherTmpOid)
00699 delete anotherTmpOid;
00700
00701
00702 if(certAlg->hasParameters())
00703 {
00704 tmpSignerInfo->signatureAlgorithm.m.parametersPresent = 1;
00705
00706 CPKIFBufferPtr params = certAlg->parameters();
00707 tmpSignerInfo->signatureAlgorithm.parameters.numocts = params->GetLength();
00708 tmpSignerInfo->signatureAlgorithm.parameters.data = new unsigned char[tmpSignerInfo->signatureAlgorithm.parameters.numocts];
00709 memcpy((void*)tmpSignerInfo->signatureAlgorithm.parameters.data, params->GetBuffer(), tmpSignerInfo->signatureAlgorithm.parameters.numocts);
00710 }
00711 else
00712 tmpSignerInfo->signatureAlgorithm.m.parametersPresent = 0;
00713
00714 tmpSignerInfo->m.unsignedAttrsPresent = 0;
00715 {
00716 CPKIFAttributeList sas;
00717 siPos->GetUnsignedAttributes(sas);
00718
00719 SetupAttributesInObjectiveStructure(sas, tmpSignerInfo->unsignedAttrs);
00720
00721 if(!sas.empty())
00722 tmpSignerInfo->m.unsignedAttrsPresent = 1;
00723 }
00724 }
00725 else
00726 {
00727
00728
00729 switch(siPos->GetSignerIdentifierChoice())
00730 {
00731 case CPKIFSignerInfo::SKID:
00732 {
00733 CPKIFBufferPtr skidBuf = siPos->GetSKID();
00734 tmpSignerInfo->version = CACCMSv3;
00735
00736
00737 tmpSignerInfo->sid.t = 2;
00738 tmpSignerInfo->sid.u.subjectKeyIdentifier = new CACCMSSubjectKeyIdentifier;
00739 tmpSignerInfo->sid.u.subjectKeyIdentifier->numocts = skidBuf->GetLength();
00740 tmpSignerInfo->sid.u.subjectKeyIdentifier->data = new unsigned char[tmpSignerInfo->sid.u.subjectKeyIdentifier->numocts];
00741 memcpy((void*)tmpSignerInfo->sid.u.subjectKeyIdentifier->data, skidBuf->GetBuffer(), tmpSignerInfo->sid.u.subjectKeyIdentifier->numocts);
00742 }
00743 break;
00744 case CPKIFSignerInfo::ISSUERANDSERIAL:
00745 {
00746 tmpSignerInfo->version = CACCMSv1;
00747
00748 CPKIFIssuerAndSerialNumberPtr issAndSN = siPos->GetIssuerAndSerialNumber();
00749 CPKIFNamePtr name = issAndSN->GetName();
00750 const char* sn = issAndSN->GetSerialNumber();
00751
00752
00753 tmpSignerInfo->sid.t = 1;
00754 tmpSignerInfo->sid.u.issuerAndSerialNumber = new CACCMSIssuerAndSerialNumber;
00755 tmpSignerInfo->sid.u.issuerAndSerialNumber->serialNumber = sn;
00756
00757 CACASNWRAPPER_CREATE(CACX509V3Name, objPDU);
00758 CACX509V3Name *tmpName = NULL;
00759 CPKIFBufferPtr nameBuf = name->rawName();
00760 tmpName = objPDU.Decode(nameBuf->GetBuffer(), nameBuf->GetLength());
00761
00762 CopyName(&tmpSignerInfo->sid.u.issuerAndSerialNumber->issuer, *tmpName);
00763
00764 }
00765 break;
00766 default:
00767 throw CPKIFMessageException(TOOLKIT_MESSAGE_ASN, COMMON_UNSUPPORTED_CHOICE, "Unsupported signer info choice");
00768 }
00769
00770
00771 CPKIFStringPtr str2(new std::string(siPos->GetDigestAlg()->oid()->ToString()));
00772 ASN1OBJID* tmpOid = ConvertStringToASN1OBJID(str2);
00773 CopyOID(&tmpSignerInfo->digestAlgorithm.algorithm, tmpOid);
00774 if(tmpOid)
00775 delete tmpOid;
00776
00777 tmpSignerInfo->digestAlgorithm.m.parametersPresent = 1;
00778 tmpSignerInfo->digestAlgorithm.parameters.data = nullParams;
00779 tmpSignerInfo->digestAlgorithm.parameters.numocts = 2;
00780
00781 tmpSignerInfo->m.signedAttrsPresent = 0;
00782
00783 {
00784 CPKIFAttributeList sas;
00785 siPos->GetSignedAttributes(sas);
00786
00787 AddSignedAttributes(hashResult, nHashResult, eContentType, sas);
00788 SetupAttributesInObjectiveStructure(sas, tmpSignerInfo->signedAttrs);
00789
00790 if(!sas.empty())
00791 tmpSignerInfo->m.signedAttrsPresent = 1;
00792 }
00793
00794 CPKIFAlgorithmIdentifierPtr sigAlg = siPos->GetSignatureAlgorithm();
00795 CPKIFBufferPtr sig = siPos->GetSignature();
00796
00797 tmpSignerInfo->signature.numocts = sig->GetLength();
00798 tmpSignerInfo->signature.data = new unsigned char[tmpSignerInfo->signature.numocts];
00799 memcpy((void*)tmpSignerInfo->signature.data, sig->GetBuffer(), tmpSignerInfo->signature.numocts);
00800
00801
00802 CPKIFStringPtr thurdStr(new std::string(sigAlg->oid()->ToString()));
00803 ASN1OBJID* thirdTmpOid = ConvertStringToASN1OBJID(thurdStr);
00804 CopyOID(&tmpSignerInfo->signatureAlgorithm.algorithm, thirdTmpOid);
00805 if(thirdTmpOid)
00806 delete thirdTmpOid;
00807
00808
00809 if(sigAlg->hasParameters())
00810 {
00811 CPKIFBufferPtr algParams = sigAlg->parameters();
00812 tmpSignerInfo->signatureAlgorithm.m.parametersPresent = 1;
00813 tmpSignerInfo->signatureAlgorithm.parameters.numocts = algParams->GetLength();
00814
00815 tmpSignerInfo->signatureAlgorithm.parameters.data = new unsigned char[tmpSignerInfo->signatureAlgorithm.parameters.numocts];
00816 memcpy((void*)tmpSignerInfo->signatureAlgorithm.parameters.data, algParams->GetBuffer(), tmpSignerInfo->signatureAlgorithm.parameters.numocts);
00817 }
00818 else
00819 {
00820 tmpSignerInfo->signatureAlgorithm.m.parametersPresent = 0;
00821 }
00822
00823 tmpSignerInfo->m.unsignedAttrsPresent = 0;
00824 {
00825 CPKIFAttributeList sas;
00826 siPos->GetUnsignedAttributes(sas);
00827
00828 SetupAttributesInObjectiveStructure(sas, tmpSignerInfo->unsignedAttrs);
00829
00830 if(!sas.empty())
00831 tmpSignerInfo->m.unsignedAttrsPresent = 1;
00832 }
00833 }
00834 }
00842 HashInfo* ComputeSignedAttrHash(
00844 CACCMSSignerInfo* si,
00846 IPKIFCryptoMisc* cMisc)
00847 {
00848 if(si->m.signedAttrsPresent)
00849 {
00850 CPKIFAlgorithm * hashAlg = GetCACHashAlg(&si->digestAlgorithm);
00851 if(!hashAlg)
00852 return NULL;
00853
00854 OOCTXT ctxt;
00855 initContext (&ctxt);
00856 setBEREncBufPtr(&ctxt, NULL, 0);
00857 OOCTXT* pctxt = &ctxt;
00858
00859 unsigned char* tmpP = NULL;
00860 int len = BEREncCACCMSSignedAttributes(pctxt, &si->signedAttrs, ASN1EXPL);
00861 if(0 < len)
00862 {
00863 tmpP = (unsigned char*)getBEREncBufPtr(&ctxt);
00864 }
00865
00866 IPKIFHashContext* hc = NULL;
00867 HashInfo* hi = new HashInfo();
00868 try
00869 {
00870 hi->m_hashAlg = hashAlg->HashAlg();
00871 hc = cMisc->HashInit(hi->m_hashAlg);
00872 cMisc->HashUpdate(hc, tmpP, len);
00873 int nResultLen = MAXHASH;
00874 cMisc->HashFinal(hc, hi->m_hashResult, &nResultLen);
00875 delete hc;
00876 }
00877 catch(CPKIFException& e)
00878 {
00879 if(NULL != hc)
00880 delete hc;
00881
00882 if(NULL != hi)
00883 delete hi;
00884
00885
00886 freeContext(&ctxt);
00887 throw e;
00888 }
00889
00890
00891
00892 freeContext(&ctxt);
00893
00894 return hi;
00895 }
00896 else
00897 return NULL;
00898 }
00909 bool CompareHashes(
00911 HashInfo* hi2,
00913 CACCMSSignerInfo* si)
00914 {
00915 if(NULL == hi2 || NULL == si || !si->m.signedAttrsPresent)
00916 return false;
00917
00918 DListNode* cur = si->signedAttrs.head;
00919 while(NULL != cur)
00920 {
00921 CACCMSAttribute* curAttr = (CACCMSAttribute*)cur->data;
00922 CPKIFOIDPtr curAttrType(new CPKIFOID(curAttr->attrType.subid, curAttr->attrType.numids));
00923 if(*g_messageDigestAttribute == *curAttrType)
00924 {
00925 CACASNWRAPPER_CREATE(CACCMSAttributeValues, attrValues);
00926 attrValues.Decode(curAttr->attrValues);
00927
00928 if(0 != attrValues->count)
00929 {
00930 CACCMSAttributeValue* curVal = (CACCMSAttributeValue*)attrValues->head->data;
00931
00932 OOCTXT ctxt;
00933 initContext (&ctxt);
00934 setBERDecBufPtr(&ctxt, curVal->data, curVal->numocts, NULL, NULL);
00935 OOCTXT* pctxt = &ctxt;
00936
00937 unsigned char* hashVal = NULL;
00938 unsigned int hashValLen = 0;
00939
00940 int stat = decodeDynOctStr (pctxt, (const OSOCTET* *)&hashVal, (OSUINT32 *)&hashValLen, ASN1EXPL, curVal->numocts);
00941 if (stat != ASN_OK)
00942 {
00943
00944
00945 freeContext(&ctxt);
00946 throw CPKIFMessageException(TOOLKIT_MESSAGE_ASN, ASN1_DECODE_ERROR, "Failed to decode hash value");
00947 }
00948
00949 bool match = true;
00950 if(hi2->m_hashAlg != hashValLen)
00951 match = false;
00952
00953 if(0 != memcmp(hi2->m_hashResult, hashVal, hashValLen))
00954 match = false;
00955
00956
00957
00958
00959
00960
00961
00962
00963 freeContext(&ctxt);
00964
00965 return match;
00966 }
00967 }
00968
00969 cur = cur->next;
00970 }
00971
00972 return false;
00973 }
00974
00975
00976
00977
00978
00986 bool RIDMatch(
00988 CACCMSRecipientIdentifier* rid,
00990 CPKIFNamePtr& issuer,
00992 const char* serial,
00994 CPKIFSubjectKeyIdentifierPtr& skid)
00995 {
00996
00997 if(NULL == rid)
00998 return false;
00999
01000 switch(rid->t)
01001 {
01002 case 1:
01003 {
01004 if(NULL == serial
01005 || issuer == (CPKIFName*)NULL
01006 || NULL == rid->u.issuerAndSerialNumber
01007 || NULL == rid->u.issuerAndSerialNumber->serialNumber)
01008 return false;
01009
01010 CACASNWRAPPER_CREATE(CACX509V3Name, objPDU);
01011 ASN1OpenType* data1 = objPDU.Encode(&(rid->u.issuerAndSerialNumber->issuer));
01012 CPKIFBufferPtr tmpBuf;
01013 if(data1 != NULL)
01014 {
01015 tmpBuf = CPKIFBufferPtr(new CPKIFBuffer(data1->data, data1->numocts));
01016 delete data1;
01017 }
01018 CPKIFNamePtr ridName(new CPKIFName(tmpBuf));
01019
01020 if(0 == stricmp(rid->u.issuerAndSerialNumber->serialNumber, serial) &&
01021 *ridName == *issuer)
01022 return true;
01023 else
01024 return false;
01025 }
01026 break;
01027 case 2:
01028 {
01029 if(skid == (CPKIFSubjectKeyIdentifier*)NULL
01030 || NULL == rid->u.subjectKeyIdentifier
01031 || NULL == rid->u.subjectKeyIdentifier->data
01032 || 0 == rid->u.subjectKeyIdentifier->numocts)
01033 return false;
01034
01035 CPKIFBufferPtr skidBuf = skid->KeyIdentifier();
01036
01037 if(skidBuf == (CPKIFBuffer*)NULL ||
01038 rid->u.subjectKeyIdentifier->numocts != skidBuf->GetLength())
01039 return false;
01040
01041 if(0 == memcmp(skidBuf->GetBuffer(), rid->u.subjectKeyIdentifier->data, rid->u.subjectKeyIdentifier->numocts))
01042 return true;
01043 else
01044 return false;
01045 }
01046 break;
01047 default:
01048 return false;
01049 }
01050 }
01058 bool RIDMatch(
01060 CACCMSKeyAgreeRecipientIdentifier* rid,
01062 CPKIFNamePtr& issuer,
01064 const char* serial,
01066 CPKIFSubjectKeyIdentifierPtr& skid)
01067 {
01068
01069 if(NULL == rid)
01070 return false;
01071
01072 switch(rid->t)
01073 {
01074 case 1:
01075 {
01076 if(NULL == serial
01077 || issuer == (CPKIFName*)NULL
01078 || NULL == rid->u.issuerAndSerialNumber
01079 || NULL == rid->u.issuerAndSerialNumber->serialNumber)
01080 return false;
01081
01082 CACASNWRAPPER_CREATE(CACX509V3Name, objPDU);
01083 ASN1OpenType* data1 = objPDU.Encode(&(rid->u.issuerAndSerialNumber->issuer));
01084 CPKIFBufferPtr tmpBuf;
01085 if(data1 != NULL)
01086 {
01087 tmpBuf = CPKIFBufferPtr(new CPKIFBuffer(data1->data, data1->numocts));
01088 delete data1;
01089 }
01090 CPKIFNamePtr ridName(new CPKIFName(tmpBuf));
01091
01092 if(0 == stricmp(rid->u.issuerAndSerialNumber->serialNumber, serial) &&
01093 *ridName == *issuer)
01094 return true;
01095 else
01096 return false;
01097 }
01098 break;
01099 case 2:
01100 {
01101 if(skid == (CPKIFSubjectKeyIdentifier*)NULL
01102 || NULL == rid->u.rKeyId->subjectKeyIdentifier.data
01103 || 0 == rid->u.rKeyId->subjectKeyIdentifier.numocts)
01104 return false;
01105
01106 CPKIFBufferPtr skidBuf = skid->KeyIdentifier();
01107
01108 if(skidBuf == (CPKIFBuffer*)NULL ||
01109 rid->u.rKeyId->subjectKeyIdentifier.numocts != skidBuf->GetLength())
01110 return false;
01111
01112 if(0 == memcmp(skidBuf->GetBuffer(), rid->u.rKeyId->subjectKeyIdentifier.data, rid->u.rKeyId->subjectKeyIdentifier.numocts))
01113 return true;
01114 else
01115 return false;
01116 }
01117 break;
01118 default:
01119 return false;
01120 }
01121 }
01122
01123
01124
01135 CPKIFKeyMaterialPtr GetSymmetricKey(
01137 const CPKIFKEKRecipInfoDetailsPtr& kek,
01139 IPKIFCryptoRawOperations* cKeyID,
01141 CACCMSRecipientInfos* ris)
01142 {
01143
01144
01145 CPKIFKeyMaterialPtr km;
01146
01147
01148 if(NULL == ris || 0 == ris->count || kek == (CPKIFKEKRecipInfoDetails*)NULL)
01149 return km;
01150
01151
01152 CPKIFBufferPtr kid = kek->GetKeyIdentifier();
01153 if(kid == (CPKIFBuffer*)NULL)
01154 return km;
01155
01156
01157 DListNode* cur = ris->head;
01158 while(NULL != cur)
01159 {
01160 CACCMSRecipientInfo* ri = (CACCMSRecipientInfo*)cur->data;
01161
01162 switch(ri->t)
01163 {
01164 case 3:
01165 {
01166
01167 CACCMSKEKRecipientInfo* kekri = ri->u.kekri;
01168
01169
01170 CPKIFBuffer tmpKID(false, (unsigned char*)kekri->kekid.keyIdentifier.data, kekri->kekid.keyIdentifier.numocts);
01171 if(*kid == tmpKID)
01172 {
01173
01174
01175 CPKIFKeyMaterialPtr kmFound(new CPKIFKeyMaterial);
01176 unsigned char* pResult = new unsigned char[kekri->encryptedKey.numocts];
01177 int nResultLen = kekri->encryptedKey.numocts;
01178
01179 CPKIFKeyMaterialPtr theKEK = kek->GetKEK();
01180
01181 if(kekri->keyEncryptionAlgorithm.m.parametersPresent)
01182 {
01183 OOCTXT ctxt;
01184 initContext (&ctxt);
01185 setBERDecBufPtr(&ctxt, kekri->keyEncryptionAlgorithm.parameters.data, kekri->keyEncryptionAlgorithm.parameters.numocts, NULL, NULL);
01186 OOCTXT* pctxt = &ctxt;
01187
01188 unsigned char* hashVal = NULL;
01189 unsigned int hashValLen = 0;
01190
01191 int stat = decodeDynOctStr (pctxt, (const OSOCTET* *)&hashVal, (OSUINT32 *)&hashValLen, ASN1EXPL, kekri->keyEncryptionAlgorithm.parameters.numocts);
01192 if (stat != ASN_OK)
01193 {
01194
01195
01196 freeContext(&ctxt);
01197 throw CPKIFMessageException(TOOLKIT_MESSAGE_ASN, ASN1_DECODE_ERROR, "Failed to decode hash value");
01198 }
01199
01200 theKEK->SetIV(hashVal, hashValLen);
01201
01202
01203
01204
01205 freeContext(&ctxt);
01206 }
01207
01208 try
01209 {
01210 cKeyID->Decrypt(*theKEK, (unsigned char*)kekri->encryptedKey.data, kekri->encryptedKey.numocts, pResult, &nResultLen);
01211 }
01212 catch(...)
01213 {
01214
01215 if(pResult)
01216 delete[] pResult;
01217
01218 throw;
01219 }
01220
01221
01222 kmFound->SetSymmetricKey(pResult, nResultLen);
01223
01224
01225 memset(pResult, 0, nResultLen); delete[] pResult;
01226 return kmFound;
01227 }
01228 break;
01229 }
01230 case 1:
01231 case 2:
01232 default:
01233
01234 break;
01235 }
01236
01237 cur = cur->next;
01238 }
01239
01240
01241 return km;
01242 }
01250 CPKIFCertificatePtr GetOriginatorCertFromOriginatorInfo(
01252 CACCMSKeyAgreeRecipientInfo* kari,
01254 CACCMSOriginatorInfo* oi)
01255 {
01256 CPKIFCertificatePtr emptyCert;
01257 if(!kari || !oi || !oi->m.certsPresent)
01258 return emptyCert;
01259
01260 DListNode* iter = oi->certs.head;
01261 while(NULL != iter)
01262 {
01263 CACCMSCertificateChoices* curChoice = (CACCMSCertificateChoices*)iter->data;
01264 if(T_CACCMSCertificateChoices_certificate != curChoice->t)
01265 {
01266 iter = iter->next;
01267 continue;
01268 }
01269
01270 ASN1OpenType* cert = (ASN1OpenType*)curChoice->u.certificate;
01271
01272 try
01273 {
01274 CPKIFCertificatePtr newCert(new CPKIFCertificate());
01275 newCert->Decode(cert->data, cert->numocts);
01276
01277 if(T_CACCMSOriginatorIdentifierOrKey_subjectKeyIdentifier == kari->originator.t)
01278 {
01279 CPKIFSubjectKeyIdentifierPtr skid = newCert->GetExtension<CPKIFSubjectKeyIdentifier>();
01280 if(skid != (CPKIFSubjectKeyIdentifier*)NULL)
01281 {
01282 CPKIFBufferPtr skidBuf = skid->KeyIdentifier();
01283 if(skidBuf->GetLength() == (kari->originator.u.subjectKeyIdentifier->numocts) &&
01284 0 == memcmp(skidBuf->GetBuffer(), kari->originator.u.subjectKeyIdentifier->data, skidBuf->GetLength()))
01285 return newCert;
01286 }
01287 }
01288 else if(T_CACCMSOriginatorIdentifierOrKey_originatorKey == kari->originator.t)
01289 {
01290 CPKIFBufferPtr rawKey = newCert->SubjectPublicKeyInfo()->rawKey();
01291 if(rawKey->GetLength() == (kari->originator.u.originatorKey->publicKey.numbits/8) &&
01292 0 == memcmp(rawKey->GetBuffer(), kari->originator.u.originatorKey->publicKey.data, rawKey->GetLength()))
01293 return newCert;
01294 }
01295 else if(T_CACCMSOriginatorIdentifierOrKey_issuerAndSerialNumber == kari->originator.t)
01296 {
01297
01298 }
01299 }
01300 catch(CPKIFException&)
01301 {
01302
01303 }
01304 catch(std::bad_alloc& ba)
01305 {
01306
01307 throw ba;
01308 }
01309
01310 iter = iter->next;
01311 }
01312 return emptyCert;
01313 }
01314
01327 CPKIFBufferPtr GetOriginatorPublicKey(
01329 CACCMSKeyAgreeRecipientInfo* kari,
01331 CACCMSOriginatorInfo* oi,
01333 CPKIFCertificatePtr& origCert)
01334 {
01335
01336 CPKIFCertificatePtr emptyCert;
01337 origCert = emptyCert;
01338
01339 CPKIFBufferPtr origPubKey;
01340 if(T_CACCMSOriginatorIdentifierOrKey_originatorKey == kari->originator.t)
01341 {
01342
01343 CPKIFBufferPtr tmprv(new CPKIFBuffer(kari->originator.u.originatorKey->publicKey.data, kari->originator.u.originatorKey->publicKey.numbits/8));
01344 origPubKey = tmprv;
01345 }
01346
01347 if(oi)
01348 {
01349
01350 origCert = GetOriginatorCertFromOriginatorInfo(kari, oi);
01351 }
01352
01353 if(origCert == (CPKIFCertificate*)NULL)
01354 {
01355
01356 }
01357
01358 if(origCert != (CPKIFCertificate*)NULL && origPubKey == (CPKIFBuffer*)NULL)
01359 {
01360 origPubKey = origCert->GetSubjectPublicKeyInfo()->rawKey();
01361 }
01362
01363 return origPubKey;
01364 }
01365
01374 CPKIFKeyMaterialPtr GetSymmetricKey(
01376 CPKIFCredentialPtr& cred,
01378 IPKIFCryptoKeyIDOperations* cKeyID,
01380 CACCMSRecipientInfos* ris,
01381 IPKIFCryptoKeyAgree* ka,
01382 IPKIFCryptoRawOperations* cRaw,
01383 CACCMSOriginatorInfo* oi)
01384 {
01385 CPKIFKeyMaterialPtr km;
01386 if(NULL == ris || 0 == ris->count)
01387 return km;
01388
01389
01390 CPKIFCertificatePtr cert = cred->GetCertificate();
01391 if(cert == (CPKIFCertificate*)NULL)
01392 return km;
01393
01394 CPKIFNamePtr issuer = cert->Issuer();
01395 const char* serial = cert->SerialNumber();
01396 CPKIFSubjectKeyIdentifierPtr skid = cert->GetExtension<CPKIFSubjectKeyIdentifier>();
01397
01398 DListNode* cur = ris->head;
01399 while(NULL != cur)
01400 {
01401 CACCMSRecipientInfo* ri = (CACCMSRecipientInfo*)cur->data;
01402
01403 switch(ri->t)
01404 {
01405 case 1:
01406 {
01407 CACCMSKeyTransRecipientInfo* ktri = ri->u.ktri;
01408 if(RIDMatch(&ktri->rid, issuer, serial, skid))
01409 {
01410 unsigned char* pResult = new unsigned char[ktri->encryptedKey.numocts];
01411 int nResultLen = ktri->encryptedKey.numocts;
01412
01413
01414 try
01415 {
01416 cKeyID->Decrypt(*cred, (unsigned char*)ktri->encryptedKey.data, ktri->encryptedKey.numocts, pResult, &nResultLen);
01417 }
01418 catch(CPKIFException& e)
01419 {
01420 if(pResult)
01421 delete[] pResult;
01422
01423 throw e;
01424 }
01425 catch(std::exception& se)
01426 {
01427 if(pResult)
01428 delete[] pResult;
01429
01430 throw se;
01431 }
01432
01433 CPKIFKeyMaterialPtr kmFound(new CPKIFKeyMaterial);
01434 kmFound->SetSymmetricKey(pResult, nResultLen);
01435 delete[] pResult;
01436 return kmFound;
01437 }
01438 }
01439 break;
01440 case 2:
01441 {
01442 if(!ka) break;
01443
01444 CACCMSKeyAgreeRecipientInfo* kari = ri->u.kari;
01445
01446
01447 CPKIFOIDPtr kekAlgOID(new CPKIFOID(kari->keyEncryptionAlgorithm.algorithm.subid, kari->keyEncryptionAlgorithm.algorithm.numids));
01448 CPKIFAlgorithm* kekAlg = CPKIFAlgorithm::GetAlg(kekAlgOID);
01449
01450
01451 CPKIFCertificatePtr origCert;
01452 CPKIFBufferPtr origPublicKey = GetOriginatorPublicKey(kari, oi, origCert);
01453 if(origCert != (CPKIFCertificate*)NULL)
01454 {
01455
01456
01457 }
01458 CPKIFAlgorithm * kwAlg = 0;
01459
01460
01461
01462 IPKIFKeyAgreeContextPtr ctx;
01463
01464 if(*kekAlgOID == *g_ecdh_std_sha1kdf) {
01465 if(!ri->u.kari->keyEncryptionAlgorithm.m.parametersPresent) {
01466
01467
01468 break;
01469 }
01470 CACASNWRAPPER_CREATE(ECC_CMS_SharedInfo,ecsPDU);
01471 ECC_CMS_SharedInfo * si = ecsPDU.Decode( ri->u.kari->keyEncryptionAlgorithm.parameters );
01472 if(!si) {
01473 break;
01474 }
01475 CPKIFOIDPtr kwAlgOID(new CPKIFOID(si->keyInfo.algorithm.subid,si->keyInfo.algorithm.numids));
01476 kwAlg = CPKIFAlgorithm::GetAlg(kwAlgOID);
01477 if(!kwAlg) {
01478
01479 break;
01480 }
01481 ctx = ka->SecretAgree(cred,origPublicKey, kekAlg);
01482
01483 } else if(*kekAlgOID == *g_ecmqv_sha1kdf) {
01484 if(!ri->u.kari->keyEncryptionAlgorithm.m.parametersPresent) {
01485
01486
01487 break;
01488 }
01489 if(!ri->u.kari->m.ukmPresent) {
01490
01491
01492 break;
01493 }
01494 CACASNWRAPPER_CREATE(ECC_CMS_SharedInfo,ecsPDU);
01495 ECC_CMS_SharedInfo * si = ecsPDU.Decode( ri->u.kari->keyEncryptionAlgorithm.parameters );
01496 if(!si) {
01497 break;
01498 }
01499 CPKIFOIDPtr kwAlgOID(new CPKIFOID(si->keyInfo.algorithm.subid,si->keyInfo.algorithm.numids));
01500 kwAlg = CPKIFAlgorithm::GetAlg(kwAlgOID);
01501 if(!kwAlg) {
01502
01503 break;
01504 }
01505 CACASNWRAPPER_CREATE(MQVuserKeyingMaterial,ukmPDU);
01506 MQVuserKeyingMaterial * ukm = ukmPDU.Decode(ri->u.kari->ukm.data, ri->u.kari->ukm.numocts);
01507 CPKIFBufferPtr ephemPK(new CPKIFBuffer(ukm->ephemeralPublicKey.publicKey.data,ukm->ephemeralPublicKey.publicKey.numbits/8));
01508 ctx = ka->SecretAgree(cred, ephemPK, origPublicKey, kekAlg);
01509
01510 } else {
01511 break;
01512 }
01513
01514 CPKIFKeyMaterialPtr kek;
01515 CPKIFBufferPtr sharedInfo(new CPKIFBuffer(ri->u.kari->keyEncryptionAlgorithm.parameters.data,ri->u.kari->keyEncryptionAlgorithm.parameters.numocts));
01516 ctx->AppendSharedInfo(sharedInfo);
01517 kek = ka->DeriveKey(ctx,kwAlg->KeySize());
01518 if(!kek) break;
01519 kek->SetSymmetricKeyAlgorithm(kwAlg->SymkeyAlg());
01520 kek->SetMode(kwAlg->SymkeyMode());
01521
01522
01523 DListNode* node = kari->recipientEncryptedKeys.head;
01524 CACCMSRecipientEncryptedKey* rid = NULL;
01525 for(OSUINT32 ii = 0; ii < kari->recipientEncryptedKeys.count; ++ii)
01526 {
01527 rid = (CACCMSRecipientEncryptedKey*)node->data;
01528 if(RIDMatch(&rid->rid, issuer, serial, skid))
01529 {
01530
01531 unsigned char* pResult = new unsigned char[rid->encryptedKey.numocts];
01532 int nResultLen = rid->encryptedKey.numocts;
01533
01534 try
01535 {
01536 cRaw->Decrypt(*kek, (unsigned char*)rid->encryptedKey.data, rid->encryptedKey.numocts, pResult, &nResultLen);
01537 }
01538 catch(CPKIFException& e)
01539 {
01540 if(pResult)
01541 delete[] pResult;
01542
01543 throw e;
01544 }
01545 catch(std::exception& se)
01546 {
01547 if(pResult)
01548 delete[] pResult;
01549
01550 throw se;
01551 }
01552
01553
01554 CPKIFKeyMaterialPtr kmFound(new CPKIFKeyMaterial);
01555 kmFound->SetSymmetricKey(pResult, nResultLen);
01556 delete[] pResult;
01557 return kmFound;
01558 }
01559 node = node->next;
01560 }
01561
01562 }
01563 break;
01564 case 3:
01565
01566 break;
01567 }
01568
01569 cur = cur->next;
01570 }
01571
01572 return km;
01573 }
01581 CPKIFCredentialPtr AutoDiscoverDecryptionKey(
01583 IPKIFCryptoKeyIDOperations* cKeyID,
01585 CACCMSRecipientInfos* ris)
01586 {
01587
01588
01589 CPKIFCredentialPtr tmpCred;
01590 if(NULL == cKeyID || NULL == ris || 0 == ris->count)
01591 return tmpCred;
01592
01593
01594 bitset<9> ku = PKIFCRYPTO::KeyEncipherment;
01595 CPKIFCredentialList vKeyID;
01596 try
01597 {
01598 cKeyID->GetKeyList(vKeyID, &ku);
01599 }
01600 catch(CPKIFException& e)
01601 {
01602 throw e;
01603 }
01604
01605 CPKIFCredentialList::iterator pos, match;
01606 CPKIFCredentialList::iterator end = vKeyID.end();
01607 for(pos = vKeyID.begin(); pos != end; ++pos)
01608 {
01609 CPKIFCertificatePtr cert = (*pos)->GetCertificate();
01610 if(cert == (CPKIFCertificate*)NULL)
01611 continue;
01612
01613 CPKIFNamePtr issuer = cert->Issuer();
01614 const char* serial = cert->SerialNumber();
01615 CPKIFSubjectKeyIdentifierPtr skid = cert->GetExtension<CPKIFSubjectKeyIdentifier>();
01616
01617
01618
01619 DListNode* cur = ris->head;
01620 while(NULL != cur)
01621 {
01622 CACCMSRecipientInfo* ri = (CACCMSRecipientInfo*)cur->data;
01623
01624 switch(ri->t)
01625 {
01626 case 1:
01627 {
01628 CACCMSKeyTransRecipientInfo* ktri = ri->u.ktri;
01629 if(RIDMatch(&ktri->rid, issuer, serial, skid))
01630 return *pos;
01631 }
01632 break;
01633 case 2:
01634 case 3:
01635
01636 break;
01637 }
01638
01639 cur = cur->next;
01640 }
01641 }
01642
01643 return tmpCred;
01644 }
01654 void EncodeIVAsOctetString(
01656 unsigned char* iv,
01658 int ivLen,
01660 unsigned char** encodedIV,
01662 int* encodedIVLen)
01663 {
01664 OOCTXT ctxt;
01665 initContext (&ctxt);
01666 setBEREncBufPtr(&ctxt, NULL, 0);
01667 OOCTXT* pctxt = &ctxt;
01668
01669 int stat = encodeOctStr (pctxt, (const OSOCTET*)iv, (OSUINT32)ivLen, ASN1EXPL);
01670 if (stat < 0)
01671 {
01672 throw CPKIFMessageException(TOOLKIT_MESSAGE_ASN, ASN1_ENCODE_ERROR, "Failed to encode IV value");
01673 }
01674
01675 *encodedIVLen = stat;
01676 char* tmpP = (char*)getBEREncBufPtr(&ctxt);
01677
01678 *encodedIV = new unsigned char[*encodedIVLen];
01679 memcpy(*encodedIV, tmpP, *encodedIVLen);
01680
01681
01682 freeEncodeBuffer(&ctxt);
01683 memFreeAll(&ctxt);
01684 }
01685
01686
01687
01699 CPKIFBufferPtr PKIFCMS_API Countersign(
01701 CPKIFSignerInfoPtr& siToCounterSign,
01703 CPKIFSignerInfoPtr& countersignerSI,
01705 IPKIFMediatorPtr& mediator)
01706 {
01707
01708
01709
01710 if(siToCounterSign == (CPKIFSignerInfo*)NULL || countersignerSI == (CPKIFSignerInfo*)NULL || NULL == mediator)
01711 throw CPKIFMessageException(TOOLKIT_MESSAGE, COMMON_INVALID_INPUT, "One or more NULL parameters passed to VerifyCounterSignatures.");
01712
01713 CPKIFBufferPtr sigBP = siToCounterSign->GetSignature();
01714 if(sigBP == (CPKIFBuffer*)NULL)
01715 throw CPKIFMessageException(TOOLKIT_MESSAGE, COMMON_INVALID_INPUT, "The SignerInfo to countersign does not contain a signature.");
01716
01717 IPKIFCryptoMisc* cMisc = mediator->GetMediator<IPKIFCryptoMisc>();
01718 if(NULL == cMisc)
01719 throw CPKIFMessageException(TOOLKIT_MESSAGE, COMMON_MEDIATOR_MISSING, "IPKIFCryptoMisc interface is not available.");
01720
01721
01722
01723
01724
01725 CPKIFAlgorithmIdentifierPtr counterSignerDigestAlg = countersignerSI->GetDigestAlg();
01726 PKIFCRYPTO::HASH_ALG ha = PKIFCRYPTO::SHA1;
01727 if(!GetCACHashAlg(counterSignerDigestAlg->oid(), &ha))
01728 throw CPKIFMessageException(TOOLKIT_MESSAGE, COMMON_UNSUPPORTED_ALG, "Unsupported hashing algorithm encountered during countersignature generation.");
01729
01730 unsigned char hashResult[MAXHASH];
01731 int hashResultLen = MAXHASH;
01732 if(!countersignerSI->Decoded())
01733 {
01734 CPKIFCredentialPtr cred = countersignerSI->GetCredential();
01735 if(cred == (CPKIFCredential*)NULL)
01736 throw CPKIFMessageException(TOOLKIT_MESSAGE, COMMON_INVALID_INPUT, "The SignerInfo of the countersigner does not contain a credential.");
01737
01738 IPKIFHashContext* hi = cMisc->HashInit(ha);
01739 cMisc->HashUpdate(hi, (unsigned char*)sigBP->GetBuffer(), sigBP->GetLength());
01740 cMisc->HashFinal(hi, hashResult, &hashResultLen);
01741 delete hi;
01742 }
01743
01744
01745
01746
01747
01748
01749
01750 PKIFCMSMessageMemoryHelper mhSignerInfo;
01751 mhSignerInfo.pSignerInfo = new CACCMSSignerInfo;
01752 GetSignerInfo(mhSignerInfo.pSignerInfo, countersignerSI, hashResult, hashResultLen, mediator, g_data, ha, true);
01753
01754
01755
01756
01757 CACASNWRAPPER_CREATE(CACCMSSignerInfo, tmpPDU);
01758 ASN1OpenType* data1 = tmpPDU.Encode(mhSignerInfo.pSignerInfo);
01759
01760
01761 CPKIFBufferPtr data1Buf(new CPKIFBuffer(data1->data, data1->numocts));
01762 CPKIFSignerInfoPtr newCountersignerSI(new CPKIFSignerInfo(data1Buf));
01763
01764 countersignerSI = newCountersignerSI;
01765
01766 CPKIFBufferPtr tmp;
01767 try
01768 {
01769
01770 CPKIFBufferPtr tmpTmp(new CPKIFBuffer((unsigned char*)data1->data, data1->numocts));
01771 tmp = tmpTmp;
01772 delete data1; data1 = NULL;
01773 }
01774 catch(std::bad_alloc& ba)
01775 {
01776 if(data1)
01777 delete data1;
01778 throw ba;
01779 }
01780
01781 return tmp;
01782 }
01783
01800 void PKIFCMS_API VerifyCounterSignatures(
01803 CPKIFSignedDataPtr& sd,
01806 CPKIFSignerInfoPtr& si,
01809 IPKIFMediatorPtr& mediator,
01812 CPKIFPathSettingsPtr& settings,
01815 CPKIFSignerInfoList& sis,
01818 vector<CMSVerificationStatus>& statusVector,
01821 CPKIFCertificateList& certVector,
01824 vector<CPKIFCertificatePathPtr>& pathVector)
01825 {
01826 CPKIFFuncStoragePtr keyUsageSigFunctor3(new CPKIFFuncStorage(keyUsageChecker_Signature));
01827
01828
01829
01830
01831 if(sd == (CPKIFSignedData*)NULL || si == (CPKIFSignerInfo*)NULL || mediator == (IPKIFMediator*)NULL)
01832 throw CPKIFMessageException(TOOLKIT_MESSAGE, COMMON_INVALID_INPUT, "One or more NULL parameters passed to VerifyCounterSignatures.");
01833
01834 IPKIFCryptoRawOperations* cRaw = mediator->GetMediator<IPKIFCryptoRawOperations>();
01835 if(NULL == cRaw)
01836 throw CPKIFMessageException(TOOLKIT_MESSAGE, COMMON_MEDIATOR_MISSING, "IPKIFCryptoRawOperations interface is not available.");
01837
01838 IPKIFCryptoMisc* cMisc = mediator->GetMediator<IPKIFCryptoMisc>();
01839 if(NULL == cMisc)
01840 throw CPKIFMessageException(TOOLKIT_MESSAGE, COMMON_MEDIATOR_MISSING, "IPKIFCryptoMisc interface is not available.");
01841
01842
01843
01844
01845
01846 CPKIFCountersignatureAttributePtr csAttr = si->GetUnsignedAttribute<CPKIFCountersignatureAttribute>();
01847 if(csAttr == (CPKIFCountersignatureAttribute*)NULL)
01848 return;
01849
01850 CPKIFBufferPtr sigBP = si->GetSignature();
01851 if(sigBP == (CPKIFBuffer*)NULL)
01852 return;
01853
01854 HashInfo hi2;
01855 hi2.m_hashAlg = PKIFCRYPTO::SHA1;
01856
01857 int hashResultLen = MAXHASH;
01858
01859 PKIFCRYPTO::HASH_ALG ha = PKIFCRYPTO::SHA1;
01860
01861 CPKIFAlgorithmIdentifierPtr sigAlg = si->GetDigestAlg();
01862 GetCACHashAlg(sigAlg->oid(), &ha);
01863 GetCACHashAlg(sigAlg->oid(), &hi2.m_hashAlg);
01864
01865 IPKIFHashContext* hi = cMisc->HashInit(ha);
01866 cMisc->HashUpdate(hi, (unsigned char*)sigBP->GetBuffer(), sigBP->GetLength());
01867 cMisc->HashFinal(hi, hi2.m_hashResult, &hashResultLen);
01868 delete hi;
01869
01870
01871
01872
01873
01874
01875 CPKIFBufferList bl;
01876 csAttr->GetValues(bl);
01877
01878 CPKIFBufferList::iterator blPos;
01879 CPKIFBufferList::iterator blEnd = bl.end();
01880 int ii = 0;
01881 CPKIFCertificatePtr emptyCert;
01882 for(blPos = bl.begin(); blPos != blEnd; ++blPos, ++ii)
01883 {
01884
01885 CACASNWRAPPER_CREATE(CACCMSSignerInfo, tmpPDU);
01886 CACCMSSignerInfo* curSI = tmpPDU.Decode((*blPos)->GetBuffer(), (*blPos)->GetLength());
01887 CPKIFBufferPtr curSIBuf(new CPKIFBuffer((*blPos)->GetBuffer(), (*blPos)->GetLength()));
01888
01889
01890 CPKIFSignerInfoPtr newSI(new CPKIFSignerInfo(curSIBuf));
01891
01892 sis.push_back(newSI);
01893 statusVector.push_back(NOT_VERIFIED);
01894 certVector.push_back(emptyCert);
01895
01896
01897
01898
01899 CPKIFBufferPtr signerCert = sd->GetSignersCert(curSIBuf);
01900
01901 if(signerCert == (CPKIFCertificate*)NULL)
01902 continue;
01903 else
01904 {
01905 CPKIFCertificatePtr newSignerCert(new CPKIFCertificate);
01906 newSignerCert->Decode(signerCert->GetBuffer(), signerCert->GetLength());
01907 certVector[ii] = newSignerCert;
01908 }
01909
01910
01911 HashInfo* hi = NULL;
01912 bool deleteHI = false;
01913 if(curSI->m.signedAttrsPresent)
01914 {
01915 hi = ComputeSignedAttrHash(curSI, cMisc);
01916 deleteHI = true;
01917 if(!CompareHashes(&hi2, curSI))
01918 {
01919
01920
01921 statusVector[ii] = CMS_SIGNATURE_INVALID;
01922 delete hi;
01923 continue;
01924 }
01925 }
01926 else
01927 hi = &hi2;
01928
01929
01930 CPKIFKeyMaterial key;
01931 key.SetCertificate(signerCert->GetBuffer(), signerCert->GetLength());
01932
01933 bool bRetrySigWithParams = false;
01934
01935
01936 try
01937 {
01938 if(!cRaw->Verify(key, hi->m_hashResult, CPKIFAlgorithm::GetAlg(hi->m_hashAlg)->DigestSize(), (unsigned char*)curSI->signature.data, curSI->signature.numocts, hi->m_hashAlg))
01939 {
01940 if(NULL != hi && deleteHI)
01941 delete hi;
01942 statusVector[ii] = CMS_SIGNATURE_INVALID;
01943 return;
01944 }
01945 else
01946 {
01947 if(NULL != hi && deleteHI)
01948 delete hi;
01949 statusVector[ii] = CMS_SIGNATURE_VERIFIED;
01950 }
01951 }
01952 catch(CPKIFException& ce)
01953 {
01954 if(PKIFCAPING_KEY_IMPORT_FAILED != ce.GetErrorCode() &&
01955 PKIFCAPI_KEY_IMPORT_FAILED != ce.GetErrorCode() &&
01956 PKIF_CRYPTOPP_RAW_IMPORT_FAILED != ce.GetErrorCode() &&
01957 PKIFNSS_CERT_IMPORT_FAILED != ce.GetErrorCode())
01958 {
01959 throw ce;
01960 }
01961 else
01962 {
01963 bRetrySigWithParams = true;
01964 }
01965 }
01966 IPKIFPathBuild* cBuild = mediator->GetMediator<IPKIFPathBuild>();
01967 if(NULL == cBuild)
01968 continue;
01969
01970 IPKIFPathValidate* cValidate = mediator->GetMediator<IPKIFPathValidate>();
01971 if(NULL == cValidate)
01972 continue;
01973
01974 CPKIFCertificatePathPtr tmpPath(new CPKIFCertificatePath);
01975 pathVector.push_back(tmpPath);
01976
01977 CPKIFPathValidationResultsPtr tmpValResults(new CPKIFPathValidationResults);
01978
01979 CPKIFCertificatePtr signersCert(new CPKIFCertificate());
01980 signersCert->Decode(signerCert->GetBuffer(), signerCert->GetLength());
01981 tmpPath->SetTarget(signersCert);
01982
01983
01984
01985
01986 if(settings != (CPKIFPathSettings*)NULL)
01987 tmpPath->SetPathSettings(settings);
01988
01989 try
01990 {
01991 do
01992 {
01993 if(!cBuild->BuildPath(*tmpPath))
01994 {
01995
01996 break;
01997 }
01998 if(cValidate->ValidatePath(*tmpPath, *tmpValResults, keyUsageSigFunctor3))
01999 {
02000 if(NOT_REVOKED == tmpValResults->GetRevocationStatusMostSevere())
02001 {
02002 if(bRetrySigWithParams)
02003 {
02004 CPKIFAlgorithmIdentifierPtr wp = tmpValResults->GetWorkingParams();
02005 key.SetWorkingParameters(wp);
02006 if(!cRaw->Verify(key, hi->m_hashResult, CPKIFAlgorithm::GetAlg(hi->m_hashAlg)->DigestSize(), (unsigned char*)curSI->signature.data, curSI->signature.numocts, hi->m_hashAlg))
02007 {
02008 if(NULL != hi && deleteHI)
02009 delete hi;
02010 statusVector[ii] = CMS_SIGNATURE_INVALID;
02011 return;
02012 }
02013 else
02014 {
02015 if(NULL != hi && deleteHI)
02016 delete hi;
02017 statusVector[ii] = CMS_SIGNATURE_VERIFIED;
02018 }
02019 }
02020
02021 statusVector[ii] = REV_STATUS_VERIFIED;
02022
02023
02024 break;
02025 }
02026 else
02027 {
02028 if(bRetrySigWithParams)
02029 {
02030 CPKIFAlgorithmIdentifierPtr wp = tmpValResults->GetWorkingParams();
02031 key.SetWorkingParameters(wp);
02032 if(!cRaw->Verify(key, hi->m_hashResult, CPKIFAlgorithm::GetAlg(hi->m_hashAlg)->DigestSize(), (unsigned char*)curSI->signature.data, curSI->signature.numocts, hi->m_hashAlg))
02033 {
02034 if(NULL != hi && deleteHI)
02035 delete hi;
02036 statusVector[ii] = CMS_SIGNATURE_INVALID;
02037 return;
02038 }
02039 else
02040 {
02041 if(NULL != hi && deleteHI)
02042 delete hi;
02043 statusVector[ii] = CMS_SIGNATURE_VERIFIED;
02044 }
02045 }
02046
02047 statusVector[ii] = CERT_PATH_VERIFIED;
02048
02049
02050 break;
02051 }
02052 }
02053 else
02054 {
02055 if(!tmpValResults->GetBasicChecksSuccessfullyPerformed() ||
02056 !tmpValResults->GetCertSignaturesVerified())
02057 {
02058
02059 if(bRetrySigWithParams)
02060 {
02061 if(NULL != hi && deleteHI)
02062 delete hi;
02063 statusVector[ii] = CMS_SIGNATURE_INVALID;
02064 return;
02065 }
02066
02067 statusVector[ii] = CERT_PATH_INVALID;
02068
02069
02070 continue;
02071 }
02072 else if(REVOKED == tmpValResults->GetRevocationStatusMostSevere())
02073 {
02074 if(bRetrySigWithParams)
02075 {
02076 if(NULL != hi && deleteHI)
02077 delete hi;
02078 statusVector[ii] = CMS_SIGNATURE_INVALID;
02079 return;
02080 }
02081
02082 statusVector[ii] = REV_STATUS_INVALID;
02083
02084
02085
02086
02087 CPKIFCertificateNodeEntryPtr errantCertNode = tmpValResults->GetCertificate();
02088 if(errantCertNode != (CPKIFCertificateNodeEntry*)NULL)
02089 {
02090 CPKIFCertificatePtr errantCert = errantCertNode->GetCert();
02091 if(errantCert != (CPKIFCertificate*)NULL && *errantCert == *signersCert)
02092 {
02093
02094 continue;
02095 }
02096 }
02097 }
02098 else if(tmpValResults->GetBasicChecksSuccessfullyPerformed() &&
02099 tmpValResults->GetCertSignaturesVerified())
02100 {
02101 if(bRetrySigWithParams)
02102 {
02103 CPKIFAlgorithmIdentifierPtr wp = tmpValResults->GetWorkingParams();
02104 key.SetWorkingParameters(wp);
02105 if(!cRaw->Verify(key, hi->m_hashResult, CPKIFAlgorithm::GetAlg(hi->m_hashAlg)->DigestSize(), (unsigned char*)curSI->signature.data, curSI->signature.numocts, hi->m_hashAlg))
02106 {
02107 if(NULL != hi && deleteHI)
02108 delete hi;
02109 statusVector[ii] = CMS_SIGNATURE_INVALID;
02110 return;
02111 }
02112 else
02113 {
02114 if(NULL != hi && deleteHI)
02115 delete hi;
02116 statusVector[ii] = CMS_SIGNATURE_VERIFIED;
02117 }
02118 }
02119 statusVector[ii] = CERT_PATH_VERIFIED;
02120
02121
02122 continue;
02123 }
02124 }
02125 }while(1);
02126 }
02127 catch(CPKIFException&)
02128 {
02129
02130 continue;
02131 }
02132 }
02133
02134 }
02143 void PopulateKARIDFromKeyMaterial(
02145 CACCMSKeyAgreeRecipientIdentifier* rid,
02148 CPKIFKeyMaterialPtr& km)
02149 {
02150 CPKIFBufferPtr certBuf(new CPKIFBuffer());
02151 int rawLen = km->GetCertificateLength();
02152 unsigned char * cbRaw = certBuf->AllocateBuffer(rawLen);
02153 km->GetCertificate(cbRaw,&rawLen);
02154 CPKIFCertificatePtr cert(new CPKIFCertificate());
02155 cert->Decode(certBuf->GetBuffer(),rawLen);
02156 CPKIFSubjectKeyIdentifierPtr skid = cert->GetExtension<CPKIFSubjectKeyIdentifier>();
02157 if(skid) {
02158 CPKIFBufferPtr skidBuf = skid->KeyIdentifier();
02159 rid->t = T_CACCMSKeyAgreeRecipientIdentifier_rKeyId;
02160 rid->u.rKeyId = new CACCMSRecipientKeyIdentifier;
02161 memset(&(rid->u.rKeyId),0x00,sizeof(CACCMSRecipientKeyIdentifier));
02162 int skidLen = skidBuf->GetLength();
02163 rid->u.rKeyId->subjectKeyIdentifier.numocts = skidLen;
02164 rid->u.rKeyId->subjectKeyIdentifier.data = new unsigned char[skidLen];
02165 memcpy((void*)rid->u.rKeyId->subjectKeyIdentifier.data,skidBuf->GetBuffer(),skidLen);
02166 } else {
02167 rid->t = T_CACCMSKeyAgreeRecipientIdentifier_issuerAndSerialNumber;
02168 rid->u.issuerAndSerialNumber = new CACCMSIssuerAndSerialNumber;
02169 memset(rid->u.issuerAndSerialNumber,0x00,sizeof(CACCMSIssuerAndSerialNumber));
02170 rid->u.issuerAndSerialNumber->serialNumber = cert->SerialNumber();
02171 CPKIFBufferPtr nb = cert->Issuer()->rawName();
02172 CACASNWRAPPER_CREATE(CACX509V3Name, namePDU);
02173 CACX509V3Name * iName = namePDU.Decode(nb->GetBuffer(),nb->GetLength());
02174 CopyName(&rid->u.issuerAndSerialNumber->issuer, *iName);
02175 }
02176 }