Crypto++ has all you need to extract the key and verify a signature.
It's worth observing that for most applications that use certificates,
this is not sufficient; you should first build the certificate path,
make sure that the signatures chain back to someone you trust, and
check the revocation status, validity dates, key usage restrictions,
certificate policies, etc.  If you've taken care of appropriate
validation of the certificate and just want to use its key to verify a
signature, here's a function to get the key:

/**
 * Reads an X.509 v3 certificate from certin, extracts the
subjectPublicKeyInfo structure
 * (which is one way PK_Verifiers can get their key material) and
writes it to keyout
 *
 * @throws CryptoPP::BERDecodeError
 */
void GetPublicKeyFromCert(CryptoPP::BufferedTransformation & certin,
CryptoPP::BufferedTransformation & keyout)
{
        BERSequenceDecoder x509Cert(certin);
        BERSequenceDecoder tbsCert(x509Cert);
        // ASN.1 from RFC 3280
        // TBSCertificate  ::=  SEQUENCE  {
        // version         [0]  EXPLICIT Version DEFAULT v1,
        BERGeneralDecoder context(tbsCert,0xa0); // consume the context tag
on the version
        word32 ver;
        BERDecodeUnsigned<word32>(context,ver,INTEGER,2,2); // only want a v3
cert
        // serialNumber         CertificateSerialNumber,
        Integer serial;
        serial.BERDecode(tbsCert);
        // signature            AlgorithmIdentifier,
        BERSequenceDecoder signature(tbsCert);
        signature.SkipAll();
        // issuer               Name,
        BERSequenceDecoder issuerName(tbsCert);
        issuerName.SkipAll();
        // validity             Validity,
        BERSequenceDecoder validity(tbsCert);
        validity.SkipAll();
        // subject              Name,
        BERSequenceDecoder subjectName(tbsCert);
        subjectName.SkipAll();
        // subjectPublicKeyInfo SubjectPublicKeyInfo,
        BERSequenceDecoder spki(tbsCert);
        DERSequenceEncoder spkiEncoder(keyout);
        spki.CopyTo(spkiEncoder);
        spkiEncoder.MessageEnd();
        spki.SkipAll();
        tbsCert.SkipAll();
        x509Cert.SkipAll();
}

I'd find it useful if a similar function made its way into crypto++ :)

If your certificate is in PEM format, be sure your
BufferedTransformation has a base64 decoding filter there.

I've attached a small test program that shows how to use the key from
the certificate to verify a signature. The test program just has a
couple of DER-encoded certificates pasted into the code as byte array
literals.

HTH,

Geoff

On 3/29/07, v.miethe <[EMAIL PROTECTED]> wrote:
>
> Hi,
>
> all you need is a X.509 parser. It has nothing to do with the Crypto++
> Library.
>
>
>
> Sindolfo schrieb:
> > I need to read a public key from a certificate (cert.pem file) in
> > order to verify a signature.
> >
> > My list of files is:
> >
> > cert.pem (public key to be used in the verification)
> > application.zip (signed file)
> > signature.sig (the signature to be verified)
> >
> > The code that I found at http://www.cryptopp.com/wiki/RSA_Cryptography
> > does not fit my needs because it reads a "key.pb" (public key) not a
> > PEM encoded file.
> >
> > Can someone help me with some code to do the job?
> >
> > Thanks in advance.
> >
> >
> > >
>
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the "Crypto++ Users" 
Google Group.
To unsubscribe, send an email to [EMAIL PROTECTED]
More information about Crypto++ and this group is available at 
http://www.cryptopp.com.
-~----------~----~----~----~------~----~------~--~---

#include <string>
#include <iostream>
#include <memory>
#include <stdexcept>

#include "cryptlib.h"
#include "pubkey.h"
#include "queue.h"
#include "asn.h"
#include "rsa.h"
#include "md5.h"
#include "integer.h"
#include "oids.h"

