Home | History | Annotate | Download | only in win
      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 <wtf/text/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     // FIXME: Strings should be localizable.
     34     v.append("High Grade");
     35     v.append("Medium Grade");
     36 }
     37 
     38 String WebCore::signedPublicKeyAndChallengeString(unsigned index, const String& challenge, const KURL& url)
     39 {
     40     String keyString;
     41 
     42     HCRYPTPROV hContext = 0;
     43     HCRYPTKEY hKey = 0;
     44     PCERT_PUBLIC_KEY_INFO pPubInfo = 0;
     45 
     46     // Try to delete it if it exists already
     47     CryptAcquireContextW(&hContext, L"keygen_container", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
     48 
     49     do {
     50         if (!CryptAcquireContextW(&hContext, L"keygen_container", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
     51             break;
     52 
     53         DWORD dwPubInfoLength = 0;
     54         if (!CryptGenKey(hContext, AT_KEYEXCHANGE, 0, &hKey) || !CryptExportPublicKeyInfo(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, 0, &dwPubInfoLength))
     55             break;
     56 
     57         // Use malloc instead of new, because malloc guarantees to return a pointer aligned for all data types.
     58         pPubInfo = reinterpret_cast<PCERT_PUBLIC_KEY_INFO>(fastMalloc(dwPubInfoLength));
     59 
     60         if (!CryptExportPublicKeyInfo(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, pPubInfo, &dwPubInfoLength))
     61             break;
     62 
     63         CERT_KEYGEN_REQUEST_INFO requestInfo = { 0 };
     64         requestInfo.dwVersion = CERT_KEYGEN_REQUEST_V1;
     65         requestInfo.pwszChallengeString = L"";
     66         requestInfo.SubjectPublicKeyInfo = *pPubInfo;
     67 
     68         String localChallenge = challenge;
     69 
     70         // Windows API won't write to our buffer, although it's not declared with const.
     71         requestInfo.pwszChallengeString = const_cast<wchar_t*>(localChallenge.charactersWithNullTermination());
     72 
     73         CRYPT_ALGORITHM_IDENTIFIER signAlgo = { 0 };
     74         signAlgo.pszObjId = szOID_RSA_SHA1RSA;
     75 
     76         DWORD dwEncodedLength;
     77         if (!CryptSignAndEncodeCertificate(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, X509_KEYGEN_REQUEST_TO_BE_SIGNED, &requestInfo, &signAlgo, 0, 0, &dwEncodedLength))
     78             break;
     79 
     80         Vector<char> binary(dwEncodedLength);
     81         if (!CryptSignAndEncodeCertificate(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, X509_KEYGEN_REQUEST_TO_BE_SIGNED, &requestInfo, &signAlgo, 0, reinterpret_cast<LPBYTE>(binary.data()), &dwEncodedLength))
     82             break;
     83 
     84         keyString = base64Encode(binary);
     85     } while(0);
     86 
     87     if (pPubInfo)
     88         fastFree(pPubInfo);
     89 
     90     if (hKey)
     91         CryptDestroyKey(hKey);
     92 
     93     if (hContext)
     94         CryptReleaseContext(hContext, 0);
     95 
     96     return keyString;
     97 }
     98 
     99 } // namespace WebCore
    100