CPCA20Request.h

00001 /* [Windows 1251]
00002  * [Use `iconv -f WINDOWS-1251', if needed]
00003  */
00004 /*
00005  * Copyright(C) 2013
00006  *
00007  * Этот файл содержит информацию, являющуюся
00008  * собственностью компании Крипто-Про.
00009  *
00010  * Любая часть этого файла не может быть скопирована,
00011  * исправлена, переведена на другие языки,
00012  * локализована или модифицирована любым способом,
00013  * откомпилирована, передана по сети с или на
00014  * любую компьютерную систему без предварительного
00015  * заключения соглашения с компанией Крипто-Про.
00016  *
00017  * This is proprietary information of
00018  * Crypto-Pro company.
00019  *
00020  * Any part of this file can not be copied,
00021  * corrected, translated into other languages,
00022  * localized or modified by any means,
00023  * compiled, transferred over a network from or to
00024  * any computer system without preliminary
00025  * agreement with Crypto-Pro company
00026  */
00027 
00037 #ifndef __CPCA20_REQUEST_H__
00038 #define __CPCA20_REQUEST_H__
00039 #include "UnixRequestImpl.h"
00040 #define UR20_DISP_NEW 3
00041 #define UR20_DISP_ACCEPTED 4
00042 #define UR20_DISP_REJECTED 5
00043 #define UR20_DISP_UNDER_SUBMISSION 6
00044 #define UR20_DISP_COMPLETED 7
00045 #define UR20_DISP_APPROVED 8
00046 
00047 #ifdef DEBUG
00048 #include <iostream>
00049 #endif
00050 
00051 #ifdef UNIX
00052 #define CPCA20_ENCODING CP_UTF8
00053 #else
00054 #define CPCA20_ENCODING CP_ACP
00055 #endif // UNIX
00056 
00066 class CPCA20Request: public UnixRequestImpl
00067 {
00068     public:
00069         CPCA20Request();
00070 
00071         virtual HRESULT SetCredential(
00072             /* [in] */ UserCallbacks *_pCallbacks,
00073             /* [in] */ X509EnrollmentAuthFlags _AuthType,
00074             /* [in] */ X509EnrollmentCheckChainFlags _CheckChainType,
00075             /* [in] */ const BSTR strCredential,
00076             /* [in][out] */ CSecurePin *_sbPassword,
00077             /* [in] */ BOOL UseLocalMachineCert )
00078         {
00079             HRESULT res = UnixRequestImpl::SetCredential( _pCallbacks,
00080                           _AuthType, _CheckChainType, strCredential, _sbPassword, UseLocalMachineCert );
00081             if ( res != S_OK )
00082             { return res; }
00083 
00084             if (strCredential) {
00085                 const char *strToken = ConvertBSTRToString( strCredential );
00086                 token = strToken;
00087                 delete[] strToken;
00088             } else {
00089                 token = "";
00090             }
00091             password = _sbPassword ? _sbPassword->ptr() : "";
00092 
00093             dwCertKeySpec = 0;
00094             if ( fNeedFreeProv )
00095             {
00096                 CryptReleaseContext( hUserProv, 0 );
00097                 hUserProv = 0;
00098                 fNeedFreeProv = FALSE;
00099             }
00100             if ( pUserCert )
00101             {
00102                 CertFreeCertificateContext( pUserCert );
00103                 pUserCert = 0;
00104             }
00105             if ( hUserStore )
00106             {
00107                 CertCloseStore( hUserStore, 0 );
00108                 hUserStore = 0;
00109             }
00110 
00111             if ( _AuthType != X509AuthCertificate )
00112             {
00113                 return S_OK;
00114             }
00115 
00116             hUserStore = CertOpenSystemStore(0, _TEXT("My"));
00117 
00118             if ( hUserStore == 0 )
00119             {
00120                 res = GetLastError();
00121                 goto err;
00122             }
00123 
00124             pUserCert = GetCertContext( hUserStore );
00125 
00126             if ( pUserCert == 0 )
00127             {
00128                 CertCloseStore( hUserStore, 0 );
00129                 hUserStore = CertOpenStore(
00130                                  CERT_STORE_PROV_SYSTEM,
00131                                  0,
00132                                  0,//hProv,
00133                                  CERT_STORE_OPEN_EXISTING_FLAG | CERT_SYSTEM_STORE_LOCAL_MACHINE,
00134                                  L"My" );
00135                 if ( hUserStore == 0 )
00136                 {
00137                     res = NTE_FAIL;
00138                     goto err;
00139                 }
00140                 pUserCert = GetCertContext( hUserStore );
00141                 if ( pUserCert == 0 )
00142                 {
00143                     res = NTE_FAIL;
00144                     goto err;
00145                 }
00146             }
00147 
00148             if ( !CryptAcquireCertificatePrivateKey(
00149                         pUserCert,
00150                         0, 0, &hUserProv, &dwCertKeySpec, &fNeedFreeProv ) )
00151             {
00152                 res = GetLastError();
00153                 goto err;
00154             }
00155             if ( _sbPassword && !CryptSetProvParam( hUserProv, PP_KEYEXCHANGE_PIN,
00156                                                     ( const BYTE * )_sbPassword->ptr(), 0 ) )
00157             {
00158                 res = GetLastError();
00159                 goto err;
00160             }
00161             return S_OK;
00162 err:
00163             if ( fNeedFreeProv && hUserProv )
00164             {
00165                 CryptReleaseContext( hUserProv, 0 );
00166                 hUserProv = 0;
00167             }
00168             fNeedFreeProv = FALSE;
00169             if ( pUserCert )
00170             {
00171                 CertFreeCertificateContext( pUserCert );
00172                 pUserCert = 0;
00173             }
00174             if ( hUserStore )
00175             {
00176                 CertCloseStore( hUserStore, 0 );
00177                 hUserStore = 0;
00178             }
00179             return res;
00180         };
00181 
00182         virtual HRESULT SetCredential(
00183             /* [in] */ LONG hWnd,
00184             /* [in] */ X509EnrollmentAuthFlags anAuthType,
00185             /* [in] */ BSTR strCredential,
00186             /* [in] */ BSTR strPassword )
00187         {
00188             return UnixRequestImpl::SetCredential( hWnd, anAuthType, strCredential, strPassword );
00189         };
00190 
00191         static BOOL HexToBin( const char * src, DWORD sLen, BYTE * dst, DWORD *pdLen )
00192         {
00193             int i, j, k;
00194             for ( i = sLen, j = *pdLen; i > 0 && j > 0; i -= 2, j-- )
00195             {
00196                 BYTE b = 0;
00197                 for ( k = 0; k < 2; k++ )
00198                 {
00199                     BYTE c = ( BYTE )tolower( *src++ );
00200                     b <<= 4;
00201                     if ( c >= 'a' && c <= 'f' )
00202                     { b |= c - 'a' + 10; }
00203                     else if ( isdigit( c ) )
00204                     { b |= c - '0'; }
00205                     else
00206                     { return FALSE; }
00207                 }
00208                 *dst++ = b;
00209             }
00210             *pdLen -= j;
00211             return TRUE;
00212         }
00213 
00214         PCCERT_CONTEXT GetCertContext( HCERTSTORE hStore )
00215         {
00216 
00217             CRYPT_HASH_BLOB bHash;
00218 
00219             BYTE bSHA1Digest[20];
00220 
00221             bHash.cbData = 20;
00222             bHash.pbData = bSHA1Digest;
00223 
00224             if ( !HexToBin( Credential.c_str(), 40, bHash.pbData, &bHash.cbData ) )
00225             { return NULL; }
00226             return CertFindCertificateInStore( hStore,
00227                                                X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
00228                                                0,
00229                                                CERT_FIND_HASH,
00230                                                &bHash,
00231                                                0 );
00232         }
00233 
00234         virtual HRESULT GetRequestParams( BSTR strConfig, BSTR strTemplate, BSTR *pstrRDN, BSTR *pstrEKUsage, DWORD *pKeySpec, std::vector<AttrTriple> *pAttrs );
00235 
00236         virtual HRESULT ListRequests( BSTR strConfig, RequestMap &Requests );
00237 
00238         virtual HRESULT ListRequestsEx( BSTR strConfig, RequestMapEx & Requests, ReqType type = CA15Request );
00239 
00240         virtual HRESULT GetRequest( LONG Flags, BSTR *pstrRequest );
00241 
00242         virtual HRESULT Submit( LONG Flags, const BSTR strRequest, const BSTR strAttributes, const BSTR strConfig, LONG *pDisposition );
00243 
00244         virtual HRESULT RetrievePending( LONG RequestId, const BSTR strConfig, LONG *pDisposition );
00245 
00246         virtual HRESULT AcknowledgeInstallCert( LONG RequestId, const BSTR strConfig );
00247 
00248         virtual HRESULT GetLastStatus( LONG *pStatus );
00249 
00250         virtual HRESULT GetRequestId( LONG *pRequestId );
00251 
00252         virtual HRESULT GetRequestStrId ( uintptr_t *pRequestId );
00253 
00254         virtual HRESULT GetCACertificate( LONG fExchangeCertificate, const BSTR strConfig, LONG Flags, BSTR *pstrCertificate );
00255 
00256         virtual HRESULT GetCertificate( LONG Flags, BSTR *pstrCertificate );
00257 
00258         virtual HRESULT GetIssuedCertificate( const BSTR strConfig, LONG RequestId, const BSTR strSerialNumber, LONG *pDisposition );
00259 
00260         virtual HRESULT GetErrorMessageText( LONG hrMessage, LONG Flags, BSTR *pstrErrorMessageText );
00261 
00262         virtual HRESULT RegisterUser( BSTR bstrConfig, void * pUserInfo );
00263 
00264         virtual HRESULT GetUserRegisterInfo( BSTR bstrConfig, void * pUserInfo );
00265 
00266         virtual HRESULT GetUserRegisterStatus( BSTR bstrConfig, LONG * pUserRegisterId, LONG * pUserRegisterStatus );
00267 
00268         virtual HRESULT GetCAProperty( const BSTR strConfig, LONG PropId, LONG PropIndex, LONG PropType, LONG Flags, VARIANT *pvarPropertyValue );
00269 
00270         virtual HRESULT GetCAPropertyFlags( const BSTR strConfig, LONG PropId, LONG *pPropFlags );
00271 
00272         virtual HRESULT GetCAPropertyDisplayName( const BSTR strConfig, LONG PropId, BSTR *pstrDisplayName );
00273 
00274         virtual HRESULT GetFullResponseProperty( LONG PropId, LONG PropIndex, LONG PropType, LONG Flags, VARIANT *pvarPropertyValue );
00275 
00276         virtual HRESULT GetRequestIdString( BSTR *pstrRequestId );
00277 
00278         virtual HRESULT GetIssuedCertificate2( BSTR strConfig, BSTR strRequestId, BSTR strSerialNumber, LONG *pDisposition );
00279 
00280         virtual HRESULT GetRefreshPolicy( VARIANT_BOOL *pValue );
00281 
00282         virtual HRESULT CA20GetEnrollParams( const std::string & UIURL,
00283                                              std::vector<std::string> &templates,
00284                                              std::vector<std::string> &EKUs,
00285                                              std::vector<std::string> &keySpecs,
00286                                              std::string & strDN );
00287 
00288         static const std::string optionsControllerURL;
00289         static const std::string registrationRequestControllerURL;
00290         static const std::string certificateRequestControllerURL;
00291         static const std::string certificateGetControllerURL;
00292         static const std::string certificateTemplateControllerURL;
00293         static const std::string CACertificateControllerURL;
00294 
00295     private:
00296         std::string token;
00297         std::string password;
00298         std::string certRequestID;
00299         std::string pkcs7;
00300 
00301         BSTR bstrRequestHTML;
00302         BSTR bstrCertHTML;
00303         std::string strCertificate;
00304         std::string strSerial;
00305         HCERTSTORE hUserStore;
00306         PCCERT_CONTEXT pUserCert;
00307         BOOL fNeedFreeProv;
00308         DWORD dwCertKeySpec;
00309         HCRYPTPROV hUserProv;
00310         unsigned int CPCA20_URL_RETRIEVER_TIMEOUT;
00311 
00312         std::string removeBackSlashFromUrl( std::string const& UIURL )
00313         {
00314             std::string ret = UIURL + "/";
00315             ret.erase( ret.find_last_not_of( '/' ) + 1 );
00316             return ret;
00317         }
00318 
00319         std::string makeURLwithFolder( std::string const& UIURLwithFolder, std::string const& ContollerURL )
00320         {
00321             std::string urlGet = removeBackSlashFromUrl( UIURLwithFolder );
00322             size_t pos = urlGet.find_last_of( '/' );
00323             std::string tmp = UIURLwithFolder.substr( 0, pos  );
00324             tmp += "/api/"            ;
00325             tmp += urlGet.substr( pos + 1 );
00326             tmp += "/";
00327             tmp += ContollerURL;
00328             return tmp;
00329         }
00330 
00331         std::string makeURL( std::string const& UIURL, std::string const& ContollerURL )
00332         {
00333             std::string urlGet = removeBackSlashFromUrl( UIURL );
00334             std::string tmp = urlGet;
00335             tmp += "/api/";
00336             tmp += ContollerURL;
00337             return tmp;
00338         }
00339 
00340         std::string makeSecureURL( std::string const& UIURL, std::string const& ContollerURL )
00341         {
00342             std::string urlGet = removeBackSlashFromUrl( UIURL );
00343             std::string tmp = urlGet;
00344             tmp += "/2/api/";
00345             tmp += ContollerURL;
00346             return tmp;
00347         }
00348 
00349         std::string makeCertRequestURL( std::string const& UIURLwithID, std::string const& ContollerURL )
00350         {
00351             std::string urlGet = UIURLwithID;
00352             size_t pos = UIURLwithID.find_last_of( '/' );
00353             urlGet = UIURLwithID.substr( 0, pos );
00354             urlGet += "/api/"            ;
00355             urlGet += ContollerURL;
00356             urlGet += "/";
00357             urlGet += UIURLwithID.substr( pos + 1 );
00358             return urlGet;
00359         }
00360 
00361         std::string makeSecureCertRequestURL( std::string const& UIURLwithID, std::string const& ContollerURL )
00362         {
00363             std::string urlGet = UIURLwithID;
00364             size_t pos = UIURLwithID.find_last_of( '/' );
00365             urlGet = UIURLwithID.substr( 0, pos );
00366             pos = UIURLwithID.find_last_of( '/' );
00367             urlGet = UIURLwithID.substr( 0, pos );
00368             urlGet += "/2/api/"            ;
00369             urlGet += ContollerURL;
00370             urlGet += "/";
00371             urlGet += UIURLwithID.substr( pos + 1 );
00372             return urlGet;
00373         }
00374 
00375         bool ConvertJsonResponseCodepage( std::string & response )
00376         {
00377 #ifdef DEBUG
00378             std::cerr << response << std::endl;
00379 #endif
00380             bool ret(false);
00381             int wchars_num =  MultiByteToWideChar( CP_UTF8 , 0 , response.c_str () , -1, NULL , 0 );
00382             if (!wchars_num)
00383                 return ret;
00384 
00385             std::wstring outResponse;
00386             outResponse.resize( wchars_num );
00387 
00388             if ( !MultiByteToWideChar( CP_UTF8 , 0 , response.c_str () , -1,  &outResponse[0], wchars_num ) )
00389             { return ret; }
00390 
00391             // response может занимать различное количество байт в зависимости от кодировки
00392             response.clear();
00393             int chars_num = WideCharToMultiByte(CPCA20_ENCODING, 0, outResponse.c_str(), -1, NULL, 0, 0, NULL);
00394             if (!chars_num)
00395                 return ret;
00396 
00397             response.resize(chars_num);
00398             if (!WideCharToMultiByte(CPCA20_ENCODING, 0, outResponse.c_str(), -1, &response[0], chars_num, 0, NULL))
00399             { return ret; }
00400 
00401             return true;
00402         }
00403 
00404         // метод конвертирует полученные данные для регистрации пользователя в UTF8
00405         // считаем, что для windows данные пришли в кодировке CP_ACP, а для UNIX - CP_UTF8
00406         bool ConvertJsonMessageCodepage( std::string & message )
00407         {
00408             std::wstring wmessage( message.length(), L' ' );
00409 
00410             bool ret( false );
00411             if (!MultiByteToWideChar(CPCA20_ENCODING, 0, message.c_str(), -1, &wmessage[0], int(wmessage.size() + 1)))
00412             { return ret; }
00413 
00414             message.resize( wmessage.size() * 2 + 1 );
00415 
00416             if (!WideCharToMultiByte(CP_UTF8, 0, wmessage.c_str(), -1, &message[0], int(message.size() + 1), 0, NULL))
00417             { return ret; }
00418 
00419             return true;
00420         }
00421 
00422         std::string makeBasicAuth();
00423 };
00424 #endif  // __CPCA20_REQUEST_H__

Документация по КриптоПро CAPILite. Последние изменения: Tue Sep 8 12:03:29 2020. Создано системой  doxygen 1.4.5-20051109