using namespace std;
using namespace CryptoPP;


void GetPublicKeyFromCert(CryptoPP::BufferedTransformation & certin, 
CryptoPP::BufferedTransformation & keyout);


/**
 * Reads an X.509 v3 certificate from certin, extracts the subjectPublicKeyInfo 
structure
 * (which is one way PK_Verifiers can get their key material) and writes it to 
keyout
 *
 * @throws CryptoPP::BERDecodeError
 */
void GetPublicKeyFromCert(CryptoPP::BufferedTransformation & certin, 
CryptoPP::BufferedTransformation & keyout)
{
        BERSequenceDecoder x509Cert(certin);
        BERSequenceDecoder tbsCert(x509Cert);
        // ASN.1 from RFC 3280
        // TBSCertificate  ::=  SEQUENCE  {
        // version         [0]  EXPLICIT Version DEFAULT v1,
        BERGeneralDecoder context(tbsCert,0xa0); // consume the context tag on 
the version
        word32 ver;
        BERDecodeUnsigned<word32>(context,ver,INTEGER,2,2); // only want a v3 
cert         
        // serialNumber         CertificateSerialNumber,
        Integer serial;
        serial.BERDecode(tbsCert);
        // signature            AlgorithmIdentifier,
        BERSequenceDecoder signature(tbsCert);
        signature.SkipAll();
        // issuer               Name,
        BERSequenceDecoder issuerName(tbsCert);
        issuerName.SkipAll();
        // validity             Validity,
        BERSequenceDecoder validity(tbsCert);
        validity.SkipAll();
        // subject              Name,
        BERSequenceDecoder subjectName(tbsCert);
        subjectName.SkipAll();
        // subjectPublicKeyInfo SubjectPublicKeyInfo,
        BERSequenceDecoder spki(tbsCert);
        DERSequenceEncoder spkiEncoder(keyout);
        spki.CopyTo(spkiEncoder);
        spkiEncoder.MessageEnd();
        spki.SkipAll();
        tbsCert.SkipAll();
        x509Cert.SkipAll();
}

// A very simple test of the above function

// a smart pointer for PK_Verifier so less cleanup is needed if something throws
typedef std::auto_ptr<CryptoPP::PK_Verifier> PK_VerifierPtr;

// Signature Algorithm OIDs commonly used in certs that have RSA keys
DEFINE_OID(CryptoPP::ASN1::pkcs_1()+4, md5withRSAEncryption);
DEFINE_OID(CryptoPP::ASN1::pkcs_1()+5, sha1withRSAEncryption);

