1 /* 2 * Copyright (C) 2008-2009 Torch Mobile Inc. 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library General Public License 15 * along with this library; see the file COPYING.LIB. If not, write to 16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 17 * Boston, MA 02110-1301, USA. 18 */ 19 20 #include "config.h" 21 #include "SSLKeyGenerator.h" 22 23 #include "Base64.h" 24 #include "CString.h" 25 26 #include <windows.h> 27 #include <wincrypt.h> 28 29 namespace WebCore { 30 31 void WebCore::getSupportedKeySizes(Vector<String>& v) 32 { 33 v.append("High Grade"); 34 v.append("Medium Grade"); 35 } 36 37 String WebCore::signedPublicKeyAndChallengeString(unsigned index, const String& challenge, const KURL& url) 38 { 39 String keyString; 40 41 HCRYPTPROV hContext = 0; 42 HCRYPTKEY hKey = 0; 43 PCERT_PUBLIC_KEY_INFO pPubInfo = 0; 44 45 // Try to delete it if it exists already 46 CryptAcquireContext(&hContext, _T("keygen_container"), MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET); 47 48 do { 49 if (!CryptAcquireContext(&hContext, _T("keygen_container"), MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET)) 50 break; 51 52 DWORD dwPubInfoLength = 0; 53 if (!CryptGenKey(hContext, AT_KEYEXCHANGE, 0, &hKey) || !CryptExportPublicKeyInfo(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, 0, &dwPubInfoLength)) 54 break; 55 56 // Use malloc instead of new, because malloc guarantees to return a pointer aligned for all data types. 57 pPubInfo = reinterpret_cast<PCERT_PUBLIC_KEY_INFO>(fastMalloc(dwPubInfoLength)); 58 59 if (!CryptExportPublicKeyInfo(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, pPubInfo, &dwPubInfoLength)) 60 break; 61 62 CERT_KEYGEN_REQUEST_INFO requestInfo = { 0 }; 63 requestInfo.dwVersion = CERT_KEYGEN_REQUEST_V1; 64 requestInfo.pwszChallengeString = L""; 65 requestInfo.SubjectPublicKeyInfo = *pPubInfo; 66 67 String localChallenge = challenge; 68 69 // Windows API won't write to our buffer, although it's not declared with const. 70 requestInfo.pwszChallengeString = const_cast<wchar_t*>(localChallenge.charactersWithNullTermination()); 71 72 CRYPT_ALGORITHM_IDENTIFIER signAlgo = { 0 }; 73 signAlgo.pszObjId = szOID_RSA_SHA1RSA; 74 75 DWORD dwEncodedLength; 76 if (!CryptSignAndEncodeCertificate(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, X509_KEYGEN_REQUEST_TO_BE_SIGNED, &requestInfo, &signAlgo, 0, 0, &dwEncodedLength)) 77 break; 78 79 Vector<char> binary(dwEncodedLength); 80 if (!CryptSignAndEncodeCertificate(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, X509_KEYGEN_REQUEST_TO_BE_SIGNED, &requestInfo, &signAlgo, 0, reinterpret_cast<LPBYTE>(binary.data()), &dwEncodedLength)) 81 break; 82 83 Vector<char> base64; 84 base64Encode(binary, base64); 85 keyString = String(base64.data(), base64.size()); 86 87 } while(0); 88 89 if (pPubInfo) 90 fastFree(pPubInfo); 91 92 if (hKey) 93 CryptDestroyKey(hKey); 94 95 if (hContext) 96 CryptReleaseContext(hContext, 0); 97 98 return keyString; 99 } 100 101 } // namespace WebCore 102