"""
predicates.py:
This file contains basic predicates as well as event and telemetry predicates used by the
gds_test_api.py. The predicates are organized by type and can be used to search histories.
:author: koran
"""
from inspect import signature
from fprime_gds.common.data_types.ch_data import ChData
from fprime_gds.common.data_types.event_data import EventData
##########################################################################################
# Base class/helpers
##########################################################################################
[docs]class predicate:
[docs] def __call__(self, item):
"""
A parent class to ensure that all predicates are callable, and return readable strings
"""
raise NotImplementedError(
"This predicate did not override __call__(self, object)"
)
[docs] def __str__(self):
"""
Returns a string outlining the evaluation done by the predicate.
"""
raise NotImplementedError("This predicate did not override __str__(self)")
[docs] def __repr__(self):
"""
Unless manually overwritten by a subclass both repr and str will return the same string.
"""
return str(self)
[docs]def is_predicate(pred):
"""
a helper function to determine if an object can be used as a predicate.
:return: a boolean value of whether the function is a predicate instance or has
both __str__ and __call__ methods.
"""
if isinstance(pred, predicate):
return True
if callable(pred):
sig = signature(pred.__call__)
arg_count = len(sig.parameters)
if arg_count == 1:
if hasattr(pred, "__str__"):
return True
return False
[docs]def get_descriptive_string(value, pred_function):
"""
a helper function that formats a predicate and argument in a nice human-readable format
Args:
value: the argument of the predicate
pred_function: a predicate function
"""
return "F({}), where F(x) evaluates\n\t {}".format(value, pred_function)
##########################################################################################
# Comparison predicates
##########################################################################################
[docs]class less_than(predicate):
def __init__(self, value):
"""
A predicate that evaluates a less-than comparison
:param value: To return true, the predicate must be called on an object that is less
than this value
"""
self.upper_limit = value
[docs] def __call__(self, actual):
"""
:param actual: the value to compare
"""
try:
return actual < self.upper_limit
except TypeError:
return False
[docs] def __str__(self):
"""
Returns a string outlining the evaluation done by the predicate.
"""
return "x < {}".format(self.upper_limit)
[docs]class greater_than(predicate):
def __init__(self, value):
"""
A predicate that evaluates a greater-than comparison
:param value: To return true, the predicate must be called on an object that is less
than this value
"""
self.lower_limit = value
[docs] def __call__(self, actual):
"""
:param actual: the value to compare
"""
try:
return actual > self.lower_limit
except TypeError:
return False
[docs] def __str__(self):
"""
Returns a string outlining the evaluation done by the predicate.
"""
return "x > {}".format(self.lower_limit)
[docs]class equal_to(predicate):
def __init__(self, value):
"""
A predicate that evaluates an equivalent comparison
:param value: To return true, the predicate must be called on an object that is equal
to this value
"""
self.expected = value
[docs] def __call__(self, actual):
"""
:param actual: the value to compare
"""
try:
return actual == self.expected
except TypeError:
return False
[docs] def __str__(self):
"""
Returns a string outlining the evaluation done by the predicate.
"""
return "x == {}".format(self.expected)
[docs]class not_equal_to(predicate):
def __init__(self, value):
"""
A predicate that evaluates a not-equivalent comparison
:param value: To return true, the predicate must be called on an object that is not
equal to this value
"""
self.expected = value
[docs] def __call__(self, actual):
"""
:param actual: the value to compare
"""
try:
return actual != self.expected
except TypeError:
return False
[docs] def __str__(self):
"""
Returns a string outlining the evaluation done by the predicate.
"""
return "x != {}".format(self.expected)
[docs]class less_than_or_equal_to(predicate):
def __init__(self, value):
"""
A predicate that evaluates a less-than-or-equals comparison
:param value: To return true, the predicate must be called on an object that is less
than or equal to this value
"""
self.upper_limit = value
[docs] def __call__(self, actual):
"""
:param actual: the value to compare
"""
try:
return actual <= self.upper_limit
except TypeError:
return False
[docs] def __str__(self):
"""
Returns a string outlining the evaluation done by the predicate.
"""
return "x <= {}".format(self.upper_limit)
[docs]class greater_than_or_equal_to(predicate):
def __init__(self, value):
"""
A predicate that evaluates greater-than-or-equals comparison
:param value: To return true, the predicate must be called on an object that is
greater than or equal to this value
"""
self.lower_limit = value
[docs] def __call__(self, actual):
"""
:param actual: the value to compare
"""
try:
return actual >= self.lower_limit
except TypeError:
return False
[docs] def __str__(self):
"""
Returns a string outlining the evaluation done by the predicate.
"""
return "x >= {}".format(self.lower_limit)
[docs]class within_range(predicate):
def __init__(self, lower, upper):
"""
A predicate that evaluates if the argument is between the two values
:param lower: To return true, the predicate must be called on an object that is
greater than this value
:param upper: To return true, the predicate must be called on an object that is less
than this value
"""
self.upper_limit = upper
self.lower_limit = lower
[docs] def __call__(self, actual):
"""
:param actual: the value to evaluate
"""
try:
return actual >= self.lower_limit and actual <= self.upper_limit
except TypeError:
return False
[docs] def __str__(self):
"""
Returns a string outlining the evaluation done by the predicate.
"""
return "{} <= x <= {}".format(self.lower_limit, self.upper_limit)
##########################################################################################
# Set predicates
##########################################################################################
[docs]class is_a_member_of(predicate):
def __init__(self, collection):
"""
Constructs a predicate that evaluates if the argument is equivalent to any member in the set
:param collection: To return true, the predicate must be called on an object that is
equivalent to any object in this list
"""
self.set = collection
[docs] def __call__(self, item):
"""
Evaluates the predicate
:param item: the object to search for then evaluate
"""
for x in self.set:
if item == x:
return True
return False
[docs] def __str__(self):
"""
Returns a string outlining the evaluation done by the predicate.
"""
return "x \u2208 {}".format(self.set)
[docs]class is_not_a_member_of(predicate):
def __init__(self, collection):
"""
Constructs a predicate that evaluates if the argument is not equivalent to all members in
the set
:param collection: To return true, the predicate must be called on an object that is
not equivalent to any object in this collection
"""
self.set = collection
[docs] def __call__(self, item):
"""
:param item: the object to search for then evaluate
"""
for x in self.set:
if item == x:
return False
return True
[docs] def __str__(self):
"""
Returns a string outlining the evaluation done by the predicate.
"""
return "x \u2209 {}".format(self.set)
##########################################################################################
# Logic predicates
##########################################################################################
[docs]class always_true(predicate):
[docs] def __call__(self, obj):
"""
used as a placeholder by other predicates. This is like a logical TRUE signal.
:param obj: the object or value to evaluate
"""
return True
[docs] def __str__(self):
"""
Returns a string outlining the evaluation done by the predicate.
"""
return "True"
[docs]class invert(predicate):
def __init__(self, pred):
"""
A predicate that negates a given predicate. This predicate can be used like a NOT
gate when combining predicates.
:param pred: The predicate to be negated.
"""
if is_predicate(pred):
self.pred = pred
[docs] def __call__(self, item):
"""
:param item: the object or value to evaluate
"""
return not self.pred(item)
[docs] def __str__(self):
"""
Returns a string outlining the evaluation done by the predicate.
"""
return "\u02DC({}).".format(self.pred)
[docs]class satisfies_all(predicate):
def __init__(self, pred_list):
"""
A predicate that evaluates if the argument satisfies all predicates in the given list.
This predicate can be used like an AND gate of N elements when combining predicates.
:param pred_list: a list of predicates
"""
self.p_list = []
for pred in pred_list:
if is_predicate(pred):
self.p_list.append(pred)
[docs] def __call__(self, item):
"""
:param item: the object or value to evaluate
"""
for pred in self.p_list:
if not pred(item):
return False
return True
[docs] def __str__(self):
"""
Returns a string outlining the evaluation done by the predicate.
"""
return "\u2200 P \u2208 A : P(x) is True, when A is {}".format(self.p_list)
[docs]class satisfies_any(predicate):
def __init__(self, pred_list):
"""
A predicate that evaluates if the argument satisfies any predicate in the given list.
This predicate can be used like an OR gate of N elements when combining predicates.
:param pred_list: a list of predicates
"""
self.p_list = []
for pred in pred_list:
if is_predicate(pred):
self.p_list.append(pred)
[docs] def __call__(self, item):
"""
:param item: the object or value to evaluate
"""
for pred in self.p_list:
if pred(item):
return True
return False
[docs] def __str__(self):
"""
Returns a string outlining the evaluation done by the predicate.
"""
return "\u2203 P \u2208 A : P(x) is True, when A is {}".format(self.p_list)
##########################################################################################
# Test API predicates
##########################################################################################
[docs]class args_predicate(predicate):
def __init__(self, args):
"""
A predicate for evaluating argument fields. Arguments can be specified by value, by
predicate or as don't care (None). By inserting None into the argument list, args_predicate
will accept any response given for that argument index.
Args:
args: a list of expected arguments (list of values, predicates, and None)
"""
self.arg_spec = []
ignored = always_true()
if not isinstance(args, (list, tuple)):
args = [args]
for arg in args:
if arg is None:
self.arg_spec.append(ignored)
elif is_predicate(arg):
self.arg_spec.append(arg)
else:
self.arg_spec.append(equal_to(arg))
[docs] def __call__(self, actual):
"""
Determines if the given array satisfies the given argument specification.
"""
if not isinstance(actual, (list, tuple)):
actual = [actual]
if len(actual) != len(self.arg_spec):
return False
for i in range(len(self.arg_spec)):
if not self.arg_spec[i](actual[i]):
return False
return True
[docs] def __str__(self):
"""
Returns a string outlining the evaluation done by the predicate.
"""
return "True IFF \u2200 pi \u2208 P and xi \u2208 x; pi(xi) is True. Where P is {}".format(
self.arg_spec
)
[docs]class event_predicate(predicate):
def __init__(
self, id_pred=None, args_pred=None, severity_pred=None, time_pred=None
):
"""
A predicate for specifying an EventData object from data_types.event_data. This predicate
can be used to search a history. If arguments passed into this constructor are not
subclasses of predicate, they will be ignored. If an argument is unspecified, the predicate
will ignore that field when evaluating an EventData object.
Args:
id_pred: optional predicate to call on the EventData instance's id field
args_pred: optional predicate to call on a list of the EventData 's argument values
severity_pred: optional predicate to call on the EvenetData instances severity field
time_pred: optional predicate to call on the EventData instance's timestamp
"""
true_pred = always_true()
self.id_pred = true_pred
self.args_pred = true_pred
self.severity_pred = true_pred
self.time_pred = true_pred
if is_predicate(id_pred):
self.id_pred = id_pred
if is_predicate(args_pred):
self.args_pred = args_pred
if is_predicate(severity_pred):
self.severity_pred = severity_pred
if is_predicate(time_pred):
self.time_pred = time_pred
[docs] def __call__(self, event):
"""
The event_predicate checks that the telemetry object is an instance of EventData and will
raise an error if the check fails. Then event_predicate will evaluate whether event's
EventData fields satisfy the id_pred, value_pred, and time_pred specified.
Args:
event: an instance of EventData (object)
"""
if not isinstance(event, EventData):
return False
if self.id_pred(event.get_id()):
if self.time_pred(event.get_time()):
if self.severity_pred(event.get_severity()):
args = []
for arg in event.get_args():
args.append(arg.val)
if self.args_pred(args):
return True
return False
[docs] def __str__(self):
"""
Returns a string outlining the evaluation done by the predicate.
"""
msg = "True IFF: x is an EventData object"
if not isinstance(self.id_pred, always_true):
msg += " and x's id satisfies ({})".format(self.id_pred)
if not isinstance(self.args_pred, always_true):
msg += " and x's args satisfy ({})".format(self.args_pred)
if not isinstance(self.severity_pred, always_true):
msg += " and x's severity satisfies ({})".format(self.severity_pred)
if not isinstance(self.time_pred, always_true):
msg += " and x's time satisfies ({})".format(self.time_pred)
return msg
[docs]class telemetry_predicate(predicate):
def __init__(self, id_pred=None, value_pred=None, time_pred=None):
"""
A predicate for specifying a ChData object from data_types.ch_data. This predicate can be
used to search a history. If arguments passed into this constructor are not subclasses of
predicate, they will be ignored.If an argument is unspecified, the predicate will ignore
that field when evaluating an EventData object.
Args:
id_pred: optional predicate to call on the ChData instance's id field
value_pred: optional predicate to call on the ChData instance's id field
time_pred: optional predicate to call on the ChData instance's timestamp
"""
true_pred = always_true()
self.id_pred = true_pred
self.value_pred = true_pred
self.time_pred = true_pred
if is_predicate(id_pred):
self.id_pred = id_pred
if is_predicate(value_pred):
self.value_pred = value_pred
if is_predicate(time_pred):
self.time_pred = time_pred
[docs] def __call__(self, telemetry):
"""
The telemetry_predicate checks that the telemetry object is an instance of ChData and will
raise an error if the check fails. Then telemetry_predicate will evaluate whether
telemetry's ChData fields satisfy the id_pred, value_pred and time_pred specified.
Args:
telemetry: an instance of ChData (object)
"""
if not isinstance(telemetry, ChData):
return False
if self.id_pred(telemetry.get_id()):
if self.value_pred(telemetry.get_val()):
if self.time_pred(telemetry.get_time()):
return True
return False
[docs] def __str__(self):
"""
Returns a string outlining the evaluation done by the predicate.
"""
msg = "True IFF: x is a ChData object"
if not isinstance(self.id_pred, always_true):
msg += " and x's id satisfies ({})".format(self.id_pred)
if not isinstance(self.value_pred, always_true):
msg += " and x's value satisfies ({})".format(self.value_pred)
if not isinstance(self.time_pred, always_true):
msg += " and x's time satisfies ({})".format(self.time_pred)
return msg


