PCCERT_CONTEXT SSL_SOCKET :: CreateOurCertificate() { // CertCreateSelfSignCertificate(0,&SubjectName,0,0,0,0,0,0); HRESULT hr = 0; HCRYPTPROV hProv = NULL; PCCERT_CONTEXT p = 0; HCRYPTKEY hKey = 0; CERT_NAME_BLOB sib = { 0 }; BOOL AX = 0; // Step by step to create our own certificate try { // Create the subject char cb[1000] = {0}; sib.pbData = (BYTE*)cb; sib.cbData = 1000; wchar_t* szSubject= L"CN=Certificate"; if (!CertStrToName(CRYPT_ASN_ENCODING, szSubject,0,0,sib.pbData,&sib.cbData,NULL)) throw; // Acquire Context wchar_t* pszKeyContainerName = L"Container"; if (!CryptAcquireContext(&hProv,pszKeyContainerName,MS_DEF_PROV,PROV_RSA_FULL,CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET)) { hr = GetLastError(); if (GetLastError() == NTE_EXISTS) { if (!CryptAcquireContext(&hProv,pszKeyContainerName,MS_DEF_PROV,PROV_RSA_FULL,CRYPT_MACHINE_KEYSET)) { throw; } } else throw; } // Generate KeyPair if (!CryptGenKey(hProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hKey)) throw; // Generate the certificate CRYPT_KEY_PROV_INFO kpi = {0}; kpi.pwszContainerName = pszKeyContainerName; kpi.pwszProvName = MS_DEF_PROV; kpi.dwProvType = PROV_RSA_FULL; kpi.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID; kpi.dwKeySpec = AT_KEYEXCHANGE; SYSTEMTIME et; GetSystemTime(&et); et.wYear += 1; CERT_EXTENSIONS exts = {0}; p = CertCreateSelfSignCertificate(hProv,&sib,0,&kpi,NULL,NULL,&et,&exts); AX = CryptFindCertificateKeyProvInfo(p,CRYPT_FIND_MACHINE_KEYSET_FLAG,NULL) ; /* hCS = CertOpenStore(CERT_STORE_PROV_MEMORY,0,0,CERT_STORE_CREATE_NEW_FLAG,0); AX = CertAddCertificateContextToStore(hCS,p,CERT_STORE_ADD_NEW,0); AX = CryptFindCertificateKeyProvInfo(p,CRYPT_FIND_MACHINE_KEYSET_FLAG,NULL);*/ } catch(...) { } if (hKey) CryptDestroyKey(hKey); hKey = 0; if (hProv) CryptReleaseContext(hProv,0); hProv = 0; return p; }
/* * '_sspiGetCredentials()' - Retrieve an SSL/TLS certificate from the system store * If one cannot be found, one is created. */ BOOL /* O - 1 on success, 0 on failure */ _sspiGetCredentials(_sspi_struct_t *conn, /* I - Client connection */ const LPWSTR container, /* I - Cert container name */ const TCHAR *cn, /* I - Common name of certificate */ BOOL isServer) /* I - Is caller a server? */ { HCERTSTORE store = NULL; /* Certificate store */ PCCERT_CONTEXT storedContext = NULL; /* Context created from the store */ PCCERT_CONTEXT createdContext = NULL; /* Context created by us */ DWORD dwSize = 0; /* 32 bit size */ PBYTE p = NULL; /* Temporary storage */ HCRYPTPROV hProv = (HCRYPTPROV) NULL; /* Handle to a CSP */ CERT_NAME_BLOB sib; /* Arbitrary array of bytes */ SCHANNEL_CRED SchannelCred; /* Schannel credential data */ TimeStamp tsExpiry; /* Time stamp */ SECURITY_STATUS Status; /* Status */ HCRYPTKEY hKey = (HCRYPTKEY) NULL; /* Handle to crypto key */ CRYPT_KEY_PROV_INFO kpi; /* Key container info */ SYSTEMTIME et; /* System time */ CERT_EXTENSIONS exts; /* Array of cert extensions */ CRYPT_KEY_PROV_INFO ckp; /* Handle to crypto key */ BOOL ok = TRUE; /* Return value */ DEBUG_printf(("_sspiGetCredentials(conn=%p, container=%p, cn=\"%s\", isServer=%d)", conn, container, cn, isServer)); if (!conn) return (FALSE); if (!cn) return (FALSE); if (!CryptAcquireContextW(&hProv, (LPWSTR) container, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET)) { if (GetLastError() == NTE_EXISTS) { if (!CryptAcquireContextW(&hProv, (LPWSTR) container, MS_DEF_PROV_W, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET)) { DEBUG_printf(("_sspiGetCredentials: CryptAcquireContext failed: %x\n", GetLastError())); ok = FALSE; goto cleanup; } } } store = CertOpenStore(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, hProv, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_NO_CRYPT_RELEASE_FLAG | CERT_STORE_OPEN_EXISTING_FLAG, L"MY"); if (!store) { DEBUG_printf(("_sspiGetCredentials: CertOpenSystemStore failed: %x\n", GetLastError())); ok = FALSE; goto cleanup; } dwSize = 0; if (!CertStrToName(X509_ASN_ENCODING, cn, CERT_OID_NAME_STR, NULL, NULL, &dwSize, NULL)) { DEBUG_printf(("_sspiGetCredentials: CertStrToName failed: %x\n", GetLastError())); ok = FALSE; goto cleanup; } p = (PBYTE) malloc(dwSize); if (!p) { DEBUG_printf(("_sspiGetCredentials: malloc failed for %d bytes", dwSize)); ok = FALSE; goto cleanup; } if (!CertStrToName(X509_ASN_ENCODING, cn, CERT_OID_NAME_STR, NULL, p, &dwSize, NULL)) { DEBUG_printf(("_sspiGetCredentials: CertStrToName failed: %x", GetLastError())); ok = FALSE; goto cleanup; } sib.cbData = dwSize; sib.pbData = p; storedContext = CertFindCertificateInStore(store, X509_ASN_ENCODING|PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, &sib, NULL); if (!storedContext) { /* * If we couldn't find the context, then we'll * create a new one */ if (!CryptGenKey(hProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hKey)) { DEBUG_printf(("_sspiGetCredentials: CryptGenKey failed: %x", GetLastError())); ok = FALSE; goto cleanup; } ZeroMemory(&kpi, sizeof(kpi)); kpi.pwszContainerName = (LPWSTR) container; kpi.pwszProvName = MS_DEF_PROV_W; kpi.dwProvType = PROV_RSA_FULL; kpi.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID; kpi.dwKeySpec = AT_KEYEXCHANGE; GetSystemTime(&et); et.wYear += 10; ZeroMemory(&exts, sizeof(exts)); createdContext = CertCreateSelfSignCertificate(hProv, &sib, 0, &kpi, NULL, NULL, &et, &exts); if (!createdContext) { DEBUG_printf(("_sspiGetCredentials: CertCreateSelfSignCertificate failed: %x", GetLastError())); ok = FALSE; goto cleanup; } if (!CertAddCertificateContextToStore(store, createdContext, CERT_STORE_ADD_REPLACE_EXISTING, &storedContext)) { DEBUG_printf(("_sspiGetCredentials: CertAddCertificateContextToStore failed: %x", GetLastError())); ok = FALSE; goto cleanup; } ZeroMemory(&ckp, sizeof(ckp)); ckp.pwszContainerName = (LPWSTR) container; ckp.pwszProvName = MS_DEF_PROV_W; ckp.dwProvType = PROV_RSA_FULL; ckp.dwFlags = CRYPT_MACHINE_KEYSET; ckp.dwKeySpec = AT_KEYEXCHANGE; if (!CertSetCertificateContextProperty(storedContext, CERT_KEY_PROV_INFO_PROP_ID, 0, &ckp)) { DEBUG_printf(("_sspiGetCredentials: CertSetCertificateContextProperty failed: %x", GetLastError())); ok = FALSE; goto cleanup; } } ZeroMemory(&SchannelCred, sizeof(SchannelCred)); SchannelCred.dwVersion = SCHANNEL_CRED_VERSION; SchannelCred.cCreds = 1; SchannelCred.paCred = &storedContext; /* * SSPI doesn't seem to like it if grbitEnabledProtocols * is set for a client */ if (isServer) SchannelCred.grbitEnabledProtocols = SP_PROT_SSL3TLS1; /* * Create an SSPI credential. */ Status = AcquireCredentialsHandle(NULL, UNISP_NAME, isServer ? SECPKG_CRED_INBOUND:SECPKG_CRED_OUTBOUND, NULL, &SchannelCred, NULL, NULL, &conn->creds, &tsExpiry); if (Status != SEC_E_OK) { DEBUG_printf(("_sspiGetCredentials: AcquireCredentialsHandle failed: %x", Status)); ok = FALSE; goto cleanup; } cleanup: /* * Cleanup */ if (hKey) CryptDestroyKey(hKey); if (createdContext) CertFreeCertificateContext(createdContext); if (storedContext) CertFreeCertificateContext(storedContext); if (p) free(p); if (store) CertCloseStore(store, 0); if (hProv) CryptReleaseContext(hProv, 0); return (ok); }
::PCCERT_CONTEXT acquire () { HRESULT hr = 0; HCRYPTPROV hProv = NULL; PCCERT_CONTEXT p = 0; HCRYPTKEY hKey = 0; CERT_NAME_BLOB sib = { 0 }; BOOL AX = 0; try { char cb[1000] = {0}; sib.pbData = (BYTE*)cb; sib.cbData = 1000; wchar_t* szSubject= L"CN=Certificate"; if (!CertStrToNameW(CRYPT_ASN_ENCODING, szSubject,0,0,sib.pbData,&sib.cbData,NULL)) throw; wchar_t* pszKeyContainerName = L"Container"; if (!CryptAcquireContextW(&hProv,pszKeyContainerName,MS_DEF_PROV_W,PROV_RSA_FULL,CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET)) { hr = GetLastError(); if (GetLastError() == NTE_EXISTS) { if (!CryptAcquireContextW(&hProv,pszKeyContainerName,MS_DEF_PROV_W,PROV_RSA_FULL,CRYPT_MACHINE_KEYSET)) { throw; } } else throw; } if (!CryptGenKey(hProv, AT_KEYEXCHANGE, CRYPT_EXPORTABLE, &hKey)) throw; CRYPT_KEY_PROV_INFO kpi = {0}; kpi.pwszContainerName = pszKeyContainerName; kpi.pwszProvName = MS_DEF_PROV_W; kpi.dwProvType = PROV_RSA_FULL; kpi.dwFlags = CERT_SET_KEY_CONTEXT_PROP_ID; kpi.dwKeySpec = AT_KEYEXCHANGE; SYSTEMTIME et; GetSystemTime(&et); et.wYear += 1; CERT_EXTENSIONS exts = {0}; p = CertCreateSelfSignCertificate(hProv,&sib,0,&kpi,NULL,NULL,&et,&exts); AX = CryptFindCertificateKeyProvInfo(p,CRYPT_FIND_MACHINE_KEYSET_FLAG,NULL) ; } catch(...) { } // cleanup. if (hKey) CryptDestroyKey(hKey); hKey = 0; if (hProv) CryptReleaseContext(hProv,0); hProv = 0; // return certificate. return (p); }