crypto_cryptoapi.c

Go to the documentation of this file.
00001 
00016 #include "includes.h"
00017 #include <windows.h>
00018 #include <wincrypt.h>
00019 
00020 #include "common.h"
00021 #include "crypto.h"
00022 
00023 #ifndef MS_ENH_RSA_AES_PROV
00024 #ifdef UNICODE
00025 #define MS_ENH_RSA_AES_PROV \
00026 L"Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)"
00027 #else
00028 #define MS_ENH_RSA_AES_PROV \
00029 "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)"
00030 #endif
00031 #endif /* MS_ENH_RSA_AES_PROV */
00032 
00033 #ifndef CALG_HMAC
00034 #define CALG_HMAC (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_HMAC)
00035 #endif
00036 
00037 #ifdef CONFIG_TLS_INTERNAL
00038 #ifdef __MINGW32_VERSION
00039 /*
00040  * MinGW does not yet include all the needed definitions for CryptoAPI, so
00041  * define here whatever extra is needed.
00042  */
00043 
00044 static PCCERT_CONTEXT WINAPI
00045 (*CertCreateCertificateContext)(DWORD dwCertEncodingType,
00046                                 const BYTE *pbCertEncoded,
00047                                 DWORD cbCertEncoded)
00048 = NULL; /* to be loaded from crypt32.dll */
00049 
00050 static BOOL WINAPI
00051 (*CryptImportPublicKeyInfo)(HCRYPTPROV hCryptProv, DWORD dwCertEncodingType,
00052                             PCERT_PUBLIC_KEY_INFO pInfo, HCRYPTKEY *phKey)
00053 = NULL; /* to be loaded from crypt32.dll */
00054 
00055 
00056 static int mingw_load_crypto_func(void)
00057 {
00058         HINSTANCE dll;
00059 
00060         /* MinGW does not yet have full CryptoAPI support, so load the needed
00061          * function here. */
00062 
00063         if (CertCreateCertificateContext)
00064                 return 0;
00065 
00066         dll = LoadLibrary("crypt32");
00067         if (dll == NULL) {
00068                 wpa_printf(MSG_DEBUG, "CryptoAPI: Could not load crypt32 "
00069                            "library");
00070                 return -1;
00071         }
00072 
00073         CertCreateCertificateContext = (void *) GetProcAddress(
00074                 dll, "CertCreateCertificateContext");
00075         if (CertCreateCertificateContext == NULL) {
00076                 wpa_printf(MSG_DEBUG, "CryptoAPI: Could not get "
00077                            "CertCreateCertificateContext() address from "
00078                            "crypt32 library");
00079                 return -1;
00080         }
00081 
00082         CryptImportPublicKeyInfo = GetProcAddress(
00083                 dll, "CryptImportPublicKeyInfo");
00084         if (CryptImportPublicKeyInfo == NULL) {
00085                 wpa_printf(MSG_DEBUG, "CryptoAPI: Could not get "
00086                            "CryptImportPublicKeyInfo() address from "
00087                            "crypt32 library");
00088                 return -1;
00089         }
00090 
00091         return 0;
00092 }
00093 
00094 #else /* __MINGW32_VERSION */
00095 
00096 static int mingw_load_crypto_func(void)
00097 {
00098         return 0;
00099 }
00100 
00101 #endif /* __MINGW32_VERSION */
00102 #endif /* CONFIG_TLS_INTERNAL */
00103 
00104 
00105 static void cryptoapi_report_error(const char *msg)
00106 {
00107         char *s, *pos;
00108         DWORD err = GetLastError();
00109 
00110         if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
00111                           FORMAT_MESSAGE_FROM_SYSTEM,
00112                           NULL, err, 0, (LPTSTR) &s, 0, NULL) == 0) {
00113                 wpa_printf(MSG_DEBUG, "CryptoAPI: %s: %d", msg, (int) err);
00114         }
00115 
00116         pos = s;
00117         while (*pos) {
00118                 if (*pos == '\n' || *pos == '\r') {
00119                         *pos = '\0';
00120                         break;
00121                 }
00122                 pos++;
00123         }
00124 
00125         wpa_printf(MSG_DEBUG, "CryptoAPI: %s: %d: (%s)", msg, (int) err, s);
00126         LocalFree(s);
00127 }
00128 
00129 
00130 int cryptoapi_hash_vector(ALG_ID alg, size_t hash_len, size_t num_elem,
00131                           const u8 *addr[], const size_t *len, u8 *mac)
00132 {
00133         HCRYPTPROV prov;
00134         HCRYPTHASH hash;
00135         size_t i;
00136         DWORD hlen;
00137         int ret = 0;
00138 
00139         if (!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, 0)) {
00140                 cryptoapi_report_error("CryptAcquireContext");
00141                 return -1;
00142         }
00143 
00144         if (!CryptCreateHash(prov, alg, 0, 0, &hash)) {
00145                 cryptoapi_report_error("CryptCreateHash");
00146                 CryptReleaseContext(prov, 0);
00147                 return -1;
00148         }
00149 
00150         for (i = 0; i < num_elem; i++) {
00151                 if (!CryptHashData(hash, (BYTE *) addr[i], len[i], 0)) {
00152                         cryptoapi_report_error("CryptHashData");
00153                         CryptDestroyHash(hash);
00154                         CryptReleaseContext(prov, 0);
00155                 }
00156         }
00157 
00158         hlen = hash_len;
00159         if (!CryptGetHashParam(hash, HP_HASHVAL, mac, &hlen, 0)) {
00160                 cryptoapi_report_error("CryptGetHashParam");
00161                 ret = -1;
00162         }
00163 
00164         CryptDestroyHash(hash);
00165         CryptReleaseContext(prov, 0);
00166 
00167         return ret;
00168 }
00169 
00170 
00171 int md4_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
00172 {
00173         return cryptoapi_hash_vector(CALG_MD4, 16, num_elem, addr, len, mac);
00174 }
00175 
00176 
00177 void des_encrypt(const u8 *clear, const u8 *key, u8 *cypher)
00178 {
00179         u8 next, tmp;
00180         int i;
00181         HCRYPTPROV prov;
00182         HCRYPTKEY ckey;
00183         DWORD dlen;
00184         struct {
00185                 BLOBHEADER hdr;
00186                 DWORD len;
00187                 BYTE key[8];
00188         } key_blob;
00189         DWORD mode = CRYPT_MODE_ECB;
00190 
00191         key_blob.hdr.bType = PLAINTEXTKEYBLOB;
00192         key_blob.hdr.bVersion = CUR_BLOB_VERSION;
00193         key_blob.hdr.reserved = 0;
00194         key_blob.hdr.aiKeyAlg = CALG_DES;
00195         key_blob.len = 8;
00196 
00197         /* Add parity bits to the key */
00198         next = 0;
00199         for (i = 0; i < 7; i++) {
00200                 tmp = key[i];
00201                 key_blob.key[i] = (tmp >> i) | next | 1;
00202                 next = tmp << (7 - i);
00203         }
00204         key_blob.key[i] = next | 1;
00205 
00206         if (!CryptAcquireContext(&prov, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL,
00207                                  CRYPT_VERIFYCONTEXT)) {
00208                 wpa_printf(MSG_DEBUG, "CryptoAPI: CryptAcquireContext failed: "
00209                            "%d", (int) GetLastError());
00210                 return;
00211         }
00212 
00213         if (!CryptImportKey(prov, (BYTE *) &key_blob, sizeof(key_blob), 0, 0,
00214                             &ckey)) {
00215                 wpa_printf(MSG_DEBUG, "CryptoAPI: CryptImportKey failed: %d",
00216                            (int) GetLastError());
00217                 CryptReleaseContext(prov, 0);
00218                 return;
00219         }
00220 
00221         if (!CryptSetKeyParam(ckey, KP_MODE, (BYTE *) &mode, 0)) {
00222                 wpa_printf(MSG_DEBUG, "CryptoAPI: CryptSetKeyParam(KP_MODE) "
00223                            "failed: %d", (int) GetLastError());
00224                 CryptDestroyKey(ckey);
00225                 CryptReleaseContext(prov, 0);
00226                 return;
00227         }
00228 
00229         os_memcpy(cypher, clear, 8);
00230         dlen = 8;
00231         if (!CryptEncrypt(ckey, 0, FALSE, 0, cypher, &dlen, 8)) {
00232                 wpa_printf(MSG_DEBUG, "CryptoAPI: CryptEncrypt failed: %d",
00233                            (int) GetLastError());
00234                 os_memset(cypher, 0, 8);
00235         }
00236 
00237         CryptDestroyKey(ckey);
00238         CryptReleaseContext(prov, 0);
00239 }
00240 
00241 
00242 #ifdef EAP_TLS_FUNCS
00243 int md5_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
00244 {
00245         return cryptoapi_hash_vector(CALG_MD5, 16, num_elem, addr, len, mac);
00246 }
00247 
00248 
00249 int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
00250 {
00251         return cryptoapi_hash_vector(CALG_SHA, 20, num_elem, addr, len, mac);
00252 }
00253 
00254 
00255 struct aes_context {
00256         HCRYPTPROV prov;
00257         HCRYPTKEY ckey;
00258 };
00259 
00260 
00261 void * aes_encrypt_init(const u8 *key, size_t len)
00262 {
00263         struct aes_context *akey;
00264         struct {
00265                 BLOBHEADER hdr;
00266                 DWORD len;
00267                 BYTE key[16];
00268         } key_blob;
00269         DWORD mode = CRYPT_MODE_ECB;
00270 
00271         if (len != 16)
00272                 return NULL;
00273 
00274         key_blob.hdr.bType = PLAINTEXTKEYBLOB;
00275         key_blob.hdr.bVersion = CUR_BLOB_VERSION;
00276         key_blob.hdr.reserved = 0;
00277         key_blob.hdr.aiKeyAlg = CALG_AES_128;
00278         key_blob.len = len;
00279         os_memcpy(key_blob.key, key, len);
00280 
00281         akey = os_zalloc(sizeof(*akey));
00282         if (akey == NULL)
00283                 return NULL;
00284 
00285         if (!CryptAcquireContext(&akey->prov, NULL,
00286                                  MS_ENH_RSA_AES_PROV, PROV_RSA_AES,
00287                                  CRYPT_VERIFYCONTEXT)) {
00288                 wpa_printf(MSG_DEBUG, "CryptoAPI: CryptAcquireContext failed: "
00289                            "%d", (int) GetLastError());
00290                 os_free(akey);
00291                 return NULL;
00292         }
00293 
00294         if (!CryptImportKey(akey->prov, (BYTE *) &key_blob, sizeof(key_blob),
00295                             0, 0, &akey->ckey)) {
00296                 wpa_printf(MSG_DEBUG, "CryptoAPI: CryptImportKey failed: %d",
00297                            (int) GetLastError());
00298                 CryptReleaseContext(akey->prov, 0);
00299                 os_free(akey);
00300                 return NULL;
00301         }
00302 
00303         if (!CryptSetKeyParam(akey->ckey, KP_MODE, (BYTE *) &mode, 0)) {
00304                 wpa_printf(MSG_DEBUG, "CryptoAPI: CryptSetKeyParam(KP_MODE) "
00305                            "failed: %d", (int) GetLastError());
00306                 CryptDestroyKey(akey->ckey);
00307                 CryptReleaseContext(akey->prov, 0);
00308                 os_free(akey);
00309                 return NULL;
00310         }
00311 
00312         return akey;
00313 }
00314 
00315 
00316 void aes_encrypt(void *ctx, const u8 *plain, u8 *crypt)
00317 {
00318         struct aes_context *akey = ctx;
00319         DWORD dlen;
00320 
00321         os_memcpy(crypt, plain, 16);
00322         dlen = 16;
00323         if (!CryptEncrypt(akey->ckey, 0, FALSE, 0, crypt, &dlen, 16)) {
00324                 wpa_printf(MSG_DEBUG, "CryptoAPI: CryptEncrypt failed: %d",
00325                            (int) GetLastError());
00326                 os_memset(crypt, 0, 16);
00327         }
00328 }
00329 
00330 
00331 void aes_encrypt_deinit(void *ctx)
00332 {
00333         struct aes_context *akey = ctx;
00334         if (akey) {
00335                 CryptDestroyKey(akey->ckey);
00336                 CryptReleaseContext(akey->prov, 0);
00337                 os_free(akey);
00338         }
00339 }
00340 
00341 
00342 void * aes_decrypt_init(const u8 *key, size_t len)
00343 {
00344         return aes_encrypt_init(key, len);
00345 }
00346 
00347 
00348 void aes_decrypt(void *ctx, const u8 *crypt, u8 *plain)
00349 {
00350         struct aes_context *akey = ctx;
00351         DWORD dlen;
00352 
00353         os_memcpy(plain, crypt, 16);
00354         dlen = 16;
00355 
00356         if (!CryptDecrypt(akey->ckey, 0, FALSE, 0, plain, &dlen)) {
00357                 wpa_printf(MSG_DEBUG, "CryptoAPI: CryptDecrypt failed: %d",
00358                            (int) GetLastError());
00359         }
00360 }
00361 
00362 
00363 void aes_decrypt_deinit(void *ctx)
00364 {
00365         aes_encrypt_deinit(ctx);
00366 }
00367 
00368 #ifdef CONFIG_TLS_INTERNAL
00369 
00370 struct crypto_hash {
00371         enum crypto_hash_alg alg;
00372         int error;
00373         HCRYPTPROV prov;
00374         HCRYPTHASH hash;
00375         HCRYPTKEY key;
00376 };
00377 
00378 struct crypto_hash * crypto_hash_init(enum crypto_hash_alg alg, const u8 *key,
00379                                       size_t key_len)
00380 {
00381         struct crypto_hash *ctx;
00382         ALG_ID calg;
00383         struct {
00384                 BLOBHEADER hdr;
00385                 DWORD len;
00386                 BYTE key[32];
00387         } key_blob;
00388 
00389         os_memset(&key_blob, 0, sizeof(key_blob));
00390         switch (alg) {
00391         case CRYPTO_HASH_ALG_MD5:
00392                 calg = CALG_MD5;
00393                 break;
00394         case CRYPTO_HASH_ALG_SHA1:
00395                 calg = CALG_SHA;
00396                 break;
00397         case CRYPTO_HASH_ALG_HMAC_MD5:
00398         case CRYPTO_HASH_ALG_HMAC_SHA1:
00399                 calg = CALG_HMAC;
00400                 key_blob.hdr.bType = PLAINTEXTKEYBLOB;
00401                 key_blob.hdr.bVersion = CUR_BLOB_VERSION;
00402                 key_blob.hdr.reserved = 0;
00403                 /*
00404                  * Note: RC2 is not really used, but that can be used to
00405                  * import HMAC keys of up to 16 byte long.
00406                  * CRYPT_IPSEC_HMAC_KEY flag for CryptImportKey() is needed to
00407                  * be able to import longer keys (HMAC-SHA1 uses 20-byte key).
00408                  */
00409                 key_blob.hdr.aiKeyAlg = CALG_RC2;
00410                 key_blob.len = key_len;
00411                 if (key_len > sizeof(key_blob.key))
00412                         return NULL;
00413                 os_memcpy(key_blob.key, key, key_len);
00414                 break;
00415         default:
00416                 return NULL;
00417         }
00418 
00419         ctx = os_zalloc(sizeof(*ctx));
00420         if (ctx == NULL)
00421                 return NULL;
00422 
00423         ctx->alg = alg;
00424 
00425         if (!CryptAcquireContext(&ctx->prov, NULL, NULL, PROV_RSA_FULL, 0)) {
00426                 cryptoapi_report_error("CryptAcquireContext");
00427                 os_free(ctx);
00428                 return NULL;
00429         }
00430 
00431         if (calg == CALG_HMAC) {
00432 #ifndef CRYPT_IPSEC_HMAC_KEY
00433 #define CRYPT_IPSEC_HMAC_KEY 0x00000100
00434 #endif
00435                 if (!CryptImportKey(ctx->prov, (BYTE *) &key_blob,
00436                                     sizeof(key_blob), 0, CRYPT_IPSEC_HMAC_KEY,
00437                                     &ctx->key)) {
00438                         cryptoapi_report_error("CryptImportKey");
00439                         CryptReleaseContext(ctx->prov, 0);
00440                         os_free(ctx);
00441                         return NULL;
00442                 }
00443         }
00444 
00445         if (!CryptCreateHash(ctx->prov, calg, ctx->key, 0, &ctx->hash)) {
00446                 cryptoapi_report_error("CryptCreateHash");
00447                 CryptReleaseContext(ctx->prov, 0);
00448                 os_free(ctx);
00449                 return NULL;
00450         }
00451 
00452         if (calg == CALG_HMAC) {
00453                 HMAC_INFO info;
00454                 os_memset(&info, 0, sizeof(info));
00455                 switch (alg) {
00456                 case CRYPTO_HASH_ALG_HMAC_MD5:
00457                         info.HashAlgid = CALG_MD5;
00458                         break;
00459                 case CRYPTO_HASH_ALG_HMAC_SHA1:
00460                         info.HashAlgid = CALG_SHA;
00461                         break;
00462                 default:
00463                         /* unreachable */
00464                         break;
00465                 }
00466 
00467                 if (!CryptSetHashParam(ctx->hash, HP_HMAC_INFO, (BYTE *) &info,
00468                                        0)) {
00469                         cryptoapi_report_error("CryptSetHashParam");
00470                         CryptDestroyHash(ctx->hash);
00471                         CryptReleaseContext(ctx->prov, 0);
00472                         os_free(ctx);
00473                         return NULL;
00474                 }
00475         }
00476 
00477         return ctx;
00478 }
00479 
00480 
00481 void crypto_hash_update(struct crypto_hash *ctx, const u8 *data, size_t len)
00482 {
00483         if (ctx == NULL || ctx->error)
00484                 return;
00485 
00486         if (!CryptHashData(ctx->hash, (BYTE *) data, len, 0)) {
00487                 cryptoapi_report_error("CryptHashData");
00488                 ctx->error = 1;
00489         }
00490 }
00491 
00492 
00493 int crypto_hash_finish(struct crypto_hash *ctx, u8 *mac, size_t *len)
00494 {
00495         int ret = 0;
00496         DWORD hlen;
00497 
00498         if (ctx == NULL)
00499                 return -2;
00500 
00501         if (mac == NULL || len == NULL)
00502                 goto done;
00503 
00504         if (ctx->error) {
00505                 ret = -2;
00506                 goto done;
00507         }
00508 
00509         hlen = *len;
00510         if (!CryptGetHashParam(ctx->hash, HP_HASHVAL, mac, &hlen, 0)) {
00511                 cryptoapi_report_error("CryptGetHashParam");
00512                 ret = -2;
00513         }
00514         *len = hlen;
00515 
00516 done:
00517         if (ctx->alg == CRYPTO_HASH_ALG_HMAC_SHA1 ||
00518             ctx->alg == CRYPTO_HASH_ALG_HMAC_MD5)
00519                 CryptDestroyKey(ctx->key);
00520 
00521         os_free(ctx);
00522 
00523         return ret;
00524 }
00525 
00526 
00527 struct crypto_cipher {
00528         HCRYPTPROV prov;
00529         HCRYPTKEY key;
00530 };
00531 
00532 
00533 struct crypto_cipher * crypto_cipher_init(enum crypto_cipher_alg alg,
00534                                           const u8 *iv, const u8 *key,
00535                                           size_t key_len)
00536 {       
00537         struct crypto_cipher *ctx;
00538         struct {
00539                 BLOBHEADER hdr;
00540                 DWORD len;
00541                 BYTE key[32];
00542         } key_blob;
00543         DWORD mode = CRYPT_MODE_CBC;
00544 
00545         key_blob.hdr.bType = PLAINTEXTKEYBLOB;
00546         key_blob.hdr.bVersion = CUR_BLOB_VERSION;
00547         key_blob.hdr.reserved = 0;
00548         key_blob.len = key_len;
00549         if (key_len > sizeof(key_blob.key))
00550                 return NULL;
00551         os_memcpy(key_blob.key, key, key_len);
00552 
00553         switch (alg) {
00554         case CRYPTO_CIPHER_ALG_AES:
00555                 if (key_len == 32)
00556                         key_blob.hdr.aiKeyAlg = CALG_AES_256;
00557                 else if (key_len == 24)
00558                         key_blob.hdr.aiKeyAlg = CALG_AES_192;
00559                 else
00560                         key_blob.hdr.aiKeyAlg = CALG_AES_128;
00561                 break;
00562         case CRYPTO_CIPHER_ALG_3DES:
00563                 key_blob.hdr.aiKeyAlg = CALG_3DES;
00564                 break;
00565         case CRYPTO_CIPHER_ALG_DES:
00566                 key_blob.hdr.aiKeyAlg = CALG_DES;
00567                 break;
00568         case CRYPTO_CIPHER_ALG_RC2:
00569                 key_blob.hdr.aiKeyAlg = CALG_RC2;
00570                 break;
00571         case CRYPTO_CIPHER_ALG_RC4:
00572                 key_blob.hdr.aiKeyAlg = CALG_RC4;
00573                 break;
00574         default:
00575                 return NULL;
00576         }
00577 
00578         ctx = os_zalloc(sizeof(*ctx));
00579         if (ctx == NULL)
00580                 return NULL;
00581 
00582         if (!CryptAcquireContext(&ctx->prov, NULL, MS_ENH_RSA_AES_PROV,
00583                                  PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
00584                 cryptoapi_report_error("CryptAcquireContext");
00585                 goto fail1;
00586         }
00587 
00588         if (!CryptImportKey(ctx->prov, (BYTE *) &key_blob,
00589                             sizeof(key_blob), 0, 0, &ctx->key)) {
00590                 cryptoapi_report_error("CryptImportKey");
00591                 goto fail2;
00592         }
00593 
00594         if (!CryptSetKeyParam(ctx->key, KP_MODE, (BYTE *) &mode, 0)) {
00595                 cryptoapi_report_error("CryptSetKeyParam(KP_MODE)");
00596                 goto fail3;
00597         }
00598 
00599         if (iv && !CryptSetKeyParam(ctx->key, KP_IV, (BYTE *) iv, 0)) {
00600                 cryptoapi_report_error("CryptSetKeyParam(KP_IV)");
00601                 goto fail3;
00602         }
00603 
00604         return ctx;
00605 
00606 fail3:
00607         CryptDestroyKey(ctx->key);
00608 fail2:
00609         CryptReleaseContext(ctx->prov, 0);
00610 fail1:
00611         os_free(ctx);
00612         return NULL;
00613 }
00614 
00615 
00616 int crypto_cipher_encrypt(struct crypto_cipher *ctx, const u8 *plain,
00617                           u8 *crypt, size_t len)
00618 {
00619         DWORD dlen;
00620 
00621         os_memcpy(crypt, plain, len);
00622         dlen = len;
00623         if (!CryptEncrypt(ctx->key, 0, FALSE, 0, crypt, &dlen, len)) {
00624                 cryptoapi_report_error("CryptEncrypt");
00625                 os_memset(crypt, 0, len);
00626                 return -1;
00627         }
00628 
00629         return 0;
00630 }
00631 
00632 
00633 int crypto_cipher_decrypt(struct crypto_cipher *ctx, const u8 *crypt,
00634                           u8 *plain, size_t len)
00635 {
00636         DWORD dlen;
00637 
00638         os_memcpy(plain, crypt, len);
00639         dlen = len;
00640         if (!CryptDecrypt(ctx->key, 0, FALSE, 0, plain, &dlen)) {
00641                 cryptoapi_report_error("CryptDecrypt");
00642                 return -1;
00643         }
00644 
00645         return 0;
00646 }
00647 
00648 
00649 void crypto_cipher_deinit(struct crypto_cipher *ctx)
00650 {
00651         CryptDestroyKey(ctx->key);
00652         CryptReleaseContext(ctx->prov, 0);
00653         os_free(ctx);
00654 }
00655 
00656 
00657 struct crypto_public_key {
00658         HCRYPTPROV prov;
00659         HCRYPTKEY rsa;
00660 };
00661 
00662 struct crypto_private_key {
00663         HCRYPTPROV prov;
00664         HCRYPTKEY rsa;
00665 };
00666 
00667 
00668 struct crypto_public_key * crypto_public_key_import(const u8 *key, size_t len)
00669 {
00670         /* Use crypto_public_key_from_cert() instead. */
00671         return NULL;
00672 }
00673 
00674 
00675 struct crypto_private_key * crypto_private_key_import(const u8 *key,
00676                                                       size_t len,
00677                                                       const char *passwd)
00678 {
00679         /* TODO */
00680         return NULL;
00681 }
00682 
00683 
00684 struct crypto_public_key * crypto_public_key_from_cert(const u8 *buf,
00685                                                        size_t len)
00686 {
00687         struct crypto_public_key *pk;
00688         PCCERT_CONTEXT cc;
00689 
00690         pk = os_zalloc(sizeof(*pk));
00691         if (pk == NULL)
00692                 return NULL;
00693 
00694         cc = CertCreateCertificateContext(X509_ASN_ENCODING |
00695                                           PKCS_7_ASN_ENCODING, buf, len);
00696         if (!cc) {
00697                 cryptoapi_report_error("CryptCreateCertificateContext");
00698                 os_free(pk);
00699                 return NULL;
00700         }
00701 
00702         if (!CryptAcquireContext(&pk->prov, NULL, MS_DEF_PROV, PROV_RSA_FULL,
00703                                  0)) {
00704                 cryptoapi_report_error("CryptAcquireContext");
00705                 os_free(pk);
00706                 CertFreeCertificateContext(cc);
00707                 return NULL;
00708         }
00709 
00710         if (!CryptImportPublicKeyInfo(pk->prov, X509_ASN_ENCODING |
00711                                       PKCS_7_ASN_ENCODING,
00712                                       &cc->pCertInfo->SubjectPublicKeyInfo,
00713                                       &pk->rsa)) {
00714                 cryptoapi_report_error("CryptImportPublicKeyInfo");
00715                 CryptReleaseContext(pk->prov, 0);
00716                 os_free(pk);
00717                 CertFreeCertificateContext(cc);
00718                 return NULL;
00719         }
00720 
00721         CertFreeCertificateContext(cc);
00722 
00723         return pk;
00724 }
00725 
00726 
00727 int crypto_public_key_encrypt_pkcs1_v15(struct crypto_public_key *key,
00728                                         const u8 *in, size_t inlen,
00729                                         u8 *out, size_t *outlen)
00730 {
00731         DWORD clen;
00732         u8 *tmp;
00733         size_t i;
00734 
00735         if (*outlen < inlen)
00736                 return -1;
00737         tmp = malloc(*outlen);
00738         if (tmp == NULL)
00739                 return -1;
00740 
00741         os_memcpy(tmp, in, inlen);
00742         clen = inlen;
00743         if (!CryptEncrypt(key->rsa, 0, TRUE, 0, tmp, &clen, *outlen)) {
00744                 wpa_printf(MSG_DEBUG, "CryptoAPI: Failed to encrypt using "
00745                            "public key: %d", (int) GetLastError());
00746                 os_free(tmp);
00747                 return -1;
00748         }
00749 
00750         *outlen = clen;
00751 
00752         /* Reverse the output */
00753         for (i = 0; i < *outlen; i++)
00754                 out[i] = tmp[*outlen - 1 - i];
00755 
00756         os_free(tmp);
00757 
00758         return 0;
00759 }
00760 
00761 
00762 int crypto_private_key_sign_pkcs1(struct crypto_private_key *key,
00763                                   const u8 *in, size_t inlen,
00764                                   u8 *out, size_t *outlen)
00765 {
00766         /* TODO */
00767         return -1;
00768 }
00769 
00770 
00771 void crypto_public_key_free(struct crypto_public_key *key)
00772 {
00773         if (key) {
00774                 CryptDestroyKey(key->rsa);
00775                 CryptReleaseContext(key->prov, 0);
00776                 os_free(key);
00777         }
00778 }
00779 
00780 
00781 void crypto_private_key_free(struct crypto_private_key *key)
00782 {
00783         if (key) {
00784                 CryptDestroyKey(key->rsa);
00785                 CryptReleaseContext(key->prov, 0);
00786                 os_free(key);
00787         }
00788 }
00789 
00790 
00791 int crypto_global_init(void)
00792 {
00793         return mingw_load_crypto_func();
00794 }
00795 
00796 
00797 void crypto_global_deinit(void)
00798 {
00799 }
00800 
00801 #endif /* CONFIG_TLS_INTERNAL */
00802 
00803 #endif /* EAP_TLS_FUNCS */
00804 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on Sat Nov 21 23:16:50 2009 for hostapd by  doxygen 1.6.1