Working with SheKnows media I had the opportunity to work on many different aspects of their sites from updating their existing blog contributor onboarding flow, creating and documenting advertisements. Working with Project Mangagers and the engineering team, I created the lo to hi-fi wireframes of the onboarding flow. I worked to cut down and make the process more approachable while also elevating the UI, and finally created the responsive versions. As they moved forward with the total site redesign they used this template for all future onboarding flows.
Kard helps users maximize their credit card rewards; a chrome notification appears when you land on a merchants site that has a deal with one of your credit cards. Users can see a list of deals, curated from the list of cards in your wallet, in real-time. As the Product Designer, I conducted conducted user research, competitive analysis, branding, logo creation, wireframing, prototyping, user testing, and email design.
LookBooker is an online booking aggregator for hair and beauty services that allows user to search, select, and instantly confirm salon appointments, 24/7. Lookbooker's mission is to connect consumers looking for salon appointments with salons looking for consumers. I conducted competitive/comparative analysis, designed marking assets to be sent out to over 70,000 subscribers, redesigned app features to ensure usability, and designed app interfaces to add to the existing platform.
Nestie enables apartment seekers to find their next apartment from departing tenants instead of brokers. Based on our research we looked into these areas of opportunity; communicating the value propostion of Nestie, creating a verification process, and building out a secure and transparent payment process. To UX these opportunities we conducted user research, competitive analysis, wireframing, prototyping, and user testing.
We jumped into research, looking specifically at other peer to peer sights to see common themes. We broke down findings from various sites to see their payment flows, verification methods. We conducted contextual inquiries to see how users were interacting with the current Nestie site. After gather the mass of information, we worked to synthesize findings and pull out general themes to aid us in the redesign. Findings allowed us to understand that overall users did not understand the portrayal of value proposition.
Building off the existing platform, we began implementing features and building in new pages. Once the mid-fi pages had been completed, we made a prototype to test on users. Taking careful note of how users interacted with the initial prototype and listening to any feedback they had to offer, we synthesized results and began on the second iteration. We went through the same process for the second prototype, which lead us to the final prototype.
The final prototype included; verification badges to indicate to users this is a safe platform, the reworked inbox page to better demonstrate its use as a thread for a specific apartment, and a progress bar to show the transparency that Nestie offers.
This was a passion piece for me, and is not affiliated with CFS. After looking at the Center for Food Safety site I saw an opportunity to improve upon the existing site by elevating not only the UI, but the UX of it as well.
Tasked to redesign the Hotel Tonight mobile application in hopes of keeping up with competitors, we focused to create a unique experience that held true to the brand. In order to keep up with the competitors, Hotel Tonight being a last minute hotel booking application needs to focus on increasing the return rate of existing users and likewise increase the rate of new users. In a feedback loop, Hotel Tonight wants to increase the number of rooms being sold which will encourage more hotels to offer rooms and increase the room availability to consumers.
Having received the area of opportunity we dove into researching how to define and tackle the problems. By developing a initial screener and survey, it helped us familiarize ourselves with the users behaviors. We asked a few basic questions that had to do with how/when/why a user books travel accommodations. We aggregated this information and pulled out a few common themes. After gathering this information we went onto comparative and competitive analysis to see what was already out there and why it was doing well. From these side by side comparison we found elements that were common and began devising a plan of action. Items that were common across the board included: a sorting feature(to sort by price, location, etc.), collect a list of favorites or wish list hotels, and a calendar feature to compare price trends.
Once we put the screens into InVision to make a clickable prototype, we began rounds of user testing. Overall we found that users were having trouble navigating through the tasks because of unfamiliarity of icons, and lack direction on our part (as we didn’t add hotel names which lead to confusion to where they should be clicking). Readability was also an issue. Coming back in with a different approach we aimed to revise the areas of confusion. It was clear we needed to change the existing logos in the nav bar, reorganize what remained and what should be added to the nav bar, and added text to be able to differentiate between hotels. We then went through another round of user testing, which provided more promising feedback. Users more easily could navigate through the interface. Users picked up on the idea of favoriting a hotel and then having saved into the heart or “favorites” tab. There still were a few things to be improved on: the briefcase in the bottom nav was confused as a calendar, the calendar icon didn’t indicate price trends, and icons and text needs to be increased. Taking the notes we did a final reworking of our prototype and took it up to a hi-fidelity mockup. We ironed out the last few problem areas. We increased size of icons and text to help with readability and usability. Finally, we broke down the price trends and calendar feature into two different tabs to ensure ease of use.


