00001
00009 #include "Certificate.h"
00010 #include "AlgorithmIdentifier.h"
00011 #include "Name.h"
00012 #include "Validity.h"
00013 #include "SubjectPublicKeyInfo.h"
00014 #include "PKIFCryptUtils.h"
00015
00016 #include "PKIFX509Extensions2.h"
00017 #include "IPKIFCryptoRaw.h"
00018 #include "ExtensionsMatch.h"
00019 #include "PKIFException.h"
00020 #include "ASN1Helper.h"
00021 #include "Buffer.h"
00022 #include "PKIFTime.h"
00023 #include "PKIFCommonErrors.h"
00024 #include "PKIFBase64.h"
00025 #include "BasicConstraints.h"
00026
00027 #include "PKIX1Explicit88.h"
00028 #include "PKIX1Implicit88.h"
00029
00030 #include <vector>
00031 using namespace std;
00032
00034 struct CPKIFCertificateImpl
00035 {
00043 CPKIFCertificateImpl ();
00044 void populateExtensionsVector();
00045
00046
00047 void ClearContent();
00048
00049 CPKIFBufferPtr m_rawCert;
00050 CPKIFASNWrapper<CACX509V3Certificate> m_signedCert;
00051 CPKIFAlgorithmIdentifierPtr m_signatureAlgFromSignedMacro;
00052 std::vector<CPKIFX509ExtensionPtr> m_exts;
00053
00054
00055 CPKIFAlgorithmIdentifierPtr m_signatureAlg;
00056 CPKIFNamePtr m_issuer;
00057 CPKIFValidityPtr m_validity;
00058 CPKIFNamePtr m_subject;
00059 CPKIFSubjectPublicKeyInfoPtr m_subjectPublicKeyInfo;
00060
00061
00062 bool m_bSelfSigned;
00063 bool m_bSelfSignedSet;
00064 bool m_bSelfIssued;
00065 bool m_bSelfIssuedSet;
00066
00067
00068 CPKIFCertificate * m_this;
00069 };
00077 CPKIFCertificateImpl::CPKIFCertificateImpl ()
00078 : m_signedCert(BEREncCACX509V3Certificate, BERDecCACX509V3Certificate)
00079 {
00080 }
00081
00094 void CPKIFCertificateImpl::populateExtensionsVector()
00095 {
00096 if(NULL == m_signedCert.data())
00097 throw CPKIFException(TOOLKIT_X509_ASN, COMMON_INVALID_INPUT, "Attempted to read data from a certificate object prior to parsing a certificate.");
00098
00099
00100 if(!m_exts.empty())
00101 return;
00102
00103
00104 if(0 == m_signedCert->tbsCertificate.m.extensionsPresent)
00105 {
00106 m_exts.clear();
00107 return;
00108 }
00109
00110
00111
00112 CPKIFX509ExtensionMediator2 * mediator = CPKIFX509ExtensionMediator2::GetInstance();
00113 m_this->IPKIFHasExtensions::GetExtensions (mediator, m_exts);
00114 }
00115
00116
00124 void CPKIFCertificateImpl::ClearContent()
00125 {
00126 CPKIFBufferPtr tmpBuf;
00127 m_rawCert = tmpBuf;
00128
00129 m_exts.clear();
00130
00131 CPKIFAlgorithmIdentifierPtr tmpAlg;
00132 m_signatureAlg = tmpAlg;
00133
00134 CPKIFNamePtr tmpIss;
00135 m_issuer = tmpIss;
00136 CPKIFValidityPtr tmpVal;
00137 m_validity = tmpVal;
00138 CPKIFNamePtr tmpSub;
00139 m_subject = tmpSub;
00140 CPKIFSubjectPublicKeyInfoPtr tmpSPKI;
00141 m_subjectPublicKeyInfo = tmpSPKI;
00142
00143 m_bSelfSigned = false;
00144 m_bSelfSignedSet = false;
00145 m_bSelfIssued = false;
00146 m_bSelfIssuedSet = false;
00147 }
00148
00150
00151
00152
00153
00154
00155
00156
00164 CPKIFCertificate::CPKIFCertificate(void)
00165 :m_impl (new CPKIFCertificateImpl)
00166 {
00167
00168 m_impl->m_bSelfSigned = false;
00169 m_impl->m_bSelfSignedSet = false;
00170 m_impl->m_bSelfIssued = false;
00171 m_impl->m_bSelfIssuedSet = false;
00172 m_impl->m_this = this;
00173 }
00181 CPKIFCertificate::~CPKIFCertificate(void)
00182 {
00183 if(m_impl)
00184 {
00185 delete m_impl;
00186 m_impl = 0;
00187 }
00188 }
00197 bool CPKIFCertificate::IsSelfIssued() const
00198 {
00199 if(!m_impl->m_bSelfIssuedSet)
00200 {
00201 CPKIFCertificate* nonConstCert = const_cast<CPKIFCertificate*>(this);
00202 nonConstCert->m_impl->m_bSelfIssuedSet = true;
00203 nonConstCert->m_impl->m_bSelfIssued = (*Subject() == *Issuer());
00204 }
00205
00206 return m_impl->m_bSelfIssued;
00207 }
00216 bool CPKIFCertificate::IsSelfSigned() const
00217 {
00218 if(!m_impl->m_bSelfSignedSet)
00219 {
00220 CPKIFCertificate* nonConstCert = const_cast<CPKIFCertificate*>(this);
00221 nonConstCert->m_impl->m_bSelfSignedSet = true;
00222 IPKIFCryptoRaw* raw = GetPlatformCryptoRaw();
00223 if(raw)
00224 {
00225 nonConstCert->m_impl->m_bSelfSigned = raw->VerifyCertificate(*this, *this);
00226 }
00227 }
00228
00229 return m_impl->m_bSelfSigned;
00230 }
00241 CPKIFBufferPtr CPKIFCertificate::Encoded() const
00242 {
00243 return m_impl->m_rawCert;
00244 }
00245
00261 void CPKIFCertificate::Decode(
00263 const unsigned char* cert,
00265 int certLen)
00266 {
00267 try
00268 {
00269 m_impl->ClearContent();
00270 CPKIFBufferPtr tmp(new CPKIFBuffer(cert, certLen));
00271 m_impl->m_rawCert = tmp;
00272 m_impl->m_signedCert.Decode(m_impl->m_rawCert->GetBuffer(), m_impl->m_rawCert->GetLength());
00273
00274 }
00275 catch ( ... )
00276 {
00277
00278 m_impl->ClearContent();
00279 unsigned char * decoded = NULL;
00280 unsigned long decodedLen;
00281 bool b = PEMDecode_l((char *)cert, certLen, &decoded, &decodedLen);
00282 if(b)
00283 {
00284 try
00285 {
00286 m_impl->ClearContent();
00287 CPKIFBufferPtr tmp2(new CPKIFBuffer(decoded, decodedLen));
00288 m_impl->m_rawCert = tmp2;
00289 m_impl->m_signedCert.InitContext();
00290 m_impl->m_signedCert.Decode(m_impl->m_rawCert->GetBuffer(), m_impl->m_rawCert->GetLength());
00291
00292 if(NULL != decoded)
00293 delete[] decoded;
00294
00295 }catch(...)
00296 {
00297 if(NULL != decoded)
00298 delete[] decoded;
00299 m_impl->ClearContent();
00300 throw;
00301 }
00302 }
00303 else
00304 {
00305 if(NULL != decoded)
00306 delete[] decoded;
00307 m_impl->ClearContent();
00308 throw;
00309 }
00310 }
00311
00312
00313 Version();
00314 }
00325 int CPKIFCertificate::Version() const
00326 {
00327 if(NULL == m_impl->m_signedCert.data())
00328 throw CPKIFException(TOOLKIT_X509_ASN, COMMON_INVALID_INPUT, "Attempted to read data from a certificate object prior to parsing a certificate.");
00329
00330 if(!m_impl->m_signedCert->tbsCertificate.m.versionPresent)
00331 return 1;
00332
00333 switch( m_impl->m_signedCert->tbsCertificate.version )
00334 {
00335 case CACX509V3AFv1:
00336 return 1;
00337 break;
00338 case CACX509V3AFv2:
00339 return 2;
00340 break;
00341 case CACX509V3AFv3:
00342 return 3;
00343 break;
00344 default:
00345 throw CPKIFException(TOOLKIT_ASN, COMMON_UNSUPPORTED_VERSION, "Unsupported certificate version");
00346 break;
00347 }
00348 }
00361 const char* CPKIFCertificate::SerialNumber() const
00362 {
00363 if(NULL == m_impl->m_signedCert.data())
00364 throw CPKIFException(TOOLKIT_X509_ASN, COMMON_INVALID_INPUT, "Attempted to read data from a certificate object prior to parsing a certificate.");
00365
00366 return m_impl->m_signedCert->tbsCertificate.serialNumber;
00367 }
00378 CPKIFAlgorithmIdentifierPtr CPKIFCertificate::TBSSignatureAlgorithm() const
00379 {
00380 if(NULL == m_impl->m_signedCert.data())
00381 throw CPKIFException(TOOLKIT_X509_ASN, COMMON_INVALID_INPUT, "Attempted to read data from a certificate object prior to parsing a certificate.");
00382
00383 if(m_impl->m_signatureAlg == (CPKIFAlgorithmIdentifier*)NULL)
00384 {
00385
00386 CPKIFOIDPtr algOID(new CPKIFOID(m_impl->m_signedCert->tbsCertificate.signature.algorithm.subid,
00387 m_impl->m_signedCert->tbsCertificate.signature.algorithm.numids));
00388
00389 CPKIFBufferPtr paramBuf;
00390 if(m_impl->m_signedCert->tbsCertificate.signature.m.parametersPresent)
00391 {
00392 paramBuf = CPKIFBufferPtr(new CPKIFBuffer(m_impl->m_signedCert->tbsCertificate.signature.parameters.data,
00393 m_impl->m_signedCert->tbsCertificate.signature.parameters.numocts));
00394
00395
00396 }
00397
00398 CPKIFAlgorithmIdentifierPtr tmpRef(new CPKIFAlgorithmIdentifier(algOID, paramBuf));
00399
00400 CPKIFCertificate* nonConstCert = const_cast<CPKIFCertificate*>(this);
00401 nonConstCert->m_impl->m_signatureAlg = tmpRef;
00402 }
00403
00404 return m_impl->m_signatureAlg;
00405 }
00406 CPKIFAlgorithmIdentifierPtr CPKIFCertificate::SignatureAlgorithm( ) const
00407 {
00408 if(NULL == m_impl->m_signedCert.data())
00409 throw CPKIFException(TOOLKIT_X509_ASN, COMMON_INVALID_INPUT, "Attempted to read data from a certificate object prior to parsing a certificate.");
00410
00411 if(m_impl->m_signatureAlgFromSignedMacro == (CPKIFAlgorithmIdentifier*)NULL)
00412 {
00413
00414 CPKIFOIDPtr algOID(new CPKIFOID(m_impl->m_signedCert->signatureAlgorithm.algorithm.subid,
00415 m_impl->m_signedCert->signatureAlgorithm.algorithm.numids));
00416
00417 CPKIFBufferPtr paramBuf;
00418 if(m_impl->m_signedCert->signatureAlgorithm.m.parametersPresent)
00419 {
00420 paramBuf = CPKIFBufferPtr(new CPKIFBuffer(m_impl->m_signedCert->signatureAlgorithm.parameters.data,
00421 m_impl->m_signedCert->signatureAlgorithm.parameters.numocts));
00422
00423
00424 }
00425
00426 CPKIFAlgorithmIdentifierPtr tmpRef(new CPKIFAlgorithmIdentifier(algOID, paramBuf));
00427
00428 CPKIFCertificate* nonConstCert = const_cast<CPKIFCertificate*>(this);
00429 nonConstCert->m_impl->m_signatureAlgFromSignedMacro = tmpRef;
00430 }
00431
00432 return m_impl->m_signatureAlgFromSignedMacro;
00433 }
00446 CPKIFSubjectPublicKeyInfoPtr CPKIFCertificate::SubjectPublicKeyInfo( ) const
00447 {
00448 if(NULL == m_impl->m_signedCert.data())
00449 throw CPKIFException(TOOLKIT_X509_ASN, COMMON_INVALID_INPUT, "Attempted to read data from a certificate object prior to parsing a certificate.");
00450
00451 if(m_impl->m_subjectPublicKeyInfo == (CPKIFSubjectPublicKeyInfo*)NULL)
00452 {
00453
00454 CPKIFOIDPtr algOID(new CPKIFOID(m_impl->m_signedCert->tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm.subid,
00455 m_impl->m_signedCert->tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm.numids));
00456
00457 CPKIFBufferPtr paramBuf;
00458 if(m_impl->m_signedCert->tbsCertificate.subjectPublicKeyInfo.algorithm.m.parametersPresent)
00459 {
00460 paramBuf = CPKIFBufferPtr(new CPKIFBuffer(m_impl->m_signedCert->tbsCertificate.subjectPublicKeyInfo.algorithm.parameters.data,
00461 m_impl->m_signedCert->tbsCertificate.subjectPublicKeyInfo.algorithm.parameters.numocts));
00462
00463
00464 }
00465
00466 CPKIFAlgorithmIdentifierPtr tmpAlgID(new CPKIFAlgorithmIdentifier(algOID, paramBuf));
00467
00468 CPKIFBufferPtr tempBuffer(new CPKIFBuffer(m_impl->m_signedCert->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.data,
00469 m_impl->m_signedCert->tbsCertificate.subjectPublicKeyInfo.subjectPublicKey.numbits/8));
00470
00471 CPKIFSubjectPublicKeyInfo* tmpSPKI = new CPKIFSubjectPublicKeyInfo(tmpAlgID, tempBuffer);
00472 CPKIFSubjectPublicKeyInfoPtr tmpRef(tmpSPKI);
00473
00474 CPKIFCertificate* nonConstCert = const_cast<CPKIFCertificate*>(this);
00475 nonConstCert->m_impl->m_subjectPublicKeyInfo = tmpRef;
00476 }
00477
00478 return m_impl->m_subjectPublicKeyInfo;
00479 }
00489 CPKIFNamePtr CPKIFCertificate::Issuer( ) const
00490 {
00491 if(NULL == m_impl->m_signedCert.data())
00492 throw CPKIFException(TOOLKIT_X509_ASN, COMMON_INVALID_INPUT, "Attempted to read data from a certificate object prior to parsing a certificate.");
00493
00494 if(m_impl->m_issuer == (CPKIFName*)NULL)
00495 {
00496 CACASNWRAPPER_CREATE(CACX509V3Name, objPDU2);
00497 ASN1OpenType* data1 = objPDU2.Encode(&(m_impl->m_signedCert->tbsCertificate.issuer));
00498 CPKIFBufferPtr tmpBuf;
00499 if (data1 != NULL)
00500 {
00501 tmpBuf = CPKIFBufferPtr(new CPKIFBuffer(data1->data, data1->numocts));
00502 delete data1;
00503 }
00504
00505 CPKIFName* tmpName = new CPKIFName(tmpBuf);
00506 CPKIFNamePtr tmpRef(tmpName);
00507
00508 CPKIFCertificate* nonConstCert = const_cast<CPKIFCertificate*>(this);
00509 nonConstCert->m_impl->m_issuer = tmpRef;
00510 }
00511
00512 return m_impl->m_issuer;
00513 }
00523 CPKIFNamePtr CPKIFCertificate::Subject( ) const
00524 {
00525 if(NULL == m_impl->m_signedCert.data())
00526 throw CPKIFException(TOOLKIT_X509_ASN, COMMON_INVALID_INPUT, "Attempted to read data from a certificate object prior to parsing a certificate.");
00527
00528 if(m_impl->m_subject == (CPKIFName*)NULL)
00529 {
00530 CACASNWRAPPER_CREATE(CACX509V3Name, objPDU2);
00531 ASN1OpenType* data1 = objPDU2.Encode(&(m_impl->m_signedCert->tbsCertificate.subject));
00532 CPKIFBufferPtr tmpBuf;
00533 if (data1 != NULL)
00534 {
00535 tmpBuf = CPKIFBufferPtr(new CPKIFBuffer(data1->data, data1->numocts));
00536 delete data1;
00537 }
00538
00539 CPKIFName* tmpName = new CPKIFName(tmpBuf);
00540 CPKIFNamePtr tmpRef(tmpName);
00541
00542 CPKIFCertificate* nonConstCert = const_cast<CPKIFCertificate*>(this);
00543 nonConstCert->m_impl->m_subject = tmpRef;
00544 }
00545
00546 return m_impl->m_subject;
00547 }
00557 CPKIFValidityPtr CPKIFCertificate::Validity( ) const
00558 {
00559 if(NULL == m_impl->m_signedCert.data())
00560 throw CPKIFException(TOOLKIT_X509_ASN, COMMON_INVALID_INPUT, "Attempted to read data from a certificate object prior to parsing a certificate.");
00561
00562 if(m_impl->m_validity == (CPKIFValidity*)NULL)
00563 {
00564 CPKIFTimePtr notBefore;
00565 if(m_impl->m_signedCert->tbsCertificate.validity.notBefore.t == T_CACX509V3Time_utcTime)
00566 {
00567 notBefore = CPKIFTimePtr(new CPKIFTime(m_impl->m_signedCert->tbsCertificate.validity.notBefore.u.utcTime,
00568 UTCTIME));
00569 }
00570 else
00571 {
00572 notBefore = CPKIFTimePtr(new CPKIFTime(m_impl->m_signedCert->tbsCertificate.validity.notBefore.u.generalTime,
00573 GENERALIZEDTIME));
00574 }
00575
00576 CPKIFTimePtr notAfter;
00577 if(m_impl->m_signedCert->tbsCertificate.validity.notAfter.t == T_CACX509V3Time_utcTime)
00578 {
00579 notAfter = CPKIFTimePtr(new CPKIFTime(m_impl->m_signedCert->tbsCertificate.validity.notAfter.u.utcTime,
00580 UTCTIME));
00581 }
00582 else
00583 {
00584 notAfter = CPKIFTimePtr(new CPKIFTime(m_impl->m_signedCert->tbsCertificate.validity.notAfter.u.generalTime,
00585 GENERALIZEDTIME));
00586 }
00587
00588
00589 CPKIFValidity* tmpName = new CPKIFValidity(notBefore, notAfter);
00590 CPKIFValidityPtr tmpRef(tmpName);
00591
00592 CPKIFCertificate* nonConstCert = const_cast<CPKIFCertificate*>(this);
00593 nonConstCert->m_impl->m_validity = tmpRef;
00594 }
00595
00596 return m_impl->m_validity;
00597 }
00598
00599
00600
00611 void CPKIFCertificate::GetExtensionByOID(
00613 const CPKIFOID& oid,
00615 CPKIFX509ExtensionPtr& ref)
00616 {
00617 if(m_impl->m_exts.empty() && (NULL != m_impl->m_signedCert.data() && m_impl->m_signedCert->tbsCertificate.m.extensionsPresent && 0 != m_impl->m_signedCert->tbsCertificate.extensions.count))
00618 m_impl->populateExtensionsVector();
00619
00620 vector<CPKIFX509ExtensionPtr>::iterator pos;
00621 vector<CPKIFX509ExtensionPtr>::iterator end = m_impl->m_exts.end();
00622 for(pos = m_impl->m_exts.begin(); pos != end; ++pos)
00623 {
00624 if(oid == (*pos)->oid())
00625 {
00626 ref = *pos;
00627 return;
00628 }
00629 }
00630 }
00641 bool CPKIFCertificate::AreThereAnyUnprocessedCriticalExtensions(
00643 std::vector<CPKIFX509ExtensionPtr>& processedExts)
00644 {
00645
00646
00647
00648
00649
00650
00651 std::vector<CPKIFX509ExtensionPtr>::iterator pos;
00652 std::vector<CPKIFX509ExtensionPtr>::iterator end = m_impl->m_exts.end();
00653 std::vector<CPKIFX509ExtensionPtr>::iterator processedEnd = processedExts.end();
00654 ExtensionsMatch em;
00655 size_t count = processedExts.size();
00656 for(pos = m_impl->m_exts.begin(); pos != end; ++pos)
00657 {
00658 em.SetRHS(*pos);
00659 if((*pos)->isCritical() && processedEnd == find_if(processedExts.begin(), processedExts.end(), em))
00660 return true;
00661 }
00662
00663 return false;
00664 }
00672 bool CPKIFCertificate::operator==(
00674 const CPKIFCertificate& rhs) const
00675 {
00676 if(*m_impl->m_rawCert == *rhs.Encoded())
00677 return true;
00678 else
00679 {
00680 const char* lhsSN = SerialNumber();
00681 const char* rhsSN = rhs.SerialNumber();
00682
00683 if(strlen(lhsSN) != strlen(rhsSN) || 0 != stricmp(lhsSN, rhsSN))
00684 return false;
00685 else
00686 return *Issuer() == *rhs.Issuer();
00687 }
00688 }
00696 CPKIFBufferPtr CPKIFCertificate::Signature() const
00697 {
00698 CPKIFBufferPtr tmp(new CPKIFBuffer(m_impl->m_signedCert->signature.data, m_impl->m_signedCert->signature.numbits/8));
00699 return tmp;
00700 }
00701
00709 void CPKIFCertificate::GetEncodedExtensions (
00711 CPKIFBufferPtr& buf)
00712 {
00713 try
00714 {
00715 if (m_impl->m_signedCert->tbsCertificate.m.extensionsPresent)
00716 {
00717 CACASNWRAPPER_CREATE(CACX509V3Extensions, extsWrapper);
00718 ASN1OpenType *data = extsWrapper.Encode (&m_impl->m_signedCert->tbsCertificate.extensions);
00719 CPKIFBufferPtr tmp(new CPKIFBuffer(data->data, data->numocts));
00720 buf = tmp;
00721 delete data;
00722 return;
00723 }
00724 }
00725 catch (... )
00726 {
00727
00728 }
00729
00730 CPKIFBufferPtr nullExt;
00731 buf = nullExt;
00732 }
00740 CPKIFNamePtr CPKIFCertificate::GetSubjectName() const
00741 {
00742 return Subject();
00743 }
00751 CPKIFBufferPtr CPKIFCertificate::GetKey() const
00752 {
00753 CPKIFSubjectPublicKeyInfoPtr spki = SubjectPublicKeyInfo();
00754 if(spki != (CPKIFSubjectPublicKeyInfo*)NULL)
00755 return spki->rawKey();
00756 else
00757 {
00758 CPKIFBufferPtr bp;
00759 return bp;
00760 }
00761 }
00769 CPKIFNamePtr CPKIFCertificate::GetIssuerName() const
00770 {
00771 return Issuer();
00772 }
00780 CPKIFSubjectPublicKeyInfoPtr CPKIFCertificate::GetSubjectPublicKeyInfo() const
00781 {
00782 return SubjectPublicKeyInfo();
00783 }
00784
00785 bool CAC_API IsCaCertificate(CPKIFCertificatePtr& cert)
00786 {
00787 if(cert)
00788 {
00789 try
00790 {
00791 CPKIFBasicConstraintsPtr bc = cert->GetExtension<CPKIFBasicConstraints>();
00792 if(bc && bc->isCA())
00793 return true;
00794 }
00795 catch(...)
00796 {
00797 }
00798 }
00799
00800 return false;
00801 }