Home | History | Annotate | Download | only in wince
      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