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 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 UserCallbacks *_pCallbacks,
00083 X509EnrollmentAuthFlags _AuthType,
00084 X509EnrollmentCheckChainFlags _CheckChainType,
00085 const BSTR strCredential,
00086 CSecurePin *_sbPassword,
00087 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,
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 LONG hWnd,
00194 X509EnrollmentAuthFlags anAuthType,
00195 BSTR strCredential,
00196 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
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
00415
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__