Esempio n. 1
3
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;
}
Esempio n. 2
0
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;

}
Esempio n. 3
0
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);
}
Esempio n. 4
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;
}
Esempio n. 6
0
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;
}
Esempio n. 8
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;
}
Esempio n. 9
0
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;
}
Esempio n. 10
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);
  }
}
Esempio n. 11
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);

	}
}
Esempio n. 12
0
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;
}
Esempio n. 13
0
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);
}
Esempio n. 14
0
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;
}
Esempio n. 15
0
Store::Store(const std::string& storeName, HCRYPTPROV provider)
{
    m_hCertStore = CertOpenSystemStore(provider,storeName.c_str());
    m_prevCert = 0;
}
Esempio n. 16
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);
}
Esempio n. 17
0
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
Esempio n. 18
0
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);
}
Esempio n. 19
0
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
}
Esempio n. 20
0
/*
 * 서버인증에 사용할 인증서를 가져온다.
 * 이 인증서에는 개인키가 포함되어있어야 한다.
 * "인증서.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;
}
Esempio n. 21
0
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;
} 
Esempio n. 22
0
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;
}
Esempio n. 23
0
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;
}
Esempio n. 24
0
/* 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;
}
Esempio n. 25
0
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;
}
Esempio n. 27
0
// 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;
}
Esempio n. 29
0
/**
 * 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
}
Esempio n. 30
0
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);
    }