PKIFCryptoPPCredential.cpp

Go to the documentation of this file.
00001 
00010 #include "PKIFCryptoPPCredential.h"
00011 
00012 #include "ToolkitUtils.h"
00013 #include "PKIFMemoryUtils.h"
00014 #include "components.h"
00015 #include "PKIFCryptoPPErrors.h"
00016 #include "PKIFCryptoException.h"
00017 #include "Name.h"
00018 #include "Buffer.h"
00019 
00020 #include "Certificate.h"
00021 #include "SubjectKeyIdentifier.h"
00022 #include "Buffer.h"
00023 #include "PKIFAlgorithm.h"
00024 
00025 #include "PKIFKeyMaterial.h"
00026 #include "PKIFCryptoPPKeyMaterial.h"
00027 #include "OID.h"
00028 
00029 #include "cryptlib.h"
00030 #include "asn.h"
00031 #include "rsa.h"
00032 #include "dsa.h"
00033 #include "eccrypto.h"
00034 
00035 using namespace std;
00036 
00045 CPKIFCryptoPPCredential::CPKIFCryptoPPCredential()
00046 :m_pkifCert((CPKIFCertificate *)0),m_keyBuf((CPKIFBuffer *)0),m_keyAlg(0)
00047 {
00048     LOG_STRING_DEBUG(__FUNCTION__,TOOLKIT_CRYPTO_CRYPTOPPCRED,0,this);
00049         
00050 }
00059 CPKIFCryptoPPCredential::~CPKIFCryptoPPCredential(void)
00060 {
00061     LOG_STRING_DEBUG(__FUNCTION__,TOOLKIT_CRYPTO_CRYPTOPPCRED,0,this);
00062     if(m_keyBuf) {
00063         unsigned char * keydata = const_cast<unsigned char *>(m_keyBuf->GetBuffer());
00064         PKIFZero(keydata,m_keyBuf->GetLength());
00065     }
00066     /*if(m_password) {
00067         PKIFZero(m_password,m_pwLen);
00068         PKIFDelete(m_password);
00069         m_password = 0;
00070     }
00071     if(m_privateKey) {
00072         SECKEY_DestroyPrivateKey(m_privateKey);
00073         m_privateKey = 0;
00074     }*/
00075 }
00076 
00088 void CPKIFCryptoPPCredential::SetPassword(
00090     unsigned char* password, 
00092     int len)
00093 {
00094     LOG_STRING_DEBUG(__FUNCTION__,TOOLKIT_CRYPTO_CRYPTOPPCRED,0,this);
00095     RAISE_CRYPTO_EXCEPTION("Crypto++ does not support password-protected credentials",
00096         TOOLKIT_CRYPTO_CRYPTOPPCRED,COMMON_NOT_IMPLEMENTED,this);
00097 
00098 }
00110 CPKIFCertificatePtr CPKIFCryptoPPCredential::GetCertificate() const
00111 {
00112     LOG_STRING_DEBUG(__FUNCTION__,TOOLKIT_CRYPTO_CRYPTOPPCRED,0,this);
00113     return m_pkifCert;
00114 }
00115 
00116 CPKIFKeyMaterialPtr CPKIFCryptoPPCredential::GetPublicKey() const
00117 {
00118     CPKIFKeyMaterialPtr rv;
00119     // if there is a certificate, the base class method is fine
00120     if(m_pkifCert) {
00121         return CPKIFCredential::GetPublicKey();
00122     }
00123     // if the algorithm wasn't set and there's no certificate, we cannot attempt
00124     // to derive from the private key.
00125     if(!m_keyAlg) return rv;
00126 
00127     // if there's no certificate, attempt to derive from a private key.
00128     // applications are responsible for maintaining this separately or using
00129     // a certificate if the public key cannot be derived the private.
00130     CryptoPP::ASN1CryptoMaterial<CryptoPP::PrivateKey> * privKey = 0;
00131     CryptoPP::ASN1CryptoMaterial<CryptoPP::PublicKey> * pubKey = 0;
00132         
00133     // these are the algs for which we know how to derive a public key from a private key
00134     switch(m_keyAlg->AsymkeyAlg())
00135     {
00136     case PKIFCRYPTO::RSA:
00137         privKey = new CryptoPP::RSA::PrivateKey();
00138         break;
00139     case PKIFCRYPTO::DSS:
00140         privKey = new CryptoPP::DSA::PrivateKey();
00141         break;
00142     case PKIFCRYPTO::ECC:
00143         privKey = new CryptoPP::DL_PrivateKey_EC<CryptoPP::ECP>();
00144         break;
00145     }
00146     if(!privKey) {
00147         return rv;
00148     }
00149     
00150     CryptoPP::ByteQueue privq;
00151     privq.Put(m_keyBuf->GetBuffer(), m_keyBuf->GetLength());
00152 
00153     try {
00154         privKey->BERDecode(privq);
00155     } catch(CryptoPP::BERDecodeErr &) {
00156         RAISE_CRYPTO_EXCEPTION("Internal consistency error in PKIFCryptoPPCredential. Unable to BER decode private key.",
00157             TOOLKIT_CRYPTO_CRYPTOPPCRED,PKIF_CRYPTOPP_RAW_IMPORT_FAILED,this);
00158     }
00159     
00160     switch(m_keyAlg->AsymkeyAlg())
00161     {
00162     case PKIFCRYPTO::RSA:
00163         {
00164             CryptoPP::RSA::PrivateKey * k = dynamic_cast<CryptoPP::RSA::PrivateKey *>(privKey);
00165             CryptoPP::RSAES_OAEP_SHA_Decryptor d(*k);
00166             CryptoPP::RSAES_OAEP_SHA_Encryptor e(d);
00167             pubKey = new CryptoPP::RSA::PublicKey(e.AccessKey());
00168             break;
00169         }
00170     case PKIFCRYPTO::DSS:
00171         {
00172             CryptoPP::DSA::PrivateKey * k = dynamic_cast<CryptoPP::DSA::PrivateKey *>(privKey);
00173             CryptoPP::DSA::PublicKey pk;
00174             k->MakePublicKey(pk);
00175             pubKey = new CryptoPP::DSA::PublicKey(pk);
00176             break;
00177         }
00178     case PKIFCRYPTO::ECC:
00179         {
00180             CryptoPP::DL_PrivateKey_EC<CryptoPP::ECP> * k = dynamic_cast<CryptoPP::DL_PrivateKey_EC<CryptoPP::ECP> * >(privKey);
00181             CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> pk;
00182             k->MakePublicKey(pk);
00183             pubKey = new CryptoPP::DL_PublicKey_EC<CryptoPP::ECP>(pk);
00184             break;
00185         }
00186     }
00187 
00188     // if there was no public key, we may have some alg where crypto++ can't derive public from private
00189     if(!pubKey) {
00190         if(privKey) delete privKey;
00191         return rv;
00192     }
00193 
00194     CryptoPP::ByteQueue pubq;
00195     pubKey->DEREncode(pubq);
00196     delete privKey;
00197     delete pubKey;
00198     privKey = 0;
00199     pubKey = 0;
00200 
00201     CPKIFBufferPtr spkiBuf(new CPKIFBuffer);
00202     // given the sizes in question, this should be safe
00203     unsigned char * rawBuf = spkiBuf->AllocateBuffer((int)pubq.MaxRetrievable());
00204     pubq.Get(rawBuf,spkiBuf->GetLength());
00205 
00206     CPKIFCryptoPPKeyMaterialPtr cppKM(new CPKIFCryptoPPKeyMaterial());
00207     cppKM->SetRawSPKI(spkiBuf);
00208 
00209     rv = boost::dynamic_pointer_cast<CPKIFKeyMaterial, CPKIFCryptoPPKeyMaterial>(cppKM);
00210     return rv;
00211 
00212 }
00213 
00221 void CPKIFCryptoPPCredential::SetCertificate(CPKIFCertificatePtr & cert)
00222 {
00223     LOG_STRING_DEBUG(__FUNCTION__,TOOLKIT_CRYPTO_CRYPTOPPCRED,0,this);
00224     m_pkifCert = cert;
00225 }
00226 
00233 void CPKIFCryptoPPCredential::SetPrivateKey(
00236                    CPKIFBufferPtr & key
00237                    )
00238 {
00239     m_keyBuf = key;
00240 }
00241 
00248 void CPKIFCryptoPPCredential::SetAlgorithm(
00250     CPKIFAlgorithm * alg
00251     )
00252 {
00253     m_keyAlg = alg;
00254 }
00255 
00262 CPKIFAlgorithm * CPKIFCryptoPPCredential::GetAlgorithm()
00263 {
00264     return m_keyAlg;
00265 }

Generated on Mon Nov 15 11:15:54 2010 for PublicKeyInfrastructureFramework(PKIF) by  doxygen 1.5.6