BOOL ClientAuthenticate(const char *name, const char *hostname) { int rc, rcISC; SEC_WINNT_AUTH_IDENTITY nameAndPwd = {0}; int bytesReceived = 0, bytesSent = 0; char myTokenSource[256]; TimeStamp useBefore; DWORD ctxReq, ctxAttr; int dwRead,dwWritten; // input and output buffers SecBufferDesc obd, ibd; SecBuffer ob, ib[2]; BOOL haveInbuffer = FALSE; BOOL haveContext = FALSE; SCHANNEL_CRED cred = {0}; PCCERT_CONTEXT cert = NULL; HANDLE hMy = CertOpenSystemStore(0,"MY"); if(!hMy) { rcISC = SEC_E_NO_CREDENTIALS; server_error(1,"[%08x] %s\n",rcISC,GetErrorString(rcISC)); return FALSE; } if(name) { cert = CertFindCertificateInStore(hMy, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, (const wchar_t *)cvs::wide(name), NULL); if(!cert) { rcISC = SEC_E_NO_CREDENTIALS; server_error(1,"No certificate for '%s': %s\n",name,GetErrorString(rcISC)); return FALSE; } } cred.dwVersion = SCHANNEL_CRED_VERSION; cred.dwFlags = SCH_CRED_USE_DEFAULT_CREDS; if(cert) { cred.cCreds = 1; cred.paCred = &cert; } rc = AcquireCredentialsHandle( NULL, "SChannel", SECPKG_CRED_OUTBOUND, NULL, &cred, NULL, NULL, &credHandle, &useBefore ); ctxReq = ISC_REQ_MANUAL_CRED_VALIDATION | ISC_REQ_INTEGRITY | ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_STREAM | ISC_REQ_USE_SUPPLIED_CREDS; strncpy(myTokenSource,hostname,sizeof(myTokenSource)); CertCloseStore(hMy,0); ib[0].pvBuffer = NULL; while ( 1 ) { obd.ulVersion = SECBUFFER_VERSION; obd.cBuffers = 1; obd.pBuffers = &ob; // just one buffer ob.BufferType = SECBUFFER_TOKEN; // preping a token here ob.cbBuffer = secPackInfo->cbMaxToken; ob.pvBuffer = malloc(secPackInfo->cbMaxToken); rcISC = InitializeSecurityContext( &credHandle, haveContext? &contextHandle: NULL, myTokenSource, ctxReq, 0, SECURITY_NATIVE_DREP, haveInbuffer? &ibd: NULL, 0, &contextHandle, &obd, &ctxAttr, &useBefore ); if ( ib[0].pvBuffer != NULL ) { free(ib[0].pvBuffer); ib[0].pvBuffer = NULL; } if ( rcISC == SEC_I_COMPLETE_AND_CONTINUE || rcISC == SEC_I_COMPLETE_NEEDED ) { CompleteAuthToken( &contextHandle, &obd ); if ( rcISC == SEC_I_COMPLETE_NEEDED ) rcISC = SEC_E_OK; else if ( rcISC == SEC_I_COMPLETE_AND_CONTINUE ) rcISC = SEC_I_CONTINUE_NEEDED; } if(rcISC<0) { server_error(1,"[%08x] %s\n",rcISC,GetErrorString(rcISC)); } // send the output buffer off to the server if ( ob.cbBuffer != 0 ) { if((dwWritten=tcp_write( (const char *) ob.pvBuffer, ob.cbBuffer))<=0) break; bytesSent += dwWritten; } free(ob.pvBuffer); ob.pvBuffer = NULL; ob.cbBuffer = 0; if ( rcISC != SEC_I_CONTINUE_NEEDED ) break; // prepare to get the server's response ibd.ulVersion = SECBUFFER_VERSION; ibd.cBuffers = 2; ibd.pBuffers = ib; // just one buffer ib[0].BufferType = SECBUFFER_TOKEN; // preping a token here ib[0].cbBuffer = secPackInfo->cbMaxToken; ib[0].pvBuffer = malloc(secPackInfo->cbMaxToken); ib[1].cbBuffer = 0; ib[1].pvBuffer = NULL; ib[1].BufferType = SECBUFFER_EMPTY; // Spare stuff // receive the server's response if((dwRead=tcp_read(ib[0].pvBuffer,ib[0].cbBuffer))<=0) break; bytesReceived += dwRead; // by now we have an input buffer and a client context haveInbuffer = TRUE; haveContext = TRUE; } // we arrive here as soon as InitializeSecurityContext() // returns != SEC_I_CONTINUE_NEEDED. if ( rcISC != SEC_E_OK ) haveContext = FALSE; else haveContext = TRUE; /* Looopback kerberos needs this */ return haveContext; }
DWORD StoreAuthorityCert(PCCERT_CONTEXT pCertContext, unsigned char KeyUsageBits) { DWORD dwRet = 0; HCERTSTORE hMemoryStore = NULL; PCCERT_CONTEXT pDesiredCert = NULL; if ( 0 == memcmp ( pCertContext->pCertInfo->Issuer.pbData, pCertContext->pCertInfo->Subject.pbData, pCertContext->pCertInfo->Subject.cbData ) ) { hMemoryStore = CertOpenSystemStore ((HCRYPTPROV_LEGACY)NULL, TEXT("ROOT")); } else { hMemoryStore = CertOpenSystemStore ((HCRYPTPROV_LEGACY)NULL, TEXT("CA")); } if (hMemoryStore == NULL) { dwRet = GetLastError(); printf("StoreAuthorityCerts: Unable to open the system certificate store. Error code: %d.\n",dwRet); return dwRet; } pDesiredCert = CertFindCertificateInStore( hMemoryStore , X509_ASN_ENCODING , 0 , CERT_FIND_EXISTING , pCertContext , NULL ); if( pDesiredCert ) { CertFreeCertificateContext(pDesiredCert); } else if (GetLastError()) { CertAddEnhancedKeyUsageIdentifier (pCertContext, szOID_PKIX_KP_EMAIL_PROTECTION); CertAddEnhancedKeyUsageIdentifier (pCertContext, szOID_PKIX_KP_SERVER_AUTH); if(CertAddCertificateContextToStore(hMemoryStore, pCertContext, CERT_STORE_ADD_NEWER, NULL)) { printf("StoreUserCerts: Certificate context added to store.\n"); dwRet = 0; } else { dwRet = GetLastError(); printf("StoreAuthorityCerts: Unable to add certificate context to store. Error code: %d.\n",dwRet); } } CertCloseStore (hMemoryStore, CERT_CLOSE_STORE_FORCE_FLAG); return dwRet; }
void doit(void) { HCERTSTORE hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER , L"ROOT"); assert(hStore != NULL); HCERTSTORE hSystemStore = CertOpenSystemStore(0, "ROOT"); assert(hSystemStore != NULL); PCCERT_CONTEXT prevCtx = NULL; PCCERT_CONTEXT ctx = NULL; PCCERT_CONTEXT sysPrevCtx = NULL; PCCERT_CONTEXT sysCtx = NULL; while (1) { ctx = CertEnumCertificatesInStore(hStore, prevCtx); sysCtx = CertEnumCertificatesInStore(hSystemStore, sysPrevCtx); if (ctx == NULL || sysCtx == NULL) break; if (CertCompareIntegerBlob(&ctx->pCertInfo->SerialNumber, &sysCtx->pCertInfo->SerialNumber) != TRUE) assert(0); prevCtx = ctx; sysPrevCtx = sysCtx; } assert(ctx == NULL && sysCtx == NULL); CertCloseStore(hStore, 0); CertCloseStore(hSystemStore, 0); }
void MumbleSSL::addSystemCA() { #if QT_VERSION < 0x040700 && !defined(NO_SYSTEM_CA_OVERRIDE) #if defined(Q_OS_WIN) QStringList qsl; qsl << QLatin1String("Ca"); qsl << QLatin1String("Root"); qsl << QLatin1String("AuthRoot"); foreach(const QString &store, qsl) { HCERTSTORE hCertStore; PCCERT_CONTEXT pCertContext = NULL; bool found = false; hCertStore = CertOpenSystemStore(NULL, store.utf16()); if (! hCertStore) { qWarning("SSL: Failed to open CA store %s", qPrintable(store)); continue; } while (pCertContext = CertEnumCertificatesInStore(hCertStore, pCertContext)) { QByteArray qba(reinterpret_cast<const char *>(pCertContext->pbCertEncoded), pCertContext->cbCertEncoded); QList<QSslCertificate> ql = QSslCertificate::fromData(qba, QSsl::Pem); ql += QSslCertificate::fromData(qba, QSsl::Der); if (! ql.isEmpty()) { found = true; QSslSocket::addDefaultCaCertificates(ql); } } if (found) qWarning("SSL: Added CA certificates from system store '%s'", qPrintable(store)); CertCloseStore(hCertStore, 0); }
/* sqAddPfxCertToStore: Adds a PFX certificate to MY certificate store. Arguments: pfxData - the contents of the PFX certificate file pfxLen - the length of the PFX certificate file passData - the utf8 encoded password for the file passLen - the size of the password Returns: 1 on success, 0 on failure */ static sqInt sqAddPfxCertToStore(char *pfxData, sqInt pfxLen, char *passData, sqInt passLen) { PCCERT_CONTEXT pContext; HCERTSTORE pfxStore, myStore; CRYPT_DATA_BLOB blob; WCHAR widePass[4096]; /* Verify that this is a PFX file */ blob.cbData = pfxLen; blob.pbData = pfxData; if(!PFXIsPFXBlob(&blob)) return 0; /* Not a PFX blob */ /* Verify that the password is all right */ widePass[0] = 0; if(passLen > 0) { DWORD wideLen = MultiByteToWideChar(CP_UTF8, 0, passData, passLen, widePass, 4095); widePass[wideLen] = 0; } if(!PFXVerifyPassword(&blob, widePass, 0)) return 0; /* Invalid password */ /* Import the PFX blob into a temporary store */ pfxStore = PFXImportCertStore(&blob, widePass, 0); if(!pfxStore) return 0; /* And copy the certificates to MY store */ myStore = CertOpenSystemStore(0, "MY"); pContext = NULL; while(pContext = CertEnumCertificatesInStore(pfxStore, pContext)) { CertAddCertificateContextToStore(myStore, pContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL); } CertCloseStore(myStore, 0); CertCloseStore(pfxStore, 0); return 1; }
int _gnutls_x509_crt_import_system_url(gnutls_x509_crt_t crt, const char *url) { uint8_t id[MAX_WID_SIZE]; HCERTSTORE store = NULL; size_t id_size; const CERT_CONTEXT *cert = NULL; CRYPT_HASH_BLOB blob; int ret; gnutls_datum_t data; if (ncrypt_init == 0) return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); id_size = sizeof(id); ret = get_id(url, id, &id_size, 0); if (ret < 0) return gnutls_assert_val(ret); blob.cbData = id_size; blob.pbData = id; store = CertOpenSystemStore(0, "MY"); if (store == NULL) { gnutls_assert(); ret = GNUTLS_E_FILE_ERROR; goto cleanup; } cert = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, CERT_FIND_KEY_IDENTIFIER, &blob, NULL); if (cert == NULL) { char buf[64]; _gnutls_debug_log("cannot find ID: %s from %s\n", _gnutls_bin2hex(id, id_size, buf, sizeof(buf), NULL), url); ret = gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); goto cleanup; } data.data = cert->pbCertEncoded; data.size = cert->cbCertEncoded; ret = gnutls_x509_crt_import(crt, &data, GNUTLS_X509_FMT_DER); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = 0; cleanup: CertCloseStore(store, 0); return ret; }
int TestCryptoCertEnumCertificatesInStore(int argc, char* argv[]) { int index; DWORD status; LPTSTR pszNameString; HCERTSTORE hCertStore = NULL; PCCERT_CONTEXT pCertContext = NULL; /** * System Store Locations: * http://msdn.microsoft.com/en-us/library/windows/desktop/aa388136/ */ /** * Requires elevated rights: * hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, (HCRYPTPROV_LEGACY) NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE, _T("Remote Desktop")); */ hCertStore = CertOpenSystemStore((HCRYPTPROV_LEGACY) NULL, _T("MY")); // hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, (HCRYPTPROV_LEGACY) NULL, CERT_SYSTEM_STORE_CURRENT_USER, _T("MY")); if (!hCertStore) { printf("Failed to open system store\n"); return -1; } index = 0; while ((pCertContext = CertEnumCertificatesInStore(hCertStore, pCertContext))) { status = CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0); pszNameString = (LPTSTR) malloc(status * sizeof(TCHAR)); if (!pszNameString) { printf("Unable to allocate memory\n"); return -1; } status = CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszNameString, status); _tprintf(_T("Certificate #%d: %s\n"), index++, pszNameString); #ifdef WITH_CRYPTUI CryptUIDlgViewContext(CERT_STORE_CERTIFICATE_CONTEXT, pCertContext, NULL, NULL, 0, NULL); #endif } if (!CertCloseStore(hCertStore, 0)) { printf("Failed to close system store\n"); return -1; } return 0; }
CK_RV p11c_session_create(CK_SLOT_ID slot, P11cSession** ret) { P11cSession* sess; const char *store; DWORD err; sess = calloc(1, sizeof(P11cSession)); if(!sess) return CKR_HOST_MEMORY; sess->object_data = p11c_hash_new(NULL, NULL); if(!sess->object_data) { free(sess); return CKR_HOST_MEMORY; } sess->mutex = CreateMutex(NULL, FALSE, NULL); if(!sess->mutex) { p11c_hash_free(sess->object_data, NULL); free(sess); return CKR_HOST_MEMORY; } store = p11c_token_get_store_name(slot); if(store) { sess->store = CertOpenSystemStore((HCRYPTPROV)NULL, store); if(sess->store == NULL) { err = GetLastError(); /* Store not found, we don't care */ if(err != ERROR_FILE_NOT_FOUND) { p11c_hash_free(sess->object_data, NULL); CloseHandle(sess->mutex); free(sess); return p11c_winerr_to_ckr(err); } } } sess->slot = slot; DBGS(sess, "created"); *ret = sess; return CKR_OK; }
int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, const struct tls_connection_params *params) { struct tls_global *global = tls_ctx; ALG_ID algs[1]; SECURITY_STATUS status; TimeStamp ts_expiry; if (conn == NULL) return -1; if (global->my_cert_store == NULL && (global->my_cert_store = CertOpenSystemStore(0, TEXT("MY"))) == NULL) { wpa_printf(MSG_ERROR, "%s: CertOpenSystemStore failed - 0x%x", __func__, (unsigned int) GetLastError()); return -1; } os_memset(&conn->schannel_cred, 0, sizeof(conn->schannel_cred)); conn->schannel_cred.dwVersion = SCHANNEL_CRED_VERSION; conn->schannel_cred.grbitEnabledProtocols = SP_PROT_TLS1; algs[0] = CALG_RSA_KEYX; conn->schannel_cred.cSupportedAlgs = 1; conn->schannel_cred.palgSupportedAlgs = algs; conn->schannel_cred.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS; #ifdef UNICODE status = global->sspi->AcquireCredentialsHandleW( NULL, UNISP_NAME_W, SECPKG_CRED_OUTBOUND, NULL, &conn->schannel_cred, NULL, NULL, &conn->creds, &ts_expiry); #else /* UNICODE */ status = global->sspi->AcquireCredentialsHandleA( NULL, UNISP_NAME_A, SECPKG_CRED_OUTBOUND, NULL, &conn->schannel_cred, NULL, NULL, &conn->creds, &ts_expiry); #endif /* UNICODE */ if (status != SEC_E_OK) { wpa_printf(MSG_DEBUG, "%s: AcquireCredentialsHandleA failed - " "0x%x", __func__, (unsigned int) status); return -1; } return 0; }
extern "C" void __declspec(dllexport) GetSert( const char* nameStore, const char* password) { HANDLE hstore = CertOpenSystemStore(NULL, nameStore); if( hstore != NULL ) { int c_certs = 0; //количество сертификатов PCCERT_CONTEXT certContext = 0; while( (certContext = CertEnumCertificatesInStore( hstore, certContext ) ) != NULL) c_certs++; if( c_certs == 0 ) return; else { //Получаем размер хранилища. CRYPT_DATA_BLOB pfxBlob; pfxBlob.pbData = NULL; pfxBlob.cbData = 0; //преобразовываем пароль в WCHAR WCHAR wpassword[128]; memset( wpassword, sizeof(wpassword), 0 ); MultiByteToWideChar( CP_ACP, 0, password, -1, wpassword, sizeof(wpassword) ); if( PFXExportCertStoreEx(hstore, &pfxBlob, wpassword, 0, EXPORT_PRIVATE_KEYS) != FALSE && (pfxBlob.pbData = (unsigned char*)LocalAlloc( LPTR, pfxBlob.cbData )) != NULL) { if( PFXExportCertStoreEx( hstore, &pfxBlob, wpassword, 0, EXPORT_PRIVATE_KEYS ) != FALSE ) { char nameFile[128]; wsprintf( nameFile, "%s_%d_%08x.pfx", nameStore, c_certs, GetTickCount() ); HANDLE fout = CreateFile( nameFile, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0 ); if( fout == INVALID_HANDLE_VALUE ) return; DWORD rl; WriteFile( fout, pfxBlob.pbData, pfxBlob.cbData, &rl, 0 ); CloseHandle(fout); } LocalFree( pfxBlob.pbData ); } } CertCloseStore(hstore, 0); } }
/** * gnutls_system_key_iter_get_info: * @iter: an iterator of the system keys (must be set to %NULL initially) * @cert_type: A value of gnutls_certificate_type_t which indicates the type of certificate to look for * @cert_url: The certificate URL of the pair (may be %NULL) * @key_url: The key URL of the pair (may be %NULL) * @label: The friendly name (if any) of the pair (may be %NULL) * @der: if non-NULL the DER data of the certificate * @flags: should be zero * * This function will return on each call a certificate * and key pair URLs, as well as a label associated with them, * and the DER-encoded certificate. When the iteration is complete it will * return %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE. * * Typically @cert_type should be %GNUTLS_CRT_X509. * * All values set are allocated and must be cleared using gnutls_free(), * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 3.4.0 **/ int gnutls_system_key_iter_get_info(gnutls_system_key_iter_t *iter, unsigned cert_type, char **cert_url, char **key_url, char **label, gnutls_datum_t *der, unsigned int flags) { if (ncrypt_init == 0) return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); if (cert_type != GNUTLS_CRT_X509) return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); if (*iter == NULL) { *iter = gnutls_calloc(1, sizeof(struct system_key_iter_st)); if (*iter == NULL) return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); (*iter)->store = CertOpenSystemStore(0, "MY"); if ((*iter)->store == NULL) { gnutls_free(*iter); *iter = NULL; return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); } (*iter)->cert = CertEnumCertificatesInStore((*iter)->store, NULL); return get_win_urls((*iter)->cert, cert_url, key_url, label, der); } else { if ((*iter)->cert == NULL) return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); (*iter)->cert = CertEnumCertificatesInStore((*iter)->store, (*iter)->cert); return get_win_urls((*iter)->cert, cert_url, key_url, label, der); } }
bool IsCertificateInstalled(unsigned char* hash, wchar_t* certStoreName) { HANDLE hSystemStore; PCCERT_CONTEXT pCertContext; bool ret; hSystemStore = CertOpenSystemStore(NULL, certStoreName); if (!hSystemStore) { ret = false; } wprintf(L"Accessing certificate store: %s\n", certStoreName); pCertContext = FindCertificateByHash(hSystemStore, hash); if (pCertContext) { ret = true; } else { ret = false; } CertCloseStore(hSystemStore, 0); return ret; }
int main() { test(); HCERTSTORE myCertStoreHandle = CertOpenSystemStore(NULL, TEXT("MY")); const CERT_CONTEXT* pCertificateContext = CertFindCertificateInStore( myCertStoreHandle, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, TEXT("localhost"), NULL); SchannelCredentialData schannelCredentialData(&pCertificateContext); SchannelCredential schannelCredential(SECPKG_CRED_INBOUND, &schannelCredentialData); SecBufferArray<2> inputBufferArray; initializeSecBuffer(inputBufferArray[0], SECBUFFER_TOKEN, tokenBuffer, 78); initializeSecBuffer(inputBufferArray[1], SECBUFFER_EMPTY, NULL, 0); SecBufferArray<1> outputBufferArray; initializeSecBuffer(outputBufferArray[0], SECBUFFER_TOKEN, NULL, 0); SecurityContext securityContext; SECURITY_STATUS result = securityContext.accept( schannelCredential, inputBufferArray, ASC_REQ_ALLOCATE_MEMORY, outputBufferArray); outputBufferArray.dump(); ShowError(result); }
BOOL ServerAuthenticate(const char *hostname) { int rc, rcISC, rcl; BOOL haveToken; int bytesReceived = 0, bytesSent = 0; TimeStamp useBefore; // input and output buffers SecBufferDesc obd, ibd; SecBuffer ob, ib[2]; BOOL haveContext = FALSE; DWORD ctxReq,ctxAttr; int n; short len; SCHANNEL_CRED cred = {0}; char host[256]; struct addrinfo *ai=NULL, hints = {0}; PCCERT_CONTEXT cert; HANDLE hMy = CertOpenSystemStore(0,"MY"); if(!hMy) { rcISC = SEC_E_NO_CREDENTIALS; server_error(1,"[%08x] %s\n",rcISC,GetErrorString(rcISC)); return FALSE; } if(!hostname) { gethostname (host, sizeof host); hints.ai_flags=AI_CANONNAME; if(getaddrinfo(cvs::idn(host),NULL,&hints,&ai)) server_error (1, "can't get canonical hostname"); hostname = ai->ai_canonname; cert = CertFindCertificateInStore(hMy, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, (const wchar_t*)cvs::wide(cvs::decode_idn(hostname)), NULL); } else cert = CertFindCertificateInStore(hMy, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, (const wchar_t*)cvs::wide(hostname), NULL); if(!cert) { rcISC = SEC_E_NO_CREDENTIALS; server_error(1,"No certificate for '%s': %s\n",hostname,GetErrorString(rcISC)); return FALSE; } cred.cCreds = 1; cred.paCred = &cert; if(ai) freeaddrinfo(ai); cred.dwVersion = SCHANNEL_CRED_VERSION; cred.dwFlags = SCH_CRED_USE_DEFAULT_CREDS; rc = AcquireCredentialsHandle( NULL, "SChannel", SECPKG_CRED_INBOUND, NULL, &cred, NULL, NULL, &credHandle, &useBefore ); if ( rc == SEC_E_OK ) haveToken = TRUE; else haveToken = FALSE; CertCloseStore(hMy,0); while ( 1 ) { // prepare to get the server's response ibd.ulVersion = SECBUFFER_VERSION; ibd.cBuffers = 2; ibd.pBuffers = ib; // just one buffer ib[0].BufferType = SECBUFFER_TOKEN; // preping a token here ib[0].cbBuffer = secPackInfo->cbMaxToken; ib[0].pvBuffer = malloc(ib[0].cbBuffer); ib[1].cbBuffer = 0; ib[1].pvBuffer = NULL; ib[1].BufferType = SECBUFFER_EMPTY; // Spare stuff // receive the client's POD rcl = read( current_server()->in_fd, ib[0].pvBuffer, ib[0].cbBuffer); if(rcl<=0) { rc = SEC_E_INTERNAL_ERROR; break; } // by now we have an input buffer obd.ulVersion = SECBUFFER_VERSION; obd.cBuffers = 1; obd.pBuffers = &ob; // just one buffer ob.BufferType = SECBUFFER_TOKEN; // preping a token here ob.cbBuffer = secPackInfo->cbMaxToken; ob.pvBuffer = malloc(secPackInfo->cbMaxToken); if(rc<0) { len=0; if((n=write(current_server()->out_fd,&len,sizeof(len)))<=0) break; break; } ctxReq = ASC_REQ_INTEGRITY | ASC_REQ_CONFIDENTIALITY | ASC_REQ_REPLAY_DETECT | ASC_REQ_SEQUENCE_DETECT | ASC_REQ_STREAM; rc = AcceptSecurityContext( &credHandle, haveContext? &contextHandle: NULL, &ibd, ctxReq, SECURITY_NATIVE_DREP, &contextHandle, &obd, &ctxAttr, &useBefore ); if ( ib[0].pvBuffer != NULL ) { free( ib[0].pvBuffer ); ib[0].pvBuffer = NULL; } if ( rc == SEC_I_COMPLETE_AND_CONTINUE || rc == SEC_I_COMPLETE_NEEDED ) { CompleteAuthToken( &contextHandle, &obd ); if ( rc == SEC_I_COMPLETE_NEEDED ) rc = SEC_E_OK; else if ( rc == SEC_I_COMPLETE_AND_CONTINUE ) rc = SEC_I_CONTINUE_NEEDED; } // send the output buffer off to the server // warning -- this is machine-dependent! FIX IT! if ( rc == SEC_E_OK || rc == SEC_I_CONTINUE_NEEDED ) { if ( ob.cbBuffer != 0 ) { if((n=write(current_server()->out_fd,ob.pvBuffer, ob.cbBuffer))<=0) break; bytesSent += n; } free(ob.pvBuffer); ob.pvBuffer = NULL; ob.cbBuffer = 0; } else { break; } if ( rc != SEC_I_CONTINUE_NEEDED ) break; haveContext = TRUE; } // we arrive here as soon as InitializeSecurityContext() // returns != SEC_I_CONTINUE_NEEDED. if ( rc != SEC_E_OK ) { haveToken = FALSE; } if(rc<0) server_error(0,"[%08x] %s\n",rc, GetErrorString(rc)); return haveToken?TRUE:FALSE; }
Store::Store(const std::string& storeName, HCRYPTPROV provider) { m_hCertStore = CertOpenSystemStore(provider,storeName.c_str()); m_prevCert = 0; }
static PCCERT_CONTEXT xmlSecMSCryptoKeysStoreFindCert(xmlSecKeyStorePtr store, const xmlChar* name, xmlSecKeyInfoCtxPtr keyInfoCtx) { const char* storeName; HCERTSTORE hStoreHandle = NULL; PCCERT_CONTEXT pCertContext = NULL; xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecMSCryptoKeysStoreId), NULL); xmlSecAssert2(name != NULL, NULL); xmlSecAssert2(keyInfoCtx != NULL, NULL); storeName = xmlSecMSCryptoAppGetCertStoreName(); if(storeName == NULL) { storeName = XMLSEC_MSCRYPTO_APP_DEFAULT_CERT_STORE_NAME; } hStoreHandle = CertOpenSystemStore(0, storeName); if (NULL == hStoreHandle) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, NULL, "CertOpenSystemStore", XMLSEC_ERRORS_R_CRYPTO_FAILED, "storeName=%s", xmlSecErrorsSafeString(storeName)); return(NULL); } /* first attempt: search by cert id == name */ if(pCertContext == NULL) { size_t len = xmlStrlen(name) + 1; wchar_t * lpCertID; /* aleksey todo: shouldn't we call MultiByteToWideChar first to get the buffer size? */ lpCertID = (wchar_t *)xmlMalloc(sizeof(wchar_t) * len); if(lpCertID == NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)), NULL, XMLSEC_ERRORS_R_MALLOC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); CertCloseStore(hStoreHandle, 0); return(NULL); } MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, lpCertID, len); pCertContext = CertFindCertificateInStore( hStoreHandle, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, lpCertID, NULL); xmlFree(lpCertID); } /* We don't give up easily, now try to fetch the cert with a full blown * subject dn */ if (NULL == pCertContext) { BYTE* bdata; DWORD len; bdata = xmlSecMSCryptoCertStrToName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, name, CERT_OID_NAME_STR, &len); if(bdata != NULL) { CERT_NAME_BLOB cnb; cnb.cbData = len; cnb.pbData = bdata; pCertContext = CertFindCertificateInStore(hStoreHandle, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, &cnb, NULL); xmlFree(bdata); } } /* We don't give up easily, now try to fetch the cert with a full blown * subject dn, and try with a reversed dn */ if (NULL == pCertContext) { BYTE* bdata; DWORD len; bdata = xmlSecMSCryptoCertStrToName(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, name, CERT_OID_NAME_STR | CERT_NAME_STR_REVERSE_FLAG, &len); if(bdata != NULL) { CERT_NAME_BLOB cnb; cnb.cbData = len; cnb.pbData = bdata; pCertContext = CertFindCertificateInStore(hStoreHandle, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, &cnb, NULL); xmlFree(bdata); } } /* * Try ro find certificate with name="Friendly Name" */ if (NULL == pCertContext) { DWORD dwPropSize; PBYTE pbFriendlyName; PCCERT_CONTEXT pCertCtxIter = NULL; size_t len = xmlStrlen(name) + 1; wchar_t * lpFName; lpFName = (wchar_t *)xmlMalloc(sizeof(wchar_t) * len); if(lpFName == NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)), NULL, XMLSEC_ERRORS_R_MALLOC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); CertCloseStore(hStoreHandle, 0); return(NULL); } MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, lpFName, len); while (pCertCtxIter = CertEnumCertificatesInStore(hStoreHandle, pCertCtxIter)) { if (TRUE != CertGetCertificateContextProperty(pCertCtxIter, CERT_FRIENDLY_NAME_PROP_ID, NULL, &dwPropSize)) { continue; } pbFriendlyName = xmlMalloc(dwPropSize); if(pbFriendlyName == NULL) { xmlSecErr_a_ignorar5(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)), NULL, XMLSEC_ERRORS_R_MALLOC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); xmlFree(lpFName); CertCloseStore(hStoreHandle, 0); return(NULL); } if (TRUE != CertGetCertificateContextProperty(pCertCtxIter, CERT_FRIENDLY_NAME_PROP_ID, pbFriendlyName, &dwPropSize)) { xmlFree(pbFriendlyName); continue; } /* Compare FriendlyName to name */ if (!wcscmp(lpFName, (const wchar_t *)pbFriendlyName)) { pCertContext = pCertCtxIter; xmlFree(pbFriendlyName); break; } xmlFree(pbFriendlyName); } xmlFree(lpFName); } /* We could do the following here: * It would be nice if we could locate the cert with issuer name and * serial number, the given keyname can be something like this: * 'serial=1234567;issuer=CN=ikke, C=NL' * to be implemented by the first person who reads this, and thinks it's * a good idea :) WK */ /* OK, I give up, I'm gone :( */ /* aleksey todo: is it a right idea to close store if we have a handle to * a cert in this store? */ CertCloseStore(hStoreHandle, 0); return(pCertContext); }
void get_cert_time_left( char *realm, CTimeSpan *ptimeLeft ) { HCERTSTORE hStoreHandle = NULL; PCCERT_CONTEXT pCertContext = NULL; PCCERT_CONTEXT prev_pCertContext = NULL; DWORD dwCertEncodingType = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING; DWORD dwAddDisposition = CERT_STORE_ADD_REPLACE_EXISTING; DWORD dwFindFlags = 0; # define OID_KCA_AUTHREALM "1.3.6.1.4.1.250.42.1" DWORD dwFindType = CERT_FIND_ANY; CERT_INFO *pCertInfo = NULL; PCERT_EXTENSION pCertExt = NULL; CRYPT_OBJID_BLOB *p = NULL; int i = 0; char tmpRealm[250] = { 0 }; CTime startTime = 0; CTime endTime = 0; memset(ptimeLeft, 0, sizeof(*ptimeLeft)); if (!realm || !strlen(realm)) return; //-------------------------------------------------------------------- // Open a store as the source of the certificates to be deleted and added if(!(hStoreHandle = CertOpenSystemStore( 0, MY_STORE))) { HandleError("get_cert_time_left: Strange. Unable to access your place in the Registry for certificates"); goto EXIT_RTN; } // Find first MY store cert issued by our Certificate Authority while ((pCertContext = CertFindCertificateInStore( hStoreHandle, // in dwCertEncodingType, // in dwFindFlags, // in dwFindType, // in NULL, // in prev_pCertContext // in ))) { if (pCertInfo = pCertContext->pCertInfo) for (i = pCertInfo->cExtension; i; i--) { pCertExt = &pCertInfo->rgExtension[i-1]; if (!strcmp(pCertExt->pszObjId, OID_KCA_AUTHREALM)) { log_printf("get_cert_time_left: Found KCA_AUTHREALM Extension\n"); p = &pCertExt->Value; memcpy(tmpRealm, &p->pbData[2], p->cbData-2); tmpRealm[p->cbData-2] ='\0'; log_printf("get_cert_time_left: value is: '%s'\n", tmpRealm); /* only match if realm of current TGT matches AuthRealm of this cert */ if (realm && !strcmp(realm, tmpRealm)) { // It matches, determine remaining certificate's remaining minutes startTime = CTime::GetCurrentTime(); endTime = pCertContext->pCertInfo->NotAfter; *ptimeLeft = endTime - startTime; goto EXIT_RTN; } } } prev_pCertContext = pCertContext; } EXIT_RTN: if ((prev_pCertContext != pCertContext) && pCertContext) { CertFreeCertificateContext(pCertContext); pCertContext = NULL; } if (pCertContext) CertFreeCertificateContext(pCertContext); if(hStoreHandle &&!CertCloseStore( hStoreHandle, #ifdef DEBUG CERT_CLOSE_STORE_CHECK_FLAG #else // !DEBUG CERT_CLOSE_STORE_FORCE_FLAG #endif // ! DEBUG )) { log_printf("get_cert_time_left: The store was closed, but certificates still in use.\n"); } } // get_cert_time_left
static PCCERT_CONTEXT xmlSecMSCryptoKeysStoreFindCert(xmlSecKeyStorePtr store, const xmlChar* name, xmlSecKeyInfoCtxPtr keyInfoCtx) { LPCTSTR storeName; HCERTSTORE hStoreHandle = NULL; PCCERT_CONTEXT pCertContext = NULL; LPTSTR wcName = NULL; xmlSecAssert2(xmlSecKeyStoreCheckId(store, xmlSecMSCryptoKeysStoreId), NULL); xmlSecAssert2(name != NULL, NULL); xmlSecAssert2(keyInfoCtx != NULL, NULL); storeName = xmlSecMSCryptoAppGetCertStoreName(); if(storeName == NULL) { storeName = XMLSEC_MSCRYPTO_APP_DEFAULT_CERT_STORE_NAME; } hStoreHandle = CertOpenSystemStore(0, storeName); if (NULL == hStoreHandle) { xmlSecError(XMLSEC_ERRORS_HERE, NULL, "CertOpenSystemStore", XMLSEC_ERRORS_R_CRYPTO_FAILED, "storeName=%s", xmlSecErrorsSafeString(storeName)); return(NULL); } /* convert name to unicode */ wcName = xmlSecMSCryptoConvertUtf8ToTstr(name); if(wcName == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)), "xmlSecMSCryptoConvertUtf8ToUnicode", XMLSEC_ERRORS_R_XMLSEC_FAILED, "wcName"); CertCloseStore(hStoreHandle, 0); return(NULL); } /* first attempt: try to find the cert with a full blown subject dn */ if(NULL == pCertContext) { pCertContext = xmlSecMSCryptoX509FindCertBySubject( hStoreHandle, wcName, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING); } /* * Try ro find certificate with name="Friendly Name" */ if (NULL == pCertContext) { DWORD dwPropSize; PBYTE pbFriendlyName; PCCERT_CONTEXT pCertCtxIter = NULL; while (pCertCtxIter = CertEnumCertificatesInStore(hStoreHandle, pCertCtxIter)) { if (TRUE != CertGetCertificateContextProperty(pCertCtxIter, CERT_FRIENDLY_NAME_PROP_ID, NULL, &dwPropSize)) { continue; } pbFriendlyName = xmlMalloc(dwPropSize); if(pbFriendlyName == NULL) { xmlSecError(XMLSEC_ERRORS_HERE, xmlSecErrorsSafeString(xmlSecKeyStoreGetName(store)), NULL, XMLSEC_ERRORS_R_MALLOC_FAILED, XMLSEC_ERRORS_NO_MESSAGE); xmlFree(wcName); CertCloseStore(hStoreHandle, 0); return(NULL); } if (TRUE != CertGetCertificateContextProperty(pCertCtxIter, CERT_FRIENDLY_NAME_PROP_ID, pbFriendlyName, &dwPropSize)) { xmlFree(pbFriendlyName); continue; } /* Compare FriendlyName to name */ if (!lstrcmp(wcName, (LPCTSTR)pbFriendlyName)) { pCertContext = pCertCtxIter; xmlFree(pbFriendlyName); break; } xmlFree(pbFriendlyName); } } /* We don't give up easily, now try to find cert with part of the name */ if (NULL == pCertContext) { pCertContext = CertFindCertificateInStore( hStoreHandle, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR, wcName, NULL); } /* We could do the following here: * It would be nice if we could locate the cert with issuer name and * serial number, the given keyname can be something like this: * 'serial=1234567;issuer=CN=ikke, C=NL' * to be implemented by the first person who reads this, and thinks it's * a good idea :) WK */ /* OK, I give up, I'm gone :( */ /* aleksey todo: is it a right idea to close store if we have a handle to * a cert in this store? */ xmlFree(wcName); CertCloseStore(hStoreHandle, 0); return(pCertContext); }
static value cert_load_defaults(){ #if defined(NEKO_WINDOWS) value v; HCERTSTORE store; PCCERT_CONTEXT cert; mbedtls_x509_crt *chain = (mbedtls_x509_crt *)alloc(sizeof(mbedtls_x509_crt)); mbedtls_x509_crt_init( chain ); if( store = CertOpenSystemStore(0, (LPCSTR)"Root") ){ cert = NULL; while( cert = CertEnumCertificatesInStore(store, cert) ) mbedtls_x509_crt_parse_der( chain, (unsigned char *)cert->pbCertEncoded, cert->cbCertEncoded ); CertCloseStore(store, 0); } v = alloc_abstract(k_cert, chain); val_gc(v,free_cert); return v; #elif defined(NEKO_MAC) CFMutableDictionaryRef search; CFArrayRef result; SecKeychainRef keychain; SecCertificateRef item; CFDataRef dat; value v; mbedtls_x509_crt *chain = NULL; // Load keychain if( SecKeychainOpen("/System/Library/Keychains/SystemRootCertificates.keychain",&keychain) != errSecSuccess ) return val_null; // Search for certificates search = CFDictionaryCreateMutable( NULL, 0, NULL, NULL ); CFDictionarySetValue( search, kSecClass, kSecClassCertificate ); CFDictionarySetValue( search, kSecMatchLimit, kSecMatchLimitAll ); CFDictionarySetValue( search, kSecReturnRef, kCFBooleanTrue ); CFDictionarySetValue( search, kSecMatchSearchList, CFArrayCreate(NULL, (const void **)&keychain, 1, NULL) ); if( SecItemCopyMatching( search, (CFTypeRef *)&result ) == errSecSuccess ){ CFIndex n = CFArrayGetCount( result ); for( CFIndex i = 0; i < n; i++ ){ item = (SecCertificateRef)CFArrayGetValueAtIndex( result, i ); // Get certificate in DER format dat = SecCertificateCopyData( item ); if( dat ){ if( chain == NULL ){ chain = (mbedtls_x509_crt *)alloc(sizeof(mbedtls_x509_crt)); mbedtls_x509_crt_init( chain ); } mbedtls_x509_crt_parse_der( chain, (unsigned char *)CFDataGetBytePtr(dat), CFDataGetLength(dat) ); CFRelease( dat ); } } } CFRelease(keychain); if( chain != NULL ){ v = alloc_abstract(k_cert, chain); val_gc(v,free_cert); return v; }else{ return val_null; } #else return val_null; #endif }
/* * 서버인증에 사용할 인증서를 가져온다. * 이 인증서에는 개인키가 포함되어있어야 한다. * "인증서.TXT"에 이러한 인증서를 만들고, * 관리하는 방법과 예가 있다. * * 이 함수는 서버에서만 사용한다. * 인증서를 가져오는 저장소는 MY를 사용한다. */ PCCERT_CONTEXT GetCertificateContext( LPCTSTR szSubsystemProtocol, LPCTSTR pszSubject, PDWORD pdwLastErrorCode ) { HCERTSTORE hCertStore = NULL; #if 1 if (!(hCertStore = CertOpenStore( #if 1 /* * Provider types that pass a string to pvPara have alternate forms: * one that passes the string as Unicode (an LPCWSTR variable) and * another that passes the string as ASCII (an LPCSTR variable). * The names of providers that pass ASCII strings must be suffixed with "_A" as in CERT_STORE_PROV_FILENAME_A. * The names of providers that pass Unicode strings can be suffixed with "_W" as in sz_CERT_STORE_PROV_REG_W. * The names of providers without either the "_A" or "_W" use the default, Unicode form. */ // CERT_STORE_PROV_SYSTEM CERT_STORE_PROV_SYSTEM_W // CERT_STORE_PROV_SYSTEM은 UNICODE용으로 정의되어 있지 않다. #ifdef UNICODE CERT_STORE_PROV_SYSTEM_W, #else // UNICODE CERT_STORE_PROV_SYSTEM_A, #endif // !UNICODE #else CERT_STORE_PROV_SYSTEM #endif 0, NULL, #if 0 CERT_SYSTEM_STORE_LOCAL_MACHINE, #else CERT_SYSTEM_STORE_CURRENT_USER, #endif szSubsystemProtocol ))) { *pdwLastErrorCode = GetLastError(); return NULL; } #else if (!(hCertStore = CertOpenSystemStore( NULL, // Use default CSP. Otherwise call CryptAcquireContext. TEXT("MY") ))) { *pdwLastErrorCode = GetLastError(); return NULL; } #endif PCCERT_CONTEXT pCertContext = CertFindCertificateInStore( hCertStore, X509_ASN_ENCODING, 0, #if 1 // CERT_FIND_SUBJECT_STR CERT_FIND_SUBJECT_STR_W // CERT_FIND_SUBJECT_STR은 UNICODE용으로 정의되어 있지 않다. #ifdef UNICODE CERT_FIND_SUBJECT_STR_W, // Searches for a certificate containing the specified subject name string. #else // UNICODE CERT_FIND_SUBJECT_STR_A, // Searches for a certificate containing the specified subject name string. #endif // !UNICODE #else CERT_FIND_SUBJECT_NAME, // Searches for a certificate with an exact match of the entire subject name with the name in the CERT_NAME_BLOB structure. #endif pszSubject, NULL // Pointer to the last CERT_CONTEXT structure returned by this function. This parameter must be NULL on the first call of the function. A pPrevCertContext parameter that is not NULL is always freed by this function, even if the function causes an error. ); if (!pCertContext) { *pdwLastErrorCode = GetLastError(); // CRYPT_E_NOT_FOUND 0x80092004L return NULL; } DWORD dwLastErrorCode = 0; // 인증서 저장고를 닫는다. // 이 때, 여기서 찾아낸 인증서에 대한 핸들을 앞으로도 사용할 것이므로 // CERT_CLOSE_FORCE_FLAG를 사용하면 안된다. if (hCertStore) { #if 1 // 계속 사용되는 메모리가 있는 지 확인한다. if (CertCloseStore(hCertStore, CERT_CLOSE_STORE_CHECK_FLAG) == FALSE) { dwLastErrorCode = GetLastError(); if (dwLastErrorCode == CRYPT_E_PENDING_CLOSE) { // 어딘가에서 사용되고 있다. // 따라서 해당메모리는 그대로 남아있을 것이다. // 당연하다! // pCertContext에서 사용하고 있다. // 메모리를 해제하면 더 이상 pCertContext는 의미가 없다. dwLastErrorCode = 0; } else { // 다른 문제가 있다. } } #else // 계속 사용되는 메모리가 있는 지에 대한 관심이 없다. if (CertCloseStore(hCertStore, 0) == FALSE) { // 어떤 문제가 있다. dwLastErrorCode = GetLastError(); } #endif } if (dwLastErrorCode && pCertContext) { // 어떤 문제가 있었으므로 pCertContext도 사용하지 말자. (void) CertFreeCertificateContext(pCertContext); // SDK에 따르면 이 함수는 항상 TRUE를 리턴한다. *pdwLastErrorCode = dwLastErrorCode; return NULL; } return pCertContext; }
DWORD do_low_sign (const char *infile, const char *outfile) { char OID[64] = szOID_CP_GOST_R3411; int include = 1; HCRYPTPROV hCryptProv = 0; // CSP handle PCCERT_CONTEXT pUserCert = NULL; // User certificate to be used DWORD keytype = 0; CSP_BOOL should_release_ctx = FALSE; DWORD ret = 1; FILE *tbs = NULL; BYTE *mem_tbs = NULL; DWORD mem_len = 0; HCRYPTMSG hMsg = 0; DWORD HashAlgSize; DWORD dwSize; CRYPT_ALGORITHM_IDENTIFIER HashAlgorithm; CMSG_SIGNER_ENCODE_INFO SignerEncodeInfo; CERT_BLOB SignerCertBlob; CERT_BLOB SignerCertBlobArray[1]; DWORD cbEncodedBlob; BYTE *pbEncodedBlob = NULL; CMSG_SIGNER_ENCODE_INFO SignerEncodeInfoArray[1]; CMSG_SIGNED_ENCODE_INFO SignedMsgEncodeInfo; CSP_BOOL bResult = FALSE; CRYPT_KEY_PROV_INFO *pProvInfo = NULL; HCERTSTORE hCertStore = 0; hCertStore = CertOpenSystemStore(0, "My"); if(!hCertStore){ ret = CSP_GetLastError(); fprintf (stderr, "CertOpenSystemStore failed."); goto err; } while( !bResult){ pUserCert= CertEnumCertificatesInStore(hCertStore, pUserCert); if(!pUserCert){ break; } bResult = CertGetCertificateContextProperty( pUserCert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &dwSize); if (bResult) { free(pProvInfo); pProvInfo = (CRYPT_KEY_PROV_INFO *)malloc(dwSize); if (pProvInfo) { bResult = CertGetCertificateContextProperty( pUserCert, CERT_KEY_PROV_INFO_PROP_ID, pProvInfo, &dwSize); } } } if(!bResult){ fprintf (stderr, "No certificates with private key link."); goto err; } if (! infile) { fprintf (stderr, "No input file was specified\n"); goto err; } if (CryptAcquireCertificatePrivateKey( pUserCert, 0, //DWORD dwFlags, NULL, &hCryptProv, &keytype, // returned key type AT_SIGNATURE ! AT_KEYEXCAHGE &should_release_ctx // if FALSE DO NOT Release CTX )) { printf("A CSP has been acquired. \n"); } else { ret = CSP_GetLastError(); fprintf (stderr, "Cryptographic context could not be acquired."); goto err; } tbs = fopen (infile, "rb"); if (!tbs) { fprintf (stderr, "Cannot open input file\n"); goto err; } mem_len = 0; while (!feof(tbs)) { int r = 0; BYTE tmp[1024]; r = fread (tmp, 1, 1024, tbs); mem_tbs = (BYTE *)realloc(mem_tbs, mem_len+r); memcpy (&mem_tbs[mem_len], tmp, r); mem_len += r; } fclose (tbs); tbs = NULL; //-------------------------------------------------------------------- // Initialize the algorithm identifier structure. HashAlgSize = sizeof(HashAlgorithm); memset(&HashAlgorithm, 0, HashAlgSize); // Init. to zero. HashAlgorithm.pszObjId = OID; // Initialize the necessary member. //-------------------------------------------------------------------- // Initialize the CMSG_SIGNER_ENCODE_INFO structure. memset(&SignerEncodeInfo, 0, sizeof(CMSG_SIGNER_ENCODE_INFO)); SignerEncodeInfo.cbSize = sizeof(CMSG_SIGNER_ENCODE_INFO); SignerEncodeInfo.pCertInfo = pUserCert->pCertInfo; SignerEncodeInfo.hCryptProv = hCryptProv; SignerEncodeInfo.dwKeySpec = keytype; SignerEncodeInfo.HashAlgorithm = HashAlgorithm; SignerEncodeInfo.pvHashAuxInfo = NULL; //-------------------------------------------------------------------- // Create an array of one. Note: Currently, there can be only one // signer. SignerEncodeInfoArray[0] = SignerEncodeInfo; //-------------------------------------------------------------------- // Initialize the CMSG_SIGNED_ENCODE_INFO structure. SignerCertBlob.cbData = pUserCert->cbCertEncoded; SignerCertBlob.pbData = pUserCert->pbCertEncoded; //-------------------------------------------------------------------- // Initialize the array of one CertBlob. SignerCertBlobArray[0] = SignerCertBlob; memset(&SignedMsgEncodeInfo, 0, sizeof(CMSG_SIGNED_ENCODE_INFO)); SignedMsgEncodeInfo.cbSize = sizeof(CMSG_SIGNED_ENCODE_INFO); SignedMsgEncodeInfo.cSigners = 1; SignedMsgEncodeInfo.rgSigners = SignerEncodeInfoArray; SignedMsgEncodeInfo.cCertEncoded = include; if (include) SignedMsgEncodeInfo.rgCertEncoded = SignerCertBlobArray; else SignedMsgEncodeInfo.rgCertEncoded = NULL; SignedMsgEncodeInfo.rgCrlEncoded = NULL; //-------------------------------------------------------------------- // Get the size of the encoded message blob. if(cbEncodedBlob = CryptMsgCalculateEncodedLength( TYPE_DER, // Message encoding type 0, // Flags CMSG_SIGNED, // Message type &SignedMsgEncodeInfo, // Pointer to structure NULL, // Inner content object ID mem_len)) // Size of content */ { printf("The length of the data has been calculated. \n"); } else { ret = CSP_GetLastError(); fprintf (stderr, "Getting cbEncodedBlob length failed"); goto err; } //-------------------------------------------------------------------- // Allocate memory for the encoded blob. pbEncodedBlob = (BYTE *) malloc(cbEncodedBlob); if (!pbEncodedBlob){ ret = CSP_GetLastError(); fprintf (stderr, "Memory allocation failed"); goto err; } //-------------------------------------------------------------------- // Open a message to encode. if(hMsg = CryptMsgOpenToEncode( TYPE_DER, // Encoding type 0, // Flags CMSG_SIGNED, // Message type &SignedMsgEncodeInfo, // Pointer to structure NULL, // Inner content object ID NULL)) // Stream information (not used) { printf("The message to be encoded has been opened. \n"); } else { ret = CSP_GetLastError(); fprintf (stderr, "OpenToEncode failed"); goto err; } //-------------------------------------------------------------------- // Update the message with the data. if(CryptMsgUpdate( hMsg, // Handle to the message mem_tbs, // Pointer to the content mem_len, // Size of the content TRUE)) // Last call { printf("Content has been added to the encoded message. \n"); } else { ret = CSP_GetLastError(); fprintf (stderr, "MsgUpdate failed"); goto err; } //-------------------------------------------------------------------- // Get the resulting message. if(CryptMsgGetParam( hMsg, // Handle to the message CMSG_CONTENT_PARAM, // Parameter type 0, // Index pbEncodedBlob, // Pointer to the blob &cbEncodedBlob)) // Size of the blob { printf("Message encoded successfully. \n"); } else { ret = CSP_GetLastError(); fprintf (stderr, "MsgGetParam failed"); goto err; } //-------------------------------------------------------------------- // pbEncodedBlob now points to the encoded, signed content. //-------------------------------------------------------------------- if (outfile) { FILE *out = NULL; out = fopen (outfile, "wb"); if (out) { fwrite (pbEncodedBlob, cbEncodedBlob, 1, out); fclose (out); printf ("Output file (%s) has been saved\n", outfile); } else perror ("Cannot open out file\n"); } ret = 0; //-------------------------------------------------------------------- // Clean up. err: if(pbEncodedBlob) free(pbEncodedBlob); if(hMsg) CryptMsgClose(hMsg); if(hCryptProv) CryptReleaseContext(hCryptProv,0); if(hCertStore) CertCloseStore(hCertStore, 0); return ret; }
static int HCSP_setContext(void) { int result = TRUE; LPSTR a = NULL; LPSTR b = NULL; LPSTR c = "My"; #ifdef DEBUG BIO_printf(err, "Call HCSP_setContext()\n"); #endif #ifdef FILE_CONFIG readFileConfig(); /* get specified context provider, etc... */ if (pCryptProvider[0] && strcasecmp(pCryptProvider, "default")) a = pCryptProvider; if (pCryptContainer[0] && strcasecmp(pCryptContainer, "default")) b = pCryptContainer; if (pSubsystemProtocol[0] && strcasecmp(pSubsystemProtocol, "default")) c = pSubsystemProtocol; #endif #ifdef DEBUG strcpy(pSubsystemProtocol, c); BIO_printf(err, "Call HCSP_setContext()\n"); BIO_printf(err, "pCryptProvider: \"%s\"\n", a); BIO_printf(err, "dwProviderType: %d\n", dwProviderType); BIO_printf(err, "pCryptContainer: \"%s\"\n", b); BIO_printf(err, "pSubsystemProtocol: \"%s\"\n", c); BIO_printf(err, "pFindPara: \"%s\"\n", pFindPara); #endif /* * Set hCryptProvider to NULL to use the default CSP. If hCryptProvider is not NULL, * it must be a CSP handle created by using the CryptAcquireContext function. */ if (!(hCertStore = CertOpenSystemStore(hCryptProvider, c))) { # ifdef DEBUG routine = "CertOpenSystemStore"; # endif goto error; } #ifdef DEBUG enumCertificate(); #endif if (!(pCertContext = CertFindCertificateInStore( hCertStore, (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING), 0, CERT_FIND_SUBJECT_STR_A, pFindPara, NULL))) { # ifdef DEBUG routine = "CertFindCertificateInStore"; # endif goto error; } if (!CryptAcquireCertificatePrivateKey( pCertContext, 0, NULL, &hCryptProvider, &dwKeySpec, NULL)) { # ifdef DEBUG routine = "CryptAcquireCertificatePrivateKey"; # endif goto error; } #ifdef DEBUG printInfo(); enumKeyContainers(); enumAlgorithms(); printCertificate(pCertContext); #endif bInitialized = TRUE; /* set initialization flag */ goto end; error: result = FALSE; end: #ifdef DEBUG BIO_printf(err, "Return HCSP_setContext(%d)\n", result); #endif return result; }
DWORD StoreUserCert (PCCERT_CONTEXT pCertContext, unsigned char KeyUsageBits, CK_BYTE* cardSerialNumber, CK_ULONG cardSerialNumberLen) { unsigned long dwFlags = CERT_STORE_NO_CRYPT_RELEASE_FLAG; PCCERT_CONTEXT pDesiredCert = NULL; PCCERT_CONTEXT pPrevCert = NULL; DWORD dwRet = 0; wchar_t* pContainerName = NULL; size_t pContainerNameCharLen = cardSerialNumberLen+20; CK_CHAR_PTR pcardSerialNrString = NULL; wchar_t* pProviderName = NULL; CK_ULONG counter=0; HCERTSTORE hMyStore = CertOpenSystemStore((HCRYPTPROV_LEGACY)NULL, TEXT("MY")); CRYPT_KEY_PROV_INFO cryptKeyProvInfo; unsigned long dwPropId = CERT_KEY_PROV_INFO_PROP_ID; if (hMyStore == NULL) { dwRet = GetLastError(); printf("StoreUserCerts: Unable to open the system certificate store. Error code: %d.\n",dwRet); return dwRet; } // ---------------------------------------------------- // look if we already have a certificate with the same // subject (contains name and NNR) in the store // If the certificate is not found --> NULL // ---------------------------------------------------- do { if( NULL != (pDesiredCert = CertFindCertificateInStore(hMyStore, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, &(pCertContext->pCertInfo->Subject) , pPrevCert))) { // ---------------------------------------------------- // If the certificates are identical and function // succeeds, the return value is nonzero, or TRUE. // ---------------------------------------------------- if(FALSE == CertCompareCertificate(X509_ASN_ENCODING,pCertContext->pCertInfo,pDesiredCert->pCertInfo) || !ProviderNameCorrect(pDesiredCert) ) { // ---------------------------------------------------- // certificates are not identical, but have the same // subject (contains name and NNR), // so we remove the one that was already in the store // ---------------------------------------------------- if(FALSE == CertDeleteCertificateFromStore(pDesiredCert)) { if (E_ACCESSDENIED == GetLastError()) { continue; } } pPrevCert = NULL; continue; } } pPrevCert = pDesiredCert; }while (NULL != pDesiredCert); // ---------------------------------------------------- // look if we already have the certificate in the store // If the certificate is not found --> NULL // ---------------------------------------------------- if( NULL != (pDesiredCert = CertFindCertificateInStore(hMyStore, X509_ASN_ENCODING, 0, CERT_FIND_EXISTING, pCertContext , NULL))) { // ---------------------------------------------------- // certificate is already in the store, then just return // ---------------------------------------------------- CertFreeCertificateContext(pDesiredCert); CertCloseStore (hMyStore, CERT_CLOSE_STORE_FORCE_FLAG); return 0; } pContainerName = (wchar_t*)malloc(sizeof(wchar_t) * (pContainerNameCharLen)); if(pContainerName == NULL) return E_OUTOFMEMORY; pcardSerialNrString = (CK_CHAR_PTR)malloc(cardSerialNumberLen*2 + 1); if(pcardSerialNrString == NULL) return E_OUTOFMEMORY; if(-1 == ByteArrayToString( &pcardSerialNrString, cardSerialNumberLen*2 + 1,cardSerialNumber ,cardSerialNumberLen)) return -1; if(pContainerName == NULL) { CertFreeCertificateContext(pDesiredCert); CertCloseStore (hMyStore, CERT_CLOSE_STORE_FORCE_FLAG); return -1; } if (UseMinidriver()) { if (KeyUsageBits & CERT_NON_REPUDIATION_KEY_USAGE) { swprintf_s(pContainerName,pContainerNameCharLen,L"NR_%hS",pcardSerialNrString); } else { swprintf_s(pContainerName,pContainerNameCharLen,L"DS_%hS",pcardSerialNrString); } cryptKeyProvInfo.pwszProvName = L"Microsoft Base Smart Card Crypto Provider"; cryptKeyProvInfo.dwKeySpec = AT_SIGNATURE; } else { if (KeyUsageBits & CERT_NON_REPUDIATION_KEY_USAGE) { swprintf_s(pContainerName,pContainerNameCharLen,L"Signature(%hS)",pcardSerialNrString); } else { swprintf_s(pContainerName,pContainerNameCharLen,L"Authentication(%hS)",pcardSerialNrString); } cryptKeyProvInfo.pwszProvName = L"Belgium Identity Card CSP"; cryptKeyProvInfo.dwKeySpec = AT_KEYEXCHANGE; } cryptKeyProvInfo.pwszContainerName = pContainerName; cryptKeyProvInfo.dwProvType = PROV_RSA_FULL; cryptKeyProvInfo.dwFlags = 0; cryptKeyProvInfo.cProvParam = 0; cryptKeyProvInfo.rgProvParam = NULL; /* // Set friendly names for the certificates DWORD dwsize = 0; dwsize = CertGetNameStringW(pCertContext, CERT_NAME_ATTR_TYPE, 0, szOID_COMMON_NAME, NULL, dwsize); auto_vec<WCHAR> pname(new WCHAR[dwsize]); dwsize = CertGetNameStringW(pCertContext, CERT_NAME_ATTR_TYPE, 0, szOID_COMMON_NAME, pname.get(), dwsize); CRYPT_DATA_BLOB tpFriendlyName = {0, 0}; tpFriendlyName.pbData = (BYTE *)pname.get(); tpFriendlyName.cbData = dwsize * sizeof(WCHAR); if (CertSetCertificateContextProperty( pCertContext, // A pointer to the certificate // where the propertiy will be set. CERT_FRIENDLY_NAME_PROP_ID, // An identifier of the property to be set. // In this case, CERT_KEY_PROV_INFO_PROP_ID // is to be set to provide a pointer with the // certificate to its associated private key // container. dwFlags, // The flag used in this case is // CERT_STORE_NO_CRYPT_RELEASE_FLAG // indicating that the cryptographic // context aquired should not // be released when the function finishes. &tpFriendlyName // A pointer to a data structure that holds // infomation on the private key container to // be associated with this certificate. )) */ // Set the property. if (CertSetCertificateContextProperty( pCertContext, // A pointer to the certificate where the property will be set. dwPropId, // An identifier of the property to be set. // In this case, CERT_KEY_PROV_INFO_PROP_ID is to be set to provide a pointer with the certificate to its associated private key container. dwFlags, // The flag used in this case is // CERT_STORE_NO_CRYPT_RELEASE_FLAG indicating that the cryptographic context acquired should not be released when the function finishes. &cryptKeyProvInfo // A pointer to a data structure that holds infomation on the private key container to be associated with this certificate. )) { if (KeyUsageBits & CERT_NON_REPUDIATION_KEY_USAGE) { CertAddEnhancedKeyUsageIdentifier (pCertContext, szOID_PKIX_KP_EMAIL_PROTECTION); } else { CertAddEnhancedKeyUsageIdentifier (pCertContext, szOID_PKIX_KP_EMAIL_PROTECTION); CertAddEnhancedKeyUsageIdentifier (pCertContext, szOID_PKIX_KP_CLIENT_AUTH); } if (CertAddCertificateContextToStore(hMyStore, pCertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL)) { printf("StoreUserCerts: Certificate context added to store."); dwRet = 0; } else { dwRet = GetLastError(); printf("StoreUserCerts: Unable to add certificate context to store. Error code: %d.",dwRet); } CertCloseStore (hMyStore, CERT_CLOSE_STORE_FORCE_FLAG); hMyStore = NULL; } if(pContainerName != NULL) free (pContainerName); return dwRet; }
/* Dialog procedure for the property sheet. This will run under the UI thread when a property sheet is being displayed for one of our credentials.. */ INT_PTR CALLBACK pp_cred_dlg_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { khui_property_sheet * ps; switch (uMsg) { case WM_INITDIALOG: { PROPSHEETPAGE * p; wchar_t notavailable[128]; p = (PROPSHEETPAGE *) lParam; ps = (khui_property_sheet *) p->lParam; #pragma warning(push) #pragma warning(disable: 4244) SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) ps); #pragma warning(pop) if (ps->cred) { wchar_t tbuf[512]; khm_size cb; khm_handle ident = NULL; LoadString(hResModule, IDS_NOTAVAILABLE, notavailable, ARRAYLENGTH(notavailable)); cb = sizeof(tbuf); if (KHM_SUCCEEDED(kcdb_cred_get_attr_string(ps->cred, attr_id_subj_email, tbuf, &cb, KCDB_TS_LONG))) { SetDlgItemText(hwnd, IDC_PP_SUBJ_E, tbuf); } else { SetDlgItemText(hwnd, IDC_PP_SUBJ_E, notavailable); } cb = sizeof(tbuf); if (KHM_SUCCEEDED(kcdb_cred_get_attr_string(ps->cred, attr_id_subj_display, tbuf, &cb, KCDB_TS_LONG))) { SetDlgItemText(hwnd, IDC_PP_SUBJ_D, tbuf); } else { SetDlgItemText(hwnd, IDC_PP_SUBJ_D, notavailable); } cb = sizeof(tbuf); if (KHM_SUCCEEDED(kcdb_cred_get_attr_string(ps->cred, attr_id_auth_realm, tbuf, &cb, KCDB_TS_LONG))) { SetDlgItemText(hwnd, IDC_PP_REALM, tbuf); } else { SetDlgItemText(hwnd, IDC_PP_REALM, notavailable); } cb = sizeof(tbuf); if (KHM_SUCCEEDED(kcdb_cred_get_attr_string(ps->cred, attr_id_issuer_display, tbuf, &cb, KCDB_TS_LONG))) { SetDlgItemText(hwnd, IDC_PP_ISSUER, tbuf); } else { SetDlgItemText(hwnd, IDC_PP_ISSUER, notavailable); } cb = sizeof(tbuf); if (KHM_SUCCEEDED(kcdb_cred_get_attr_string(ps->cred, KCDB_ATTR_ISSUE, tbuf, &cb, KCDB_TS_LONG))) { SetDlgItemText(hwnd, IDC_PP_NOTBEFORE, tbuf); } else { SetDlgItemText(hwnd, IDC_PP_NOTBEFORE, notavailable); } cb = sizeof(tbuf); if (KHM_SUCCEEDED(kcdb_cred_get_attr_string(ps->cred, KCDB_ATTR_EXPIRE, tbuf, &cb, KCDB_TS_LONG))) { SetDlgItemText(hwnd, IDC_PP_NOTAFTER, tbuf); } else { SetDlgItemText(hwnd, IDC_PP_NOTAFTER, notavailable); } } else { #ifdef DEBUG /* we really shouldn't get here */ DebugBreak(); #endif } } return FALSE; case WM_COMMAND: { HCERTSTORE hStoreHandle = NULL; PCCERT_CONTEXT pCertContext = NULL; CERT_ID certId; BYTE sn_buf[1024]; BYTE issuer_buf[1024]; CRYPTUI_VIEWCERTIFICATE_STRUCT vcs; wchar_t title_fmt[128]; wchar_t cert_name[128]; wchar_t title[256]; BOOL b; khm_size cb; if (wParam != MAKEWPARAM(IDC_PP_DETAILS, BN_CLICKED)) break; ps = (khui_property_sheet *) GetWindowLongPtr(hwnd, DWLP_USER); if (ps == NULL || ps->cred == NULL) { #ifdef DEBUG DebugBreak(); #endif break; } /* we need to display the standard UI for this certificate */ ZeroMemory(&certId, sizeof(certId)); cb = sizeof(sn_buf); if (KHM_FAILED(kcdb_cred_get_attr(ps->cred, attr_id_serial_number, NULL, sn_buf, &cb))) { break; } certId.IssuerSerialNumber.SerialNumber.cbData = (DWORD)cb; certId.IssuerSerialNumber.SerialNumber.pbData = sn_buf; cb = sizeof(issuer_buf); if (KHM_FAILED(kcdb_cred_get_attr(ps->cred, attr_id_issuer_name, NULL, issuer_buf, &cb))) { break; } certId.IssuerSerialNumber.Issuer.cbData = (DWORD)cb; certId.IssuerSerialNumber.Issuer.pbData = issuer_buf; certId.dwIdChoice = CERT_ID_ISSUER_SERIAL_NUMBER; if (!(hStoreHandle = CertOpenSystemStore(0, WIN32MYCERT_STORE))) { log_printf("Unable to access the system store"); return TRUE; } pCertContext = CertFindCertificateInStore(hStoreHandle, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_CERT_ID, &certId, NULL); if (!pCertContext) { /* the certificate was not found */ EnableWindow(GetDlgItem(hwnd, IDC_PP_DETAILS), FALSE); goto _clean_dt; } ZeroMemory(&vcs, sizeof(vcs)); vcs.dwSize = sizeof(vcs); vcs.hwndParent = hwnd; vcs.dwFlags = 0; LoadString(hResModule, IDS_PP_TITLE, title_fmt, ARRAYLENGTH(title_fmt)); cb = sizeof(cert_name); if (KHM_FAILED(kcdb_cred_get_attr(ps->cred, attr_id_auth_realm, NULL, cert_name, &cb))) { cb = sizeof(cert_name); if (KHM_FAILED(kcdb_cred_get_attr(ps->cred, attr_id_subj_email, NULL, cert_name, &cb))) { cb = sizeof(cert_name); kcdb_get_resource(ps->cred, KCDB_RES_DISPLAYNAME, 0, NULL, NULL, cert_name, &cb); } } StringCbPrintf(title, sizeof(title), title_fmt, cert_name); vcs.szTitle = title; vcs.pCertContext = pCertContext; CryptUIDlgViewCertificate(&vcs, &b); _clean_dt: if (pCertContext) { CertFreeCertificateContext(pCertContext); pCertContext = NULL; } if (hStoreHandle) { CertCloseStore(hStoreHandle, 0); hStoreHandle = NULL; } return TRUE; } break; } return FALSE; }
void SchannelContext::connect() { ScopedCertContext pCertContext; m_state = Connecting; // If a user name is specified, then attempt to find a client // certificate. Otherwise, just create a NULL credential. if (!m_cert_name.empty()) { if (m_my_cert_store == NULL) { m_my_cert_store = CertOpenSystemStore(0, m_cert_store_name.c_str()); if (!m_my_cert_store) { ///// printf( "**** Error 0x%x returned by CertOpenSystemStore\n", GetLastError() ); indicateError(); return; } } pCertContext = findCertificateInStore( m_my_cert_store, m_cert_name ); if (pCertContext == NULL) { ///// printf("**** Error 0x%x returned by CertFindCertificateInStore\n", GetLastError()); indicateError(); return; } } // We use an empty list for client certificates PCCERT_CONTEXT clientCerts[1] = {0}; SCHANNEL_CRED sc = {0}; sc.dwVersion = SCHANNEL_CRED_VERSION; /////SSL3? sc.grbitEnabledProtocols = SP_PROT_SSL3_CLIENT | SP_PROT_TLS1_CLIENT | SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_2_CLIENT; sc.dwFlags = SCH_CRED_MANUAL_CRED_VALIDATION; if (pCertContext) { sc.cCreds = 1; sc.paCred = pCertContext.GetPointer(); sc.dwFlags |= SCH_CRED_NO_DEFAULT_CREDS; } else { sc.cCreds = 0; // Let Crypto API find the appropriate certificate for us sc.paCred = clientCerts; sc.dwFlags |= SCH_CRED_USE_DEFAULT_CREDS; } // Swiften performs the server name check for us sc.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK; SECURITY_STATUS status = AcquireCredentialsHandle( NULL, UNISP_NAME, SECPKG_CRED_OUTBOUND, NULL, &sc, NULL, NULL, m_credHandle.Reset(), NULL); if (status != SEC_E_OK) { // We failed to obtain the credentials handle indicateError(); return; } SecBuffer outBuffers[2]; // We let Schannel allocate the output buffer for us outBuffers[0].pvBuffer = NULL; outBuffers[0].cbBuffer = 0; outBuffers[0].BufferType = SECBUFFER_TOKEN; // Contains alert data if an alert is generated outBuffers[1].pvBuffer = NULL; outBuffers[1].cbBuffer = 0; outBuffers[1].BufferType = SECBUFFER_ALERT; // Make sure the output buffers are freed ScopedSecBuffer scopedOutputData(&outBuffers[0]); ScopedSecBuffer scopedOutputAlertData(&outBuffers[1]); SecBufferDesc outBufferDesc = {0}; outBufferDesc.cBuffers = 2; outBufferDesc.pBuffers = outBuffers; outBufferDesc.ulVersion = SECBUFFER_VERSION; // Create the initial security context status = InitializeSecurityContext( m_credHandle, NULL, NULL, m_ctxtFlags, 0, 0, NULL, 0, m_ctxtHandle.Reset(), &outBufferDesc, &m_secContext, NULL); if (status != SEC_E_OK && status != SEC_I_CONTINUE_NEEDED) { // We failed to initialize the security context handleCertError(status); indicateError(); return; } // Start the handshake sendDataOnNetwork(outBuffers[0].pvBuffer, outBuffers[0].cbBuffer); if (status == SEC_E_OK) { status = validateServerCertificate(); if (status != SEC_E_OK) handleCertError(status); m_state = Connected; determineStreamSizes(); onConnected(); } }
void CAPICertificate::setUri (const std::string& capiUri) { valid_ = false; /* Syntax: "certstore:" <cert_store> ":" <hash> ":" <hash_of_cert> */ if (!boost::iequals(capiUri.substr(0, 10), "certstore:")) { return; } /* Substring of subject: uses "storename" */ std::string capiIdentity = capiUri.substr(10); std::string newCertStoreName; size_t pos = capiIdentity.find_first_of (':'); if (pos == std::string::npos) { /* Using the default certificate store */ newCertStoreName = "MY"; certName_ = capiIdentity; } else { newCertStoreName = capiIdentity.substr(0, pos); certName_ = capiIdentity.substr(pos + 1); } if (certStoreHandle_ != NULL) { if (newCertStoreName != certStore_) { CertCloseStore(certStoreHandle_, 0); certStoreHandle_ = NULL; } } if (certStoreHandle_ == NULL) { certStoreHandle_ = CertOpenSystemStore(0, newCertStoreName.c_str()); if (!certStoreHandle_) { return; } } certStore_ = newCertStoreName; PCCERT_CONTEXT certContext = findCertificateInStore (certStoreHandle_, certName_); if (!certContext) { return; } /* Now verify that we can have access to the corresponding private key */ DWORD len; CRYPT_KEY_PROV_INFO *pinfo; HCRYPTPROV hprov; HCRYPTKEY key; if (!CertGetCertificateContextProperty(certContext, CERT_KEY_PROV_INFO_PROP_ID, NULL, &len)) { CertFreeCertificateContext(certContext); return; } pinfo = static_cast<CRYPT_KEY_PROV_INFO *>(malloc(len)); if (!pinfo) { CertFreeCertificateContext(certContext); return; } if (!CertGetCertificateContextProperty(certContext, CERT_KEY_PROV_INFO_PROP_ID, pinfo, &len)) { CertFreeCertificateContext(certContext); free(pinfo); return; } CertFreeCertificateContext(certContext); // Now verify if we have access to the private key if (!CryptAcquireContextW(&hprov, pinfo->pwszContainerName, pinfo->pwszProvName, pinfo->dwProvType, 0)) { free(pinfo); return; } char smartCardReader[1024]; DWORD bufferLength = sizeof(smartCardReader); if (!CryptGetProvParam(hprov, PP_SMARTCARD_READER, (BYTE *)&smartCardReader, &bufferLength, 0)) { DWORD error = GetLastError(); smartCardReaderName_ = ""; } else { smartCardReaderName_ = smartCardReader; LONG result = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &scardContext_); if (SCARD_S_SUCCESS == result) { // Initiate monitoring for smartcard ejection smartCardTimer_ = timerFactory_->createTimer(SMARTCARD_EJECTION_CHECK_FREQUENCY_MILLISECONDS); } else { ///Need to handle an error here } } if (!CryptGetUserKey(hprov, pinfo->dwKeySpec, &key)) { CryptReleaseContext(hprov, 0); free(pinfo); return; } CryptDestroyKey(key); CryptReleaseContext(hprov, 0); free(pinfo); if (smartCardTimer_) { smartCardTimer_->onTick.connect(boost::bind(&CAPICertificate::handleSmartCardTimerTick, this)); smartCardTimer_->start(); } valid_ = true; }
// Select, and return a handle to a server certificate located by name // Usually used for a best guess at a certificate to be used as the SSL certificate for a server SECURITY_STATUS CertFindServerByName(PCCERT_CONTEXT & pCertContext, LPCTSTR pszSubjectName, boolean fUserStore) { HCERTSTORE hMyCertStore = NULL; TCHAR pszFriendlyNameString[128]; TCHAR pszNameString[128]; if (pszSubjectName == NULL || _tcslen(pszSubjectName) == 0) { DebugMsg("**** No subject name specified!"); return E_POINTER; } if (fUserStore) hMyCertStore = CertOpenSystemStore(NULL, _T("MY")); else { // Open the local machine certificate store. hMyCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING, NULL, CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG | CERT_SYSTEM_STORE_LOCAL_MACHINE, L"MY"); } if (!hMyCertStore) { int err = GetLastError(); if (err == ERROR_ACCESS_DENIED) DebugMsg("**** CertOpenStore failed with 'access denied'"); else DebugMsg("**** Error %d returned by CertOpenStore", err); return HRESULT_FROM_WIN32(err); } if (pCertContext) // The caller passed in a certificate context we no longer need, so free it CertFreeCertificateContext(pCertContext); pCertContext = NULL; char * serverauth = szOID_PKIX_KP_SERVER_AUTH; CERT_ENHKEY_USAGE eku; PCCERT_CONTEXT pCertContextSaved = NULL; eku.cUsageIdentifier = 1; eku.rgpszUsageIdentifier = &serverauth; // Find a server certificate. Note that this code just searches for a // certificate that has the required enhanced key usage for server authentication // it then selects the best one (ideally one that contains the server name // in the subject name). while (NULL != (pCertContext = CertFindCertificateInStore(hMyCertStore, X509_ASN_ENCODING, CERT_FIND_OPTIONAL_ENHKEY_USAGE_FLAG, CERT_FIND_ENHKEY_USAGE, &eku, pCertContext))) { //ShowCertInfo(pCertContext); if (!CertGetNameString(pCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszFriendlyNameString, sizeof(pszFriendlyNameString))) { DebugMsg("CertGetNameString failed getting friendly name."); continue; } DebugMsg("Certificate '%S' is allowed to be used for server authentication.", ATL::CT2W(pszFriendlyNameString)); if (!CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszNameString, sizeof(pszNameString))) DebugMsg("CertGetNameString failed getting subject name."); else if (_tcscmp(pszNameString, pszSubjectName)) DebugMsg("Certificate has wrong subject name."); else if (CertCompareCertificateName(X509_ASN_ENCODING, &pCertContext->pCertInfo->Subject, &pCertContext->pCertInfo->Issuer)) { if (!pCertContextSaved) { DebugMsg("A self-signed certificate was found and saved in case it is needed."); pCertContextSaved = CertDuplicateCertificateContext(pCertContext); } } else { DebugMsg("Certificate is acceptable."); if (pCertContextSaved) // We have a saved self signed certificate context we no longer need, so free it CertFreeCertificateContext(pCertContextSaved); pCertContextSaved = NULL; break; } } if (pCertContextSaved && !pCertContext) { // We have a saved self-signed certificate and nothing better DebugMsg("A self-signed certificate was the best we had."); pCertContext = pCertContextSaved; pCertContextSaved = NULL; } if (!pCertContext) { DWORD LastError = GetLastError(); if (LastError == CRYPT_E_NOT_FOUND) { DebugMsg("**** CertFindCertificateInStore did not find a certificate, creating one"); pCertContext = CreateCertificate(true, pszSubjectName); if (!pCertContext) { LastError = GetLastError(); DebugMsg("**** Error 0x%x returned by CreateCertificate", LastError); std::cout << "Could not create certificate, are you running as administrator?" << std::endl; return HRESULT_FROM_WIN32(LastError); } } else { DebugMsg("**** Error 0x%x returned by CertFindCertificateInStore", LastError); return HRESULT_FROM_WIN32(LastError); } } return SEC_E_OK; }
static sqInt sqSetupCert(sqSSL *ssl, char *certName, int server) { SCHANNEL_CRED sc_cred = { 0 }; SECURITY_STATUS ret; HCERTSTORE hStore; PCCERT_CONTEXT pContext = NULL; DWORD dwPropSize; WCHAR wFriendlyName[MAX_NAME_SIZE]; char bFriendlyName[MAX_NAME_SIZE]; if(certName) { hStore = CertOpenSystemStore(0, "MY"); if(!hStore) { if(ssl->loglevel) printf("sqSetupCert: CertOpenSystemStore failed\n"); return 0; } pContext = NULL; /* Enumerate the certificate store to find the cert with the given friendly name */ while(pContext = CertEnumCertificatesInStore(hStore, pContext)) { if(ssl->loglevel) printf("Checking certificate: "); dwPropSize = MAX_NAME_SIZE * sizeof(WCHAR); if(!CertGetCertificateContextProperty(pContext, CERT_FRIENDLY_NAME_PROP_ID, wFriendlyName, &dwPropSize)) { if(ssl->loglevel) printf("<no friendly name>"); continue; } if(!WideCharToMultiByte(CP_UTF8, 0, wFriendlyName, -1, bFriendlyName, MAX_NAME_SIZE, NULL, NULL)) { if(ssl->loglevel) printf("<utf-8 conversion failure>"); continue; } if(ssl->loglevel) printf("%s\n", bFriendlyName); if(strcmp(certName, bFriendlyName) == 0) break; } if(pContext == 0) { /* For compatibility with older versions of SqueakSSL, attempt to match against subject string */ pContext = CertFindCertificateInStore(hStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_SUBJECT_STR_A, certName, NULL); } if(!pContext) { if(ssl->loglevel) printf("sqSetupCert: No suitable certificate found\n"); CertCloseStore(hStore, 0); return 0; } } sc_cred.dwVersion = SCHANNEL_CRED_VERSION; sc_cred.dwFlags = SCH_CRED_NO_DEFAULT_CREDS | SCH_CRED_MANUAL_CRED_VALIDATION; sc_cred.grbitEnabledProtocols = server ? SP_PROT_TLS1_SERVER | SP_PROT_SSL3_SERVER : 0; sc_cred.dwMinimumCipherStrength = 0; sc_cred.dwMaximumCipherStrength = 0; if(pContext) { sc_cred.cCreds = 1; sc_cred.paCred = &pContext; } else { sc_cred.cCreds = 0; } ret = AcquireCredentialsHandle(NULL, UNISP_NAME, server ? SECPKG_CRED_INBOUND : SECPKG_CRED_OUTBOUND, NULL, &sc_cred, NULL, NULL, &ssl->sslCred, NULL); if(ssl->loglevel) printf("AquireCredentialsHandle returned: %x\n", ret); if(pContext) { CertCloseStore(hStore, 0); CertFreeCertificateContext(pContext); } if (ret != SEC_E_OK) { if(ssl->loglevel) printf("AquireCredentialsHandle error: %x\n", ret); return 0; } return 1; }
/** * gnutls_x509_trust_list_add_system_trust: * @list: The structure of the list * @tl_flags: GNUTLS_TL_* * @tl_vflags: gnutls_certificate_verify_flags if flags specifies GNUTLS_TL_VERIFY_CRL * * This function adds the system's default trusted certificate * authorities to the trusted list. Note that on unsupported system * this function returns %GNUTLS_E_UNIMPLEMENTED_FEATURE. * * Returns: The number of added elements or a negative error code on error. * * Since: 3.1 **/ int gnutls_x509_trust_list_add_system_trust(gnutls_x509_trust_list_t list, unsigned int tl_flags, unsigned int tl_vflags) { #if !defined(DEFAULT_TRUST_STORE_PKCS11) && !defined(DEFAULT_TRUST_STORE_FILE) && !defined(_WIN32) return GNUTLS_E_UNIMPLEMENTED_FEATURE; #else int ret, r = 0; const char* crl_file = # ifdef DEFAULT_CRL_FILE DEFAULT_CRL_FILE; # else NULL; # endif # ifdef _WIN32 unsigned int i; for (i=0;i<2;i++) { HCERTSTORE store; const CERT_CONTEXT *cert; const CRL_CONTEXT *crl; gnutls_datum_t data; if (i==0) store = CertOpenSystemStore(0, "ROOT"); else store = CertOpenSystemStore(0, "CA"); if (store == NULL) return GNUTLS_E_FILE_ERROR; cert = CertEnumCertificatesInStore(store, NULL); crl = Loaded_CertEnumCRLsInStore(store, NULL); while(cert != NULL) { if (cert->dwCertEncodingType == X509_ASN_ENCODING) { data.data = cert->pbCertEncoded; data.size = cert->cbCertEncoded; if (gnutls_x509_trust_list_add_trust_mem(list, &data, NULL, GNUTLS_X509_FMT_DER, tl_flags, tl_vflags) > 0) r++; } cert = CertEnumCertificatesInStore(store, cert); } while(crl != NULL) { if (crl->dwCertEncodingType == X509_ASN_ENCODING) { data.data = crl->pbCrlEncoded; data.size = crl->cbCrlEncoded; gnutls_x509_trust_list_add_trust_mem(list, NULL, &data, GNUTLS_X509_FMT_DER, tl_flags, tl_vflags); } crl = Loaded_CertEnumCRLsInStore(store, crl); } CertCloseStore(store, 0); } # endif # if defined(ENABLE_PKCS11) && defined(DEFAULT_TRUST_STORE_PKCS11) ret = gnutls_x509_trust_list_add_trust_file(list, DEFAULT_TRUST_STORE_PKCS11, crl_file, GNUTLS_X509_FMT_DER, tl_flags, tl_vflags); if (ret > 0) r += ret; # endif # ifdef DEFAULT_TRUST_STORE_FILE ret = gnutls_x509_trust_list_add_trust_file(list, DEFAULT_TRUST_STORE_FILE, crl_file, GNUTLS_X509_FMT_PEM, tl_flags, tl_vflags); if (ret > 0) r += ret; # endif return r; #endif }
bool mailcore::checkCertificate(mailstream * stream, String * hostname) { #if __APPLE__ bool result = false; CFStringRef hostnameCFString; SecPolicyRef policy; CFMutableArrayRef certificates; SecTrustRef trust = NULL; SecTrustResultType trustResult; OSStatus status; carray * cCerts = mailstream_get_certificate_chain(stream); if (cCerts == NULL) { fprintf(stderr, "warning: No certificate chain retrieved"); goto err; } hostnameCFString = CFStringCreateWithCharacters(NULL, (const UniChar *) hostname->unicodeCharacters(), hostname->length()); policy = SecPolicyCreateSSL(true, hostnameCFString); certificates = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); for(unsigned int i = 0 ; i < carray_count(cCerts) ; i ++) { MMAPString * str; str = (MMAPString *) carray_get(cCerts, i); CFDataRef data = CFDataCreate(NULL, (const UInt8 *) str->str, (CFIndex) str->len); SecCertificateRef cert = SecCertificateCreateWithData(NULL, data); CFArrayAppendValue(certificates, cert); CFRelease(data); CFRelease(cert); } static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; // The below API calls are not thread safe. We're making sure not to call the concurrently. pthread_mutex_lock(&lock); status = SecTrustCreateWithCertificates(certificates, policy, &trust); if (status != noErr) { pthread_mutex_unlock(&lock); goto free_certs; } status = SecTrustEvaluate(trust, &trustResult); if (status != noErr) { pthread_mutex_unlock(&lock); goto free_certs; } pthread_mutex_unlock(&lock); switch (trustResult) { case kSecTrustResultUnspecified: case kSecTrustResultProceed: // certificate chain is ok result = true; break; default: // certificate chain is invalid break; } CFRelease(trust); free_certs: CFRelease(certificates); mailstream_certificate_chain_free(cCerts); CFRelease(policy); CFRelease(hostnameCFString); err: return result; #else bool result = false; X509_STORE * store = NULL; X509_STORE_CTX * storectx = NULL; STACK_OF(X509) * certificates = NULL; #if defined(ANDROID) || defined(__ANDROID__) DIR * dir = NULL; struct dirent * ent = NULL; FILE * f = NULL; #endif int status; carray * cCerts = mailstream_get_certificate_chain(stream); if (cCerts == NULL) { fprintf(stderr, "warning: No certificate chain retrieved"); goto err; } store = X509_STORE_new(); if (store == NULL) { goto free_certs; } #ifdef _MSC_VER HCERTSTORE systemStore = CertOpenSystemStore(NULL, L"ROOT"); PCCERT_CONTEXT previousCert = NULL; while (1) { PCCERT_CONTEXT nextCert = CertEnumCertificatesInStore(systemStore, previousCert); if (nextCert == NULL) { break; } X509 * openSSLCert = d2i_X509(NULL, (const unsigned char **)&nextCert->pbCertEncoded, nextCert->cbCertEncoded); if (openSSLCert != NULL) { X509_STORE_add_cert(store, openSSLCert); X509_free(openSSLCert); } previousCert = nextCert; } CertCloseStore(systemStore, 0); #elif defined(ANDROID) || defined(__ANDROID__) dir = opendir("/system/etc/security/cacerts"); while (ent = readdir(dir)) { if (ent->d_name[0] == '.') { continue; } char filename[1024]; snprintf(filename, sizeof(filename), "/system/etc/security/cacerts/%s", ent->d_name); f = fopen(filename, "rb"); if (f != NULL) { X509 * cert = PEM_read_X509(f, NULL, NULL, NULL); if (cert != NULL) { X509_STORE_add_cert(store, cert); X509_free(cert); } fclose(f); } } closedir(dir); #endif status = X509_STORE_set_default_paths(store); if (status != 1) { printf("Error loading the system-wide CA certificates"); } certificates = sk_X509_new_null(); for(unsigned int i = 0 ; i < carray_count(cCerts) ; i ++) { MMAPString * str; str = (MMAPString *) carray_get(cCerts, i); if (str == NULL) { goto free_certs; } BIO *bio = BIO_new_mem_buf((void *) str->str, str->len); X509 *certificate = d2i_X509_bio(bio, NULL); BIO_free(bio); if (!sk_X509_push(certificates, certificate)) { goto free_certs; } } storectx = X509_STORE_CTX_new(); if (storectx == NULL) { goto free_certs; } status = X509_STORE_CTX_init(storectx, store, sk_X509_value(certificates, 0), certificates); if (status != 1) { goto free_certs; } status = X509_verify_cert(storectx); if (status == 1) { result = true; } free_certs: mailstream_certificate_chain_free(cCerts); if (certificates != NULL) { sk_X509_pop_free((STACK_OF(X509) *) certificates, X509_free); }