Exemplo n.º 1
0
String WebCore::signedPublicKeyAndChallengeString(unsigned index, const String& challenge, const KURL& url)
{
    String keyString;

    HCRYPTPROV hContext = 0;
    HCRYPTKEY hKey = 0;
    PCERT_PUBLIC_KEY_INFO pPubInfo = 0;

    // Try to delete it if it exists already
    CryptAcquireContextW(&hContext, L"keygen_container", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_DELETEKEYSET);

    do {
        if (!CryptAcquireContextW(&hContext, L"keygen_container", MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
            break;

        DWORD dwPubInfoLength = 0;
        if (!CryptGenKey(hContext, AT_KEYEXCHANGE, 0, &hKey) || !CryptExportPublicKeyInfo(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, 0, &dwPubInfoLength))
            break;

        // Use malloc instead of new, because malloc guarantees to return a pointer aligned for all data types.
        pPubInfo = reinterpret_cast<PCERT_PUBLIC_KEY_INFO>(fastMalloc(dwPubInfoLength));

        if (!CryptExportPublicKeyInfo(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, pPubInfo, &dwPubInfoLength))
            break;

        CERT_KEYGEN_REQUEST_INFO requestInfo = { 0 };
        requestInfo.dwVersion = CERT_KEYGEN_REQUEST_V1;
        requestInfo.pwszChallengeString = L"";
        requestInfo.SubjectPublicKeyInfo = *pPubInfo;

        String localChallenge = challenge;

        // Windows API won't write to our buffer, although it's not declared with const.
        requestInfo.pwszChallengeString = const_cast<wchar_t*>(localChallenge.charactersWithNullTermination());

        CRYPT_ALGORITHM_IDENTIFIER signAlgo = { 0 };
        signAlgo.pszObjId = szOID_RSA_SHA1RSA;

        DWORD dwEncodedLength;
        if (!CryptSignAndEncodeCertificate(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, X509_KEYGEN_REQUEST_TO_BE_SIGNED, &requestInfo, &signAlgo, 0, 0, &dwEncodedLength))
            break;

        Vector<char> binary(dwEncodedLength);
        if (!CryptSignAndEncodeCertificate(hContext, AT_KEYEXCHANGE, X509_ASN_ENCODING, X509_KEYGEN_REQUEST_TO_BE_SIGNED, &requestInfo, &signAlgo, 0, reinterpret_cast<LPBYTE>(binary.data()), &dwEncodedLength))
            break;

        keyString = base64Encode(binary);
    } while(0);

    if (pPubInfo)
        fastFree(pPubInfo);

    if (hKey)
        CryptDestroyKey(hKey);

    if (hContext)
        CryptReleaseContext(hContext, 0);

    return keyString;
}
Exemplo n.º 2
0
static DWORD
encodePK( DWORD size, BYTE *buffer )
{
    CERT_PUBLIC_KEY_INFO	*keyInfo = (CERT_PUBLIC_KEY_INFO *)buffer;
    DWORD			length;

    if ( ! CryptExportPublicKeyInfo( provider, AT_KEYEXCHANGE, 
				     X509_ASN_ENCODING, NULL, &length ) )
    {
	fprintf( stderr, "CryptExportPublicKeyInfo() [1] failed: 0x%x\n", GetLastError() );
	return( 0 );
    }

    if ( length > size )
    {
	fprintf( stderr, "CryptExportPublicKeyInfo() requires %d bytes\n", length );
	return( 0 );
    }

    length = size;

    if ( ! CryptExportPublicKeyInfo( provider, AT_KEYEXCHANGE, 
				     X509_ASN_ENCODING, keyInfo, &length ) )
    {
	fprintf( stderr, "CryptExportPublicKeyInfo() [2] failed: 0x%x\n", GetLastError() );
	return( 0 );
    }

    length = keyInfo->PublicKey.cbData;
    memmove( buffer, keyInfo->PublicKey.pbData, length );

    return( length );
}
Exemplo n.º 3
0
BOOL MSCAPI_Manager::BuildCertificateChain(HCRYPTPROV provider, OpString &label, OpString &shortname, SSL_ASN1Cert_list &cert)
{
	CERT_PUBLIC_KEY_INFO *pubkey = (CERT_PUBLIC_KEY_INFO *) g_memory_manager->GetTempBuf2k();
	DWORD len;

	label.Empty();
	shortname.Empty();
	cert.Resize(0);

	if(!hMYSystemStore)
		return FALSE;

	len = g_memory_manager->GetTempBuf2kLen();
	if(!CryptExportPublicKeyInfo(provider,  /*AT_SIGNATURE*/ AT_KEYEXCHANGE, (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING), pubkey, &len))
	{
		int err0 = GetLastError();
		op_memset(&pubkey, 0, sizeof(pubkey));
		len = g_memory_manager->GetTempBufLen();
		if(!CryptExportPublicKeyInfo(provider, /* AT_KEYEXCHANGE */ AT_SIGNATURE, (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING), pubkey, &len))
		{
			int err = GetLastError();
			return FALSE;
		}
	}
		
	PCCERT_CONTEXT cert_item = NULL;
	
	cert_item = CertFindCertificateInStore(hMYSystemStore, (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING), 0, CERT_FIND_PUBLIC_KEY, pubkey, cert_item);
	if(!cert_item && hUserDSSystemStore)
		cert_item = CertFindCertificateInStore(hUserDSSystemStore, (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING), 0, CERT_FIND_PUBLIC_KEY, pubkey, cert_item);

	if(!cert_item)
		return FALSE;

	
	len = CertNameToStr((X509_ASN_ENCODING | PKCS_7_ASN_ENCODING), 
		&cert_item->pCertInfo->Subject, CERT_SIMPLE_NAME_STR, NULL, 0);
	

	if(len)
	{
		if(shortname.Reserve(len+1) == NULL)
			return OpStatus::ERR_NO_MEMORY;
		
		len = CertNameToStr((X509_ASN_ENCODING | PKCS_7_ASN_ENCODING), 
			&cert_item->pCertInfo->Subject, CERT_SIMPLE_NAME_STR, shortname.DataPtr(), shortname.Capacity());
	}
	
	cert.Resize(1);
	if(cert.Error())
		return FALSE();
	
	cert[0].Set(cert_item->pbCertEncoded, cert_item->cbCertEncoded);
	
	if(cert.Error() || cert[0].GetLength() == 0)
		return FALSE;

	return TRUE;
}
Exemplo n.º 4
0
/**
 *
 * save public or private key to PEM format
 *
 * ofile   : name of file to write PEM encoded key
 * pemType : type of key being saved
 * rsa     : RSA object with public and private keys
 *
 */
int rsa_write_key(RSA* rsa,
                  const char* ofile, int pemType)
{
    DWORD  pkiLen, derLen;
    LPVOID pki, derData;
    BOOL   ok = FALSE;

    // public key?
    if (pemType == RSA_PUBLIC_KEY) {
        // get size of public key info
        if (CryptExportPublicKeyInfo(rsa->prov, AT_KEYEXCHANGE,
                                     X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                                     NULL, &pkiLen)) {
            // allocate memory
            pki = xmalloc(pkiLen);

            // export public key info
            if (CryptExportPublicKeyInfo(rsa->prov, AT_KEYEXCHANGE,
                                         X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                                         pki, &pkiLen)) {
                // get size of DER encoding
                if (CryptEncodeObjectEx(
                        X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                        X509_PUBLIC_KEY_INFO, pki, 0,
                        NULL, NULL, &derLen)) {
                    derData = xmalloc(derLen);
                    // convert to DER format
                    ok = CryptEncodeObjectEx(
                             X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                             X509_PUBLIC_KEY_INFO, pki, 0,
                             NULL, derData, &derLen);

                    // write to PEM file
                    if (ok) {
                        rsa_write_pem(RSA_PUBLIC_KEY, derData, derLen, ofile);
                        xfree(derData);
                    }
                }
            }
        }
    } else {
        // get length of PKCS#8 encoding
        if (CryptExportPKCS8(rsa->prov, AT_KEYEXCHANGE,
                             szOID_RSA_RSA, 0, NULL, NULL, &pkiLen)) {
            pki = xmalloc(pkiLen);

            if (pki != NULL) {
                // export the private key
                ok = CryptExportPKCS8(rsa->prov, AT_KEYEXCHANGE,
                                      szOID_RSA_RSA, 0x8000, NULL,
                                      pki, &pkiLen);

                // write key to PEM file
                if (ok) {
                    rsa_write_pem(RSA_PRIVATE_KEY, pki, pkiLen, ofile);
                }

                xfree(pki);
            }
        }
    }

    return ok;
}