Enumeration
Credentials.Kind
public enum Kind
Indicates how Tink authenticates the user to a financial institution.
Relationships
Member Of
Credentials
The credentials model represents a user's connection to a specific provider from where financial data is accessed.
Enumeration Cases
unknown
case unknown
An unknown kind of credentials.
password
case password
The user will authenticate the credentials with a password.
mobileBankID
case mobileBankID
The user will authenticate the credentials with Mobile BankID.
keyfob
case keyfob
The user will authenticate the credentials with a Key Fob.
thirdPartyAuthentication
case thirdPartyAuthentication
The user will authenticate the credentials with a third party app.
Properties
sortOrder
var sortOrder: Int


Value of a is {{a}} Value of b is {{b}}
Value of a is
Value of b is
Sum : {{sum}}
Calculate
Initial Value of a {{::a}}
For New Sum Set Value for a : {{a}}
Set Value for b : {{b}}
Value of sum2 {{sum}}
Calculate New sum


Together with the Ministry of LNV, NAJK, CTA, Ahold Delhaize, Danone, IBM, Google, Deloitte, Rabobank and another 10 of these partners, we take a look at how new technologies such as blockchain and A.I. strengthen farmers' income. We know that the bottleneck is not in technology itself, but more in issues such as the disadvantages of transparency and lack of long-term cooperation. How do we organize the food system in such a way that farmers can invest in the food of tomorrow?
During this event we will look with all players at the (im) possibilities of technology for:
- A unique farmers digital identity where the farmer has control over his/her own data
- New business models where, for example, employees, neighbors and consumers can participate in the company
- CO2 neutral business operations. How do we make a tradable CO2 certificate that financially rewards sustainable business?
During Strike Two you are actively introduced to technology. Together with the partners in these 3 tracks you will test the possibilities, accelerators and threats for farmers' income. As a concrete outcome of Strike Two, an innovation roadmap is made per track.
1


