Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

CryptObjects.h

Go to the documentation of this file.
00001 /*  CryptObjects.h - cryto API object wrappers
00002     Copyright (C) 2001-2004 Mark Weaver
00003     Written by Mark Weaver <mark@npsl.co.uk>
00004 
00005     Part of the Open-Win32 library.
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License as published by the Free Software Foundation; either
00009     version 2 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Library General Public License for more details.
00015 
00016     You should have received a copy of the GNU Library General Public
00017     License along with this library; if not, write to the
00018     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00019     Boston, MA  02111-1307, USA.
00020 */
00021 
00026 #ifndef OW32_CryptObjects_h
00027 #define OW32_CryptObjects_h
00028 
00029 #include <OW32/OW32Libs.h>
00030 
00031 namespace OW32 {
00032 
00033 #ifndef MY_ENCODING_TYPE
00034 #define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
00035 #endif
00036 
00038 class OW32_LIB_EXPORT CCertUtils
00039 {
00040 public:
00042     static BOOL SignAndEncodeCertificate(
00043         CRYPT_DATA_BLOB* pBlob,
00044         HCRYPTPROV hSigningProv,
00045         DWORD dwKeySpec,
00046         CRYPT_ALGORITHM_IDENTIFIER* pSigAlg,
00047         PVOID pObject,
00048         LPCSTR szStructType,
00049         DWORD dwEncodingType = MY_ENCODING_TYPE)
00050     {
00051         pBlob->cbData = 0;
00052         if (!CryptSignAndEncodeCertificate(hSigningProv, dwKeySpec, dwEncodingType,
00053             szStructType, pObject, pSigAlg, NULL, NULL, &pBlob->cbData))
00054             return FALSE;
00055         pBlob->pbData = (PBYTE)LocalAlloc(0, pBlob->cbData);
00056         if (!pBlob->pbData) return FALSE;
00057         if (!CryptSignAndEncodeCertificate(hSigningProv, dwKeySpec, dwEncodingType,
00058             szStructType, pObject, pSigAlg, NULL, pBlob->pbData, &pBlob->cbData))
00059             return FALSE;
00060         return TRUE;
00061     };
00062 
00063     /* \brief Encode an object to a CRYPT_DATA_BLOB.
00064               If we are allowed use the SP4+ version -- see the note for DecodeObject.
00065      */
00066     static BOOL EncodeObject(CRYPT_DATA_BLOB* pBlob, 
00067                       LPVOID lpvObject,
00068                       LPCSTR szStructType,
00069                       DWORD dwEncodingType = MY_ENCODING_TYPE)
00070     {
00071         pBlob->cbData = 0;
00072     #ifdef SUPPORT_SP3
00073         if (!CryptEncodeObject(dwEncodingType, szStructType, lpvObject,
00074             NULL, &pBlob->cbData)) {
00075             return FALSE;
00076         }
00077         pBlob->pbData = (PBYTE)LocalAlloc(LPTR, pBlob->cbData);
00078         if (!pBlob->pbData) return FALSE;
00079         if (!CryptEncodeObject(dwEncodingType, szStructType, lpvObject,
00080             pBlob->pbData, &pBlob->cbData)) {
00081             return FALSE;
00082         }
00083         return TRUE;
00084     #else
00085         return CryptEncodeObjectEx(dwEncodingType, szStructType,
00086             lpvObject, CRYPT_ENCODE_ALLOC_FLAG, NULL, (PVOID)&pBlob->pbData,
00087             &pBlob->cbData);
00088     #endif
00089     }
00090 };
00091     
00099 template <class T, LPCSTR defszStructType>
00100 class CCryptObject
00101 {
00102 protected:
00103     DWORD m_objectSize;
00104     T* m_object;
00105 
00106 public:
00110     BOOL DecodeObject(const BYTE* pbEncoded, DWORD cbEncoded, 
00111                       DWORD dwEncodingType = MY_ENCODING_TYPE,
00112                       LPCSTR szStructType = defszStructType)
00113     {
00114         FreeObject();
00115 
00116     // If we are allowed use the SP4+ version for decoding as it is more
00117     // efficient, otherwise use the older method of find length/allocate/decode
00118 #ifdef SUPPORT_SP3
00119         m_objectSize = 0;
00120         if (!CryptDecodeObject(dwEncodingType, X509_CERT_REQUEST_TO_BE_SIGNED, pbEncoded,
00121             cbEncoded, 0, NULL, &m_objectSize)) {
00122             return FALSE;
00123         }
00124         m_object = (T*)LocalAlloc(cbRequestInfo);
00125         if (!pRequestInfo) return FALSE;
00126         if (!CryptDecodeObject(dwEncodingType, X509_CERT_REQUEST_TO_BE_SIGNED, pbEncoded,
00127             cbEncoded, 0, (PVOID)&m_object, &m_objectSize)) {
00128             return FALSE;
00129         }
00130         return TRUE;
00131 #else
00132         return CryptDecodeObjectEx(dwEncodingType, (LPCSTR)szStructType, pbEncoded, cbEncoded,
00133                     CRYPT_DECODE_ALLOC_FLAG, NULL, (PVOID)&m_object, &m_objectSize);
00134 #endif
00135     }
00136 
00137     /* \brief Encode this object to a CRYPT_DATA_BLOB.
00138         If we are allowed use the SP4+ version -- see the note for #DecodeObject.
00139      */
00140     BOOL EncodeObject(CRYPT_DATA_BLOB* pBlob, DWORD dwEncodingType = MY_ENCODING_TYPE,
00141                       LPCSTR szStructType = defszStructType)
00142     {
00143         return CCertUtils::EncodeObject(pBlob, m_object, szStructType, dwEncodingType);
00144     }
00145 
00147     void FreeObject()
00148     {
00149         if (m_object) LocalFree(m_object);
00150         m_objectSize = 0;
00151         m_object = 0;
00152     }
00153 
00155     DWORD GetObjectSize() { return m_objectSize; }
00156 
00158     operator T*() { return m_object; }
00159 
00161     T* operator->() { return m_object; }
00162 
00164     CCryptObject()
00165     {
00166         m_objectSize = 0;
00167         m_object = 0;
00168     }
00169 
00171     ~CCryptObject()
00172     {
00173         FreeObject();
00174     }
00175 };
00176 
00182 class OW32_LIB_EXPORT CCryptDataBlob : 
00183     public CRYPT_DATA_BLOB
00184 {
00185 public:
00187     CCryptDataBlob() {
00188         cbData = 0;
00189         pbData = 0;
00190     }
00192     ~CCryptDataBlob() {
00193         Free();
00194     }
00195 
00197     void Free() {
00198         if (pbData) LocalFree(pbData);
00199         pbData = 0;
00200         cbData = 0;
00201     }
00202 };
00203 
00204 // Typedef a bunch of these things to common types to make them usuable
00205 // (TODO: complete this list)
00206 typedef CCryptObject<CERT_REQUEST_INFO,X509_CERT_REQUEST_TO_BE_SIGNED>
00207     CCertRequestInfo;
00208 
00209 typedef CCryptObject<CERT_NAME_INFO, X509_NAME> CCertNameInfo;
00210 
00211 
00212 typedef CCryptObject<CERT_BASIC_CONSTRAINTS_INFO, X509_BASIC_CONSTRAINTS>
00213     CCertBasicConstraintsInfo;
00214 
00215 //typedef CCryptObject<CERT_INFO, X509_CERT>
00216 //  CCertInfo;
00217 
00221 class OW32_LIB_EXPORT CCertContext 
00222 {
00223 protected:
00224     PCCERT_CONTEXT m_pCertContext;
00225 
00226     CCertContext(const CCertContext& );
00227     const CCertContext& operator=(const CCertContext& );
00228 
00229 public:
00231     CCertContext() {
00232         m_pCertContext = 0;
00233     }
00234 
00238     CCertContext(PCCERT_CONTEXT pCertContext) {
00239         m_pCertContext = pCertContext;
00240     }
00241 
00243     void Free() {
00244         if (m_pCertContext) {
00245             CertFreeCertificateContext(m_pCertContext);
00246             m_pCertContext = 0;
00247         }
00248     }
00249 
00251     void Attach(PCCERT_CONTEXT pCertContext) {
00252         Free();
00253         m_pCertContext = pCertContext;
00254     }
00255 
00257     PCCERT_CONTEXT Detach() {
00258         PCCERT_CONTEXT pCertContext = m_pCertContext;
00259         m_pCertContext = 0;
00260         return pCertContext;
00261     }
00262 
00264     PCCERT_CONTEXT* operator& () { return &m_pCertContext; }
00265 
00267     operator PCCERT_CONTEXT() const { return m_pCertContext; }
00268 
00270     PCCERT_CONTEXT operator->() { return m_pCertContext; }
00271 
00273     CCertContext Duplicate() {
00274         CCertContext newContext(
00275             CertDuplicateCertificateContext(m_pCertContext));
00276         return newContext;
00277     }
00278 
00280     BOOL AcquirePrivateKey(DWORD dwFlags, HCRYPTPROV* phCryptProv,
00281         DWORD* pdwKeySpec, BOOL* pfCallerFreeProv) {
00282         return CryptAcquireCertificatePrivateKey(m_pCertContext, dwFlags,
00283             NULL, phCryptProv, pdwKeySpec, pfCallerFreeProv);
00284     }
00285 
00287     BOOL GetContextProperty(DWORD dwPropId, PVOID* pvData, DWORD* pcbData = NULL)
00288     {
00289         DWORD cbData;
00290         if (!CertGetCertificateContextProperty(m_pCertContext, dwPropId, NULL, &cbData))
00291             return FALSE;
00292         *pvData = LocalAlloc(0,cbData);
00293         if (!*pvData) return FALSE;
00294         BOOL ret = CertGetCertificateContextProperty(m_pCertContext, dwPropId, *pvData, &cbData);
00295         if (!ret) {
00296             LocalFree(*pvData);
00297             return FALSE;
00298         }
00299         if (pcbData) *pcbData = cbData;
00300         return TRUE;
00301     }
00302 
00304     BOOL GetContextProperty(DWORD dwPropId, PVOID pvData, DWORD* pcbData)
00305     {
00306         return CertGetCertificateContextProperty(m_pCertContext, dwPropId, pvData, pcbData);
00307     }
00308 
00310     BOOL SetContextProperty(DWORD dwPropId, PVOID pvData, DWORD dwFlags=0)
00311     {
00312         return CertSetCertificateContextProperty(m_pCertContext, dwPropId, dwFlags, pvData);
00313     }
00314 
00316     BOOL CreateContext(const BYTE* pbCertEncoded, DWORD cbCertEncoded,
00317         DWORD dwCertEncodingType = MY_ENCODING_TYPE)
00318     {
00319         Free();
00320         m_pCertContext = CertCreateCertificateContext(dwCertEncodingType,
00321             pbCertEncoded, cbCertEncoded);
00322         return (m_pCertContext != NULL);
00323     }
00324 
00326     ~CCertContext()
00327     {
00328         Free();
00329     }
00330 };
00331 
00332 
00336 class OW32_LIB_EXPORT CCertInfo : 
00337     public CCryptObject<CERT_INFO, X509_CERT_TO_BE_SIGNED>
00338 {
00339 public:
00340     /* Constructor for an empty object */
00341     CCertInfo() {
00342     }
00343 
00345     BOOL New()
00346     {
00347         m_object = (CERT_INFO*)LocalAlloc(0,sizeof(CERT_INFO));
00348         if (!m_object) return FALSE;
00349         m_objectSize = sizeof(CERT_INFO);
00350         return TRUE;
00351     }
00352 
00354     BOOL SignAndEncode(
00355         CRYPT_DATA_BLOB* pBlob,
00356         HCRYPTPROV hSigningProv,
00357         DWORD dwKeySpec,
00358         CRYPT_ALGORITHM_IDENTIFIER* pSigAlg,
00359         LPCSTR szStructType = X509_CERT_TO_BE_SIGNED,
00360         DWORD dwEncodingType = MY_ENCODING_TYPE)
00361     {
00362         return CCertUtils::SignAndEncodeCertificate(pBlob, hSigningProv, 
00363             dwKeySpec, pSigAlg, m_object, szStructType, dwEncodingType);
00364     }
00365 };
00366 
00370 class OW32_LIB_EXPORT CCertPublicKeyInfo
00371 {
00372     CERT_PUBLIC_KEY_INFO* m_keyInfo;
00373     DWORD m_keyInfoSize;
00374 
00375 public:
00377     CCertPublicKeyInfo()
00378     {
00379         m_keyInfo = 0;
00380         m_keyInfoSize = 0;
00381     }
00382 
00383     /* \brief Tidy storage for the encapsulated public key info object */
00384     ~CCertPublicKeyInfo()
00385     {
00386         Free();
00387     }
00388 
00390     void Free()
00391     {
00392         if (m_keyInfo) LocalFree(m_keyInfo);
00393         m_keyInfo = 0;
00394         m_keyInfoSize = 0;
00395     }
00396 
00397 
00400     BOOL ExportPublicKeyInfo(HCRYPTPROV hCryptProv,
00401                  DWORD dwKeySpec, DWORD dwEncodingType)
00402     {
00403         Free();
00404         
00405         if (!CryptExportPublicKeyInfo(hCryptProv, dwKeySpec, dwEncodingType,
00406             NULL, &m_keyInfoSize))
00407             return FALSE;
00408         
00409         m_keyInfo = (CERT_PUBLIC_KEY_INFO*)LocalAlloc(0,m_keyInfoSize);
00410         if (!m_keyInfo) return FALSE;
00411 
00412         if (!CryptExportPublicKeyInfo(hCryptProv, dwKeySpec, dwEncodingType,
00413             m_keyInfo, &m_keyInfoSize))
00414             return FALSE;
00415 
00416         return TRUE;
00417     }
00418 
00420     DWORD GetKeyInfoSize() const { return m_keyInfoSize; }
00421 
00423     CERT_PUBLIC_KEY_INFO** operator& () { return &m_keyInfo; }
00424 
00425     /* \brief Extractor for the controlled object */
00426     operator CERT_PUBLIC_KEY_INFO* () const { return m_keyInfo; }
00427     
00429     CERT_PUBLIC_KEY_INFO* operator->() { return m_keyInfo; }
00430 };
00431 
00432 } // namespace OW32
00433 
00434 #endif // OW32_CryptObjects_h

Generated on Sun Jun 5 01:29:17 2005 for OW32 by  doxygen 1.3.9.1