PKIFCryptoPPKeyMaterial.cpp

Go to the documentation of this file.
00001 
00010 #include "PKIFCryptoPPKeyMaterial.h"
00011 
00012 #include "ASN1HelperLib.h"
00013 
00014 #include "Buffer.h"
00015 #include "Certificate.h"
00016 #include "SubjectPublicKeyInfo.h"
00017 #include "AlgorithmIdentifier.h"
00018 #include "ASN1Helper.h"
00019 #include "PKIFAlgorithm.h"
00020 #include "ooasn1.h"
00021 #include "PKIX1Explicit88.h"
00022 #include "PKIFCryptoException.h"
00023 #include "PKIFCryptoPPErrors.h"
00024 #include "ToolkitUtils.h"
00025 
00026 #include "boost/numeric/conversion/cast.hpp"
00027 
00028 using boost::numeric_cast;
00029 using boost::bad_numeric_cast;
00030 
00038 CPKIFCryptoPPKeyMaterial::CPKIFCryptoPPKeyMaterial(void)
00039 :m_rawSPKI((CPKIFBuffer*)0),m_alg(0),CPKIFKeyMaterial(), m_hasParams(false)
00040 {
00041 }
00042 
00050 CPKIFCryptoPPKeyMaterial::~CPKIFCryptoPPKeyMaterial(void)
00051 {
00052 }
00053 
00061 CPKIFCryptoPPKeyMaterial::CPKIFCryptoPPKeyMaterial(const CPKIFCertificate & cert)
00062 :m_rawSPKI((CPKIFBuffer*)0),m_alg(0),CPKIFKeyMaterial(), m_hasParams(false)
00063 {
00064     InitWithCert(cert);
00065 }
00066 
00074 CPKIFCryptoPPKeyMaterial::CPKIFCryptoPPKeyMaterial(CPKIFSubjectPublicKeyInfoPtr & spki)
00075 :m_rawSPKI((CPKIFBuffer*)0),m_alg(0),CPKIFKeyMaterial(), m_hasParams(false)
00076 {
00077     InitWithSPKI(spki);
00078 }
00079 
00087 CPKIFCryptoPPKeyMaterial::CPKIFCryptoPPKeyMaterial(const CPKIFKeyMaterial & km)
00088 :m_rawSPKI((CPKIFBuffer*)0),m_alg(0),CPKIFKeyMaterial(), m_hasParams(false)
00089 {
00090     InitWithKeyMaterial(km);
00091 }
00092 
00100 CPKIFBufferPtr CPKIFCryptoPPKeyMaterial::GetRawSPKI(void) const
00101 {
00102     return m_rawSPKI;
00103 }
00104 
00112 const CPKIFAlgorithm * CPKIFCryptoPPKeyMaterial::GetKeyAlg(void) const
00113 {
00114     return m_alg;
00115 }
00116 
00124 void CPKIFCryptoPPKeyMaterial::SetRawSPKI(
00126     const CPKIFBufferPtr & key
00127     )
00128 {
00129     m_rawSPKI = key;
00130     if(m_rawSPKI) {
00131         CACASNWRAPPER_CREATE(CACX509V3SubjectPublicKeyInfo, spkiPDU);
00132         CACX509V3SubjectPublicKeyInfo * spki = spkiPDU.Decode(m_rawSPKI->GetBuffer(),m_rawSPKI->GetLength());
00133         m_hasParams = (spki->algorithm.m.parametersPresent != 0);
00134         CPKIFOIDPtr algOid(new CPKIFOID(spki->algorithm.algorithm.subid, spki->algorithm.algorithm.numids));
00135         SetKeyAlg(CPKIFAlgorithm::GetAlg(algOid));
00136         CPKIFBufferPtr paramsBuf(new CPKIFBuffer());
00137         unsigned char * p = paramsBuf->AllocateBuffer(spki->algorithm.parameters.numocts);
00138         memcpy(p,spki->algorithm.parameters.data,spki->algorithm.parameters.numocts);
00139         CPKIFAlgorithmIdentifierPtr algID(new CPKIFAlgorithmIdentifier(algOid,paramsBuf));
00140         CPKIFBufferPtr keyBuf(new CPKIFBuffer());
00141         size_t keyLen = BitsToBytes(spki->subjectPublicKey.numbits);
00142         try {
00143             p = keyBuf->AllocateBuffer(numeric_cast<int>(keyLen));
00144         }catch(bad_numeric_cast &){
00145             throw CPKIFCryptoException(TOOLKIT_CRYPTO_CRYPTOPPRAW, PKIF_CRYPTOPP_RAW_IMPORT_FAILED);
00146         }
00147         memcpy(p,spki->subjectPublicKey.data,keyLen);
00148         CPKIFSubjectPublicKeyInfoPtr pkifSPKI(new CPKIFSubjectPublicKeyInfo(algID,keyBuf));
00149         SetSubjectPublicKeyInfo(pkifSPKI);
00150     } else {
00151         m_hasParams = false;
00152     }
00153 }
00154 
00164 void CPKIFCryptoPPKeyMaterial::SetKeyAlg(
00166     const CPKIFAlgorithm * alg
00167     )
00168 {
00169     m_alg = alg;
00170 }
00171 
00172 
00179 void CPKIFCryptoPPKeyMaterial::InitWithKeyMaterial(const CPKIFKeyMaterial & km)
00180 {
00181     CPKIFAlgorithmIdentifierPtr tmpAlgID = km.GetWorkingParameters();
00182     SetWorkingParameters(tmpAlgID);
00183     CPKIFSubjectPublicKeyInfoPtr spki = km.GetSubjectPublicKeyInfo();
00184     if(spki)
00185     {
00186         InitWithSPKI(spki);
00187     }else if(km.GetCertificateLength() > 0) {
00188         CPKIFCertificatePtr cert(new CPKIFCertificate);
00189         cert->Decode(km.GetCertificate(), km.GetCertificateLength());
00190         InitWithCert(*cert);
00191     } else {
00192         // XXX This should probably be a better exception, but it'll currently be reduced to
00193         // this by the caller and the caller should be checking to make sure this can never
00194         // be reached anyway.
00195         throw CPKIFCryptoException(TOOLKIT_CRYPTO_CRYPTOPPRAW, PKIF_CRYPTOPP_RAW_IMPORT_FAILED);
00196     }
00197 }
00198 
00205 void CPKIFCryptoPPKeyMaterial::InitWithSPKI(CPKIFSubjectPublicKeyInfoPtr & spki)
00206 {
00207     m_hasParams = false;
00208     SetSubjectPublicKeyInfo(spki);
00209     // crypto++ likes its public keys in the form of DER-encoded subject public key info
00210     CACASNWRAPPER_CREATE(CACX509V3SubjectPublicKeyInfo, spkiPDU);
00211     CACX509V3SubjectPublicKeyInfo spkiStruct;
00212     memset(&spkiStruct,0x00,sizeof(CACX509V3SubjectPublicKeyInfo));
00213     spkiStruct.algorithm.m.parametersPresent = spki->alg()->hasParameters() ? 1 : 0;
00214     CPKIFStringPtr str(new std::string(spki->alg()->oid()->ToString())); 
00215     ASN1OBJID* tmpOid = ConvertStringToASN1OBJID(str);
00216     spkiStruct.algorithm.algorithm = *tmpOid;
00217     CPKIFBufferPtr params = spki->alg()->parameters();
00218     if(spki->alg()->hasParameters()) {
00219         spkiStruct.algorithm.parameters.data = params->GetBuffer();
00220         spkiStruct.algorithm.parameters.numocts = params->GetLength();
00221         m_hasParams = true;
00222     } else {
00223         CPKIFAlgorithmIdentifierPtr wp = GetWorkingParameters();
00224         if(wp && wp->hasParameters()) {
00225             m_hasParams = true;
00226             params = wp->parameters();
00227             spkiStruct.algorithm.m.parametersPresent = 1;
00228             spkiStruct.algorithm.parameters.data = params->GetBuffer();
00229             spkiStruct.algorithm.parameters.numocts = params->GetLength();
00230         }
00231     }
00232     CPKIFBufferPtr rk = spki->rawKey();
00233     spkiStruct.subjectPublicKey.data = rk->GetBuffer();
00234     spkiStruct.subjectPublicKey.numbits = rk->GetLength() * 8;
00235     ASN1OpenType * encSPKI = spkiPDU.Encode(&spkiStruct);
00236     delete tmpOid;
00237     m_rawSPKI = CPKIFBufferPtr(new CPKIFBuffer(encSPKI->data,encSPKI->numocts));
00238     // make sure the helper doesn't free memory the smart pointers want to take care of
00239     spkiStruct.subjectPublicKey.data = 0;
00240     spkiStruct.algorithm.parameters.data = 0;
00241     delete encSPKI;
00242     m_alg = CPKIFAlgorithm::GetAlg(spki->alg()->oid());
00243 }
00244 
00251 void CPKIFCryptoPPKeyMaterial::InitWithCert(const CPKIFCertificate & cert)
00252 {
00253     CPKIFSubjectPublicKeyInfoPtr tmpSPKI = cert.GetSubjectPublicKeyInfo();
00254     InitWithSPKI(tmpSPKI);
00255     /* Since there's now a variant that accepts a CPKIFSubjectKeyInfo, just call that.
00256        The following is only here for reference.
00257     CPKIFBufferPtr encCert = cert.Encoded();
00258     CACASNWRAPPER_CREATE(CACX509V3Certificate, certPDU);
00259     certPDU.Decode(encCert->GetBuffer(),encCert->GetLength());
00260     CACASNWRAPPER_CREATE(CACX509V3SubjectPublicKeyInfo,spkiPDU);
00261     ASN1OpenType * encSPKI = spkiPDU.Encode(&(certPDU->tbsCertificate.subjectPublicKeyInfo));
00262     m_rawSPKI = CPKIFBufferPtr(new CPKIFBuffer(encSPKI->data,encSPKI->numocts));
00263     delete encSPKI;
00264     m_alg = CPKIFAlgorithm::GetAlg(cert.GetSubjectPublicKeyInfo()->alg()->oid());
00265     */
00266 }
00267 
00274 bool CPKIFCryptoPPKeyMaterial::HasParams() const
00275 {
00276     return m_hasParams;
00277 }

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