Unicode C
Unicode C
DSA R,S Signature Values
See more DSA Examples
Creates a DSA signature. Gets r,s values from the signature. Re-creates the DSA signature ASN.1 from the r,s values. Then verifies the signature using the re-created ASN.1 DSA signature.Chilkat Unicode C Downloads
#include <C_CkCrypt2W.h>
#include <C_CkDsaW.h>
#include <C_CkAsnW.h>
#include <C_CkXmlW.h>
void ChilkatSample(void)
{
BOOL success;
HCkCrypt2W crypt;
const wchar_t *hashStr;
HCkDsaW dsa;
const wchar_t *pemPrivateKey;
const wchar_t *asnSig;
HCkAsnW asn;
HCkXmlW xml;
const wchar_t *r;
const wchar_t *s;
HCkDsaW dsa2;
const wchar_t *pemPublicKey;
success = FALSE;
// This example requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.
crypt = CkCrypt2W_Create();
CkCrypt2W_putEncodingMode(crypt,L"hex");
CkCrypt2W_putHashAlgorithm(crypt,L"sha-1");
hashStr = CkCrypt2W_hashFileENC(crypt,L"qa_data/hamlet.xml");
wprintf(L"hash to sign: %s\n",hashStr);
dsa = CkDsaW_Create();
pemPrivateKey = CkDsaW_loadText(dsa,L"qa_data/dsa/dsaPrivKey2.pem");
success = CkDsaW_FromPem(dsa,pemPrivateKey);
if (success == FALSE) {
wprintf(L"%s\n",CkDsaW_lastErrorText(dsa));
CkCrypt2W_Dispose(crypt);
CkDsaW_Dispose(dsa);
return;
}
// Load the hash to be signed into the DSA object:
success = CkDsaW_SetEncodedHash(dsa,L"hex",hashStr);
if (success == FALSE) {
wprintf(L"%s\n",CkDsaW_lastErrorText(dsa));
CkCrypt2W_Dispose(crypt);
CkDsaW_Dispose(dsa);
return;
}
// Sign the hash.
success = CkDsaW_SignHash(dsa);
if (success == FALSE) {
wprintf(L"%s\n",CkDsaW_lastErrorText(dsa));
CkCrypt2W_Dispose(crypt);
CkDsaW_Dispose(dsa);
return;
}
// Get the ASN.1 signature.
asnSig = CkDsaW_getEncodedSignature(dsa,L"base64");
wprintf(L"Signature: %s\n",asnSig);
// Examine the details of the ASN.1 signature.
// We want to get the r,s values as hex strings..
asn = CkAsnW_Create();
success = CkAsnW_LoadEncoded(asn,asnSig,L"base64");
if (success == FALSE) {
wprintf(L"%s\n",CkAsnW_lastErrorText(asn));
CkCrypt2W_Dispose(crypt);
CkDsaW_Dispose(dsa);
CkAsnW_Dispose(asn);
return;
}
// Get the ASN.1 as XML.
xml = CkXmlW_Create();
success = CkXmlW_LoadXml(xml,CkAsnW_asnToXml(asn));
wprintf(L"Signature as XML: \n");
wprintf(L"%s\n",CkXmlW_getXml(xml));
// Sample XML shown here.
// The r and s values are the two hex strings in the XML.
// <?xml version="1.0" encoding="utf-8"?>
// <sequence>
// <int>2C187F3AB6E47A66497B86CE97BB39E2133810F5</int>
// <int>588E53D3F7B69636B48FD7175E99A3961BD7D775</int>
// </sequence>
// Pretend we're starting with r,s
r = L"2C187F3AB6E47A66497B86CE97BB39E2133810F5";
s = L"588E53D3F7B69636B48FD7175E99A3961BD7D775";
// Build the XML that will be converted to ASN.1
CkXmlW_Clear(xml);
CkXmlW_putTag(xml,L"sequence");
CkXmlW_NewChild2(xml,L"int",r);
CkXmlW_NewChild2(xml,L"int",s);
// Convert the XML to ASN.1
success = CkAsnW_LoadAsnXml(asn,CkXmlW_getXml(xml));
// Emit the signature as DER encoded ASN.1 (base64)
asnSig = CkAsnW_getEncodedDer(asn,L"base64");
// --------------------------------------------------------------------
// Verify the signature using the asnSig we built from the r,s values
// --------------------------------------------------------------------
dsa2 = CkDsaW_Create();
// Load the DSA public key to be used for verification:
pemPublicKey = CkDsaW_loadText(dsa2,L"qa_data/dsa/dsaPubKey2.pem");
success = CkDsaW_FromPublicPem(dsa2,pemPublicKey);
if (success == FALSE) {
wprintf(L"%s\n",CkDsaW_lastErrorText(dsa2));
CkCrypt2W_Dispose(crypt);
CkDsaW_Dispose(dsa);
CkAsnW_Dispose(asn);
CkXmlW_Dispose(xml);
CkDsaW_Dispose(dsa2);
return;
}
// Load the hash to be verified.
success = CkDsaW_SetEncodedHash(dsa2,L"hex",hashStr);
if (success == FALSE) {
wprintf(L"%s\n",CkDsaW_lastErrorText(dsa2));
CkCrypt2W_Dispose(crypt);
CkDsaW_Dispose(dsa);
CkAsnW_Dispose(asn);
CkXmlW_Dispose(xml);
CkDsaW_Dispose(dsa2);
return;
}
// Load the ASN.1 signature:
success = CkDsaW_SetEncodedSignature(dsa2,L"base64",asnSig);
if (success == FALSE) {
wprintf(L"%s\n",CkDsaW_lastErrorText(dsa2));
CkCrypt2W_Dispose(crypt);
CkDsaW_Dispose(dsa);
CkAsnW_Dispose(asn);
CkXmlW_Dispose(xml);
CkDsaW_Dispose(dsa2);
return;
}
// Verify:
success = CkDsaW_Verify(dsa2);
if (success == FALSE) {
wprintf(L"%s\n",CkDsaW_lastErrorText(dsa2));
}
else {
wprintf(L"DSA Signature Verified!\n");
}
CkCrypt2W_Dispose(crypt);
CkDsaW_Dispose(dsa);
CkAsnW_Dispose(asn);
CkXmlW_Dispose(xml);
CkDsaW_Dispose(dsa2);
}