Unit SChannel.Utils
Description
Helper functions for easy implementation of TLS communication by means of Windows SChannel. The functions are transport-agnostic so they could be applied to any socket implementation or even other transport.
Inspired by TLS-Sample
Uses JEDI API units
(c) Fr0sT-Brutal
License MIT
Overview
Classes, Interfaces, Objects and Records
Functions and Procedures
Types
Constants
Variables
Description
Functions and Procedures
procedure LoadSecurityLibrary; |
|
Mainly for internal use
Exceptions raised
- ESSPIError
- on error
|
procedure CreateCredentials(const User: string; out hCreds: CredHandle; var SchannelCred: SCHANNEL_CRED); |
|
Mainly for internal use.
Parameters
- SchannelCred
- - [?IN/OUT] If
SchannelCred.dwVersion = SCHANNEL_CRED_VERSION , the parameter is considered "IN/OUT" and won't be modified before AcquireCredentialsHandle call. Otherwise the parameter is considered "OUT" and is init-ed with default values. Thus user can pass desired values to AcquireCredentialsHandle function.
Exceptions raised
- ESSPIError
- on error
|
procedure VerifyServerCertificate(pServerCert: PCCERT_CONTEXT; const szServerName: string; dwCertFlags: DWORD); |
|
Validate certificate. Mainly for internal use. Gets called by CheckServerCert
Parameters
- pServerCert
- - pointer to cert context
- szServerName
- - host name of the server to check. Could be empty but appropriate flags must be set as well, otherwise the function will raise error
- dwCertFlags
- - value of
SSL_EXTRA_CERT_CHAIN_POLICY_PARA.fdwChecks field: flags defining errors to ignore. 0 to ignore nothing
Exceptions raised
- ESSPIError
- on error
|
function GetCertContext(const hContext: CtxtHandle): PCCERT_CONTEXT; |
|
Retrieve server certificate. Mainly for internal use. Gets called by CheckServerCert . Returned result must be freed via CertFreeCertificateContext .
Parameters
- hContext
- - current session context
Returns
server certificate data Exceptions raised
- ESSPIError
- on error
|
procedure Init; |
|
Load global stuff. Must be called before any other function called. Could be called multiple times without checks. Thread-unsafe! Uses global variables
Exceptions raised
- ESSPIError
- on error
|
procedure Fin; |
|
Dispose and nullify global stuff. Could be called multiple times without checks. Thread-unsafe! Uses global variables
|
procedure CreateSessionCreds(var SessionCreds: TSessionCreds); |
|
Init session creds, return data record to be used in calling other functions. Could be called multiple times (nothing will be done on already init-ed record)
Parameters
- SessionCreds
- - [IN, OUT] record that receives values. On first call must be zeroed. Alternatively, user could fill
SessionCreds.SchannelCred with desired values to tune channel properties.
Exceptions raised
- ESSPIError
- on error
|
procedure FreeSessionCreds(var SessionCreds: TSessionCreds); |
|
Finalize session creds
|
procedure FinSession(var SessionData: TSessionData); |
|
Finalize session, free credentials
|
function DoClientHandshake(var SessionData: TSessionData; var HandShakeData: THandShakeData; DebugLogFn: TDebugFn = nil): SECURITY_STATUS; |
|
Function to prepare all necessary handshake data. No transport level actions.
Function to prepare all necessary handshake data. No transport level actions. Function actions and returning data depending on input stage:
Parameters
- SessionData
- - [IN/OUT] record with session data
- HandShakeData
- - [IN/OUT] record with handshake data
- DebugLogFn
- - logging callback, could be
Nil
Exceptions raised
- ESSPIError
- on error
- ESSPIError
- on error
|
procedure GetShutdownData(const SessionData: TSessionData; const hContext: CtxtHandle; out OutBuffer: SecBuffer); |
|
Generate data to send to a server on connection shutdown
Exceptions raised
- ESSPIError
- on error
|
function GetCurrentCert(const hContext: CtxtHandle): TBytes; |
|
Retrieve server certificate linked to current context. More suitable for userland application than GetCertContext , without any SChannel-specific stuff.
Parameters
- hContext
- - current session context
Returns
server certificate data Exceptions raised
- ESSPIError
- on error
|
function CheckServerCert(const hContext: CtxtHandle; const ServerName: string; const TrustedCerts: TTrustedCerts = nil; CertCheckIgnoreFlags: TCertCheckIgnoreFlags = []): TCertCheckResult; overload; |
|
Check server certificate with a certificate that contains a common name that is not valid will be ignored. (SECURITY_FLAG_IGNORE_CERT_CN_INVALID flag will be set calling CertVerifyCertificateChainPolicy )
Parameters
- hContext
- - current session context
- ServerName
- - host name of the server to check. If empty, errors associated
- TrustedCerts
- - list of trusted certs. If cert is in this list, it won't be checked by system
- CertCheckIgnoreFlags
- - set of cert aspects to ignore when checking.
Returns
Result of cert check Exceptions raised
- ESSPIError
- on error
|
function CheckServerCert(const hContext: CtxtHandle; const SessionData: TSessionData): TCertCheckResult; overload; |
|
Check server certificate - variant using SessionData only
Returns
Result of cert check Exceptions raised
- ESSPIError
- on error
|
procedure DeleteContext(var hContext: CtxtHandle); |
|
Dispose and nullify security context
|
procedure InitBuffers(const hContext: CtxtHandle; out pbIoBuffer: TBytes; out Sizes: SecPkgContext_StreamSizes); |
|
Receive size values for current session and init buffer length to contain full message including header and trailer
Exceptions raised
- ESSPIError
- on error
|
procedure EncryptData(const hContext: CtxtHandle; const Sizes: SecPkgContext_StreamSizes; pbMessage: PByte; cbMessage: DWORD; pbIoBuffer: PByte; pbIoBufferLength: DWORD; out cbWritten: DWORD); |
|
Encrypt data (prepare for sending to server).
Parameters
- hContext
- - current session context
- Sizes
- - current session sizes
- pbMessage
- - input data to encrypt
- cbMessage
- - length of input data
- pbIoBuffer
- - buffer to receive encrypted data
- pbIoBufferLength
- - size of buffer
- cbWritten
- - [OUT] size of encrypted data written to buffer
Exceptions raised
- ESSPIError
- on error
|
function DecryptData(const hContext: CtxtHandle; const Sizes: SecPkgContext_StreamSizes; pbIoBuffer: PByte; var cbEncData: DWORD; pbDecData: PByte; cbDecDataLength: DWORD; out cbWritten: DWORD): SECURITY_STATUS; |
|
Decrypt data received from server. If input data is not processed completely, unprocessed chunk is copied to beginning of buffer. Thus subsequent call to Recv could just receive to @Buffer[DataLength]
Parameters
- hContext
- - current session context
- Sizes
- - current session sizes
- pbIoBuffer
- - input encrypted data to decrypt
- cbEncData
- - [IN/OUT] length of encrypted data in buffer. After function call it is set to amount of unprocessed data that is placed from the beginning of the buffer
- pbDecData
- - buffer to receive decrypted data
- cbDecDataLength
- - size of buffer
- cbWritten
- - [OUT] size of decrypted data written to buffer
Returns
SEC_I_CONTEXT_EXPIRED - server signaled end of session
SEC_E_OK - message processed fully
SEC_E_INCOMPLETE_MESSAGE - need more data
SEC_I_RENEGOTIATE - server wants to perform another handshake sequence
Exceptions raised
- ESSPIError
- on error or if Result is not one of above mentioned values
|
function SecIsNullHandle(const x: SecHandle): Boolean; |
|
Check if handle x is null (has both fields equal to zero)
|
function SecStatusErrStr(scRet: SECURITY_STATUS): string; |
|
Returns string representaion of given security status (locale message + constant name + numeric value)
|
function WinVerifyTrustErrorStr(Status: DWORD): string; |
|
Returns string representaion of given verify trust error (locale message + constant name + numeric value)
|
function IsWinHandshakeBug(scRet: SECURITY_STATUS): Boolean; |
|
Check if status is likely a Windows TLS v1.2 handshake bug (SEC_E_BUFFER_TOO_SMALL or SEC_E_MESSAGE_ALTERED status is returned by InitializeSecurityContext on handshake). This function only checks if parameter is one of these two values.
|
function GetSessionCredsPtr(const SessionData: TSessionData): PSessionCreds; |
|
Return effective pointer to session credentials - either personal or shared
|
Types
THandShakeStage = (...); |
|
Detect replayed messages that have been encoded by using the EncryptMessage or MakeSignature functions Encrypt messages by using the EncryptMessage function When errors occur, the remote party will be notified The security package allocates output buffers for you. When you have finished using the output buffers, free them by calling the FreeContextBuffer function Stage of handshake
Values
-
hssNotStarted: Initial stage
-
hssSendCliHello: Sending client hello
-
hssReadSrvHello: Reading server hello - general
-
hssReadSrvHelloNoRead: Reading server hello - repeat call without reading
-
hssReadSrvHelloContNeed: Reading server hello - in process, send token
-
hssReadSrvHelloOK: Reading server hello - success, send token
-
hssDone: Final stage
|
TChannelState = (...); |
|
State of secure channel
Values
-
chsNotStarted: Initial stage
-
chsHandshake: Handshaking with server
-
chsEstablished: Channel established successfully
-
chsShutdown: Sending shutdown signal and closing connection
|
TSessionFlag = (...); |
|
Session options
Values
-
sfNoServerVerify: If set, SChannel won't automatically verify server certificate by setting
ISC_REQ_MANUAL_CRED_VALIDATION flag in InitializeSecurityContextW call. User has to call manual verification via CheckServerCert after handshake is established (this allows connecting to an IP, domains with custom certs, expired certs, valid certs if system CRL is expired etc).
|
TDebugFn = procedure (const Msg: string) of object; |
|
Logging method that is used by functions to report non-critical errors and handshake details.
|
TCertCheckIgnoreFlag = (...); |
|
Flags to ignore some cert aspects when checking manually via CheckServerCert . Mirror of SECURITY_FLAG_IGNORE_* constants
Values
-
ignRevokation: don't check cert revokation (useful if CRL is unavailable)
-
ignUnknownCA: don't check CA
-
ignWrongUsage
-
ignCertCNInvalid: don't check cert name (useful when connecting by IP)
-
ignCertDateInvalid: don't check expiration date
|
TCertCheckResult = (...); |
|
Result of CheckServerCert function
Values
-
ccrValid: Cert is valid
-
ccrTrusted: Cert was in trusted list, no check was performed
-
ccrValidWithFlags: Cert is valid with some ignore flags
|
Constants
LogPrefix = '[SChannel]: '; |
|
Just a suggested prefix for log output
|
IO_BUFFER_SIZE = $10000; |
|
Size of handshake buffer
|
USED_PROTOCOLS: DWORD = SP_PROT_TLS1_1 or SP_PROT_TLS1_2; |
|
Set of used protocols. Note: TLS 1.0 is not used by default, add SP_PROT_TLS1_0 if needed
|
USED_ALGS: ALG_ID = 0; |
|
Detect messages received out of sequence
|
SSPI_FLAGS =
ISC_REQ_SEQUENCE_DETECT or
ISC_REQ_REPLAY_DETECT or
ISC_REQ_CONFIDENTIALITY or
ISC_RET_EXTENDED_ERROR or
ISC_REQ_ALLOCATE_MEMORY or
ISC_REQ_STREAM; |
|
Support a stream-oriented connection
|
S_Msg_Received = 'Received %d bytes of encrypted data / %d bytes of payload'; |
|
Messages that could be written to log by various implementations. None of these are used in this unit
|
S_Msg_SessionClosed = 'Server closed the session [SEC_I_CONTEXT_EXPIRED]'; |
|
|
S_Msg_Renegotiate = 'Server requested renegotiate'; |
|
|
S_Msg_Sending = 'Sending %d bytes of payload / %d bytes encrypted'; |
|
|
S_Msg_StartingTLS = 'Starting TLS handshake'; |
|
|
S_Msg_HShStageW1Success = 'Handshake @W1 - %d bytes sent'; |
|
|
S_Msg_HShStageW1Incomplete = 'Handshake @W1 - ! incomplete data sent'; |
|
|
S_Msg_HShStageW1Fail = 'Handshake @W1 - ! error sending data ([#%d] %s)'; |
|
|
S_Msg_HShStageRFail = 'Handshake @R - ! no data received or error receiving ([#%d] %s)'; |
|
|
S_Msg_HShStageRSuccess = 'Handshake @R - %d bytes received'; |
|
|
S_Msg_HandshakeBug = 'Handshake bug: "%s", retrying'; |
|
|
S_Msg_HShStageW2Success = 'Handshake @W2 - %d bytes sent'; |
|
|
S_Msg_HShStageW2Incomplete = 'Handshake @W2 - ! incomplete data sent'; |
|
|
S_Msg_HShStageW2Fail = 'Handshake @W2 - ! error sending data ([#%d] %s)'; |
|
|
S_Msg_HShExtraData = 'Handshake: got "%d" bytes of extra data'; |
|
|
S_Msg_Established = 'Handshake established'; |
|
|
S_Msg_SrvCredsAuth = 'Server credentials authenticated'; |
|
|
S_Msg_CredsInited = 'Credentials initialized'; |
|
|
S_Msg_AddrIsIP = 'Address "%s" is IP, verification by name is disabled'; |
|
|
S_Msg_ShuttingDownTLS = 'Shutting down TLS'; |
|
|
S_Msg_SendingShutdown = 'Sending shutdown notify - %d bytes of data'; |
|
|
S_Err_ListeningNotSupported = 'Listening is not supported with SChannel yet'; |
|
|
S_Msg_CertIsTrusted = 'Certificate is in trusted list'; |
|
|
S_Msg_CertIsValidWithFlags = 'Certificate is valid using some ignore flags'; |
|
|
Variables
hMYCertStore: HCERTSTORE = nil; |
|
|
g_pSSPI: PSecurityFunctionTable; |
|
|
Generated by PasDoc 0.16.0.