// Some test data
// The certificate used by https://mail.google.com/
unsigned char googlecert[] = {
0x30,0x82,0x03,0x21,0x30,0x82,0x02,0x8A,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x4B,
0xA5,0xAE,0x59,0xDE,0xDD,0x1C,0xC7,0x80,0x7C,0x89,0x22,0x91,0xF0,0xE2,0x43,0x30,
0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,0x05,0x00,0x30,0x4C,
0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x5A,0x41,0x31,0x25,0x30,
0x23,0x06,0x03,0x55,0x04,0x0A,0x13,0x1C,0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x43,
0x6F,0x6E,0x73,0x75,0x6C,0x74,0x69,0x6E,0x67,0x20,0x28,0x50,0x74,0x79,0x29,0x20,
0x4C,0x74,0x64,0x2E,0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x03,0x13,0x0D,0x54,
0x68,0x61,0x77,0x74,0x65,0x20,0x53,0x47,0x43,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,
0x30,0x36,0x30,0x35,0x31,0x35,0x32,0x33,0x31,0x38,0x31,0x31,0x5A,0x17,0x0D,0x30,
0x37,0x30,0x35,0x31,0x35,0x32,0x33,0x31,0x38,0x31,0x31,0x5A,0x30,0x68,0x31,0x0B,
0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,
0x03,0x55,0x04,0x08,0x13,0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,
0x31,0x16,0x30,0x14,0x06,0x03,0x55,0x04,0x07,0x13,0x0D,0x4D,0x6F,0x75,0x6E,0x74,
0x61,0x69,0x6E,0x20,0x56,0x69,0x65,0x77,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,
0x0A,0x13,0x0A,0x47,0x6F,0x6F,0x67,0x6C,0x65,0x20,0x49,0x6E,0x63,0x31,0x17,0x30,
0x15,0x06,0x03,0x55,0x04,0x03,0x13,0x0E,0x77,0x77,0x77,0x2E,0x67,0x6F,0x6F,0x67,
0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,
0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02,
0x81,0x81,0x00,0xE6,0xC5,0xC6,0x8D,0xCD,0x0B,0xA3,0x03,0x04,0xDC,0xAE,0xCC,0xC9,
0x46,0xBE,0xBD,0xCC,0x9D,0xBC,0x73,0x34,0x48,0xFE,0xD3,0x75,0x64,0xD0,0xC9,0xC9,
0x76,0x27,0x72,0x0F,0xA9,0x96,0x1A,0x3B,0x81,0xF3,0x14,0xF6,0xAE,0x90,0x56,0xE7,
0x19,0xD2,0x73,0x68,0xA7,0x85,0xA4,0xAE,0xCA,0x24,0x14,0x30,0x00,0xBA,0xE8,0x36,
0x5D,0x81,0x73,0x3A,0x71,0x05,0x8F,0xB1,0xAF,0x11,0x87,0xDA,0x5C,0xF1,0x3E,0xBF,
0x53,0x51,0x84,0x6F,0x44,0x0E,0xB7,0xE8,0x26,0xD7,0x2F,0xB2,0x6F,0xF2,0xF2,0x5D,
0xDF,0xA7,0xCF,0x8C,0xA5,0xE9,0x1E,0x6F,0x30,0x48,0x94,0x21,0x0B,0x01,0xAD,0xBA,
0x0E,0x71,0x01,0x0D,0x10,0xEF,0xBF,0xEE,0x2C,0xD3,0x8D,0xFE,0x54,0xA8,0xFE,0xD3,
0x97,0x8F,0xCB,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0xE7,0x30,0x81,0xE4,0x30,0x28,
0x06,0x03,0x55,0x1D,0x25,0x04,0x21,0x30,0x1F,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,
0x07,0x03,0x01,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x09,0x60,
0x86,0x48,0x01,0x86,0xF8,0x42,0x04,0x01,0x30,0x36,0x06,0x03,0x55,0x1D,0x1F,0x04,
0x2F,0x30,0x2D,0x30,0x2B,0xA0,0x29,0xA0,0x27,0x86,0x25,0x68,0x74,0x74,0x70,0x3A,
0x2F,0x2F,0x63,0x72,0x6C,0x2E,0x74,0x68,0x61,0x77,0x74,0x65,0x2E,0x63,0x6F,0x6D,
0x2F,0x54,0x68,0x61,0x77,0x74,0x65,0x53,0x47,0x43,0x43,0x41,0x2E,0x63,0x72,0x6C,
0x30,0x72,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x66,0x30,0x64,
0x30,0x22,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x16,0x68,0x74,
0x74,0x70,0x3A,0x2F,0x2F,0x6F,0x63,0x73,0x70,0x2E,0x74,0x68,0x61,0x77,0x74,0x65,
0x2E,0x63,0x6F,0x6D,0x30,0x3E,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,
0x86,0x32,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x77,0x77,0x77,0x2E,0x74,0x68,0x61,
0x77,0x74,0x65,0x2E,0x63,0x6F,0x6D,0x2F,0x72,0x65,0x70,0x6F,0x73,0x69,0x74,0x6F,
0x72,0x79,0x2F,0x54,0x68,0x61,0x77,0x74,0x65,0x5F,0x53,0x47,0x43,0x5F,0x43,0x41,
0x2E,0x63,0x72,0x74,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x02,
0x30,0x00,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,0x05,
0x00,0x03,0x81,0x81,0x00,0x57,0x4B,0xBC,0xA4,0x43,0xE7,0xE0,0x01,0x92,0xA0,0x96,
0x35,0xF9,0x18,0x08,0x88,0x1D,0x7B,0x70,0x19,0x8F,0xF9,0x36,0xB2,0x05,0x3A,0x05,
0xCA,0x14,0x59,0x4D,0x24,0x0E,0xE5,0x8A,0xAF,0x4E,0x87,0x5A,0xF7,0x1C,0x2A,0x96,
0x8F,0xCB,0x61,0x40,0x9E,0xD2,0xB4,0x38,0x40,0x21,0x24,0xC1,0x4F,0x1F,0xCB,0x13,
0x4A,0x8F,0x95,0x02,0xDF,0x91,0x3D,0xD6,0x40,0xEB,0x11,0x6F,0x9B,0x10,0xA1,0x6F,
0xCE,0x91,0x5E,0x30,0xF6,0x6D,0x13,0x5E,0x15,0xA4,0x2E,0xC2,0x18,0x9E,0x00,0xC3,
0xD8,0x32,0x67,0x47,0xFC,0xB8,0x1E,0x9A,0xD9,0x9A,0x8E,0xCC,0xFF,0x7C,0x12,0xB7,
0x03,0xBF,0x52,0x20,0xCF,0x21,0xF4,0xF3,0x77,0xDD,0x12,0x15,0xF0,0x94,0xFA,0x90,
0xD5,0xE3,0x59,0x68,0x81
};

