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

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