1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20 /* 21 * XSEC 22 * 23 * WinCAPICryptoProvider := Base class to handle Windows Crypto API 24 * 25 * Author(s): Berin Lautenbach 26 * 27 * $Id: WinCAPICryptoProvider.hpp 1817863 2017-12-11 22:47:43Z scantor $ 28 * 29 */ 30 31 #ifndef WINCAPICRYPTOPROVIDER_INCLUDE 32 #define WINCAPICRYPTOPROVIDER_INCLUDE 33 34 #include <xsec/framework/XSECDefs.hpp> 35 #include <xsec/enc/XSECCryptoProvider.hpp> 36 37 #if defined (XSEC_HAVE_WINCAPI) 38 39 #if defined (_WIN32_WINNT) 40 # undef _WIN32_WINNT 41 #endif 42 #define _WIN32_WINNT 0x0400 43 #include <wincrypt.h> 44 45 46 // For older versions of wincrypt.h 47 48 #if !defined (PROV_RSA_AES) 49 # define PROV_RSA_AES 24 50 # define ALG_SID_AES_128 14 51 # define ALG_SID_AES_192 15 52 # define ALG_SID_AES_256 16 53 # define ALG_SID_AES 17 54 # define CALG_AES_128 (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_AES_128) 55 # define CALG_AES_192 (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_AES_192) 56 # define CALG_AES_256 (ALG_CLASS_DATA_ENCRYPT|ALG_TYPE_BLOCK|ALG_SID_AES_256) 57 #endif 58 59 #define WINCAPI_BLOBHEADERLEN 0x08 60 #define WINCAPI_DSSPUBKEYLEN 0x08 61 #define WINCAPI_DSSSEEDLEN 0x18 62 #define WINCAPI_RSAPUBKEYLEN 0x0C 63 64 /** 65 * @defgroup wincapicrypto Windows Crypto API Interface 66 * @ingroup crypto 67 * The WinCAPI crypto provides an experimental inerface to 68 * the Windows Cryptographic API. 69 * 70 * All initialisation of the Windows providers needs to be done 71 * by the calling application. The interface will call the provided 72 * DSS (PROV_DSS) provider and RSA (PROV_RSA_FULL) provider to perform 73 * cryptographic functions. 74 * 75 * The tools use the default providers, but the calling application 76 * can use any providers that implement PROV_DSS and PROV_FULL_RSA. 77 * 78 * Note that, unlike the OpenSSL classes, the various implementation 79 * classes all require their owner provider class to be passed into 80 * the constructor. This allows them to access the RSA and DSS CAPI 81 * providers being used for the implementation. 82 * 83 * @todo Need to allow the various classes to over-ride the PROV 84 * objects to allow specific private key instances rather than one 85 * instance across the library instance. 86 */ 87 /*\@{*/ 88 89 class XSEC_EXPORT WinCAPICryptoProvider : public XSECCryptoProvider { 90 91 92 public : 93 94 /** @name Constructors and Destructors */ 95 //@{ 96 /** 97 * \brief Create a Windows CAPI interface layer 98 * 99 * Windows CSPs work under a provider model. The user should specify 100 * which CSP to use. 101 * 102 * @param provDSSName Name of DSS provider - must be of type PROV_DSS. 103 * Will use the default Windows DSS provider if nothing passed in. 104 * @param provRSAName RSA provider - must be of type PROV_RSA_FULL. 105 * Will use the default RSA_FULL provider if nothing passed in 106 * @param dwFlags If you are running XSEC as service you should specify 107 * CRYPT_MACHINE_KEYSET here 108 */ 109 110 WinCAPICryptoProvider(LPCSTR provDSSName = NULL, LPCSTR provRSAName = NULL, DWORD dwFlags = 0); 111 112 virtual ~WinCAPICryptoProvider(); 113 114 //@} 115 116 /** @name Hashing (Digest) Functions */ 117 //@{ 118 119 /** 120 * \brief Get the provider's maximum digest length. 121 * 122 * Call used by the library to max out the buffer sizes it uses. 123 * 124 * @returns maximum size to allow for 125 */ 126 virtual unsigned int getMaxHashSize() const; 127 128 /** 129 * \brief Return a hashing implementation. 130 * 131 * Call used by the library to obtain a hashing implementation from the 132 * provider. 133 * 134 * @returns a pointer to a hashing object. 135 */ 136 virtual XSECCryptoHash* hash(XSECCryptoHash::HashType type) const; 137 138 /** 139 * \brief Return an HMAC implementation. 140 * 141 * Call used by the library to obtain an HMAC implementation from the 142 * provider. The caller will need to set the key in the hash 143 * object with an XSECCryptoKeyHMAC using XSECCryptoHash::setKey(). 144 * 145 * @returns a pointer to the hashing object. 146 */ 147 virtual XSECCryptoHash* HMAC(XSECCryptoHash::HashType type) const; 148 149 /** 150 * \brief Return a HMAC key 151 * 152 * Sometimes the library needs to create an HMAC key (notably within 153 * the XKMS utilities. 154 * 155 * This function allows the library to obtain a key that can then have 156 * a value set within it. 157 */ 158 159 virtual XSECCryptoKeyHMAC* keyHMAC(void) const; 160 161 //@} 162 163 /** @name Encoding functions */ 164 //@{ 165 166 /** 167 * \brief Return a Base64 encoder/decoder implementation. 168 * 169 * Call used by the library to obtain a Base64 170 * encoder/decoder. 171 * 172 * @note Windows providers do not implement Base64, so the internal 173 * implementation (XSCrypt) is used instead. 174 * 175 * 176 * @returns Pointer to the new Base64 encoder. 177 * @see XSCryptCryptoBase64 178 */ 179 180 virtual XSECCryptoBase64* base64() const; 181 182 //@} 183 184 /** @name Keys and Certificates */ 185 //@{ 186 187 /** 188 * \brief Return a DSA key implementation object. 189 * 190 * Call used by the library to obtain a DSA key object. 191 * 192 * @returns Pointer to the new DSA key 193 * @see WinCAPICryptoKeyDSA 194 */ 195 196 virtual XSECCryptoKeyDSA* keyDSA() const; 197 198 /** 199 * \brief Return an RSA key implementation object. 200 * 201 * Call used by the library to obtain an WinCAPI RSA key object. 202 * 203 * @returns Pointer to the new RSA key 204 * @see WinCAPICryptoKeyRSA 205 */ 206 207 virtual XSECCryptoKeyRSA* keyRSA() const; 208 209 /** 210 * \brief Return an EC key implementation object. 211 * 212 * Call used by the library to obtain an WinCAPI EC key object. 213 * 214 * @returns Pointer to the new EC key 215 */ 216 217 virtual XSECCryptoKeyEC* keyEC() const; 218 219 /** 220 * \brief Return a key implementation object based on DER-encoded input. 221 * 222 * Call used by the library to obtain a key object from a DER-encoded key. 223 * 224 * @param buf DER-encoded data 225 * @param buflen length of data 226 * @param base64 true iff data is base64-encoded 227 * @returns Pointer to the new key 228 */ 229 230 virtual XSECCryptoKey* keyDER(const char* buf, unsigned long buflen, bool base64) const; 231 232 /** 233 * \brief Return an X509 implementation object. 234 * 235 * Call used by the library to obtain an object that can work 236 * with X509 certificates. 237 * 238 * @returns Pointer to the new X509 object 239 * @see WinCAPICryptoX509 240 */ 241 242 virtual XSECCryptoX509* X509() const; 243 244 //@} 245 246 /** @name Windows CAPI Specific methods */ 247 //@{ 248 249 /** 250 * \brief Returns the Crypto Provider being used for DSS 251 */ 252 getProviderDSS(void)253 HCRYPTPROV getProviderDSS(void) {return m_provDSS;} 254 255 /** 256 * \brief Returns the Provider being used for RSA functions 257 */ 258 getProviderRSA(void)259 HCRYPTPROV getProviderRSA(void) {return m_provRSA;} 260 261 /** 262 * \brief Return the internal key store provider 263 */ 264 getApacheKeyStore(void)265 HCRYPTPROV getApacheKeyStore(void) {return m_provApacheKeyStore;} 266 267 /** 268 * \brief Translate B64 I2OS integer to a WinCAPI int. 269 * 270 * Decodes a Base64 (ds:CryptoBinary) integer and reverses the order to 271 * allow loading into a Windows CAPI function. (CAPI uses Little Endian 272 * storage of integers). 273 * 274 * @param b64 Base 64 string 275 * @param b64Len Length of base64 string 276 * @param retLen Parameter to hold length of return integer 277 */ 278 279 static BYTE* b642WinBN(const char* b64, unsigned int b64Len, unsigned int& retLen); 280 281 /** 282 * \brief Translate a WinCAPI int to a B64 I2OS integer . 283 * 284 * Encodes a Windows integer in I2OSP base64 encoded format. 285 * 286 * @param n Buffer holding the Windows Integer 287 * @param nLen Length of data in buffer 288 * @param retLen Parameter to hold length of return integer 289 * @returns A pointer to a buffer holding the encoded data 290 * (transfers ownership) 291 */ 292 293 static unsigned char* WinBN2b64(BYTE* n, DWORD nLen, unsigned int &retLen); 294 295 /** 296 * \brief Determine whether a given algorithm is supported 297 * 298 * A call that can be used to determine whether a given 299 * symmetric algorithm is supported 300 */ 301 302 virtual bool algorithmSupported(XSECCryptoSymmetricKey::SymmetricKeyType alg) const; 303 304 /** 305 * \brief Determine whether a given algorithm is supported 306 * 307 * A call that can be used to determine whether a given 308 * digest algorithm is supported 309 */ 310 311 virtual bool algorithmSupported(XSECCryptoHash::HashType alg) const; 312 313 /** 314 * \brief Return a Symmetric Key implementation object. 315 * 316 * Call used by the library to obtain a bulk encryption 317 * object. 318 * 319 * @returns Pointer to the new SymmetricKey object 320 * @see XSECCryptoSymmetricKey 321 */ 322 323 virtual XSECCryptoSymmetricKey* keySymmetric(XSECCryptoSymmetricKey::SymmetricKeyType alg) const; 324 325 /** 326 * \brief Obtain some random octets 327 * 328 * For generation of IVs and the like, the library needs to be able 329 * to obtain "random" octets. The library uses this call to the 330 * crypto provider to obtain what it needs. 331 * 332 * @param buffer The buffer to place the random data in 333 * @param numOctets Number of bytes required 334 * @returns Number of bytes obtained. 335 */ 336 337 virtual unsigned int getRandom(unsigned char * buffer, unsigned int numOctets) const; 338 339 340 //@} 341 342 /** @name Information Functions */ 343 //@{ 344 345 /** 346 * \brief Returns a string that identifies the Crypto Provider 347 */ 348 349 virtual const XMLCh* getProviderName() const; 350 351 //@} 352 353 354 private: 355 HCRYPTPROV m_provDSS; 356 HCRYPTPROV m_provRSA; 357 HCRYPTPROV m_provApacheKeyStore; 358 LPCSTR m_provDSSName; 359 LPCSTR m_provRSAName; 360 bool m_haveAES; 361 DWORD m_provRSAType; 362 363 }; 364 365 /*\@}*/ 366 367 #endif /* XSEC_HAVE_WINCAPI */ 368 #endif /* WINCAPICRYPTOPROVIDER_INCLUDE */ 369 370