00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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 UserCallbacks *_pCallbacks,
00073 X509EnrollmentAuthFlags _AuthType,
00074 X509EnrollmentCheckChainFlags _CheckChainType,
00075 const BSTR strCredential,
00076 CSecurePin *_sbPassword,
00077 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,
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 LONG hWnd,
00184 X509EnrollmentAuthFlags anAuthType,
00185 BSTR strCredential,
00186 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
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
00405
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__