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
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
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
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
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
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
00369
00370 CPKIFSubjectPublicKeyInfoPtr spki = km->GetSubjectPublicKeyInfo();
00371
00372
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
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