PKIFXSECCryptoKeyRSA.cpp

Go to the documentation of this file.
00001 
00010 #include "PKIFXSECCryptoKeyRSA.h"
00011 
00012 #include "PKIFXSECCrypto.h"
00013 
00014 #include <xsec/enc/XSCrypt/XSCryptCryptoBase64.hpp>
00015 #include <xsec/enc/XSECCryptoException.hpp>
00016 #include <xsec/enc/XSECCryptoUtils.hpp>
00017 #include <xsec/framework/XSECError.hpp>
00019 struct PKIFXSECCryptoKeyRSAImpl
00020 {
00021     IPKIFMediatorPtr m_med;
00022     CPKIFKeyMaterialPtr m_km;
00023     CPKIFCredentialPtr m_cred;
00024     CPKIFBufferPtr m_oaepParams;
00025 };
00033 PKIFCRYPTO::HASH_ALG haFromHashMethod(hashMethod hm)
00034 {
00035     switch(hm) {
00036         case HASH_SHA1:
00037             return PKIFCRYPTO::SHA1;
00038             break;
00039         case HASH_MD5:
00040             return PKIFCRYPTO::MD5;
00041             break;
00042         case HASH_SHA224:
00043             return PKIFCRYPTO::SHA224;
00044             break;
00045         case HASH_SHA256:
00046             return PKIFCRYPTO::SHA256;
00047             break;
00048         case HASH_SHA384:
00049             return PKIFCRYPTO::SHA384;
00050             break;
00051         case HASH_SHA512:
00052             return PKIFCRYPTO::SHA512;
00053             break;
00054         default:
00055             break;
00056     }
00057     // this is the library's default
00058     return PKIFCRYPTO::SHA1;
00059 }
00061 
00069 PKIFXSECCryptoKeyRSA::PKIFXSECCryptoKeyRSA()
00070 :m_impl(new PKIFXSECCryptoKeyRSAImpl())
00071 {
00072 }
00073 
00081 PKIFXSECCryptoKeyRSA::~PKIFXSECCryptoKeyRSA()
00082 {
00083     if(m_impl) {
00084         delete m_impl;
00085         m_impl = 0;
00086     }
00087 }
00088 
00096 XSECCryptoKey * PKIFXSECCryptoKeyRSA::clone() const
00097 {
00098     PKIFXSECCryptoKeyRSA * rv = new PKIFXSECCryptoKeyRSA();
00099     rv->m_impl->m_cred = m_impl->m_cred;
00100     rv->m_impl->m_km = m_impl->m_km;
00101     rv->m_impl->m_med = m_impl->m_med;
00102     rv->m_impl->m_oaepParams = m_impl->m_oaepParams;
00103     return rv;
00104 }
00105 
00115 void PKIFXSECCryptoKeyRSA::setOAEPparams(unsigned char * params, unsigned int paramsLen)
00116 {
00117     m_impl->m_oaepParams = CPKIFBufferPtr(new CPKIFBuffer(params,paramsLen));
00118 }
00119 
00127 unsigned int PKIFXSECCryptoKeyRSA::getOAEPparamsLen() const
00128 {
00129     if(!m_impl->m_oaepParams) return 0;
00130     return m_impl->m_oaepParams->GetLength();
00131 }
00140 const unsigned char * PKIFXSECCryptoKeyRSA::getOAEPparams() const
00141 {
00142     if(!m_impl->m_oaepParams) return 0;
00143     return m_impl->m_oaepParams->GetBuffer();
00144 }
00145 
00153 XSECCryptoKey::KeyType PKIFXSECCryptoKeyRSA::getKeyType() const
00154 {
00155     if(!m_impl) return XSECCryptoKey::KEY_NONE;
00156     if(m_impl->m_cred) return XSECCryptoKey::KEY_RSA_PAIR;
00157     if(m_impl->m_km) return XSECCryptoKey::KEY_RSA_PUBLIC;
00158     return XSECCryptoKey::KEY_NONE;
00159 }
00160 
00161 
00172 bool PKIFXSECCryptoKeyRSA::verifySHA1PKCS1Base64Signature(
00174     const unsigned char * hashBuf,
00176     unsigned int hashLen,
00178     const char * base64Signature,
00180     unsigned int sigLen,
00182     hashMethod hm)
00183 {
00184     if(!m_impl->m_km){
00185         throw XSECCryptoException(XSECCryptoException::RSAError,
00186         "PKIFXSECCryptoKeyRSA - No key available for RSA verification");
00187     }
00188     IPKIFCryptoRawOperations* cm = m_impl->m_med->GetMediator<IPKIFCryptoRawOperations>();
00189     if(!cm) {
00190         throw XSECCryptoException(XSECCryptoException::RSAError,
00191         "PKIFXSECCryptoKeyRSA - No appropriate mediator available for RSA verification");
00192     }
00193     // Decode the signature
00194     XSCryptCryptoBase64 b64;
00195     unsigned char * decSig = new unsigned char[sigLen];
00196     b64.decodeInit();
00197     unsigned int decSigLen = b64.decode((unsigned char *) base64Signature, sigLen, decSig, sigLen);
00198     decSigLen += b64.decodeFinish(&decSig[decSigLen], sigLen - decSigLen);
00199     bool ok = false;
00200     try {
00201         ok = cm->Verify(*(m_impl->m_km),const_cast<unsigned char *>(hashBuf),hashLen,decSig,decSigLen,haFromHashMethod(hm));
00202     }catch(CPKIFException & e){
00203         throw XSECCryptoException(XSECCryptoException::RSAError, e.GetDescription());
00204     }
00205     // the key resolver class will have already verified the cert and set up the key material
00206     return ok;
00207 }
00208 
00223 unsigned int PKIFXSECCryptoKeyRSA::signSHA1PKCS1Base64Signature(
00225     unsigned char * hashBuf,
00227     unsigned int hashLen,
00229     char * base64SignatureBuf,
00231     unsigned int base64SignatureBufLen,
00233     hashMethod hm)
00234 {
00235     if(!m_impl->m_cred) {
00236         throw XSECCryptoException(XSECCryptoException::RSAError,
00237         "PKIFXSECCryptoKeyRSA - No key available for RSA signing");
00238     }
00239     IPKIFCryptoKeyIDOperations* cm = m_impl->m_med->GetMediator<IPKIFCryptoKeyIDOperations>();
00240     if(!cm) {
00241         throw XSECCryptoException(XSECCryptoException::RSAError,
00242         "PKIFXSECCryptoKeyRSA - No appropriate mediator available for RSA signing");
00243     }
00244     // slightly wasteful but this is fast, the waste is temporary, and it's safe.
00245     int sigOutLen = 2 * getLength();
00246     unsigned char * sigOut = new unsigned char[sigOutLen];
00247     try {
00248         cm->Sign(*(m_impl->m_cred),hashBuf,hashLen,sigOut,&sigOutLen,haFromHashMethod(hm));
00249     }catch(CPKIFException & e){
00250         throw XSECCryptoException(XSECCryptoException::RSAError, e.GetDescription());
00251     }
00252 
00253     // Now encode
00254     XSCryptCryptoBase64 b64;
00255     b64.encodeInit();
00256     unsigned int ret = b64.encode(sigOut, sigOutLen, (unsigned char *) base64SignatureBuf, base64SignatureBufLen);
00257     ret += b64.encodeFinish((unsigned char *) &base64SignatureBuf[ret], base64SignatureBufLen - ret);
00258     return ret;
00259 }
00260 
00271 unsigned int PKIFXSECCryptoKeyRSA::privateDecrypt(
00273     const unsigned char * inBuf,
00275     unsigned char * plainBuf,
00277     unsigned int inLength,
00279     unsigned int maxOutLength,
00281     PaddingType padding,
00283     hashMethod hm)
00284 {
00285     if(padding != PAD_PKCS_1_5) {
00286         throw XSECCryptoException(XSECCryptoException::RSAError,"PKIF only supports PKCS 1.5 padding");
00287     }
00288     if(!m_impl->m_cred) {
00289         throw XSECCryptoException(XSECCryptoException::RSAError,
00290         "PKIFXSECCryptoKeyRSA - No key available for RSA decryption");
00291     }
00292     IPKIFCryptoKeyIDOperations* cm = m_impl->m_med->GetMediator<IPKIFCryptoKeyIDOperations>();
00293     if(!cm) {
00294         throw XSECCryptoException(XSECCryptoException::RSAError,
00295         "PKIFXSECCryptoKeyRSA - No appropriate mediator available for RSA decryption");
00296     }
00297     int rv = maxOutLength;
00298     try {
00299         cm->Decrypt(*(m_impl->m_cred),const_cast<unsigned char *>(inBuf),inLength,plainBuf,&rv);
00300     } catch(CPKIFException & e) {
00301         throw XSECCryptoException(XSECCryptoException::RSAError, e.GetDescription());
00302     }
00303     return rv;
00304 }
00305 
00316 unsigned int PKIFXSECCryptoKeyRSA::publicEncrypt(
00318     const unsigned char * inBuf,
00320     unsigned char * cipherBuf,
00322     unsigned int inLength,
00324     unsigned int maxOutLength,
00326     PaddingType padding,
00328     hashMethod hm)
00329 {
00330     if(padding != PAD_PKCS_1_5) {
00331         throw XSECCryptoException(XSECCryptoException::RSAError,"PKIF only supports PKCS 1.5 padding");
00332     }
00333     if(!m_impl->m_km){
00334         throw XSECCryptoException(XSECCryptoException::RSAError,
00335         "PKIFXSECCryptoKeyRSA - No key available for RSA encryption");
00336     }
00337     IPKIFCryptoRawOperations* cm = m_impl->m_med->GetMediator<IPKIFCryptoRawOperations>();
00338     if(!cm) {
00339         throw XSECCryptoException(XSECCryptoException::RSAError,
00340         "PKIFXSECCryptoKeyRSA - No appropriate mediator available for RSA encryption");
00341     }
00342     int rv = maxOutLength;
00343     try {
00344         cm->Encrypt(*(m_impl->m_km),const_cast<unsigned char *>(inBuf),inLength,cipherBuf,&rv);
00345     } catch(CPKIFException & e) {
00346         throw XSECCryptoException(XSECCryptoException::RSAError, e.GetDescription());
00347     }
00348     return rv;
00349 }
00350 
00358 unsigned int PKIFXSECCryptoKeyRSA::getLength() const
00359 {
00360     int len = 0;
00361     CPKIFKeyMaterialPtr km;
00362     if(m_impl->m_cred) {
00363         km = m_impl->m_cred->GetPublicKey();
00364     } else {
00365         km = m_impl->m_km;
00366     }
00367     if(!km) return 0;
00368     // ideally, the key material object we've now got will just have an SPKI object ready. That's not always true
00369     // at the moment. If it's not, we can try to decode one.
00370     CPKIFSubjectPublicKeyInfoPtr spki = km->GetSubjectPublicKeyInfo();
00371     // if the key material class we're stuck with doens't keep the subject public key info handy,
00372     // extract it from the cert.
00373     if(!spki) {
00374         CPKIFCertificatePtr cert(new CPKIFCertificate());
00375         cert->Decode(km->GetCertificate(),km->GetCertificateLength());
00376         if(!cert) return 0;
00377         spki = cert->GetSubjectPublicKeyInfo();
00378     }
00379     // if after all that we still don't have a valid subjectPublicKeyInfo, this object can't offer a proper answer.
00380     if(!spki) return 0;
00381     len = (spki->numBits() / 8);
00382     return len;
00383 }
00384 
00392 void PKIFXSECCryptoKeyRSA::SetMediator(
00394    IPKIFMediatorPtr & med)
00395 {
00396     m_impl->m_med = med;
00397 }
00398 
00406 void PKIFXSECCryptoKeyRSA::SetCredential(
00408     CPKIFCredentialPtr & cred)
00409 {
00410     m_impl->m_cred = cred;
00411 }
00412 
00420 void PKIFXSECCryptoKeyRSA::SetKeyMaterial(
00422     CPKIFKeyMaterialPtr & km)
00423 {
00424     m_impl->m_km = km;
00425 }
00426 
00434 const XMLCh * PKIFXSECCryptoKeyRSA::getProviderName() const
00435 {
00436     return pkifProvName();
00437 }
00438 

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