RE: How to verify?
"Colestock, Robert" <[email protected]> Tue, 27 Mar 2001 10:14:55 -0500
| Newsgroups | gmane.ietf.sfl |
|---|---|
| Message-ID | <[email protected]> |
Erik: I am glad to hear it works. Are you running the version 1.9 SFL? There was a problem with the OPTIONAL ESSPrivacyMark on the previous release. It should be fixed when you upgrade. Bob Colestock VDA. -----Original Message----- From: Erik Rissanen [mailto:[email protected]] Sent: Tuesday, March 27, 2001 8:47 AM To: 'Colestock, Robert'; Erik Rissanen Cc: Pawling, John; '[email protected]' Subject: SV: How to verify? Hi. I have figured out what was wrong. The reason why Verify() would not use the NULL login was that PreProc() does not mark it as applicable. I did that myself, and verify now uses the login. The crash in the CSM_Buffer destructor was because I did not place a privacy mark in the security label when I generated the message. The RFCs describe the privacy mark as optional, and I didn't need it, so I just placed a NULL there. Encoding works well, but SFL will crash when processing a message with a security label with no privacy mark. I now generate a dummy privacy mark and I have successfully verified my SMIME message. Thanks for your help. Now I can start to use the ACL to do access control on the message. And I need to figure out why CML does not find a certification path for my certificates. Wish me good luck. ;-) Regards, Erik -----Ursprungligt meddelande----- FrÃ¥n: Colestock, Robert [ mailto:[email protected] <mailto:[email protected]> ] Skickat: den 26 mars 2001 21:24 Till: 'Erik Rissanen' Kopia: Pawling, John Ãmne: RE: How to verify? Erik: You only need to copy the certificate to CSM_MsgToVerify instance if it was not already present in the message. If the certificate was already in the SignedData message, then PreProc will copy the certificate to the appropriate place for you. The certificate is not in the SignerInfo, only the SignerID (SID), that identifies the certificate. The CSM_MsgToVerify::m_pMsgCertCrls will contain whatever is in the certificate bucket of the SignedData message. The only interaction with the application necessary is if the DSA parameters are not present in the user certificate (identified by the SignerInfo SID); they would be contained somewhere in the certificate path that may or may not be present in the SignedData certificate bucket. The SignedData may contain no certificates, in which case the application must lookup the SignerInfo SID and retrieve the necessary certificate(s) (enough of the certificate path to obtain the DSA params). The SFL ONLY uses the key from the certificate that matches the signer's name; it may have to check the certificate path for the DSA parameters (that may not be present in the user certificate). Seems I've said this before. As to the code; you do not have to do any of this. If the appropriate certificates are already contained in the CSM_SignerInfo (not to be confused with the SNACC ASN.1 SignerInfo class), then you are doubling up the certificate list in the certificate bucket. This operation is already done by the PreProc method, if the certificate(s) are in the SignedData. As to why it crashes, the "pCert" variable is pointing to the same memory as the certificate list (because you used the "Access..." method). This might seem confusing, but we were searching for a way for an application to use internal memory or a copy based on explicit calls to our classes; if you see "Access..." on a method name, it points to internal memory, "Get..." makes a copy that the application must delete when finished. The "pMsg->m_pMsgCertCrls->AddCert(pCert);" call takes the application memory directly, so that the application does not have to delete the "pCert" (this is described in the API document as well). Most such crashes are due to 2 pointers to the same memory, both attempting to destroy the class instances. As to why the free3 CTIL cannot process your message, I would need to see your data. Most of the above issues are related more to the data (e.g. SignedData with cert or cert-path, cert with DSA params already present), than to coding. To be flexible requires following the specification options (which allow for many choices when it comes to the presence of public information). Our library attempts to accommodate by providing the 2 steps: PreProc, where the app would then check for the presence of the appropriate info and complement if necessary, then Verify to perform the actual verification given the key info. If you see the supported signature algorithm in free3, then perhaps it fails on the digest alg? You need to check your data; considering that you have already modified the free3 CTIL, it should be an easy matter to check that the algorithm designated in the SignerInfo for the digest and signature are supported by the CTIL. (see "SetDefaultOIDs(...)", all of the algs are listed in data statements). The algorithm OIDs must match exactly. Bob Colestock VDA -----Original Message----- From: Erik Rissanen [ mailto:[email protected] <mailto:[email protected]> ] Sent: Monday, March 26, 2001 11:37 AM To: 'Colestock, Robert' Subject: SV: How to verify? You write that SFL only needs the public key to be able to verify a message, and it is not necessary to validate the certification path of the signer's certificate in order to SFL verify to succeed. Does that mean that I can just copy the certificate from the signerInfo to the CSM_MsgToVerify::m_pMsgCertCrls and Verify should work? Does SFL check that the whole certification path of the certificate is present, or does it just use the key from the certificate that matches the signer's name from CSM_MsgToVerify::m_pMsgCertCrls? I tried to just copy the certificate without validation, but Verify crashes inside the destructor of a CSM_Buffer object. Below is the code. Should Verify work? CSM_AppLogin *pAppLogin = new CSM_AppLogin("sm_free3DLLd", "sm_free3DLL NULL NULL NULL sm_FREE3"); CSM_MsgToVerify *pMsg = new CSM_MsgToVerify(pAppLogin, (CSM_Buffer *) pci->content.value); pMsg->PreProc(pAppLogin); // Just add the certificate from the SignerInfo to the list of verified certificates. pSI = pMsg->m_pSignerInfos->SetCurrToFirst(); CSM_CertificateChoiceLst *pCerts = pSI->AccessCerts(); CSM_CertificateChoice *pCert = pCerts->SetCurrToFirst(); if (!pMsg->m_pMsgCertCrls) pMsg->m_pMsgCertCrls = new CSM_MsgCertCrls; pMsg->m_pMsgCertCrls->AddCert(pCert); // The call below crashes SM_RET_VAL VerRes = pMsg->Verify(pAppLogin); Can you see anything abviously wrong with this? When I trace the code with the debugger I can see that in CSM_MsgSignerInfo::Verify on line 510 in file sm_MsgSignerInfo the call the CSM_SignBuf::GetFirstInstance(pCSMIME, &alg1, &alg2) returns NULL. After that the execution quickly returns two method calls and crashes in the CSM_Buffer destructor. I modified the default algorithm of the NULL login to rsa as you suggested. When I list the algorithms that the instance supports, I get RSA, but still it seems like SFL is unable to find an instance that supports the needed algorithm, or? Any suggestions on how to track this problem? Regards, Erik -----Ursprungligt meddelande----- FrÃ¥n: Colestock, Robert [ mailto:[email protected] <mailto:[email protected]> < mailto:[email protected] <mailto:[email protected]> > ] Skickat: den 23 mars 2001 17:58 Till: 'Erik Rissanen' Kopia: [email protected] Ãmne: RE: How to verify? Erik: A certificate path is just a group of certificates; they are inserted into the "m_pMsgCertCrls" variable 1 certificate at a time. If you have an ASN.1 encoded sequence of or set of certificates, simply navigate the list to insert a single certificate at a time into the member variable (that is what we do when re receive a message in pre-proc from the SignedData certificate bucket). You may not need the entire certificate path to verify if the DSA parameters are present in the user certificate. From a strict security standpoint you should get the entire path and verify that the user certificate signature is valid before calling the SFL verify, but the verify itself just needs the appropriate public key and DSA parameters (which may be in an issuer certificate). Your 6 steps are correct. You are correct, the NULL login only does DSA (oops). Temporarily I would suggest you override the default to rsa by changing the line in sm_free3.cpp from: if (pFree == NULL) { // THIS MEMORY will be returned in the CSM_Tokeninterface *. // generate a new FREE CTI class if ((pFree = new CSM_Free3(id_dsa)) == NULL) // DEFAULT DSA SME_THROW(SM_MEMORY_ERROR, NULL, NULL); // CSM_Free3 constructor set's Alg IDs } TO ... if ((pFree = new CSM_Free3(rsa)) == NULL) // DEFAULT DSA ... around line 3638 in "CSM_TokenInterface *CSM_Free3::AddLoginStatic(...)". I will fix this to allow both DSA and RSA for the next release. Sorry, I cannot help you with the CML, I do not believe it is related, but you can re-test with the above change to see if it makes a difference. If you still have problems with the CML lookup (it should work fine when the entries are present), e-mail back with your specific setup details for the CML, we will re-investigate. The CSM_MsgToVerify::m_pSignerInfos load could be a but, but this load is related to the presence of the CSMIME structure, since it aligns which instances can verify. This logic resides together at this time; it could be split to separately load SignerInfos, then align the logins through SignerInfo algs (at the time it seemed wasteful in performance to loop 2ce, but there are not many SignerInfos). Bob Colestock VDA -----Original Message----- From: Erik Rissanen [ mailto:[email protected] <mailto:[email protected]> < mailto:[email protected] <mailto:[email protected]> > ] Sent: Friday, March 23, 2001 7:27 AM To: 'Colestock, Robert' Cc: [email protected] Subject: SV: How to verify? You write that the application does not need to do anything if the signer's certificate is included in the message (did I understand you correctly?), but the SFL API documentation seems to claim otherwise. I am a bit confused about the SFL api documentation section 6.2.2.3. It states that the application has to obtain the ASN encoded certification path for each signature that it wishes to be verified. The path is to be inserted in CSM_MsgToVerify::m_pMsgCertCrls before the call to CSM_MsgToVerify::Verify. How is the path to be inserted? I can figure out from the API documentation which method to call if I want to insert a CRL, an AC or a certificate, but I cannot find anything about certification paths in the CSM_MsgCertCrls documentation. Are the following steps the correct way to verify a SMIME message: 1) Instantiate a CSM_Applogin with the sm_free3 NULL login as descibed in your reply. 2) Instantiate a CSM_MsgToVerify with my SMIME message and call PreProc(). 3) Extract the signer certificate from the CSM_MsgToVerify. 4) Use CML to obtain an ASN encoded certification path for the certificate. 5) Insert the certification path into the CSM_MsgToVerify according to above. 6) Call CSM_MsgToVerify::Verify. The CSM_CSInst instance that I get when I initiate a NULL CSM_AppLogin, does not list RSA as one of its supported algorithms. I am using RSA certificates, so will that be a problem? Also for some reason CML returns CM_NO_PATH_FOUND when I try to build the certification path (step 4 above). I don't know why, since all the necessary certificates are in the SRL database. Could it be caused because the CSM_CSInst does not list RSA? One more thing: Some of the overloaded versions of CSM_MsgToVerify::CSM_MsgToVerify and CSM_MsgToVerify::PreProc do not process the signerInfos so that they become available in CSM_MsgToVerify::m_pSignerInfos. Is this a bug? For instance: // Does not work: CSM_ContentInfoMsg *pcim = new CSM_ContentInfoMsg(pSMIMEMsg); CSM_MsgToVerify *pMsg = new CSM_MsgToVerify(pcim); pMsg->PreProc(pAppLogin); // pMsg->m_pSignerInfos == NULL now //Works: // pci is SNACC ContentInfo with signedData in pci->content CSM_MsgToVerify *pMsg = new CSM_MsgToVerify(pAppLogin, (CSM_Buffer *) pci->content.value); pMsg->PreProc(pAppLogin); // pMsg->m_pSignerInfos != NULL now Regards, Erik -----Ursprungligt meddelande----- FrÃ¥n: Colestock, Robert [ mailto:[email protected] <mailto:[email protected]> < mailto:[email protected] <mailto:[email protected]> > < mailto:[email protected] <mailto:[email protected]> < mailto:[email protected] <mailto:[email protected]> > > ] Skickat: den 22 mars 2001 15:45 Till: 'Erik Rissanen' Kopia: [email protected] Ãmne: RE: How to verify? Erik: Step 5 is not appropriate. If the signing certifcate is already contained in the message, pre-proc has already loaded it into the appropriate place for the verify functionality to process the public key. The only application interaction necessary in the verification is if the certificate is not in the message; in this case it would be necessary to access the SID from the SignerInfo(s) and lookup the certificate (from ldap, or local storage???). In this case, the certificate would have to be added to the CSM_MsgToVerify certificate bucket before calling the Verify method. The login certificate is only used to load the signer's certificate on origination of a signed message. Bob Colestock VDA -----Original Message----- From: Erik Rissanen [ mailto:[email protected] <mailto:[email protected]> < mailto:[email protected] <mailto:[email protected]> > < mailto:[email protected] <mailto:[email protected]> < mailto:[email protected] <mailto:[email protected]> > > ] Sent: Thursday, March 22, 2001 6:56 AM To: 'Colestock, Robert'; Erik Rissanen Cc: [email protected] Subject: SV: How to verify? Thank you for your reply. So now I have a CSM_CSInst to use for the verification. But I still don't understand how I should put the public key in it. I assume that my application has to do as follows: 1) Instantiate a CSM_Applogin with the sm_free3 NULL login as descibed in your reply. 2) Instantiate a CSM_MsgToVerify with my SMIME message and call PreProc(). 3) Extract the signer certificate from the CSM_MsgToVerify 4) Validate the certificate (with CML). 5) Insert the certificate into the CSM_CSInst contained in the CSM_Applogin??? 6) Call CSM_MsgToVerify::Verify. Is this correct and how do I perform step 5? Regards, Erik -----Ursprungligt meddelande----- FrÃ¥n: Colestock, Robert [ mailto:[email protected] <mailto:[email protected]> < mailto:[email protected] <mailto:[email protected]> > < mailto:[email protected] <mailto:[email protected]> < mailto:[email protected] <mailto:[email protected]> > > ] Skickat: den 21 mars 2001 17:07 Till: Erik Rissanen Kopia: [email protected] Ãmne: RE: How to verify? Erik: There were some problems with NULL logins, depending on your release. The original intent was that the application would use the same logins (always present) for verification that are used for signing. Since our original design, our own uses of the library dictate that we many times generate a login only when we need it. You can use the CSM_CSInst with a private key for verification. As to the NULL logins, it should work fine in the newest version; for DSA verification it is now built-in, you no longer need to use the Free3 CTIL (assuming SHA1 and DSA). You do not have to link directly, the BuildArgs should be "sm_free3DLL NULL NULL NULL sm_FREE3" (it no longer needs a certificate). You should be able to copy the init logic from the sm_free3.cpp/h files on your release. I have included just these source files. Sorry about the confusion in our APIs, actual usage of the SFL library is very different from our original design intentions causing undue complexity. Some issues are being corrected (like the NULL login with no certificate, and the newest built-in instance for SHA1, SHA2, AES, and DSA verify). Bob Colestock VDA. -----Original Message----- From: Erik Rissanen [ mailto:[email protected] <mailto:[email protected]> < mailto:[email protected] <mailto:[email protected]> > < mailto:[email protected] <mailto:[email protected]> < mailto:[email protected] <mailto:[email protected]> > > ] Sent: Wednesday, March 21, 2001 10:07 AM To: '[email protected]' Subject: SFL: How to verify? I am trying to use SFL to verify a signed SMIME message. The message has one signerinfo with a security label and nothing else. The signers PKC is included in the SignerInfo. I don't understand how to initialize the sm_free3 CTIL to use for verification. I have successfully used SFL and sm_free3 to sign messages. For signing I initialized a SM_Applogin with the sm_free3 DLL and a PKCS#12 file. The resulting CSM_CSInst is associated with the private key and signing works fine. But having each CSM_CSInst instance to represent a private key doesn't make sense for verify, since there is no associated private key for the opperation. So how do I initialize a CSM_CSInst instance in this case? I don't understand the API documentation on this point. The approach I have tried is to compile time link with the sm_free3 DLL and do: CSM_CSInst *pInst = pSMIME->m_pCSInsts->AppendL(); CSM_Free3 *pFree3 = new CSM_Free3(); pFree3->AddLogin(certBuffer, NULL, NULL, "NULL"); pInst->SetTokenInterface(pFree3); Where certBuffer contains the certificate from the SMIME message SignerInfo. This causes a crash in the destructor of a CSM_Buffer when CSM_DataToVerify::Verify returns, so I guess I am doing something wrong. Is the code above the correct approach? Any help would be greatly appreciated. Regards, Erik Rissanen