Hi Steve, Just to clear things:
1. You are verifying DSA signatures created by some other app/lib/person and not by you using Apache XSEC C++ lib? 2. DSA key length used for that signature != 1024 bits? Best regards, Milan > -----Original Message----- > From: Cullum, Steve [mailto:[EMAIL PROTECTED] > Sent: Monday, May 23, 2005 7:54 PM > To: 'security-dev@xml.apache.org' > Subject: RE: XML Security-C:: HCRYPTPROV DSS/RSA providers > not set via Win CAPI CryptoX509 using just the PCCERT_CONTEXT > cosntructor > > > Ooops.. > > My last post didn't actually make a point... > > Q) Is it a limitation in xml-security to only allow keys of length 40. > > The following thread - discusses this topic in more detail... > > http://groups-beta.google.com/group/microsoft.public.platforms > dk.security/br > owse_frm/thread/b24b3cfdeac53dd1/ea4a951d04202694?q=DSA+signat > ure+length+46& > rnum=15&hl=en#ea4a951d04202694 > > -----Original Message----- > From: Cullum, Steve > Sent: 23 May 2005 16:52 > To: 'security-dev@xml.apache.org' > Subject: RE: XML Security-C:: HCRYPTPROV DSS/RSA providers > not set via Win CAPI CryptoX509 using just the PCCERT_CONTEXT > cosntructor > > > Berin, > > Using the latest version of xml-security from CVS - I can > clone the X509 cert using WINCAPI but I get errors during > sig->validate() regarding and invalid signature. I tried the > same sequence of code using the OpenSSL providers and got > something very similar. > > Using WINCAPI - the message > An error occured in the XML-Security-C Crypto routines > Message: WinCAPI:DSA::VerifyBase64Signature - Expect 40 > bytes in a DSA signature > > Using OPENSSL - the message > An error occured in the XML-Security-C Crypto routines > Message: OpenSSL:DSA - Signature Length incorrect > > (*) Do these errors relate to the certificte or the signature > in the XML document? > > (*) For the OpenSSL test, I exported the key as a BASE64 DER > encoded certificate and manually removed the ----BEGIN > CERTIFICATE---- and ----END > CERTIFICATE---- headers. Was this the correct thing to do? > > > > bool WinCAPICryptoKeyDSA::verifyBase64Signature(unsigned char > * hashBuf, unsigned int hashLen, char * base64Signature, > unsigned int sigLen) { > .. hashBuf= [data] > .. hashLen= 20 > .. base64Signature > "MCwCFFiTYY7/B+tYizrqccMZJKVQC6RyAhQUoVXtXfNUVEFZlaE3USajTEqUzQ==" > .. sigLen= 64 > > b64.decodeInit(); > rawSigLen = b64.decode((unsigned char *) base64Signature, > sigLen, rawSig, sigLen); > rawSigLen += b64.decodeFinish(&rawSig[rawSigLen], sigLen - > rawSigLen); > > .. rawSigLen = 46 > > if (rawSigLen != 40) > { > throw XSECCryptoException(XSECCryptoException::DSAError, > "WinCAPI:DSA::VerifyBase64Signature - Expect 40 bytes > in a DSA signature"); > } > } > > > > > // > // validate.cpp : Defines the entry point for the console > application. // #include "stdafx.h" > > #include "IOStreamOutputter.hpp" > > #define USE_WINCAPI > > // XML-Security-C (XSEC) > #pragma comment (lib, "crypt32.lib") > #pragma comment (lib, "xerces-c_2D.lib") > #pragma comment (lib, "xsec_1D.lib") > > > #include <xsec/framework/XSECProvider.hpp> > #include <xsec/dsig/DSIGReference.hpp> > > #ifdef USE_WINCAPI > #include <xsec/enc/WinCAPI/WinCAPICryptoKeyHMAC.hpp> > #include <xsec/enc/WinCAPI/WinCAPICryptoProvider.hpp> > #include <xsec/enc/WinCAPI/WinCAPICryptoX509.hpp> > #endif > > #ifdef USE_OPENSSL > #include <xsec/enc/OpenSSL/OpenSSLCryptoKeyHMAC.hpp> > #include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp> > #include <xsec/enc/XSECCryptoException.hpp> > #endif // USE_OPENSSL > > #include <xsec/framework/XSECException.hpp> > #include <xsec/enc/XSECCryptoException.hpp> > > // Xerces > #include <xercesc/util/PlatformUtils.hpp> > #include <xercesc/parsers/XercesDOMParser.hpp> > #include <xercesc/framework/MemBufInputSource.hpp> > > > #if defined(_WIN32) > # include <xsec/utils/winutils/XSECURIResolverGenericWin32.hpp> > #else > # include <xsec/utils/unixutils/XSECURIResolverGenericUnix.hpp> > #endif > > > XERCES_CPP_NAMESPACE_USE > > TCHAR *docToValidate = 0x00; > #define IDATTRIBUTENS > "http://schemas.xmlsoap.org/ws/2002/07/utility" > #define IDATTRIBUTENAME "Id" > #define MY_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) > #define SIGNER_NAME L"MYSIGNER" > #define CERT_STORE_NAME L"MY" > > void ReadFile(TCHAR *fileName, TCHAR **chars, DWORD *len /* > in TCHARS */) { > DWORD bytesRead = 0; > HANDLE hfp = CreateFile(fileName, GENERIC_READ, > FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); > *len = GetFileSize(hfp, NULL); > > *len /= sizeof(TCHAR); // convert length from bytes to TCHAR's > *chars = (TCHAR *)malloc(*len * sizeof(TCHAR)); // dont mul by > sizeof(TCHAR) > ReadFile(hfp, (LPVOID)*chars, *len * sizeof(TCHAR), > &bytesRead, NULL); > CloseHandle(hfp); > } > > > int main (int argc, char **argv) { > > try > { > XMLPlatformUtils::Initialize(); > XSECPlatformUtils::Initialise(); > } > catch (const XMLException &e) > { > cerr << "Error during initialisation of Xerces" << endl; > cerr << "Error Message = : " << e.getMessage() << endl; > } > > // Use xerces to parse the document > XercesDOMParser * parser = new XercesDOMParser; > parser->setDoNamespaces(true); > parser->setCreateEntityReferenceNodes(true); > parser->setDoSchema(true); > > // Create an input source > DWORD len = 0; > ReadFile(_T("c:\\apache\\signedxml\\nocert.xml"), > &docToValidate, &len); > MemBufInputSource* memIS = new MemBufInputSource ((const > XMLByte*) docToValidate, (unsigned int) len, "XSECMem"); > > parser->parse(*memIS); > int errorCount = parser->getErrorCount(); > if (errorCount > 0) { > cerr << "Error parsing input document\n"; > exit (1); > } > > DOMDocument *doc = parser->getDocument(); > docSetup(doc); > > // Now create a signature object to validate the document > XSECProvider prov; > > DSIGSignature * sig = prov.newSignatureFromDOM(doc); > > // Register defined attribute name > sig->registerIdAttributeName(MAKE_UNICODE_STRING("ID")); > sig->registerIdAttributeNameNS(MAKE_UNICODE_STRING(IDATTRIBUTENS), > MAKE_UNICODE_STRING(IDATTRIBUTENAME)); > > try > { > #ifdef USE_WINCAPI > HCERTSTORE certStore = NULL; > PCCERT_CONTEXT certContext = NULL; > > certStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, > NULL, CERT_SYSTEM_STORE_CURRENT_USER, CERT_STORE_NAME); > if(certStore == NULL) > { > cout << "Certificate store cannot be opened\n"; > exit (1); > } > > // find signer's certificate. -- this certificate must > have access to the signer's private key. > certContext = CertFindCertificateInStore(certStore, > MY_TYPE, 0, CERT_FIND_SUBJECT_STR, SIGNER_NAME, NULL); > if(certContext == NULL) > { > cout << "unable to find signers certificate\n"; > exit (1); > } > > WinCAPICryptoProvider * cp = new > WinCAPICryptoProvider(NULL, NULL, CRYPT_MACHINE_KEYSET); > XSECPlatformUtils::SetCryptoProvider(cp); > WinCAPICryptoX509 * x509 = new WinCAPICryptoX509(certContext, > cp->getProviderRSA(), cp->getProviderDSS()); > #endif // USE_WINCAPI > > #ifdef USE_OPENSSL > OpenSSLCryptoX509 * x509 = new OpenSSLCryptoX509(); > TCHAR *b64; > DWORD b64Len; > ReadFile(_T("c:\\apache\\signedxml\\nocert.cer"), &b64, &b64Len); > x509->loadX509Base64Bin(b64, (unsigned int) b64Len); > #endif // USE_OPENSSL > > // in my XML file i have no keyinfo > sig->load(); > sig->setSigningKey(x509->clonePublicKey()); > > if (sig->verify()) > { > cout << "Signature Valid\n"; > } > else > { > char * err = XMLString::transcode(sig->getErrMsgs()); > cout << "Incorrect Signature\n"; > cout << err << endl; > XSEC_RELEASE_XMLCH(err); > } > } > catch (XSECException &e) > { > cerr << "An error occured during a signature load\n > Message: " << > e.getMsg() << endl; > exit(1); > } > catch (XSECCryptoException &e) { > cerr << "An error occured in the XML-Security-C Crypto routines\n > Message: " << e.getMsg() << endl; > exit(1); > } > > // Clean up > > delete memIS; > delete parser; > > return 0; > } > > > > > > >