// The certificate for the thawte CA that issued the above
unsigned char thawtecert[] = {
0x30,0x82,0x03,0x23,0x30,0x82,0x02,0x8C,0xA0,0x03,0x02,0x01,0x02,0x02,0x04,0x30,
0x00,0x00,0x02,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,
0x05,0x00,0x30,0x5F,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,
0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0A,0x13,0x0E,0x56,0x65,0x72,0x69,
0x53,0x69,0x67,0x6E,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x37,0x30,0x35,0x06,0x03,
0x55,0x04,0x0B,0x13,0x2E,0x43,0x6C,0x61,0x73,0x73,0x20,0x33,0x20,0x50,0x75,0x62,
0x6C,0x69,0x63,0x20,0x50,0x72,0x69,0x6D,0x61,0x72,0x79,0x20,0x43,0x65,0x72,0x74,
0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,
0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x34,0x30,0x35,0x31,0x33,0x30,0x30,0x30,
0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x34,0x30,0x35,0x31,0x32,0x32,0x33,0x35,0x39,
0x35,0x39,0x5A,0x30,0x4C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,
0x5A,0x41,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0A,0x13,0x1C,0x54,0x68,0x61,
0x77,0x74,0x65,0x20,0x43,0x6F,0x6E,0x73,0x75,0x6C,0x74,0x69,0x6E,0x67,0x20,0x28,
0x50,0x74,0x79,0x29,0x20,0x4C,0x74,0x64,0x2E,0x31,0x16,0x30,0x14,0x06,0x03,0x55,
0x04,0x03,0x13,0x0D,0x54,0x68,0x61,0x77,0x74,0x65,0x20,0x53,0x47,0x43,0x20,0x43,
0x41,0x30,0x81,0x9F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,
0x01,0x05,0x00,0x03,0x81,0x8D,0x00,0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xD4,0xD3,
0x67,0xD0,0x8D,0x15,0x7F,0xAE,0xCD,0x31,0xFE,0x7D,0x1D,0x91,0xA1,0x3F,0x0B,0x71,
0x3C,0xAC,0xCC,0xC8,0x64,0xFB,0x63,0xFC,0x32,0x4B,0x07,0x94,0xBD,0x6F,0x80,0xBA,
0x2F,0xE1,0x04,0x93,0xC0,0x33,0xFC,0x09,0x33,0x23,0xE9,0x0B,0x74,0x2B,0x71,0xC4,
0x03,0xC6,0xD2,0xCD,0xE2,0x2F,0xF5,0x09,0x63,0xCD,0xFF,0x48,0xA5,0x00,0xBF,0xE0,
0xE7,0xF3,0x88,0xB7,0x2D,0x32,0xDE,0x98,0x36,0xE6,0x0A,0xAD,0x00,0x7B,0xC4,0x64,
0x4A,0x3B,0x84,0x75,0x03,0xF2,0x70,0x92,0x7D,0x0E,0x62,0xF5,0x21,0xAB,0x69,0x36,
0x84,0x31,0x75,0x90,0xF8,0xBF,0xC7,0x6C,0x88,0x1B,0x06,0x95,0x7C,0xC9,0xE5,0xA8,
0xDE,0x75,0xA1,0x2C,0x7A,0x68,0xDF,0xD5,0xCA,0x1C,0x87,0x58,0x60,0x19,0x02,0x03,
0x01,0x00,0x01,0xA3,0x81,0xFE,0x30,0x81,0xFB,0x30,0x12,0x06,0x03,0x55,0x1D,0x13,
0x01,0x01,0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01,0x00,0x30,0x0B,0x06,
0x03,0x55,0x1D,0x0F,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x11,0x06,0x09,0x60,0x86,
0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x28,0x06,
0x03,0x55,0x1D,0x11,0x04,0x21,0x30,0x1F,0xA4,0x1D,0x30,0x1B,0x31,0x19,0x30,0x17,
0x06,0x03,0x55,0x04,0x03,0x13,0x10,0x50,0x72,0x69,0x76,0x61,0x74,0x65,0x4C,0x61,
0x62,0x65,0x6C,0x33,0x2D,0x31,0x35,0x30,0x31,0x06,0x03,0x55,0x1D,0x1F,0x04,0x2A,
0x30,0x28,0x30,0x26,0xA0,0x24,0xA0,0x22,0x86,0x20,0x68,0x74,0x74,0x70,0x3A,0x2F,
0x2F,0x63,0x72,0x6C,0x2E,0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6E,0x2E,0x63,0x6F,
0x6D,0x2F,0x70,0x63,0x61,0x33,0x2E,0x63,0x72,0x6C,0x30,0x32,0x06,0x08,0x2B,0x06,
0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x26,0x30,0x24,0x30,0x22,0x06,0x08,0x2B,0x06,
0x01,0x05,0x05,0x07,0x30,0x01,0x86,0x16,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x6F,
0x63,0x73,0x70,0x2E,0x74,0x68,0x61,0x77,0x74,0x65,0x2E,0x63,0x6F,0x6D,0x30,0x34,
0x06,0x03,0x55,0x1D,0x25,0x04,0x2D,0x30,0x2B,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,
0x07,0x03,0x01,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x09,0x60,
0x86,0x48,0x01,0x86,0xF8,0x42,0x04,0x01,0x06,0x0A,0x60,0x86,0x48,0x01,0x86,0xF8,
0x45,0x01,0x08,0x01,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,
0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x55,0xAC,0x63,0xEA,0xDE,0xA1,0xDD,0xD2,0x90,
0x5F,0x9F,0x0B,0xCE,0x76,0xBE,0x13,0x51,0x8F,0x93,0xD9,0x05,0x2B,0xC8,0x1B,0x77,
0x4B,0xAD,0x69,0x50,0xA1,0xEE,0xDE,0xDC,0xFD,0xDB,0x07,0xE9,0xE8,0x39,0x94,0xDC,
0xAB,0x72,0x79,0x2F,0x06,0xBF,0xAB,0x81,0x70,0xC4,0xA8,0xED,0xEA,0x53,0x34,0xED,
0xEF,0x1E,0x53,0xD9,0x06,0xC7,0x56,0x2B,0xD1,0x5C,0xF4,0xD1,0x8A,0x8E,0xB4,0x2B,
0xB1,0x37,0x90,0x48,0x08,0x42,0x25,0xC5,0x3E,0x8A,0xCB,0x7F,0xEB,0x6F,0x04,0xD1,
0x6D,0xC5,0x74,0xA2,0xF7,0xA2,0x7C,0x7B,0x60,0x3C,0x77,0xCD,0x0E,0xCE,0x48,0x02,
0x7F,0x01,0x2F,0xB6,0x9B,0x37,0xE0,0x2A,0x2A,0x36,0xDC,0xD5,0x85,0xD6,0xAC,0xE5,
0x3F,0x54,0x6F,0x96,0x1E,0x05,0xAF
};

