00001
00009 #include "components.h"
00010 #include "PKIFKeyMaterial.h"
00011 #include "PKIFCryptoException.h"
00012 #include "PKIFCryptoErrors.h"
00013 #include "ToolkitUtils.h"
00014 #include "SubjectPublicKeyInfo.h"
00015 #include "PKIFMemoryUtils.h"
00016
00017 #include <cstring>
00018
00020 struct CPKIFKeyMaterialImpl
00021 {
00022
00023
00025 unsigned char* m_cert;
00027 int m_certLen;
00028
00029 PKIFCRYPTO::SYMKEY_ALG m_symAlg;
00030 PKIFCRYPTO::SYMKEY_MODE m_mode;
00032 unsigned char* m_symKey;
00034 int m_symKeyLen;
00036 unsigned char* m_symKeyIV;
00038 int m_symKeyIVLen;
00039
00040 CPKIFAlgorithmIdentifierPtr m_workingParams;
00041 CPKIFSubjectPublicKeyInfoPtr m_spki;
00042
00043 void FreeAllMembers();
00044 };
00046
00056 int CPKIFKeyMaterial::GetCertificateLength() const
00057 {
00058 return m_impl->m_certLen;
00059 }
00068 void CPKIFKeyMaterial::SetWorkingParameters(
00070 CPKIFAlgorithmIdentifierPtr& algID)
00071 {
00072 m_impl->m_workingParams = algID;
00073 }
00082 CPKIFAlgorithmIdentifierPtr CPKIFKeyMaterial::GetWorkingParameters() const
00083 {
00084 return m_impl->m_workingParams;
00085 }
00094 void CPKIFKeyMaterial::SetMode(PKIFCRYPTO::SYMKEY_MODE mode)
00095 {
00096 m_impl->m_mode = mode;
00097 }
00105 PKIFCRYPTO::SYMKEY_MODE CPKIFKeyMaterial::GetMode()const
00106 {
00107 return m_impl->m_mode;
00108 }
00116 int CPKIFKeyMaterial::GetSymmetricKeyLength() const
00117 {
00118 return m_impl->m_symKeyLen;
00119 }
00128 PKIFCRYPTO::SYMKEY_ALG CPKIFKeyMaterial::GetSymmetricKeyAlgorithm() const
00129 {
00130 return m_impl->m_symAlg;
00131 }
00139 void CPKIFKeyMaterial::SetSymmetricKeyAlgorithm(
00142 PKIFCRYPTO::SYMKEY_ALG alg)
00143 {
00144 m_impl->m_symAlg = alg;
00145 }
00146
00154 CPKIFKeyMaterial::CPKIFKeyMaterial(void)
00155 :m_impl (new CPKIFKeyMaterialImpl)
00156 {
00157 LOG_STRING_DEBUG("CPKIFKeyMaterial::CPKIFKeyMaterial(void)", TOOLKIT_CRYPTO_KEYMATERIAL, 0, this);
00158
00159 m_impl->m_symKey = NULL;
00160 m_impl->m_symKeyLen = 0;
00161
00162 m_impl->m_cert = NULL;
00163 m_impl->m_certLen = 0;
00164
00165 m_impl->m_symKeyIV = NULL;
00166 m_impl->m_symKeyIVLen = 0;
00167
00168 m_impl->m_mode = PKIFCRYPTO::ECB;
00169 }
00177 CPKIFKeyMaterial::~CPKIFKeyMaterial(void)
00178 {
00179 LOG_STRING_DEBUG("CPKIFKeyMaterial::~CPKIFKeyMaterial(void)", TOOLKIT_CRYPTO_KEYMATERIAL, 0, this);
00180
00181 m_impl->FreeAllMembers();
00182
00183 delete m_impl;
00184 m_impl = NULL;
00185 }
00193 void CPKIFKeyMaterialImpl::FreeAllMembers()
00194 {
00195 LOG_STRING_DEBUG("CPKIFKeyMaterial::FreeAllMembers()", TOOLKIT_CRYPTO_KEYMATERIAL, 0, this);
00196
00197 if(NULL != m_symKeyIV)
00198 {
00199 PKIFZero(m_symKeyIV, m_symKeyIVLen);
00200 delete[] m_symKeyIV; m_symKeyIV = NULL;
00201 }
00202
00203 if(NULL != m_symKey)
00204 {
00205 PKIFZero(m_symKey,m_symKeyLen);
00206 delete[] m_symKey; m_symKey = NULL;
00207 }
00208
00209 if(NULL != m_cert)
00210 {
00211 delete[] m_cert; m_cert = NULL;
00212 }
00213
00214 m_certLen = 0;
00215 m_symKeyLen = 0;
00216 m_symKeyIVLen = 0;
00217 }
00226 bool CPKIFKeyMaterial::ContainsSymmetricKeyMaterial() const
00227 {
00228 return NULL != m_impl->m_symKey;
00229 }
00237 bool CPKIFKeyMaterial::ContainsCertificate() const
00238 {
00239 return NULL != m_impl->m_cert;
00240 }
00250 void CPKIFKeyMaterial::SetCertificate(
00252 const unsigned char* cert,
00254 int certLen)
00255 {
00256 LOG_STRING_DEBUG("CPKIFKeyMaterial::SetCertificate(const unsigned char* cert, int certLen)", TOOLKIT_CRYPTO_KEYMATERIAL, 0, this);
00257
00258 if(NULL == cert || 0 == certLen)
00259 throw CPKIFCryptoException(TOOLKIT_CRYPTO, COMMON_INVALID_INPUT, "cert parameter must not be NULL and certLen parameter must not be 0.");
00260
00261
00262 unsigned char* tmpCert = new unsigned char[certLen];
00263 memcpy(tmpCert, cert, certLen);
00264
00265 m_impl->FreeAllMembers();
00266
00267 m_impl->m_cert = tmpCert;
00268 m_impl->m_certLen = certLen;
00269 }
00297 void CPKIFKeyMaterial::GetCertificate(
00300 unsigned char* cert,
00303 int* certLen) const
00304 {
00305 LOG_STRING_DEBUG("CPKIFKeyMaterial::GetCertificate(unsigned char* cert, int* certLen)", TOOLKIT_CRYPTO_KEYMATERIAL, 0, this);
00306
00307 if(NULL == certLen)
00308 throw CPKIFCryptoException(TOOLKIT_CRYPTO, COMMON_INVALID_INPUT, "certLen parameter must not be NULL.");
00309
00310 *certLen = m_impl->m_certLen;
00311 if(NULL == cert)
00312 return;
00313
00314 int copyLen = m_impl->m_certLen > *certLen ? *certLen : m_impl->m_certLen;
00315 memcpy(cert, m_impl->m_cert, copyLen);
00316 }
00327 const unsigned char* CPKIFKeyMaterial::GetCertificate() const
00328 {
00329 return m_impl->m_cert;
00330 }
00340 void CPKIFKeyMaterial::SetSymmetricKey(
00342 const unsigned char* key,
00344 int keyLen)
00345 {
00346 LOG_STRING_DEBUG("CPKIFKeyMaterial::SetSymmetricKey(const unsigned char* key, int keyLen)", TOOLKIT_CRYPTO_KEYMATERIAL, 0, this);
00347
00348 if(NULL == key || 0 == keyLen)
00349 throw CPKIFCryptoException(TOOLKIT_CRYPTO, COMMON_INVALID_INPUT, "key parameter must not be NULL and keyLen parameter must not be 0.");
00350
00351
00352 unsigned char* tmpKey = new unsigned char[keyLen];
00353 memcpy(tmpKey, key, keyLen);
00354
00355 m_impl->FreeAllMembers();
00356
00357 m_impl->m_symKey = tmpKey;
00358 m_impl->m_symKeyLen = keyLen;
00359 }
00372 void CPKIFKeyMaterial::GetSymmetricKey(
00375 unsigned char* key,
00378 int* keyLen,
00380 PKIFCRYPTO::SYMKEY_ALG* alg) const
00381 {
00382 LOG_STRING_DEBUG("CPKIFKeyMaterial::GetSymmetricKey(unsigned char* key, int* keyLen, SYMKEY_ALG* alg)", TOOLKIT_CRYPTO_KEYMATERIAL, 0, this);
00383
00384 if(NULL == keyLen)
00385 throw CPKIFCryptoException(TOOLKIT_CRYPTO, COMMON_INVALID_INPUT, "keyLen parameter must not be NULL.");
00386
00387 *keyLen = m_impl->m_symKeyLen;
00388 if(NULL == key)
00389 return;
00390
00391 int copyLen = m_impl->m_symKeyLen > *keyLen ? *keyLen : m_impl->m_symKeyLen;
00392 memcpy(key, m_impl->m_symKey, copyLen);
00393
00394 if(NULL != alg)
00395 *alg = m_impl->m_symAlg;
00396 }
00408 const unsigned char* CPKIFKeyMaterial::GetSymmetricKey() const
00409 {
00410 return m_impl->m_symKey;
00411 }
00421 void CPKIFKeyMaterial::SetIV(
00423 const unsigned char* iv,
00425 int ivLen)
00426 {
00427 LOG_STRING_DEBUG("CPKIFKeyMaterial::SetIV(const unsigned char* iv, int ivLen)", TOOLKIT_CRYPTO_KEYMATERIAL, 0, this);
00428
00429 if(NULL == iv || 0 == ivLen)
00430 throw CPKIFCryptoException(TOOLKIT_CRYPTO, COMMON_INVALID_INPUT, "iv parameter must not be NULL and ivLen parameter must not be 0.");
00431
00432
00433 unsigned char* tmpIV = new unsigned char[ivLen];
00434 memcpy(tmpIV, iv, ivLen);
00435
00436 if(NULL != m_impl->m_symKeyIV)
00437 {
00438 delete[] m_impl->m_symKeyIV; m_impl->m_symKeyIV = NULL;
00439 }
00440
00441 m_impl->m_symKeyIV = tmpIV;
00442 m_impl->m_symKeyIVLen = ivLen;
00443 }
00455 void CPKIFKeyMaterial::GetIV(
00457 unsigned char* iv,
00460 int* ivLen) const
00461 {
00462 LOG_STRING_DEBUG("CPKIFKeyMaterial::GetIV(unsigned char* iv, int* ivLen)", TOOLKIT_CRYPTO_KEYMATERIAL, 0, this);
00463
00464 if(NULL == ivLen)
00465 throw CPKIFCryptoException(TOOLKIT_CRYPTO, COMMON_INVALID_INPUT, "ivLen parameter must not be NULL.");
00466
00467 if(NULL == iv)
00468 {
00469 *ivLen = m_impl->m_symKeyIVLen;
00470 return;
00471 }
00472 if(m_impl->m_symKeyIVLen > *ivLen)
00473 throw CPKIFCryptoException(TOOLKIT_CRYPTO, COMMON_INVALID_INPUT, "Input buffer too small.");
00474
00475 *ivLen = m_impl->m_symKeyIVLen;
00476
00477 int copyLen = m_impl->m_symKeyIVLen > *ivLen ? *ivLen : m_impl->m_symKeyIVLen;
00478 memcpy(iv, m_impl->m_symKeyIV, copyLen);
00479 }
00489 const unsigned char* CPKIFKeyMaterial::GetIV() const
00490 {
00491 return m_impl->m_symKeyIV;
00492 }
00493
00501 bool CPKIFKeyMaterial::ContainsPublicKeyMaterial() const
00502 {
00503 return m_impl->m_spki != (CPKIFSubjectPublicKeyInfo*)NULL;
00504 }
00512 void CPKIFKeyMaterial::SetSubjectPublicKeyInfo(
00514 const CPKIFSubjectPublicKeyInfoPtr& spki)
00515 {
00516 m_impl->m_spki = spki;
00517 }
00525 CPKIFSubjectPublicKeyInfoPtr CPKIFKeyMaterial::GetSubjectPublicKeyInfo() const
00526 {
00527 return m_impl->m_spki;
00528 }
00529
00537 CPKIFKeyMaterialPtr CPKIFKeyMaterial::CreateWithSymmetricKey(
00539 const CPKIFKeyMaterialPtr & km)
00540 {
00541 if(!km->ContainsSymmetricKeyMaterial()) {
00542 throw CPKIFCryptoException(TOOLKIT_CRYPTO, COMMON_INVALID_INPUT, "A symmetric key is required.");
00543 }
00544 CPKIFKeyMaterialPtr rv(new CPKIFKeyMaterial());
00545 rv->SetSymmetricKey(km->GetSymmetricKey(),km->GetSymmetricKeyLength());
00546 rv->SetMode(km->GetMode());
00547 rv->SetSymmetricKeyAlgorithm(km->GetSymmetricKeyAlgorithm());
00548 int ivLen = 0;
00549 km->GetIV(NULL,&ivLen);
00550 if(ivLen > 0) {
00551 rv->SetIV(km->GetIV(),ivLen);
00552 }
00553 return rv;
00554 }