PKIFXSECCryptoSymmetricKey.cpp

Go to the documentation of this file.
00001 
00010 #include "PKIFXSECCrypto.h"
00011 #include "PKIFXSECCryptoSymmetricKey.h"
00012 #include "PKIFXSECCryptoKeyRaw.h"
00013 
00014 #include "PKIFAlgorithm.h"
00015 
00016 #include <xsec/utils/XSECPlatformUtils.hpp>
00018 struct PKIFXSECCryptoSymmetricKeyImpl
00019 {
00020     IPKIFCryptoRawOperations * m_raw; //WEAK
00021     IPKIFRawCryptContext * m_ctx;
00022     XSECCryptoSymmetricKey::SymmetricKeyType m_kt;
00023     bool m_bIVSent;
00024 };
00026 
00033 XSECCryptoSymmetricKey::SymmetricKeyType getXSECKeyType(PKIFCRYPTO::SYMKEY_ALG alg)
00034 {
00035     switch(alg) {
00036         case PKIFCRYPTO::TDES:
00037             return XSECCryptoSymmetricKey::KEY_3DES_192;
00038             break;
00039         case PKIFCRYPTO::AES128:
00040             return XSECCryptoSymmetricKey::KEY_AES_128;
00041             break;
00042         case PKIFCRYPTO::AES192:
00043             return XSECCryptoSymmetricKey::KEY_AES_192;
00044             break;
00045         case PKIFCRYPTO::AES256:
00046             return XSECCryptoSymmetricKey::KEY_AES_256;
00047             break;
00048     }
00049     // default: but without compiler warnings
00050     return XSECCryptoSymmetricKey::KEY_NONE;
00051 }
00059 PKIFCRYPTO::SYMKEY_ALG getPKIFKeyType(XSECCryptoSymmetricKey::SymmetricKeyType alg)
00060 {
00061     switch(alg) {
00062         case XSECCryptoSymmetricKey::KEY_3DES_192:
00063             return PKIFCRYPTO::TDES;
00064             break;
00065         case XSECCryptoSymmetricKey::KEY_AES_128:
00066             return PKIFCRYPTO::AES128;
00067             break;
00068         case XSECCryptoSymmetricKey::KEY_AES_192:
00069             return PKIFCRYPTO::AES192;
00070             break;
00071         case XSECCryptoSymmetricKey::KEY_AES_256:
00072             return PKIFCRYPTO::AES256;
00073             break;
00074     }
00075     // the library's default, in case we somehow got the NONE type
00076     return PKIFCRYPTO::AES128;
00077 }
00078 
00084 PKIFCRYPTO::SYMKEY_MODE getPKIFMode(XSECCryptoSymmetricKey::SymmetricKeyMode mode)
00085 {
00086     switch(mode) {
00087         case XSECCryptoSymmetricKey::MODE_CBC:
00088             return PKIFCRYPTO::CBC;
00089             break;
00090         case XSECCryptoSymmetricKey::MODE_ECB:
00091             return PKIFCRYPTO::ECB;
00092             break;
00093     }
00094     // default: but without compiler warnings
00095     return PKIFCRYPTO::ECB;
00096 }
00097 
00105 PKIFXSECCryptoSymmetricKey::PKIFXSECCryptoSymmetricKey()
00106 :m_rawKey(new PKIFXSECCryptoKeyRaw()),m_impl(new PKIFXSECCryptoSymmetricKeyImpl)
00107 {
00108     m_impl->m_raw = 0;
00109     m_impl->m_ctx = 0;
00110     m_impl->m_bIVSent = false;
00111 }
00112 
00120 PKIFXSECCryptoSymmetricKey::PKIFXSECCryptoSymmetricKey(
00122     IPKIFCryptoRawOperations * raw)
00123 :m_rawKey(new PKIFXSECCryptoKeyRaw()), m_impl(new PKIFXSECCryptoSymmetricKeyImpl)
00124 {
00125     m_impl->m_raw = raw;
00126     m_impl->m_ctx = 0;
00127     m_impl->m_bIVSent = false;
00128 }
00129 
00137 PKIFXSECCryptoSymmetricKey::~PKIFXSECCryptoSymmetricKey()
00138 {
00139     if(m_rawKey) {
00140         delete m_rawKey;
00141         m_rawKey = 0;
00142     }
00143     if(m_impl) {
00144         // don't free the mediator. we don't own it
00145         delete m_impl;
00146         m_impl = 0;
00147     }
00148 }
00149 
00158 XSECCryptoKey * PKIFXSECCryptoSymmetricKey::clone() const
00159 {
00160     CPKIFKeyMaterialPtr kp = m_rawKey->getPKIFKeyMaterial();
00161     PKIFXSECCryptoSymmetricKey * rv = new PKIFXSECCryptoSymmetricKey(m_impl->m_raw);
00162     rv->setPKIFKeyMaterial(kp);
00163     // XXX *** !!! should the context be cloned too?
00164     return rv;
00165 }
00166 
00174 void PKIFXSECCryptoSymmetricKey::setKey(
00176     const unsigned char * inBuf,
00178     unsigned int inLength)
00179 {
00180     m_rawKey->setKey(inBuf,inLength);
00181     m_rawKey->getPKIFKeyMaterial()->SetSymmetricKeyAlgorithm(getPKIFKeyType(m_impl->m_kt));
00182 }
00183 
00190 unsigned int PKIFXSECCryptoSymmetricKey::getKey(
00192     safeBuffer &outBuf)
00193 {
00194     return m_rawKey->getKey(outBuf);
00195 }
00196 
00204 CPKIFKeyMaterialPtr PKIFXSECCryptoSymmetricKey::getPKIFKeyMaterial()
00205 {
00206     return m_rawKey->getPKIFKeyMaterial();
00207 }
00208 
00216 void PKIFXSECCryptoSymmetricKey::setPKIFKeyMaterial(
00218     CPKIFKeyMaterialPtr & km)
00219 {
00220     m_rawKey->setPKIFKeyMaterial(km);
00221 }
00222 
00230 const XMLCh * PKIFXSECCryptoSymmetricKey::getProviderName() const
00231 {
00232     return m_rawKey->getProviderName();
00233 }
00234 
00242 XSECCryptoSymmetricKey::SymmetricKeyType PKIFXSECCryptoSymmetricKey::getSymmetricKeyType() const
00243 {
00244     if(!m_rawKey || !m_rawKey->getPKIFKeyMaterial()) return XSECCryptoSymmetricKey::KEY_NONE;
00245     return getXSECKeyType(m_rawKey->getPKIFKeyMaterial()->GetSymmetricKeyAlgorithm());
00246 }
00247 
00255 void PKIFXSECCryptoSymmetricKey::setSymmetricType(XSECCryptoSymmetricKey::SymmetricKeyType type)
00256 {
00257     m_impl->m_kt = type;
00258 }
00259 
00267 bool PKIFXSECCryptoSymmetricKey::decryptInit(
00269     bool doPad,
00271     SymmetricKeyMode mode,
00274     const unsigned char * iv)
00275 {
00276     if(!m_rawKey || !m_rawKey->getPKIFKeyMaterial()) return false;
00277     if(XSECCryptoSymmetricKey::MODE_NONE == mode) return false;
00278     if(!m_impl->m_raw) return false;
00279     PKIFCRYPTO::SYMKEY_MODE pkifMode = getPKIFMode(mode);
00280     CPKIFKeyMaterialPtr km = m_rawKey->getPKIFKeyMaterial();
00281     km->SetMode(pkifMode);
00282     if(iv) {
00283         CPKIFAlgorithm * alg = CPKIFAlgorithm::GetAlg(km->GetSymmetricKeyAlgorithm(),pkifMode);
00284         if(!alg) return false;
00285         km->SetIV(iv,alg->BlockSize());
00286     }
00287     if(m_impl->m_ctx) {
00288         delete m_impl->m_ctx;
00289         m_impl->m_ctx = 0;
00290     }
00291     // API change means the real init needs to be done later
00292     //m_impl->m_ctx = m_impl->m_raw->CryptInit(*km);
00293     //return (m_impl->m_ctx != 0);
00294     return true;
00295 }
00296 
00304 unsigned int PKIFXSECCryptoSymmetricKey::decrypt(
00306     const unsigned char * inBuf,
00308     unsigned char * plainBuf,
00310     unsigned int inLength,
00312     unsigned int maxOutLength)
00313 {
00314     if(!m_rawKey || !m_rawKey->getPKIFKeyMaterial()) return 0;
00315     // Due to API change, this context will no longer ever be set up by now.
00316     //if(!m_impl->m_ctx) return 0;
00317     CPKIFKeyMaterialPtr km = m_rawKey->getPKIFKeyMaterial();
00318     unsigned int processedLength = 0;
00319     unsigned char * ctCurr = const_cast<unsigned char *>(inBuf);
00320     // the only mode supported by both PKIF and xsec that requires an IV is CBC.
00321     // if xsec didn't pass it in before, it'll be the first block
00322     CPKIFAlgorithm * alg = CPKIFAlgorithm::GetAlg(km->GetSymmetricKeyAlgorithm(),km->GetMode());
00323     if(!alg) return 0;
00324     if(inLength < alg->BlockSize()) return 0;
00325     if(alg->NeedsIV() && !km->GetIV()) {
00326         km->SetIV(inBuf,alg->BlockSize());
00327         processedLength += alg->BlockSize();
00328         ctCurr += alg->BlockSize();
00329     }
00330     int outLen = maxOutLength;
00331     if(!m_impl->m_ctx) m_impl->m_ctx = m_impl->m_raw->CryptInit(*km);
00332     if(!m_impl->m_ctx) return 0;
00333     m_impl->m_raw->Decrypt(m_impl->m_ctx,ctCurr,inLength - processedLength,plainBuf,&outLen,false);
00334     return outLen;
00335 }
00343 unsigned int PKIFXSECCryptoSymmetricKey::decryptFinish(
00345     unsigned char * plainBuf,
00347     unsigned int maxOutLength)
00348 {
00349     if(!m_rawKey || !m_rawKey->getPKIFKeyMaterial()) return false;
00350     if(!m_impl->m_ctx) return false;
00351     int outLen = maxOutLength;
00352     m_impl->m_raw->Decrypt(m_impl->m_ctx,0,0,plainBuf,&outLen,true);
00353     return outLen;
00354 }
00355 
00363 bool PKIFXSECCryptoSymmetricKey::encryptInit(
00365     bool doPad,
00367     SymmetricKeyMode mode,
00369     const unsigned char * iv)
00370 {
00371     if(!m_rawKey || !m_rawKey->getPKIFKeyMaterial()) return false;
00372     if(XSECCryptoSymmetricKey::MODE_NONE == mode) return false;
00373     if(!m_impl->m_raw) return false;
00374     PKIFCRYPTO::SYMKEY_MODE pkifMode = getPKIFMode(mode);
00375     CPKIFKeyMaterialPtr km = m_rawKey->getPKIFKeyMaterial();
00376     km->SetMode(pkifMode);
00377     CPKIFAlgorithm * alg = CPKIFAlgorithm::GetAlg(km->GetSymmetricKeyAlgorithm(),pkifMode);
00378     if(!alg) return false;
00379     if(iv) {
00380         km->SetIV(iv,alg->BlockSize());
00381     
00382     } else if(!iv && alg->NeedsIV()) {
00383         PKIFXSECCrypto * cp = dynamic_cast<PKIFXSECCrypto *>(XSECPlatformUtils::g_cryptoProvider);
00384         if(!cp) return false;
00385         int ivLen = alg->BlockSize();
00386         unsigned char * ivBuf = new unsigned char[ivLen];
00387         cp->getRandom(ivBuf,ivLen);
00388         km->SetIV(ivBuf,ivLen);
00389         delete[] ivBuf;
00390     }
00391     if(m_impl->m_ctx) {
00392         delete m_impl->m_ctx;
00393         m_impl->m_ctx = 0;
00394     }
00395     m_impl->m_ctx = m_impl->m_raw->CryptInit(*km);
00396     return (m_impl->m_ctx != 0);
00397 }
00398 
00406 unsigned int PKIFXSECCryptoSymmetricKey::encrypt(
00408     const unsigned char * inBuf,
00410     unsigned char * cipherBuf,
00412     unsigned int inLength,
00414     unsigned int maxOutLength)
00415 {
00416     if(!m_rawKey || !m_rawKey->getPKIFKeyMaterial()) return 0;
00417     if(!m_impl->m_ctx) return 0;
00418     CPKIFKeyMaterialPtr km = m_rawKey->getPKIFKeyMaterial();
00419     unsigned int processedLength = 0;
00420     
00421     // the only mode supported by both PKIF and xsec that requires an IV is CBC.
00422     // if xsec didn't pass it in before, it'll be the first block
00423     CPKIFAlgorithm * alg = CPKIFAlgorithm::GetAlg(km->GetSymmetricKeyAlgorithm(),km->GetMode());
00424     if(!alg) return 0;
00425     if(inLength < alg->BlockSize()) return 0;
00426     if(alg->NeedsIV() && !m_impl->m_bIVSent) {
00427         memcpy(cipherBuf,km->GetIV(),alg->BlockSize());
00428         processedLength += alg->BlockSize();
00429         m_impl->m_bIVSent = true;
00430     }
00431     
00432     int outLen = maxOutLength - processedLength;
00433     unsigned char * ptBuf = const_cast<unsigned char *>(inBuf);
00434     m_impl->m_raw->Encrypt(m_impl->m_ctx,ptBuf,inLength,cipherBuf+processedLength,&outLen,false);
00435     processedLength += outLen;
00436     return processedLength;
00437 }
00438 
00446 unsigned int PKIFXSECCryptoSymmetricKey::encryptFinish(
00448     unsigned char * plainBuf,
00450     unsigned int maxOutLength)
00451 {
00452     if(!m_rawKey || !m_rawKey->getPKIFKeyMaterial()) return false;
00453     if(!m_impl->m_ctx) return false;
00454     int outLen = maxOutLength;
00455     m_impl->m_raw->Encrypt(m_impl->m_ctx,0,0,plainBuf,&outLen,true);
00456     return outLen;
00457 }
00458 

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