int main(int argc, char **argv)
{
        // an easy program to verify the signature on one certificate using the
        // public key from another. This is really just a test for 
GetPublicKeyFromCert()!
        // you need to do a great deal more verification before deciding to 
trust a
        // certificate in most applications.
        ByteQueue googleq, thawteq, googletbs, thawtespki;
        SecByteBlock certSignature;
        googleq.Put(googlecert,sizeof(googlecert));
        thawteq.Put(thawtecert,sizeof(thawtecert));
        try {
                GetPublicKeyFromCert(thawteq,thawtespki);
        }catch(std::exception &){
                cerr << "Failed to extract the public key from the CA 
certificate." << endl;
                return 1;
        }
        cout << "Public key read from Thawte CA certificate." << endl;
        
        OID sigAlgOID;
                
        try {
                // first, extract the data that the signature covers
                BERSequenceDecoder x509Cert(googleq);
                BERSequenceDecoder tbsCert(x509Cert);
                DERSequenceEncoder tbsEnc(googletbs);
                tbsCert.TransferAllTo(tbsEnc);
                tbsEnc.MessageEnd();
                // find the algorithm used to sign the data
                BERSequenceDecoder sigAlg(x509Cert);
                sigAlgOID.BERDecode(sigAlg);
                sigAlg.SkipAll();
                // extract the actual signature
                unsigned int unused = 0;
                BERDecodeBitString(x509Cert,certSignature,unused);
                cout << "Signature decoded. " << unused << " bits unused in the 
encoding." << endl;
                x509Cert.SkipAll();
        }catch(std::exception &){
                cerr << "Error decoding the Google server certificate for 
signature verification." << endl;
                return 1;
        }
        PK_VerifierPtr verifier;
        if(sigAlgOID == md5withRSAEncryption()) {
                verifier = PK_VerifierPtr(new 
RSASS<PKCS1v15,CryptoPP::MD5>::Verifier(thawtespki));
                cout << "Signature algorithm is RSA with MD5 hash." << endl;
        } else if(sigAlgOID == sha1withRSAEncryption()) {
                verifier = PK_VerifierPtr(new 
RSASS<PKCS1v15,CryptoPP::SHA1>::Verifier(thawtespki));
                cout << "Signature algorithm is RSA with SHA1 hash." << endl;
        } else {
                cerr << "This test program does not support the algorithm used 
for signing." << endl;
                return 1;
        }
        
        if(certSignature.size() != verifier->SignatureLength()) {
                cerr << "The signature size is does not match the algorithm 
used for signing." << endl;
                return 1;
        }
        CryptoPP::SignatureVerificationFilter vf(*verifier);
        try {
                vf.Put(certSignature,certSignature.size());
                googletbs.TransferAllTo(vf);
                vf.MessageEnd();
        }catch(std::exception &e){
                cerr << "Caught an exception while verifying the signature:" << 
endl;
                cerr << "\t" << e.what() << endl;
                return 1;
        }
        if(vf.GetLastResult()) {
                cout << "The signature verified." << endl;
        } else {
                cout << "Signature verification failed." << endl;
        }
        return 0;
}

Reply via email to