diff --git a/README.md b/README.md index 7cd7e1e..57c5998 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ + # snet-sdk-python - + SingularityNET SDK for Python ## Package @@ -10,78 +11,144 @@ The package is published in PyPI at the following link: |----------------------------------------------|---------------------------------------------------------------------| |[snet.sdk](https://pypi.org/project/snet.sdk/)|Integrate SingularityNET services seamlessly into Python applications| -## Getting Started - -These instructions are for the development and use of the SingularityNET SDK for Python. - ### Core concepts The SingularityNET SDK allows you to make calls to SingularityNET services programmatically from your application. To communicate between clients and services, SingularityNET uses [gRPC](https://grpc.io/). -To handle payment of services, SingularityNET uses [Ethereum state channels](https://dev.singularitynet.io/docs/concepts/multi-party-escrow/). -The SingularityNET SDK abstracts and manages state channels with service providers on behalf of the user and handles authentication with the SingularityNET services. +To handle payment of services, SingularityNET uses +[Ethereum state channels](https://dev.singularitynet.io/docs/concepts/multi-party-escrow/). +The SingularityNET SDK abstracts and manages state channels with service providers on behalf of the user and +handles authentication with the SingularityNET services. + +## Getting Started + +These instructions are for the development and use of the SingularityNET SDK for Python. ### Usage -To call a SingularityNET service, the user must be able to deposit funds (AGIX tokens) to the [Multi-Party Escrow](https://dev.singularitynet.io/docs/concepts/multi-party-escrow/) Smart Contract. -To deposit these tokens or do any other transaction on the Ethereum blockchain, the user must possess an Ethereum identity with available Ether. +To call a service on a SingularityNET platform, the user must be able to deposit funds (AGIX tokens) to the +[Multi-Party Escrow](https://dev.singularitynet.io/docs/concepts/multi-party-escrow/) Smart Contract. +To deposit these tokens or do any other transaction on the Ethereum blockchain. -Once you have installed snet-sdk in your current environment, you can import it into your Python script and create an instance of the base sdk class: +Once you have installed snet-sdk in your current environment, you can import it into your Python script and create an +instance of the base sdk class: ```python from snet import sdk -config = { - "private_key": 'YOUR_PRIVATE_WALLET_KEY', - "eth_rpc_endpoint": f"https://sepolia.infura.io/v3/YOUR_INFURA_KEY", - "email": "your@email.com", - "concurrency": False, - "identity_name": "local_name_for_that_identity", - "identity_type": "key", - "network": "sepolia", - "force_update": False - } + +config = sdk.config.Config(private_key="YOUR_PRIVATE_KEY", + eth_rpc_endpoint=f"https://sepolia.infura.io/v3/YOUR_INFURA_KEY", + concurrency=False, + force_update=False) snet_sdk = sdk.SnetSDK(config) ``` -The `config` parameter is a Python dictionary. -See [test_sdk_client.py](https://github.com/singnet/snet-sdk-python/blob/master/testcases/functional_tests/test_sdk_client.py) for a reference. -#### Config options description +The `config` parameter is an instance of the `Config` class. +See [config.py](https://github.com/singnet/snet-sdk-python/blob/master/docs/main/config.md) +for a reference. + +##### Config parameters description -private_key: Your wallet's private key that will be used to pay for calls. Is **required** to make a call; -eth_rpc_endpoint: RPC endpoint that is used to access the Ethereum network. Is **required** to make a call; -email: Your email; -identity_name: Name that will be used locally to save your wallet settings. You can check your identities in the `~/.snet/config` file; -identity_type: Type of your wallet authentication. Note that snet-sdk currently supports only "key" identity_type; -network: You can set the Ethereum network that will be used to make a call; -force_update: If set to False, will reuse the existing gRPC stubs (if any) instead of downloading proto and regenerating them every time. +- `private_key`: Your wallet's private key that will be used to pay for calls. Is **required** in config; +- `eth_rpc_endpoint`: RPC endpoint that is used to access the Ethereum network. Is **required** in config; +- `wallet_index`: The index of the wallet that will be used to pay for calls; +- `ipfs_endpoint`: IPFS endpoint that is used to access IPFS; +- `concurrency`: If set to True, will enable concurrency for the SDK; +- `force_update`: If set to False, will reuse the existing gRPC stubs (if any) instead of downloading proto and regenerating them every time. +- `mpe_contract_address`: The address of the Multi-Party Escrow smart contract; +- `token_contract_address`: The address of the SingularityNET token smart contract; +- `registry_contract_address`: The address of the Registry smart contract; +- `signer_private_key`: The private key of the signer. Used to sign the service call. Equals to `private_key` by default. -##### List organizations and their services +#### List organizations and their services You can use the sdk client instance`s methods get_organization_list() to list all organizations and get_services_list("org_id") to list all services of a given organization. ```python -print(snet_sdk.get_organization_list()) -print(snet_sdk.get_services_list("26072b8b6a0e448180f8c0e702ab6d2f")) +orgs_list = snet_sdk.get_organization_list() +print(*orgs_list, sep="\n") +# ... +# GoogleOrg3 +# 26072b8b6a0e448180f8c0e702ab6d2f +# 43416d873fcb454589900189474b2eaa +# ... ``` -##### Free call configuration +```python +org_id = "26072b8b6a0e448180f8c0e702ab6d2f" +services_list = snet_sdk.get_services_list(org_id=org_id) +print(*services_list, sep="\n") +# Exampleservice +``` -If you want to use the free calls you will need to pass these arguments to the create_service_client() method: +### Calling the service -``` -"free_call_auth_token-bin":"f2548d27ffd319b9c05918eeac15ebab934e5cfcd68e1ec3db2b92765", -"free-call-token-expiry-block":172800, -``` -You can receive these for a given service from the [Dapp](https://beta.singularitynet.io/) -#### Calling the service -Now, the instance of the sdk can be used to create the service client instances. -Continuing from the previous code here is an example using `Exampleservice` from the `26072b8b6a0e448180f8c0e702ab6d2f` organization: +Now, the instance of the sdk can be used to create the service client instances, using `create_service_client()` method. +Continuing from the previous code here is an example using `Exampleservice` from the `26072b8b6a0e448180f8c0e702ab6d2f` +organization: ```python service_client = snet_sdk.create_service_client(org_id="26072b8b6a0e448180f8c0e702ab6d2f", service_id="Exampleservice", group_name="default_group") ``` + +After executing this code, you should have client libraries created for this service. They are located at the following +path: `~/.snet/org_id/service_id/python/` + +_Note_: Currently you can only save files to `~/.snet/`. + +The instance of service_client that has been generated can be utilized to invoke the methods that the service offers. +You can list these using the `get_services_and_messages_info_as_pretty_string()` method: + +```python +print(service_client.get_services_and_messages_info_as_pretty_string()) +# Service: Calculator +# Method: add, Input: Numbers, Output: Result +# Method: sub, Input: Numbers, Output: Result +# Method: mul, Input: Numbers, Output: Result +# Method: div, Input: Numbers, Output: Result +# Message: Numbers +# Field: float a +# Field: float b +# Message: Result +# Field: float value + +``` + +To invoke the service's methods, you can use the `call_rpc()` method. This method requires the names of the method and +data object, along with the data itself, to be passed into it. +To continue with our example, here’s a call to the *mul* method of the *Exampleservice* from the +*26072b8b6a0e448180f8c0e702ab6d2f* organization: + +```python +result = service_client.call_rpc("mul", "Numbers", a=20, b=3) +print(f"Calculating 20 * 3: {result}") +# Calculating 20 * 3: 60.0 +``` + +For more information about gRPC and how to use it with Python, please see: +- [gRPC Basics - Python](https://grpc.io/docs/tutorials/basic/python.html) +- [gRPC Python’s documentation](https://grpc.io/grpc/python/) + +_Note_: In this example, the user doesn't deposit funds to MPE, doesn't open a channel, and doesn't +perform other actions related to payment. In this case, the choice of payment strategy, as well as, if necessary, +opening a channel and depositing funds into MPE occurs automatically. For more information on payment, please +visit the [Payment](#payment) section. + +## Payment + +### Free call + +If you want to use the free calls you will need to pass these arguments to the `create_service_client()` method: + +```python +free_call_auth_token_bin = "f2548d27ffd319b9c05918eeac15ebab934e5cfcd68e1ec3db2b92765", +free_call_token_expiry_block = 172800 +``` + +You can receive these for a given service from the [Dapp](https://beta.singularitynet.io/) + Creating a service client with free calls included would look like this: ```python service_client = snet_sdk.create_service_client(org_id="26072b8b6a0e448180f8c0e702ab6d2f", @@ -91,29 +158,115 @@ service_client = snet_sdk.create_service_client(org_id="26072b8b6a0e448180f8c0e7 free_call_token_expiry_block=172800) ``` -After executing this code, you should have client libraries created for this service. They are located at the following path: `~/.snet/org_id/service_id/python/` +### Paid call + +#### Open channel with the specified amount of funds and expiration + +`open_channel()`[[1]](#1-this-method-uses-a-call-to-a-paid-smart-contract-function) opens a payment channel with the specified amount of AGIX tokens in cogs and expiration time. +Expiration is payment channel's TTL in blocks. When opening a channel, funds are taken from MPE. So they must be +pre-deposited on it. For this, you can use the `deposit_to_escrow_account()`[[1]](#1-this-method-uses-a-call-to-a-paid-smart-contract-function) +method. -Note: Currently you can only save files to `~/.snet/`. We will fix this in the future. ```python -service_client.deposit_and_open_channel(123456, 33333) +snet_sdk.account.deposit_to_escrow_account(123456) +service_client.open_channel(amount=123456, expiration=33333) ``` -`deposit_and_open_channel(amount, expiration)` function deposits the specified amount of AGIX tokens in cogs into an MPE smart contract and opens a payment channel. Expiration is payment channel's TTL in blocks. -The instance of service_client that has been generated can be utilized to invoke the methods that the service offers. You can list these using the get_services_and_messages_info_as_pretty_string() method: + +You can also use the `deposit_and_open_channel()`[[1]](#1-this-method-uses-a-call-to-a-paid-smart-contract-function) +method instead. It does the same as the previous one, but first deposits the specified amount of AGIX tokens in cogs +into an MPE. + ```python -print(service_client.get_services_and_messages_info_as_pretty_string()) +service_client.deposit_and_open_channel(amount=123456, expiration=33333) ``` -To invoke the service`s methods, you can use the the call_rpc() method. This method requires the names of the method and data object, along with the data itself, to be passed into it. -To continue with our example, here’s a call to the *mul* method of the *Exampleservice* from the *26072b8b6a0e448180f8c0e702ab6d2f* organization: +#### Extend expiration and add funds + +`open_channel()` as well as `deposit_and_open_channel()` returns the payment channel. You can use it to add funds to it +and extend its expiration using the following methods: +`add_funds()`[[1]](#1-this-method-uses-a-call-to-a-paid-smart-contract-function), +`extend_expiration`[[1]](#1-this-method-uses-a-call-to-a-paid-smart-contract-function) +and `extend_and_add_funds()`[[1]](#1-this-method-uses-a-call-to-a-paid-smart-contract-function). ```python -result = service_client.call_rpc("mul", "Numbers", a=20, b=3) -print(f"Calculating 20 * 3: {result}") # Calculating 20 * 3: 60.0 +payment_channel = service_client.open_channel(amount=123456, expiration=33333) + +payment_channel.add_funds(amount=123456) +payment_channel.extend_expiration(expiration=33333) + +payment_channel.extend_and_add_funds(amount=123456, expiration=33333) ``` -For more information about gRPC and how to use it with Python, please see: -- [gRPC Basics - Python](https://grpc.io/docs/tutorials/basic/python.html) -- [gRPC Python’s documentation](https://grpc.io/grpc/python/) +## Other useful features + +#### Get the current block number + +Service client also provides several useful functions. If you need to find out the number of +the current block in the blockchain, there is a `get_current_block_number()` method for this: + +```python +block_number = service_client.get_current_block_number() +print(f"Current block is {block_number}") +# Current block is 6574322 +``` + +#### Get the service call price + +To find out the price of calling a service function, you need to use the `get_price()` method: + +```python +price = service_client.get_price() +print(f"The price in cogs for calling the service {service_client.service_id} is {price}") +# The price in cogs for calling the service Exampleservice is 1 +``` + +#### Get the metadata of the service + +The metadata of services is stored in IPFS. To view it, you need to call the `get_service_metadata()` method, passing +the organization id and the service id to it. + +```python +service_metadata = snet_sdk.get_service_metadata(org_id="26072b8b6a0e448180f8c0e702ab6d2f", service_id="Exampleservice") +print(*service_metadata.m.items(), sep="\n", end="\n\n") +print(*service_metadata.get_tags(), sep=",", end="\n\n") +print(*service_metadata.get_all_endpoints_for_group(group_name="default_group"), sep=",", end="\n\n") + +# ('version', 1) +# ('display_name', 'Example service') +# ('encoding', 'proto') +# ('service_type', 'grpc') +# ('model_ipfs_hash', 'QmeyrQkEyba8dd4rc3jrLd5pEwsxHutfH2RvsSaeSMqTtQ') +# ('mpe_address', '0x7E0aF8988DF45B824b2E0e0A87c6196897744970') +# ('groups', [{'free_calls': 0, 'free_call_signer_address': '0x7DF35C98f41F3Af0df1dc4c7F7D4C19a71Dd059F', 'daemon_addresses': ['0x0709e9b78756b740ab0c64427f43f8305fd6d1a7'], 'pricing': [{'default': True, 'price_model': 'fixed_price', 'price_in_cogs': 1}], 'endpoints': ['http://node1.naint.tech:62400'], 'group_id': '/mb90Qs8VktxGQmU0uRu0bSlGgqeDlYrKrs+WbsOvOQ=', 'group_name': 'default_group'}]) +# ('service_description', {'url': 'https://ropsten-v2-publisher.singularitynet.io/org', 'short_description': 'Example service', 'description': 'Example service'}) +# ('media', [{'order': 1, 'url': 'https://ropsten-marketplace-service-assets.s3.us-east-1.amazonaws.com/26072b8b6a0e448180f8c0e702ab6d2f/services/d05c62bf9aa84843a195457d98417f4e/assets/20240327124952_asset.jpeg', 'file_type': 'image', 'asset_type': 'hero_image', 'alt_text': ''}]) +# ('contributors', [{'name': 'test', 'email_id': ''}]) +# ('tags', ['exampleservice']) +# +# exampleservice +# +# http://node1.naint.tech:62400 +``` + +#### Get raw services and messages info + +In the section [Calling the service](#calling-the-service) we already talked about the function +`get_services_and_messages_info_as_pretty_string()`, with which you can get information about the methods and +messages of a service. But if you need to process lists of services and messages, it is better to use the +`get_services_and_messages_info()` method. + +```python +services, messages = service_client.get_services_and_messages_info() +print(services) +print(messages) + +# {'Calculator': [('add', 'Numbers', 'Result'), ('sub', 'Numbers', 'Result'), ('mul', 'Numbers', 'Result'), ('div', 'Numbers', 'Result')]} +# {'Numbers': [('float', 'a'), ('float', 'b')], 'Result': [('float', 'value')]} +``` + +--- + +###### 1 This method uses a call to a paid smart contract function. --- @@ -146,4 +299,4 @@ $ pip install -e . ## License This project is licensed under the MIT License - see the -[LICENSE](https://github.com/singnet/snet-sdk-python/blob/master/LICENSE) file for details. \ No newline at end of file +[LICENSE](https://github.com/singnet/snet-sdk-python/blob/master/LICENSE) file for details. diff --git a/docs/main/account.md b/docs/main/account.md new file mode 100644 index 0000000..c951c99 --- /dev/null +++ b/docs/main/account.md @@ -0,0 +1,208 @@ +## module: sdk.account + +[Link](https://github.com/singnet/snet-sdk-python/blob/master/snet/sdk/account.py) to GitHub + +Entities: +1. [TransactionError](#class-transactionerror) + - [\_\_init\_\_](#__init__) + - [\_\_str\_\_](#__str__) +2. [Account](#class-account) + - [\_\_init\_\_](#__init__-1) + - [_get_nonce](#_get_nonce) + - [_get_gas_price](#_get_gas_price) + - [_send_signed_transaction](#_send_signed_transaction) + - [send_transaction](#send_transaction) + - [_parse_receipt](#_parse_receipt) + - [escrow_balance](#escrow_balance) + - [deposit_to_escrow_account](#deposit_to_escrow_account) + - [approve_transfer](#approve_transfer) + - [allowance](#allowance) + +### Class `TransactionError` + +extends: `Exception` + +is extended by: - + +#### description + +`TransactionError` is a custom exception class that is raised when an Ethereum transaction receipt has a status of 0. +This indicates that the transaction failed. Can provide a custom message. Optionally includes receipt + +#### attributes + +- `message` (str): The exception message. +- `receipt` (dict): The transaction receipt. + +#### methods + +#### `__init__` + +Initializes the exception with the provided message and receipt. + +###### args: + +- `message` (str): The exception message. +- `receipt` (dict): The transaction receipt. Defaults to _None_. + +###### returns: + +- _None_ + +#### `__str__` + +Returns a string representation of the `TransactionError` object. + +###### returns: + +- A string containing the `message` attribute of the TransactionError object. (str) + +### Class `Account` + +extends: - + +is extended by: - + +#### description + +`Account` is responsible for managing the Ethereum account associated with the SingularityNET platform. +It provides methods for interacting with the MultiPartyEscrow contract, the SingularityNetToken contract, and +the Ethereum blockchain. + +#### attributes + +- `config` (dict): The configuration settings for the account. _Note_: In fact, this is the same config +from `SnetSDK`. +- `web3` (Web3): An instance of the `Web3` class for interacting with the Ethereum blockchain. +- `mpe_contract` (MPEContract): An instance of the `MPEContract` class for interacting with +the MultiPartyEscrow contract. +- `token_contract` (Contract): An instance of the `Contract` class from the `web3` library for interacting +with the SingularityNET AGIX Token contract. +- `private_key` (str): The private key associated with the account. +- `signer_private_key` (str): The private key used for signing transactions. +- `address` (str): The Ethereum address associated with the account. +- `signer_address` (str): The Ethereum address used for signing transactions. +- `nonce` (int): The nonce value for the account. + +#### methods + +#### `__init__` + +Initializes a new instance of the `Account` class. + +###### args: + +- `w3` (Web3): An instance of the `Web3` class. +- `config` (dict): A dictionary containing the configuration settings. +- `mpe_contract` (MPEContract): An instance of the `MPEContract` class. + +###### returns: + +- _None_ + +#### `_get_nonce` + +Returns the next nonce for a transaction. + +###### returns: + +- The next nonce for a transaction. (int) + +#### `_get_gas_price` + +Calculates the gas price for a transaction. + +Retrieves the current gas price from the Ethereum network using the web3 and increases it +according to a certain algorithm so that the transaction goes faster. + +###### returns: + +- The calculated gas price. (int) + +#### `_send_signed_transaction` + +Sends a signed transaction to the Ethereum blockchain. + +Builds a transaction using the given contract function and arguments, signs it with the private key of the account, +and sends it to the Ethereum blockchain. + +###### args: + +- `contract_fn`: The contract function to be called. +- `*args`: The arguments to pass to the contract function. + +###### returns: + +- Hash of the sent transaction. (HexStr | str) + +#### `send_transaction` + +Sends a transaction by calling the given contract function with the provided arguments. + +###### args: + +- `contract_fn`: The contract function to be called. +- `*args`: The arguments to pass to the contract function. + +###### returns: + +- The transaction receipt indicating the success or failure of the transaction. (TxReceipt) + +#### `_parse_receipt` + +Parses the receipt of a transaction and returns the result as a JSON string. + +###### args: + +- `receipt` (TxReceipt): The receipt of the transaction. +- `event` (Event): The event to process the receipt with. +- `encoder` (JSONEncoder): The JSON encoder to use. Defaults to json.JSONEncoder. + +###### returns: + +- The result of processing the receipt as a JSON string. (str) + +###### raises: + +- TransactionError: If the transaction status is 0, indicating a failed transaction. + +#### `escrow_balance` + +Retrieves the escrow balance for the current account. + +###### returns: + +- The escrow balance in cogs. (int) + +#### `deposit_to_escrow_account` + +Deposit the specified amount of AGIX tokens in cogs into the MPE account. + +###### args: + +- `amount_in_cogs` (int): The amount of AGIX tokens in cogs to deposit. + +###### returns: + +- The transaction receipt of the transaction. (TxReceipt) + +#### `approve_transfer` + +Approves a transfer of a specified amount of AGIX tokens in cogs to the MPE contract. + +###### args: + +- `amount_in_cogs` (int): The amount of AGIX tokens in cogs to approve for transfer. + +###### returns: + +- The transaction receipt of the transaction. (TxReceipt) + +#### `allowance` + +Retrieves the allowance of the current account for the MPE contract. + +###### returns: + +- The allowance in cogs. (int) + diff --git a/docs/main/client_lib_generator.md b/docs/main/client_lib_generator.md new file mode 100644 index 0000000..77cd6d5 --- /dev/null +++ b/docs/main/client_lib_generator.md @@ -0,0 +1,75 @@ +## module: sdk.client_lib_generator + +[Link](https://github.com/singnet/snet-sdk-python/blob/master/snet/sdk/client_lib_generator.py) to GitHub + +Entities: +1. [ClientLibGenerator](#class-clientlibgenerator) + - [\_\_init\_\_](#__init__) + - [generate_client_library](#generate_client_library) + - [_get_service_metadata_from_registry](#_get_service_metadata_from_registry) + - [_get_service_registration](#_get_service_registration) + +### Class `ClientLibGenerator` + +extends: - + +is extended by: - + +#### description + +This class is used to generate client library files for a given service. + +#### attributes + +- `sdk_config` (Config): An instance of the `Config` class +- `registry_contract` (web3.contract.Contract): An instance of the `Contract` class (from `snet.cli`) for interacting with the Registry contract. +- `org_id` (str): The organization ID of the service. +- `service_id` (str): The service ID. +- `language` (str): The language of the client library. Default is `python`. +- `protodir` (str): The directory where the .proto files are located. Default is `~/.snet`. + +#### methods + +#### `__init__` + +Initializes a new instance of the class. Initializes the attributes by arguments values. + +###### args: + +- `sdk_config` (Config): An instance of the `Config` class +- `registry_contract` (web3.contract.Contract): An instance of the `Contract` class (from `snet.cli`) for interacting with the Registry contract. +- `org_id` (str): The organization ID of the service. +- `service_id` (str): The service ID. + +###### returns: + +- _None_ + +#### `generate_client_library` + +Generates client library stub files based on specified organization and service ids, including: +- getting service metadata from Registry +- getting .proto file from IPFS +- compiling .proto file to stub file and saving it in a given directory + +#### `_get_service_metadata_from_registry` + +Retrieves service metadata. Fetches the service registration from the Registry contract, extracts the metadata URI, +downloads the metadata from IPFS, and parses it into a `MPEServiceMetadata` object. + +###### returns: + +- The service metadata. (MPEServiceMetadata) + +#### `_get_service_registration` + +Retrieves the service registration from the Registry contract using the `getServiceRegistrationById` function of it. + +###### returns: + +- Dictionary containing the service registration. (dict[str, Any]) + +###### raises: + +- `Exception`: If the service with the specified ID is not found in the organization. + diff --git a/docs/main/concurrency_manager.md b/docs/main/concurrency_manager.md new file mode 100644 index 0000000..ff578fa --- /dev/null +++ b/docs/main/concurrency_manager.md @@ -0,0 +1,133 @@ +## module: sdk.concurrency_manager + +[Link](https://github.com/singnet/snet-sdk-python/blob/master/snet/sdk/concurrency_manager.py) to GitHub + +Entities: +1. [ConcurrencyManager](#class-concurrencymanager) + - [\_\_init\_\_](#__init__) + - [concurrent_calls](#concurrent_calls) + - [get_token](#get_token) + - [__get_token](#__get_token) + - [__get_stub_for_get_token](#__get_stub_for_get_token) + - [__get_token_for_amount](#__get_token_for_amount) + - [record_successful_call](#record_successful_call) + +### Class `ConcurrencyManager` + +extends: - + +is extended by: - + +#### description + +`ConcurrencyManager` provides a mechanism for managing the concurrency of service calls in the SDK. +It ensures that only a certain number of concurrent calls are made and handles the retrieval and management +of tokens for making service calls. + +#### attributes + +- `__concurrent_calls` (int): The number of concurrent calls allowed. +- `__token` (str): The token used for concurrent calls. +- `__planned_amount` (int): The planned amount for the payment. +- `__used_amount` (int): The amount used for the payment. + +#### methods + +#### `__init__` + +Initializes a new instance of the class. + +###### args: + +- concurrent_calls (int): The number of concurrent calls allowed. + +###### returns: + +- _None_ + +#### `concurrent_calls` + +decorator: `@property` + +Returns the number of concurrent calls allowed. + +###### returns: + +- The number of concurrent calls allowed. (int) + +#### `get_token` + +Retrieves a token for making service calls. + +###### args: + +- `service_client` (ServiceClient): The service client instance. +- `channel` (PaymentChannel): The payment channel instance. +- `service_call_price` (int): The price of a service call. + +###### returns: + +- The token for making service calls. (str) + +#### `__get_token` + +Retrieves a token for a service call. + +###### args: + +- `service_client` (ServiceClient): The service client instance. +- `channel` (PaymentChannel): The payment channel instance. +- `service_call_price` (int): The price of a service call. +- `new_token` (bool): Whether is needed a new token. Defaults to `False`. + +###### returns: + +- The token for the service call. (str) + +###### raises: + +- grpc.RpcError: If an error occurs while retrieving the token. + +#### `__get_stub_for_get_token` + +Retrieves the gRPC service stub for the TokenServiceStub. + +###### args: + +- `service_client` (ServiceClient): The service client instance. + +###### returns: + +- The gRPC service stub for the TokenServiceStub. (ServiceStub) + +#### `__get_token_for_amount` + +Retrieves a token for a given amount from the token service. + +This function retrieves a token for a given amount from the token service. It first retrieves the nonce +from the channel state, then it creates a stub for the token service using the `get_stub_for_get_token` +method. It then imports the `token_service_pb2` module and retrieves the current block number from the +service client's SDK web3 instance. It generates a message using the `solidity_keccak` method from the +`web3.Web3` class and generates signatures using the `generate_signature` method from the service client. +It creates a `TokenRequest` object with the necessary parameters and sends it to the token service using +the `GetToken` method of the stub. Finally, it returns the token reply object containing the token. + +###### args: + +- `service_client` (ServiceClient): The service client instance. +- `channel` (PaymentChannel): The payment channel instance. +- `amount` (int): The amount for which the token is requested. + +###### returns: + +- The token reply object containing the token. (Any) + +#### `record_successful_call` + +Increments the `__used_amount` attribute by 1 to record a successful call. + +###### returns: + +- _None_ + + \ No newline at end of file diff --git a/docs/main/config.md b/docs/main/config.md new file mode 100644 index 0000000..8954be0 --- /dev/null +++ b/docs/main/config.md @@ -0,0 +1,97 @@ +## module: sdk.config + +[Link](https://github.com/singnet/snet-sdk-python/blob/master/snet/sdk/config.py) to GitHub + +Entities: +1. [Config](#class-config) + - [\_\_init\_\_](#__init__) + - [\_\_getitem\_\_](#__getitem__) + - [get](#get) + - [get_ipfs_endpoint](#get_ipfs_endpoint) + + +### Class `Config` + +extends: - + +is extended by: - + +#### description + +This is a configuration manager for the SDK. It is responsible for handling configuration settings for the SDK. + +#### attributes + +- `__config` (dict): The dictionary containing: + - `private_key` (str): Your wallet's private key that will be used to pay for calls. Is **required** in config. + - `eth_rpc_endpoint` (str): RPC endpoint that is used to access the Ethereum network. Is **required** in config. + - `wallet_index` (int): The index of the wallet that will be used to pay for calls. + - `ipfs_endpoint` (str): IPFS endpoint that is used to access IPFS. Defaults to _"/dns/ipfs.singularitynet.io/tcp/80/"_. + - `concurrency` (bool): If set to True, will enable concurrency for the SDK. + - `force_update` (bool): If set to False, will reuse the existing gRPC stubs (if any) instead of downloading proto +and regenerating them every time. + - `mpe_contract_address` (str): The address of the Multi-Party Escrow smart contract. + - `token_contract_address` (str): The address of the SingularityNET token smart contract. + - `registry_contract_address` (str): The address of the Registry smart contract. + - `signer_private_key` (str): The private key of the signer. Used to sign the service call. Equals to `private_key` +by default. + +#### methods + +#### `__init__` + +Initializes a new instance of the class. Sets `__config` fields from passed arguments. + +###### args: + +- `private_key` (str): Your wallet's private key that will be used to pay for calls. Is **required** in config. +- `eth_rpc_endpoint` (str): RPC endpoint that is used to access the Ethereum network. Is **required** in config. +- `wallet_index` (int): The index of the wallet that will be used to pay for calls. Defaults to _0_. +- `ipfs_endpoint` (str): IPFS endpoint that is used to access IPFS. Defaults to _None_. +- `concurrency` (bool): If set to True, will enable concurrency for the SDK. Defaults to _True_. +- `force_update` (bool): If set to False, will reuse the existing gRPC stubs (if any) instead of downloading proto +and regenerating them every time. Defaults to _False_. +- `mpe_contract_address` (str): The address of the Multi-Party Escrow smart contract. Defaults to _None_. +- `token_contract_address` (str): The address of the SingularityNET token smart contract. Defaults to _None_. +- `registry_contract_address` (str): The address of the Registry smart contract. Defaults to _None_. +- `signer_private_key` (str): The private key of the signer. Used to sign the service call. Equals to `private_key` +by default. + +###### returns: + +- _None_ + +#### `__getitem__` + +Overrides the `__getitem__` Python special method. Returns the value associated with the given key from +the `__config` dict. + +###### args: + +- `key` (str): The key of the value to retrieve. + +###### returns: + +- The value associated with the given key. (Any) + +#### `get` + +Returns the value associated with the given key from the `__config` dict or the default value if the key is not found. + +###### args: + +- `key` (str): The key of the value to retrieve. +- `default` (Any): The default value to return if the key is not found. Defaults to _None_. + +###### returns: + +- The value associated with the given key or the default value if the key is not found. (Any) + +#### `get_ipfs_endpoint` + +Returns the `ipfs_endpoint` field value from the `__config` dict. + +###### returns: + +- The IPFS endpoint. (str) + diff --git a/docs/main/init.md b/docs/main/init.md new file mode 100644 index 0000000..d97949b --- /dev/null +++ b/docs/main/init.md @@ -0,0 +1,214 @@ +## module: sdk.\_\_init\_\_ + +[Link](https://github.com/singnet/snet-sdk-python/blob/master/snet/sdk/__init__.py) to GitHub + +Entities: +1. [SnetSDK](#class-snetsdk) + - [\_\_init\_\_](#__init__) + - [create_service_client](#create_service_client) + - [get_service_stub](#get_service_stub) + - [get_path_to_pb_files](#get_path_to_pb_files) + - [get_module_by_keyword](#get_module_by_keyword) + - [get_service_metadata](#get_service_metadata) + - [_get_first_group](#_get_first_group) + - [_get_group_by_group_name](#_get_group_by_group_name) + - [_get_service_group_details](#_get_service_group_details) + - [get_organization_list](#get_organization_list) + - [get_services_list](#get_services_list) + +### Class `SnetSDK` + +extends: - + +is extended by: - + +#### description + +The SnetSDK class is the main entry point for interacting with the SingularityNET platform. +It provides methods for creating service clients, managing identities, and configuring the SDK. + +#### attributes + +- `_sdk_config` (Config): An instance of the `Config` class. +- `_metadata_provider` (MetadataProvider): An instance of the `MetadataProvider` class. _Note_: There is currently only +one implementation of `MetadataProvider` which is `IPFSMetadataProvider`, so this attribute can only be initialized to +`IPFSMetadataProvider` at this time. +- `web3` (Web3): An instance of the `Web3` class for interacting with the Ethereum blockchain. +- `mpe_contract` (MPEContract): An instance of the `MPEContract` class for interacting with the MultiPartyEscrow contract. +- `ipfs_client` (ipfshttpclient.Client): An instance of the `ipfshttpclient.Client` class for interacting with the +InterPlanetary File System. +- `registry_contract` (Contract): An instance of the `Contract` class (from `snet.cli`) for interacting with the Registry contract. +- `account` (Account): An instance of the `Account` class for interacting with the MultiPartyEscrow and +SingularityNetToken contracts. + +#### methods + +#### `__init__` + +Initializes a new instance of the `SnetSDK` class. Initializes `web3` with the specified Ethereum RPC endpoint. +Instantiates the MPE contract with the specified contract address if provided, otherwise uses the default MPE contract. +Instantiates the IPFS client with the specified IPFS endpoint if provided, otherwise uses the default IPFS endpoint. +Instantiates the Registry contract with the specified contract address if provided, otherwise uses the default Registry +contract. Instantiates the Account object with the specified Web3 client, SDK configuration, and MPE contract. + +###### args: + +- `sdk_config` (Config): A `Config` object containing the SDK configuration. +- `metadata_provider` (MetadataProvider): A `MetadataProvider` object. Defaults to _None_. + +###### returns: + +- _None_ + +#### `create_service_client` + +If `force_update` is True or if there are no gRPC stubs for the given service, the proto files are loaded +and compiled using the `generate_client_library()` method of the `ClientLibGenerator` class instance. +It then initializes `payment_channel_management_strategy` to `DefaultPaymentStrategy` if it is not specified. +It also sets the `options` dictionary with some default values. If `self._metadata_provider` is not specified +it is initialized by `IPFSMetadataProvider`. It also gets the service stub using the `self.get_service_stub` +method and the pb2 module using the `self.get_module_by_keyword` method. Finally, it creates a new instance +of the `ServiceClient` class with all the required parameters, which is then returned. + +###### args: + +- `org_id` (str): The ID of the organization. +- `service_id` (str): The ID of the service. +- `group_name` (str): The name of the payment group. Defaults to _None_. +- `payment_channel_management_strategy` (PaymentStrategy): The payment channel management strategy. Defaults to _None_. +- `free_call_auth_token_bin` (str): The free call authentication token in binary format. Defaults to _None_. +- `free_call_token_expiry_block` (int): The block number when the free call token expires. Defaults to _None_. +- `options` (dict): Additional options for the service client. Defaults to _None_. +- `concurrent_calls` (int): The number of concurrent calls allowed. Defaults to 1. + +###### returns: + +- The created service client instance. (ServiceClient) + +#### `get_service_stub` + +Retrieves the gRPC service stub for the given organization and service ID. + +###### args: + +- `org_id` (str): The ID of the organization. +- `service_id` (str): The ID of the service. + +###### returns: + +- The gRPC service stub for the given organization and service ID. (ServiceStub) + +###### raises: + +- Exception: If an error occurs while importing a module. + +#### `get_path_to_pb_files` + +Returns the path to the directory containing the protobuf files for a given organization and service. + +###### args: + +- `org_id` (str): The ID of the organization. +- `service_id` (str): The ID of the service. + +###### returns: + +- The path to the directory containing the protobuf files. (str) + +#### `get_module_by_keyword` + +Retrieves the module name from the given organization ID, service ID, and keyword. + +###### args: + +- `org_id` (str): The ID of the organization. +- `service_id` (str): The ID of the service. +- `keyword` (str): The keyword used to search for the module. + +###### returns: + +- The module name extracted from the file name. (ModuleName) + +#### `get_service_metadata` + +Retrieves metadata for a given service in a given organization using Registry first and then IPFS. + +###### args: + +- `org_id` (str): The ID of the organization. +- `service_id` (str): The ID of the service. + +###### returns: + +- The metadata for the service. (MPEServiceMetadata) + +###### raises: + +- Exception: If the service is not found in the specified organization. + +#### `_get_first_group` + +Returns the first payment group from the given service metadata. + +###### args: + +- `service_metadata` (MPEServiceMetadata): An instance of `MPEServiceMetadata` class. + +###### returns: + +- The first group from the service metadata. (dict) + +#### `_get_group_by_group_name` + +Returns a payment group from the given service metadata based on the group name. + +###### args: + +- `service_metadata` (MPEServiceMetadata): An instance of `MPEServiceMetadata` class. +- `group_name` (str): The name of the group to search for. + +###### returns: + +- The group with the matching group name, or an empty dictionary if no match is found. (dict) + +#### `_get_service_group_details` + +Returns a payment group from the given service metadata based on the group name or the first payment group if +group name is not specified. + +###### args: + +- `service_metadata` (MPEServiceMetadata): An instance of `MPEServiceMetadata` class. +- `group_name` (str): The name of the group to search for. + +###### returns: + +- The group with the matching group name, or the first group if name is not specified. (dict) + +###### raises: + +- Exception: If no groups are found for the given service. + +#### `get_organization_list` + +Retrieves a list of organization IDs from the Registry contract. + +###### returns: + +- A list of strings representing the organization IDs. (list) + +#### `get_services_list` + +Retrieves a list of service IDs for a given organization from the Registry contract. + +###### args: + +- `org_id` (str): The ID of the organization. + +###### returns: + +- A list of strings representing the service IDs. (list) + +###### raises: + +- Exception: If the organization with the given ID does not exist. diff --git a/docs/main/service_client.md b/docs/main/service_client.md new file mode 100644 index 0000000..11df1b9 --- /dev/null +++ b/docs/main/service_client.md @@ -0,0 +1,373 @@ +## module: sdk.service_client + +[Link](https://github.com/singnet/snet-sdk-python/blob/master/snet/sdk/service_client.py) to GitHub + +Entities: +1. [ServiceClient](#class-serviceclient) + - [\_\_init\_\_](#__init__) + - [call_rpc](#call_rpc) + - [_generate_grpc_stub](#_generate_grpc_stub) + - [get_grpc_base_channel](#get_grpc_base_channel) + - [_get_grpc_channel](#_get_grpc_channel) + - [_get_service_call_metadata](#_get_service_call_metadata) + - [_filter_existing_channels_from_new_payment_channels](#_filter_existing_channels_from_new_payment_channels) + - [load_open_channels](#load_open_channels) + - [get_current_block_number](#get_current_block_number) + - [update_channel_states](#update_channel_states) + - [default_channel_expiration](#default_channel_expiration) + - [_generate_payment_channel_state_service_client](#_generate_payment_channel_state_service_client) + - [open_channel](#open_channel) + - [deposit_and_open_channel](#deposit_and_open_channel) + - [get_price](#get_price) + - [generate_signature](#generate_signature) + - [generate_training_signature](#generate_training_signature) + - [get_free_call_config](#get_free_call_config) + - [get_service_details](#get_service_details) + - [get_concurrency_flag](#get_concurrency_flag) + - [get_concurrency_token_and_channel](#get_concurrency_token_and_channel) + - [set_concurrency_token_and_channel](#set_concurrency_token_and_channel) + - [get_path_to_pb_files](#get_path_to_pb_files) + - [get_services_and_messages_info](#get_services_and_messages_info) + - [get_services_and_messages_info_as_pretty_string](#get_services_and_messages_info_as_pretty_string) + +### Class `ServiceClient` + +extends: - + +is extended by: - + +#### description + +This class is responsible for creating a client for interacting with a service. +It initializes various attributes and sets up a gRPC channel for communication with the service. +The class is used to manage the communication and payment channel management for a service in the SDK. + +#### attributes + +- `org_id` (str): The organization id. +- `service_id` (str): The service id. +- `options` (dict): Additional options for the service client. +- `group` (dict): The payment group details. +- `service_metadata` (MPEServiceMetadata): An instance of the `MPEServiceMetadata` class with the metadata of +the specified service. +- `payment_strategy` (PaymentStrategy): The payment strategy. _Note_: In fact, this is an instance of one of +the `PaymentStrategy` inheritor classes. +- `expiry_threshold` (int): The payment expiration threshold (in blocks). +- `__base_grpc_channel` (grpc.Channel): The base gRPC channel. +- `grpc_channel` (grpc.Channel): The gRPC channel with interceptor. +- `payment_channel_provider` (PaymentChannelProvider): An instance of the `PaymentChannelProvider` class for +working with channels and interacting with MPE. +- `service` (Any): The gRPC service stub instance. +- `pb2_module` (ModuleType): The imported protobuf module. +- `payment_channels` (list[PaymentChannel]): The list of payment channels. +- `last_read_block` (int): The last read block number. +- `account` (Account): An instance of the `Account` class for interacting with the MultiPartyEscrow and +SingularityNetToken contracts. +- `sdk_web3` (Web3): The `Web3` instance. +- `mpe_address` (str): The MPE contract address. + +#### methods + +#### `__init__` + +Initializes a new instance of the class. + +###### args: + +- `org_id` (str): The ID of the organization. +- `service_id` (str): The ID of the service. +- `service_metadata` (MPEServiceMetadata): The metadata for the service. +- `group` (dict): The payment group from the service metadata. +- `service_stub` (ServiceStub): The gRPC service stub. +- `payment_strategy` (PaymentStrategy): The payment channel management strategy. +- `options` (dict): Additional options for the service client. +- `mpe_contract` (MPEContract): The MPE contract instance. +- `account` (Account): An instance of the `Account` class. +- `sdk_web3` (Web3): The `Web3` instance. +- `pb2_module` (str | ModuleType): The module containing the gRPC message definitions. + +###### returns: + +- _None_ + +#### `call_rpc` + +Calls an RPC method on the service client and returns its result. + +###### args: + +- `rpc_name` (str): The name of the RPC method to call. +- `message_class` (str): The name of the message class to use for the request. +- `**kwargs`: Keyword arguments to pass to the message class constructor, in fact, these are the values +that are passed to the called method as arguments. + +###### returns: + +- The response from the RPC method call. (Any) + +#### `_generate_grpc_stub` + +Generates a gRPC stub instance for the given service stub. + +###### args: + +- `service_stub` (ServiceStub): The gRPC service stub. + +###### returns: + +- stub_instance (object): The generated gRPC stub instance. + +#### `get_grpc_base_channel` + +Returns the base gRPC channel used by the service client. + +###### returns: + +- `self.__base_grpc_channel` (grpc.Channel) + +#### `_get_grpc_channel` + +Returns a gRPC channel based on the provided endpoint. + +Retrieves the endpoint from the options dictionary or from the service metadata. If no endpoint is provided, +it uses the first endpoint from the group specified in the service metadata. The endpoint is parsed using +the `urlparse` function to extract the hostname and port. If a port is specified, it is concatenated with +the hostname to form the channel endpoint. Otherwise, only the hostname is used as the channel endpoint. +The scheme of the endpoint is used to determine the type of channel to be created. If the scheme is "http", +an insecure channel is created using the channel endpoint. If the scheme is "https", a secure channel is +created using the channel endpoint and the root certificates. If the scheme is neither "http" nor "https", +a ValueError is raised with an error message. + +###### returns: + +- The gRPC channel based on the provided endpoint. (grpc.Channel) + +###### raises: + +- ValueError: If the scheme in the service metadata is neither "http" nor "https". + +#### `_get_service_call_metadata` + +Retrieves the metadata required for making a service call using the payment strategy. + +###### returns: + +- Payment metadata. (list[tuple[str, Any]]) + + + +#### `_filter_existing_channels_from_new_payment_channels` + +Filters the new channel list so that only those that are not yet among the existing ones remain, +and returns them as a list. + +###### args: + +- `new_payment_channels` (list[PaymentChannel]): A list of `PaymentChannel` objects representing the new +payment channels to filter. + +###### returns: + +- A list of the new payment channels that are not already in the `self.payment_channels` list. (list[PaymentChannel]) + +#### `load_open_channels` + +Load open payment channels and update the payment channels list. + +Retrieves open payment channels from the payment channel provider based on the current account, payment address, +group ID, and last read block. It then filters out any existing channels from the new payment channels and +updates the payment channels list with the new channels. Finally, it updates the last read block with the +current block number and returns the updated payment channels list. + +###### returns: + +- The updated payment channels list. (list[PaymentChannel]) + +#### `get_current_block_number` + +Returns the current block number from the Ethereum blockchain using Web3. + +###### returns: + +- The current block number. (int) + +#### `update_channel_states` + +Updates the state of each channel in the `payment_channels` list. + +###### returns: + +- `self.payment_channels` with updated states. (list[PaymentChannel]) + +#### `default_channel_expiration` + +Returns the default expiration time for the payment channel, calculated as the current block number +plus the expiry threshold. + +###### returns: + +- The default expiration time for a payment channel (block number). (int) + +#### `_generate_payment_channel_state_service_client` + +Generates a payment channel state service client. + +Creates a gRPC channel using the base channel and imports the necessary modules for the +state service. It then uses the imported module to create a PaymentChannelStateServiceStub object, which +is the client for the payment channel state service. + +###### returns: + +- Payment channel state service client stub. (Any) + +#### `open_channel` + +Opens a payment channel with the specified amount of AGIX tokens in cogs and expiration time. + +###### args: + +- `amount` (int): The amount of AGIX tokens in cogs to deposit into the channel. +- `expiration` (int): The expiration time of the payment channel in blocks. + +###### returns: + +- Newly opened payment channel. (PaymentChannel) + +#### `deposit_and_open_channel` + +Deposits the specified amount of tokens into the MPE smart contract and opens a payment channel +with its amount of AGIX tokens in cogs and expiration time. + +###### args: + +- `amount` (int): The amount of AGIX tokens in cogs to deposit into the channel. +- `expiration` (int): The expiration time of the payment channel in blocks. + +###### returns: + +- Newly opened payment channel. (PaymentChannel) + +#### `get_price` + +Returns the price in cogs of the service group's pricing. + +###### returns: + +- The price in cogs of the service group's pricing. (int) + +#### `generate_signature` + +Generates a signature for the given message using the account's signer private key. + +###### args: + +- `message` (str | bytes): The message to sign. + +###### returns: + +- The generated signature. (bytes) + +#### `generate_training_signature` + +Generates a training signature by signing a message using the account's signer private key. + +###### args: + +- `text` (str): The text to be included in the message. +- `address` (str): The address to be included in the message. +- `block_number` (int): The block number to be included in the message. + +###### returns: + +- The generated training signature. (str | bytes) + +#### `get_free_call_config` + +Retrieves the free call configuration from the `self.options` dict. + +###### returns: + +- A tuple containing the email, free call auth token bin, and free call token expiry block. (tuple[str, str, int]) + +#### `get_service_details` + +Retrieves the details of the service. + +###### returns: + +- A tuple containing the organization ID, service ID, group ID, and the first endpoint for the group. +(tuple[str, str, str, str]) + +#### `get_concurrency_flag` + +Returns the value of the `concurrency` option from the `self.options` dict. +If the option is not present, it returns `True` by default. + +###### returns: + +- A value indicating whether concurrency is enabled or not. (bool) + +#### `get_concurrency_token_and_channel` + +Retrieves the concurrency token and channel from the payment strategy. + +###### returns: + +- The concurrency token and channel obtained from the payment strategy. (tuple[str, PaymentChannel]) + +#### `set_concurrency_token_and_channel` + +Sets the concurrency token and channel for the payment strategy. + +###### args: + +- `token` (str): The concurrency token. +- `channel` (PaymentChannel): The payment channel. + +###### returns: + +- _None_ + +#### `get_path_to_pb_files` + +Returns the path to the directory containing the protobuf files for a given organization and service. + +###### args: + +- `org_id` (str): The ID of the organization. +- `service_id` (str): The ID of the service. + +###### returns: + +- The path to the directory containing the protobuf files. (str) + +#### `get_services_and_messages_info` + +Retrieves information about services and messages defined in a protobuf file. + +This function reads the content of a protobuf file and extracts information about the services and messages defined in it. +It uses regular expressions to match service definitions, RPC methods, message definitions, and fields within messages. + +###### returns: + +- A tuple containing: + - services (dict): A dictionary containing information about the services defined in the protobuf file. + The keys are the names of the services, and the values are lists of tuples representing the RPC methods. + Each tuple contains the method name, input type, and output type. + - messages (dict): A dictionary containing information about the messages defined in the protobuf file. + The keys are the names of the messages, and the values are lists of tuples representing the fields within the messages. + Each tuple contains the field type and field name. + + (tuple[dict[str, list], dict[str, list]]) + +#### `get_services_and_messages_info_as_pretty_string` + +Retrieves information about the services and messages defined in the protobuf file and returns it as a +formatted string. + +_Note_: it first calls the [get_services_and_messages_info](#get_services_and_messages_info) method and then converts +the result into a formatted string. + +###### returns: + +- A formatted string containing information about the services and messages defined in the protobuf file. (str) diff --git a/docs/metadata_provider/ipfs_metadata_provider.md b/docs/metadata_provider/ipfs_metadata_provider.md new file mode 100644 index 0000000..85cbad5 --- /dev/null +++ b/docs/metadata_provider/ipfs_metadata_provider.md @@ -0,0 +1,79 @@ +## module: sdk.metadata_provider.ipfs_metadata_provider + +[Link](https://github.com/singnet/snet-sdk-python/blob/master/snet/sdk/metadata_provider/metadata_provider.py) to GitHub + +Entities: +1. [IPFSMetadataProvider](#class-transactionerror) + - [\_\_init\_\_](#__init__) + - [fetch_org_metadata](#fetch_org_metadata) + - [fetch_service_metadata](#fetch_service_metadata) + - [enhance_service_metadata](#enhance_service_metadata) + +### Class `IPFSMetadataProvider` + +extends: `object` + +is extended by: - + +#### description + +Class for extracting metadata from Interplanetary Filesystem (IPFS). + +#### attributes + +- `registry_contract` (Contract): An instance of the `Contract` class (from `snet.cli`) for interacting with the Registry contract. +- `ipfs_client` (ipfshttpclient.Client): An instance of the `ipfshttpclient.Client` class for interacting with the +InterPlanetary File System. + +#### methods + +#### `__init__` + +Initializes a new instance of the class. + +###### args: + +- `ipfs_client` (ipfshttpclient.Client): The IPFS client to use for fetching metadata. +- `registry_contract` (Contract): The contract instance of the registry. + +###### returns: + +- _None_ + +#### `fetch_org_metadata` + +Retrieves metadata for the specified organization ID from IPFS. + +###### args: + +- org_id (str): The ID of the organization. + +###### returns: + +- Metadata of a specified organization. (dict | OrganizationMetadata (from `snet.cli`)) + +#### `fetch_service_metadata` + +Retrieves metadata for the specified service from the metadata provider. + +###### args: + +- org_id (str): The ID of the organization. +- service_id (str): The ID of the service. + +###### returns: + +- Metadata of a specified service. (dict | MPEServiceMetadata (from `snet.cli`)) + +#### `enhance_service_metadata` + +Enhances the service group details by merging them with the organization group details. + +###### args: + +- service_metadata (dict): The metadata of the service. +- org_metadata (dict): The metadata of the organization. + +###### returns: + +- Metadata of a specified service. (dict | MPEServiceMetadata (from `snet.cli`)) diff --git a/docs/metadata_provider/metadata_provider.md b/docs/metadata_provider/metadata_provider.md new file mode 100644 index 0000000..a3118af --- /dev/null +++ b/docs/metadata_provider/metadata_provider.md @@ -0,0 +1,59 @@ +## module: sdk.metadata_provider.metadata_provider + +[Link](https://github.com/singnet/snet-sdk-python/blob/master/snet/sdk/metadata_provider/metadata_provider.py) to GitHub + +Entities: +1. [MetadataProvider](#abstract-class-metadataprovider) + - [fetch_org_metadata](#fetch_org_metadata) + - [fetch_service_metadata](#fetch_service_metadata) + - [enhance_service_group_details](#enhance_service_group_details) + +### Abstract Class `MetadataProvider` + +extends: `object` + +is extended by: - + +#### description + +Abstract class for retrieving metadata from a metadata provider. + +#### methods + +#### abstract `fetch_org_metadata` + +Retrieves metadata for the specified organization ID from the metadata provider. + +###### args: + +- org_id (str): The ID of the organization. + +###### returns: + +- Metadata of a specified organization. (dict | OrganizationMetadata (from `snet.cli`)) + +#### abstract `fetch_service_metadata` + +Retrieves metadata for the specified service from the metadata provider. + +###### args: + +- org_id (str): The ID of the organization. +- service_id (str): The ID of the service. + +###### returns: + +- Metadata of a specified service. (dict | MPEServiceMetadata (from `snet.cli`)) + +#### abstract `enhance_service_group_details` + +Enhances the service group details by merging them with the organization group details. + +###### args: + +- service_metadata (dict): The metadata of the service. +- org_metadata (dict): The metadata of the organization. + +###### returns: + +- Metadata of a specified service. (dict | MPEServiceMetadata (from `snet.cli`)) diff --git a/docs/metadata_provider/service_metadata.md b/docs/metadata_provider/service_metadata.md new file mode 100644 index 0000000..d06f1c2 --- /dev/null +++ b/docs/metadata_provider/service_metadata.md @@ -0,0 +1,730 @@ +## module: sdk.metadata_provider.service_metadata + +[Link](https://github.com/singnet/snet-sdk-python/blob/master/snet/sdk/metadata_provider/service_metadata.py) to GitHub + +Entities: +1. [AssetType](#class-assettype) + - [is_single_value](#is_single_value) +2. [MPEServiceMetadata](#class-mpeservicemetadata) + - [\_\_init\_\_](#__init__) + - [set_simple_field](#set_simple_field) + - [set_fixed_price_in_cogs](set_fixed_price_in_cogs) + - [set_method_price_in_cogs](set_method_price_in_cogs) + - [add_group](#add_group) + - [remove_group](#remove_group) + - [get_tags](#get_tags) + - [add_tag](#add_tag) + - [remove_tag](#remove_tag) + - [add_asset](#add_asset) + - [remove_all_assets](#remove_all_assets) + - [remove_asset](#remove_asset) + - [add_endpoint_to_group](#add_endpoint_to_group) + - [remove_all_endpoints_for_group](#remove_all_endpoints_for_group) + - [is_group_name_exists](#is_group_name_exists) + - [get_group_by_group_id](#get_group_by_group_id) + - [set_free_calls_for_group](#set_free_calls_for_group) + - [set_freecall_signer_address](#set_freecall_signer_address) + - [get_json](#get_json) + - [get_json_pretty](#get_json_pretty) + - [set_from_json](#set_from_json) + - [load](#load) + - [save_pretty](#save_pretty) + - [\_\_getitem\_\_](#__getitem__) + - [\_\_contains\_\_](#__contains__) + - [get_group_name_nonetrick](#get_group_name_nonetrick) + - [get_group](#get_group) + - [get_group_id_base64](#get_group_id_base64) + - [get_group_id](#get_group_id) + - [get_payment_address](#get_payment_address) + - [add_daemon_address_to_group](#add_daemon_address_to_group) + - [remove_all_daemon_addresses_for_group](#remove_all_daemon_addresses_for_group) + - [get_all_endpoints_for_group](#get_all_endpoints_for_group) + - [get_all_group_endpoints](#get_all_group_endpoints) + - [get_all_endpoints_with_group_name](#get_all_endpoints_with_group_name) + - [get_endpoints_for_group](#get_endpoints_for_group) + - [add_contributor](#add_contributor) + - [remove_contributor_by_email](#remove_contributor_by_email) + - [group_init](#group_init) + - [add_media](#add_media) + - [remove_media](#remove_media) + - [remove_all_media](#remove_all_media) + - [swap_media_order](#swap_media_order) + - [change_media_order](#change_media_order) + - [_is_asset_type_exists](#_is_asset_type_exists) + - [add_description](#add_description) +3. [load_mpe_service_metadata](#function-load_mpe_service_metadata) +4. [mpe_service_metadata_from_json](#function-mpe_service_metadata_from_json) + +### Class `AssetType` + +extends: `Enum` + +is extended by: - + +#### description + +This is an `enum` that represents the type of asset in the service metadata. + +#### members + +- `HERO_IMAGE` (str): The hero image asset type. Equals to "hero_image". +- `IMAGES` (str): The images asset type. Equals to "images". +- `DOCUMENTATION` (str): The documentation asset type. Equals to "documentation". +- `TERMS_OF_USE` (str): The terms of use asset type. Equals to "terms_of_use". + +#### methods + +#### `is_single_value` + +Static method. Checks if the asset type is a single value (`HERO_IMAGE`, `DOCUMENTATION` or `TERMS_OF_USE`). + +###### args: + +- `asset_type` (str): The asset type to check. + +###### returns: + +- `True` if the asset type is a single value, `False` otherwise. (bool) + +### Class `MPEServiceMetadata` + +extends: - + +is extended by: - + +#### description + +This class represents the service metadata. + +#### attributes + +- `m` (dict): A dictionary that contains all the service metadata fields. + +#### methods + +#### `__init__` + +Initializes a new instance of the class. Initializes the `m` dict with empty or default values. + +###### returns: + +- _None_ + +#### `set_simple_field` + +Sets a new value for a specified field in the `m` dict. Supported fields are: `display_name`, `encoding`, +`model_ipfs_hash`, `mpe_address`, `service_type`, `payment_expiration_threshold`, `service_description`. +If the field is not supported, an exception is raised. + +###### args: + +- `f` (str): The field name to set. +- `v` (Any): The value to set. + +###### returns: + +- _None_ + +###### raises: + +- `Exception`: If the field name is unknown. + +#### `set_fixed_price_in_cogs` + +Sets a new value for the `fixed_price` field in the specified payment group. + +###### args: + +- `group_name` (str): The name of the payment group. +- `price` (int): The new value for the `fixed_price` field. + +###### returns: + +- _None_ + +###### raises: + +- `Exception`: If the payment group with the specified name is not found. + +#### `set_method_price_in_cogs` + +Sets the price for a specific method in a service within a payment group. It checks if the group exists, then updates +the pricing details accordingly. If the pricing model or service does not exist, it creates a new one. + +###### args: + +- `group_name` (str): The name of the payment group. +- `package_name` (str): The name of the package. +- `service_name` (str): The name of the service. +- `method` (str): The name of the method. +- `price` (int): The new price for the method. + +###### returns: + +- _None_ + +###### raises: + +- `Exception`: If the payment group with the specified name is not found. + +#### `add_group` + +Adds a new payment group to the `m` dict. + +###### args: + +- `group_name` (str): The name of the new payment group. + +###### returns: + +- _None_ + +###### raises: + +- `Exception`: If the payment group with the specified name already exists. + +#### `remove_group` + +Removes a payment group from the `m` dict. + +###### args: + +- `group_name` (str): The name of the payment group to remove. + +###### returns: + +- _None_ + +#### `get_tags` + +Returns the list of tags from the `m` dict. If the `tags` field does not exist, an empty list is returned. + +###### returns: + +- The list of tags. (list[str]) + +#### `add_tag` + +Adds a new tag to the `tags` field in the `m` dict. If the tag already exists, it is not added again. + +###### args: + +- `tag_name` (str): The name of the new tag. + +###### returns: + +- _None_ + +#### `remove_tag` + +Removes a tag from the `tags` field in the `m` dict. If the tag does not exist, nothing happens. + +###### args: + +- `tag_name` (str): The name of the tag to remove. + +###### returns: + +- _None_ + +#### `add_asset` + +Adds a new asset to the `assets` field in the `m` dict. If the asset already exists, it is not added again. + +###### args: + +- `asset_ipfs_hash` (str): The IPFS hash of the asset. +- `asset_type` (str): The type of the asset. + +###### returns: + +- _None_ + +###### raises: + +- `Exception`: If the asset type is not supported. + +#### `remove_all_assets` + +Removes all assets from the `assets` field in the `m` dict. + +###### returns: + +- _None_ + +#### `remove_asset` + +Removes an asset from the `assets` field in the `m` dict. If the asset does not exist, nothing happens. +If the asset type is not supported, an exception is raised. + +###### args: + +- `asste_type` (str): The type of the asset to remove. + +###### returns: + +- _None_ + +###### raises: + +- `Exception`: If the asset type is not supported. + +#### `add_endpoint_to_group` + +Checks the endpoint is valid and adds it to the `endpoints` field of the specified payment group in the `m` dict. +If the endpoint is not valid or if the group does not exist or if the endpoint is already present, an exception is +raised. + +###### args: + +- `group_name` (str): The name of the payment group. +- `endpoint` (str): The new endpoint to add. + +###### returns: + +- _None_ + +###### raises: + +- `Exception`: If the payment group with the specified name is not found, if the endpoint is not valid, or if the +endpoint is already present. + +#### `remove_all_endpoints_from_group` + +Removes all endpoints from the `endpoints` field of the specified payment group in the `m` dict. If the group +does not exist, an exception is raised. + +###### args: + +- `group_name` (str): The name of the payment group. + +###### returns: + +- _None_ + +###### raises: + +- `Exception`: If the payment group with the specified name is not found. + +#### `is_group_name_exists` + +Checks if the payment group with the specified name exists in the `m` dict. + +###### args: + +- `group_name` (str): The name of the payment group. + +###### returns: + +- _True_ if the payment group exists, _False_ otherwise. (bool) + +#### `get_group_by_group_id` + +Returns group with given group id (returns _None_ if it doesn't exist). + +###### args: + +- `group_id` (str): The id of the payment group. + +###### returns: + +- The group with the given id. (dict[str, Any] | None) + +#### `set_free_calls_for_group` + +Sets the `free_calls` field of the specified payment group in the `m` dict, if the group exists. + +###### args: + +- `group_name` (str): The name of the payment group. +- `free_calls` (int): The new value for the `free_calls` field - amount of free calls. + +###### returns: + +- _None_ + +#### `set_freecall_signer_address` + +Sets the `freecall_signer_address` field of the specified payment group in the `m` dict, if the group exists. + +###### args: + +- `group_name` (str): The name of the payment group. +- `freecall_signer_address` (str): The new value for the `freecall_signer_address` field. + +###### returns: + +- _None_ + +#### `get_json` + +Returns the JSON representation of the `m` dict. + +###### returns: + +- The JSON representation of the `m` dict. (str) + +#### `get_json_pretty` + +Returns the pretty-printed JSON representation of the `m` dict. + +###### returns: + +- The pretty-printed JSON representation of the `m` dict. (str) + +#### `set_from_json` + +Sets the `m` dict from the service metadata JSON representation. + +###### args: + +- `j` (str): The service metadata JSON representation. + +###### returns: + +- _None_ + +#### `load` + +Loads the service metadata from the specified file and sets it in the `m` dict. + +###### args: + +- `file_name` (str): The name of the file containing the service metadata. + +###### returns: + +- _None_ + +#### `save_pretty` + +Saves the pretty-printed JSON representation of the `m` dict to the specified file. + +###### args: + +- `file_name` (str): The name of the file to save. + +###### returns: + +- _None_ + +#### `__getitem__` + +Overrides the `__getitem__` Python special method. Returns the value associated with the given key from +the `m` dict. + +###### args: + +- `key` (str): The name of the field. + +###### returns: + +- The value associated with the given key. (Any) + +#### `__contains__` + +Overrides the `__contains__` Python special method. + +###### args: + +- `key` (str): The name of the field. + +###### returns: + +- _True_ if the key is in the `m` dict, _False_ otherwise. (bool) + +#### `get_group_name_nonetrick` + +Returns a group name from metadata. If no group name is provided (group_name=None), it checks if there's only one +group in the metadata and returns its name. If there are multiple groups, it raises an exception, requiring a +specific group name to be provided. If a group name is provided, it simply returns that name. + +###### args: + +- `group_name` (str): The name of the payment group. Defaults to _None_. + +###### returns: + +- The name of the payment group. (str) + +###### raises: + +- `Exception`: If there are no groups in the metadata or if there are multiple groups in the metadata and no +group name is provided. + +#### `get_group` + +Retrieves a group from metadata by its name. If no name is provided, it uses `get_group_name_nonetrick` to determine +the name. Searches for a matching group in the metadata and returns it. If no matching group is found, +raises an exception. + +###### args: + +- `group_name` (str): The name of the payment group. Defaults to _None_. + +###### returns: + +- The payment group. (dict[str, Any]) + +###### raises: + +- `Exception`: If no group with the specified name is found in the `m` dict. + +#### `get_group_id_base64` + +Returns the group id base64 encoded. + +###### args: + +- `group_name` (str): The name of the payment group. Defaults to _None_. + +###### returns: + +- The group id base64 encoded. (str) + +#### `get_group_id` + +Returns the group id as bytes from `m` dict. + +###### args: + +- `group_name` (str): The name of the payment group. Defaults to _None_. + +###### returns: + +- The group id. (bytes) + +#### `get_payment_address` + +Returns the payment address of the group from `m` dict. + +###### args: + +- `group_name` (str): The name of the payment group. Defaults to _None_. + +###### returns: + +- The payment address. (str) + +#### `add_daemon_address_to_group` + +Adds a daemon address to the `daemon_addresses` field of the specified payment group in the `m` dict. + +###### args: + +- `group_name` (str): The name of the payment group. +- `daemon_address` (str): The new daemon address to add. + +###### returns: + +- _None_ + +###### raises: + +- `Exception`: If the payment group with the specified name does not exist. + +#### `remove_all_daemon_addresses_for_group` + +Removes all daemon addresses from the `daemon_addresses` field of the specified payment group in the `m` dict. + +###### args: + +- `group_name` (str): The name of the payment group. + +###### returns: + +- _None_ + +###### raises: + +- `Exception`: If the payment group with the specified name does not exist. + +#### `get_all_endpoints_for_group` + +Returns all endpoints from the `endpoints` field of the specified payment group in the `m` dict. + +###### args: + +- `group_name` (str): The name of the payment group. + +###### returns: + +- The list of endpoints. (list[str]) + +#### `get_all_group_endpoints` + +Returns all endpoints from the `endpoints` of all payment groups in the `m` dict. + +###### returns: + +- The list of endpoints. (list[str]) + +#### `get_all_endpoints_with_group_name` + +Returns all endpoints from the `endpoints` for all payment groups in the `m` dict as dict with the group name as key +and the list of endpoints as value. + +###### returns: + +- Group names with lists of endpoints. (dict[str, list[str]]) + +#### `get_endpoints_for_group` + +Returns a list of endpoints that belong to a specific payment group. If no group name is provided, it will use +the default group name (if only one group exists). + +###### args: + +- `group_name` (str): The name of the payment group. Defaults to _None_. + +###### returns: + +- The list of endpoints. (list[str]) + +#### `add_contributor` + +Adds a contributor to the `contributors` field of the `m` dict. + +###### args: + +- `name` (str): The name of the contributor. +- `email_id` (str): The email id of the contributor. + +###### returns: + +- _None_ + +#### `remove_contributor_by_email` + +Removes contributors with the specified email from the `contributors` field of the `m` dict. + +###### args: + +- `email_id` (str): The email id of the contributor. + +###### returns: + +- _None_ + +#### `group_init` + +Initializes a new payment group in the `m` dict. Prompts the user to enter several fields, such as fixed price, +endpoints, etc. + +###### args: + +- `group_name` (str): The name of the payment group. + +###### returns: + +- _None_ + +###### raises: + +- `Exception`: If user enters same endpoints. +- `ValueError`: If user enters non-integer fixed price. + +#### `add_media` + +Adds a new media to the `media` field of the `m` dict. + +###### args: + +- `url` (str): The url of the media. +- `media_type` (str): The type of the media. +- `hero_img` (bool): Whether the media is a hero image. Defaults to _False_. + +###### returns: + +- _None_ + +#### `remove_media` + +Removes an individual media from the `media` field of the `m` dict using unique order key. + +###### args: + +- `order` (int): The order of the media. + +###### returns: + +- _None_ + +###### raises: + +- `Exception`: If the media with the specified order does not exist. + +#### `remove_all_media` + +Removes all individual media from the `media` field of the `m` dict. + +###### returns: + +- _None_ + +#### `swap_media_order` + +Swap orders of two different media given their individual orders. + +###### args: + +- `move_from` (int): The order of the first media to be moved. +- `move_to` (int): The order of the second media to be moved. + +###### returns: + +- _None_ + +###### raises: + +- `Exception`: If at least one of the media with the specified orders does not exist. + +#### `change_media_order` + +Mini REPL to change order of all individual media + +###### returns: + +- _None_ + +#### `_is_asset_type_exists` + +Returns whether the asset type exists in the media field of the `m` dict. + +###### returns: + +- _True_ if the asset type exists, _False_ otherwise. (bool) + +#### `add_description` + +Adds a new description to the `description` field of the `m` dict. Prompts the user to enter user guide url, +service long description and service short description. + +###### returns: + +- _None_ + +### Function `load_mpe_service_metadata` + +Loads the service metadata from the JSON file to `MPEServiceMetadata` object. + +###### args: + +- `f` (str): The name of the file containing the service metadata as JSON. + +###### returns: + +- The service metadata. (MPEServiceMetadata) + +### Function `mpe_service_metadata_from_json` + +Loads the service metadata from the JSON string to `MPEServiceMetadata` object. + +###### args: + +- `j` (str): The service metadata JSON representation. + +###### returns: + +- The service metadata. (MPEServiceMetadata) + diff --git a/docs/mpe/mpe_contract.md b/docs/mpe/mpe_contract.md new file mode 100644 index 0000000..461b795 --- /dev/null +++ b/docs/mpe/mpe_contract.md @@ -0,0 +1,169 @@ +## module: sdk.mpe.mpe_contract + +[Link](https://github.com/singnet/snet-sdk-python/blob/master/snet/sdk/mpe/mpe_contract.py) to GitHub + +Entities: +1. [MPEContract](#class-mpecontract) + - [\_\_init\_\_](#__init__) + - [balance](#balance) + - [deposit](#deposit) + - [open_channel](#open_channel) + - [deposit_and_open_channel](#deposit_and_open_channel) + - [channel_add_funds](#channel_add_funds) + - [channel_extend](#channel_extend) + - [channel_extend_and_add_funds](#channel_extend_and_add_funds) + - [_fund_escrow_account](#_fund_escrow_account) + +### Class `MPEContract` + +extends: - + +is extended by: - + +#### description + +The `MPEContract` class is responsible for interacting with the MultiPartyEscrow +contract on the Ethereum blockchain. It provides methods for retrieving the balance of an address, depositing +funds into the contract, opening a channel, adding funds to a channel, extending the expiration of a channel, and more. + +#### attributes + +- `web3` (Web3): An instance of the Web3 class for interacting with the Ethereum blockchain. +- `contract` (Contract): An instance of the `Contract` class from the `web3` library for interacting +with the MultiPartyEscrow contract. +- `event_topics` (list): A list of event topics for the MultiPartyEscrow contract. +- `deployment_block` (int | BlockNumber): The block number at which the MultiPartyEscrow contract was deployed. + +#### methods + +#### `__init__` + +Initializes a new instance of the class. The class is initialized with a Web3 object and an optional contract address. +If no contract address is provided, it uses the default MultiPartyEscrow contract. + +###### args: + +- `w3` (Web3): An instance of the `Web3` class. +- `address` (str): The address of the MultiPartyEscrow contract. Defaults to None. + +###### returns: + +- _None_ + +#### `balance` + +Returns the balance of the given address in the MPE contract in cogs. + +###### args: + +- `address` (str): The address to retrieve the balance for. + +###### returns: + +- The balance in cogs. (int) + +#### `deposit` + +Deposit the specified amount of AGIX tokens in cogs into the MultiPartyEscrow contract. + +###### args: + +- `account` (Account): The account instance used to send the transaction. +- `amount_in_cogs` (int): The amount of AGIX tokens in cogs to deposit. + + +###### returns: + +- The transaction receipt of the deposit transaction. (TxReceipt) + +#### `open_channel` + +Opens a payment channel with the specified amount of AGIX tokens in cogs (taken from MPE) and expiration time. + +###### args: + +- `account` (Account): The account object used to send the transaction. +- `payment_address` (str): The address of the payment recipient. +- `group_id` (str): The ID of the payment group. +- `amount` (int): The amount of AGIX tokens in cogs to deposit into the channel. +- `expiration` (int): The expiration time of the payment channel in blocks. + +###### returns: + +- The transaction receipt of the transaction. (TxReceipt) + +#### `deposit_and_open_channel` + +Opens a payment channel with the specified amount of AGIX tokens in cogs (which are previously deposited on MPE) +and expiration time. The account must have sufficient allowance to perform the deposit, otherwise the account +first approves the transfer. + +###### args: + +- `account` (Account): The account object used to send the transaction. +- `payment_address` (str): The address of the payment recipient. +- `group_id` (str): The ID of the payment group. +- `amount` (int): The amount of AGIX tokens in cogs first for deposit on MPE, then for deposit on the channel. +- `expiration` (int): The expiration time of the payment channel in blocks. + +###### returns: + +- The transaction receipt of the transaction. (TxReceipt) + +#### `channel_add_funds` + +Adds funds to an existing payment channel. + +###### args: + +- `account` (Account): The account object used to sign the transaction. +- `channel_id` (int): The ID of the payment channel. +- `amount` (int): The amount of funds to add to the channel. + +###### returns: + +- The transaction receipt of the transaction. (TxReceipt) + +#### `channel_extend` + +Extends the expiration time of a payment channel. + +###### args: + +- `account` (Account): The account object used to send the transaction. +- `channel_id` (int): The ID of the payment channel. +- `expiration` (int): The new expiration time of the payment channel in blocks. + +###### returns: + +- The transaction receipt of the transaction. (TxReceipt) + +#### `channel_extend_and_add_funds` + +Extends the expiration time of a payment channel and adds funds to it. + +###### args: + +- `account` (Account): The account object used to send the transaction. +- `channel_id` (int): The ID of the payment channel. +- `expiration` (int): The new expiration time of the payment channel in blocks. +- `amount` (int): The amount of funds to add to the channel. + +###### returns: + +- The transaction receipt of the transaction. (TxReceipt) + +#### `_fund_escrow_account` + +Funds the escrow account for the given account with the specified amount. + +###### args: + +- `account` (Account): The account object used to send the transaction and for which +the escrow account needs to be funded. +- `amount` (int): The amount to be funded into the escrow account. + +###### returns: + +- The transaction receipt of the transaction. (TxReceipt | _None_) + diff --git a/docs/mpe/payment_channel.md b/docs/mpe/payment_channel.md new file mode 100644 index 0000000..b5d33d6 --- /dev/null +++ b/docs/mpe/payment_channel.md @@ -0,0 +1,106 @@ +## module: sdk.mpe.payment_channel + +[Link](https://github.com/singnet/snet-sdk-python/blob/master/snet/sdk/mpe/payment_channel.py) to GitHub + +Entities: +1. [PaymentChannel](#class-paymentchannel) + - [\_\_init\_\_](#__init__) + - [add_funds](#add_funds) + - [extend_expiration](#extend_expiration) + - [extend_and_add_funds](#extend_and_add_funds) + - [sync_state](#sync_state) + - [_get_current_channel_state](#_get_current_channel_state) + +### Class `PaymentChannel` + +extends: - + +is extended by: - + +#### description + +The PaymentChannel (payment_channel.py:8-65:135) class is responsible for managing a payment channel +in the SingularityNET platform. + +#### attributes + +- `channel_id` (int): The ID of the payment channel. +- `web3` (Web3): An instance of the `Web3` class for interacting with the Ethereum blockchain. +- `account` (Account): An instance of the `Account` class for interacting with the MultiPartyEscrow and SingularityNetToken contracts. +- `mpe_contract` (MPEContract): An instance of the `MPEContract` class for interacting with the MultiPartyEscrow contract. +- `payment_channel_state_service_client` (ServiceStub): A stub for interacting with PaymentChannelStateService via gRPC. +- `state` (dict): The current state of the payment channel. It contains the following keys: + - `nonce` (int): The current nonce of the payment channel. + - `last_signed_amount` (int): The last signed amount of the payment channel. + +#### methods + +#### `__init__` + +Initializes a new instance of the class. + +###### args: + +- `channel_id` (str): The ID of the payment channel. +- `w3` (Web3): An instance of the `Web3` class for interacting with the Ethereum blockchain. +- `account` (Account): An instance of the `Account` class for managing Ethereum accounts. +- `payment_channel_state_service_client` (ServiceStub): A stub for interacting with PaymentChannelStateService via gRPC. +- `mpe_contract` (MPEContract): An instance of the `MPEContract` class for interacting with the MultiPartyEscrow contract. + +###### returns: + +- _None_ + +#### `add_funds` + +Adds funds to the payment channel. + +###### args: + +- `amount` (int): The amount of funds to add to the payment channel. + +###### returns: + +- The transaction receipt of the transaction. (TxReceipt) + +#### `extend_expiration` + +Extends the expiration time of the payment channel. + +###### args: + +- `expiration` (int): The new expiration time of the payment channel in blocks. + +###### returns: + +- The transaction receipt of the transaction. (TxReceipt) + +#### `extend_and_add_funds` + +Extends the expiration time of a payment channel and adds funds to it. + +###### args: + +- `expiration` (int): The new expiration time of the payment channel in blocks. +- `amount` (int): The amount of funds to add to the channel. + +###### returns: + +- The transaction receipt of the transaction. (TxReceipt) + +#### `sync_state` + +This method gets the channel state data from the MPE and the daemon and updates all values of the state field. + +###### returns: + +- _None_ + +#### `_get_current_channel_state` + +Receives channel state data from the daemon via gRPC using PaymentChannelStateService and returns it. + +###### returns: + +- A tuple containing the current nonce and the current signed amount of funds. (tuple[int, int]) + diff --git a/docs/mpe/payment_channel_provider.md b/docs/mpe/payment_channel_provider.md new file mode 100644 index 0000000..803f3b6 --- /dev/null +++ b/docs/mpe/payment_channel_provider.md @@ -0,0 +1,117 @@ +## module: sdk.mpe.payment_channel_provider + +[Link](https://github.com/singnet/snet-sdk-python/blob/master/snet/sdk/mpe/payment_channel_provider.py) to GitHub + +Entities: +1. [PaymentChannelProvider](#class-paymentchannelprovider) + - [\_\_init\_\_](#__init__) + - [get_past_open_channels](#get_past_open_channels) + - [open_channel](#open_channel) + - [deposit_and_open_channel](#deposit_and_open_channel) + - [_get_newly_opened_channel](#_get_newly_opened_channel) + +### Class `PaymentChannelProvider` + +extends: `object` + +is extended by: - + +#### description + +A class for managing payment channels. + +#### attributes + +- `web3` (Web3): An instance of the `Web3` class for interacting with the Ethereum blockchain. +- `mpe_contract` (MPEContract): An instance of the `MPEContract` class for interacting with the MultiPartyEscrow contract. +with the MultiPartyEscrow contract. +- `event_topics` (list): A list of event topics for the MultiPartyEscrow contract. +- `deployment_block` (int | BlockNumber): The block number at which the MultiPartyEscrow contract was deployed. +- `payment_channel_state_service_client` (ServiceStub): A stub for interacting with PaymentChannelStateService via gRPC. + +#### methods + +#### `__init__` + +Initializes a new instance of the class. + +###### args: + +- `w3` (Web3): An instance of the `Web3` class for interacting with the Ethereum blockchain. +- payment_channel_state_service_client` (ServiceStub): A stub for interacting with PaymentChannelStateService via gRPC. +- `mpe_contract` (MPEContract): An instance of the `MPEContract` class for interacting with the MultiPartyEscrow contract. + +###### returns: + +- _None_ + +#### `get_past_open_channels` + +Extracts a list of all past open payment channels from the blockchain, filters it by account and payment group, +and returns it. + +###### args: + +- `account` (Account): The account object to filter the channels by its address and signer address. +- `payment_address` (str): The payment address to filter the channels by. +- `group_id` (str): The group ID to filter the channels by. +- `starting_block_number` (int): The starting block number of the block range. Defaults to 0. +- `to_block_number` (int): The ending block number of the block range. Defauls to _None_. + +###### returns: + +- A list of payment channels. (list[PaymentChannel]) + +#### `open_channel` + +Opens a payment channel with the specified amount of AGIX tokens in cogs (taken from MPE) and expiration time. +And then returns it. + +###### args: + +- `account` (Account): The account object used to send the transaction. +- `amount` (int): The amount of AGIX tokens in cogs to deposit into the channel. +- `expiration` (int): The expiration time of the payment channel in blocks. +- `payment_address` (str): The address of the payment recipient. +- `group_id` (str): The ID of the payment group. + +###### returns: + +- The newly opened payment channel. (PaymentChannel) + +#### `deposit_and_open_channel` + +Opens a payment channel with the specified amount of AGIX tokens in cogs (which are previously deposited on MPE) +and expiration time. And then returns it. + +###### args: + +- `account` (Account): The account object used to send the transaction. +- `amount` (int): The amount of AGIX tokens in cogs to deposit into the channel. +- `expiration` (int): The expiration time of the payment channel in blocks. +- `payment_address` (str): The address of the payment recipient. +- `group_id` (str): The ID of the payment group. + +###### returns: + +- The newly opened payment channel. (PaymentChannel) + +#### `_get_newly_opened_channel` + +Retrieves the newly opened payment channel from blockchain based on the given data. + +###### args: + +- `receipt` (dict): The receipt of the transaction that opened the payment channel. +- `account` (Account): The account object associated with the payment channel. +- `payment_address` (str): The payment address of the payment channel. +- `group_id` (str): The ID of the payment group. + +###### returns: + +- The newly opened payment channel. (PaymentChannel) + +###### raises: + +- Exception: If no payment channels are found for the given data. + diff --git a/docs/payment_strategies/default_payment_strategy.md b/docs/payment_strategies/default_payment_strategy.md new file mode 100644 index 0000000..dd271e5 --- /dev/null +++ b/docs/payment_strategies/default_payment_strategy.md @@ -0,0 +1,96 @@ +## module: sdk.payment_strategies.default_payment_strategy + +[Link](https://github.com/singnet/snet-sdk-python/blob/master/snet/sdk/payment_strategies/default_payment_strategy.py) to GitHub + +Entities: +1. [DefaultPaymentStrategy](#class-defaultpaymentstrategy) + - [\_\_init\_\_](#__init__) + - [set_concurrency_token](#set_concurrency_token) + - [set_channel](#set_channel) + - [get_payment_metadata](#get_payment_metadata) + - [get_concurrency_token_and_channel](#get_concurrency_token_and_channel) + +### Class `DefaultPaymentStrategy` + +extends: `PaymentStrategy` + +is extended by: - + +#### description + +The `DefaultPaymentStrategy` class is an implementation of the `PaymentStrategy`. It defines and returns +payment metadata for a given service client, taking into account free calls, concurrency, and various +payment strategies. In fact, it is not an implementation of a payment strategy on its own, this class is used +by default and selects a payment strategy from `FreeCallPaymentStrategy`, `PaidCallPaymentStrategy` +and `PrePaidPaymentStrategy`. + +#### attributes + +- `concurrent_calls` (int): The number of concurrent calls allowed. +- `concurrencyManager` (ConcurrencyManager): An instance of the `ConcurrencyManager` class for managing concurrency. +- `channel` (PaymentChannel): The payment channel used for a specific service call. + +#### methods + +#### `__init__` + +Initializes a new instance of the class. + +###### args: + +- `concurrent_calls` (int): The number of concurrent calls allowed. Defaults to 1. + +###### returns: + +- _None_ + +#### `set_concurrency_token` + +Sets the concurrency token for the concurrency manager. + +###### args: + +- `token` (str): The token to be set. + +###### returns: + +- _None_ + +#### `set_channel` + +Sets a new channel object. + +###### args: + +- `channel` (PaymentChannel): The channel to set for the `DefaultPaymentStrategy` object. + +###### returns: + +- _None_ + +#### `get_payment_metadata` + +Retrieves payment metadata for the specified service client. Depending on several conditions, creates +an instance of one of the `FreeCallPaymentStrategy`, `PaidCallPaymentStrategy` and `PrePaidPaymentStrategy` +classes and calls the method of the same name in it. + +###### args: + +- `service_client` (ServiceClient): The service client object. + +###### returns: + +- The payment metadata. (list[tuple[str, Any]]) + +#### `get_concurrency_token_and_channel` + +Retrieves the concurrency token and channel for a given service client. + +###### args: + +- `service_client` (ServiceClient): The service client instance. + +###### returns: + +- The concurrency token and channel. (tuple[str, PaymentChannel]) + diff --git a/docs/payment_strategies/freecall_payment_strategy.md b/docs/payment_strategies/freecall_payment_strategy.md new file mode 100644 index 0000000..a563660 --- /dev/null +++ b/docs/payment_strategies/freecall_payment_strategy.md @@ -0,0 +1,70 @@ +## module: sdk.payment_strategies.freecall_payment_strategy + +[Link](https://github.com/singnet/snet-sdk-python/blob/master/snet/sdk/payment_strategies/freecall_payment_strategy.py) to GitHub + +Entities: +1. [FreeCallPaymentStrategy](#class-freecallpaymentstrategy) + - [is_free_call_available](#is_free_call_available) + - [get_payment_metadata](#get_payment_metadata) + - [generate_signature](#generate_signature) + +### Class `FreeCallPaymentStrategy` + +extends: `PaymentStrategy` + +is extended by: - + +#### description + +The `FreeCallPaymentStrategy` class is a concrete implementation of the `PaymentStrategy` interface. +It allows you to use free calls (which can be received from the [Dapp](https://beta.singularitynet.io/)) to +call services. + +#### methods + +#### `is_free_call_available` + +Checks if a free call is available for a given service client. + +###### args: + +- `service_client` (ServiceClient): The service client instance. + +###### returns: + +- True if a free call is available, False otherwise. (bool) + +###### raises: + +- Exception: If an error occurs while checking the free call availability. + +_Note_: If any exception occurs during the process, it returns False. + +#### `get_payment_metadata` + +Retrieves the payment metadata for a service client with the field `snet-paument-type` equals to `free-call` +using the provided free call configuration. + +###### args: + +- `service_client` (ServiceClient): The service client instance. + +###### returns: + +- The payment metadata. (list[tuple[str, Any]]) + +#### `generate_signature` + +Generates a signature for the given service client using the provided free call configuration. + +###### args: + +- `service_client` (ServiceClient): The service client instance. + +###### returns: + +- A tuple containing the generated signature and the current block number. (tuple[bytes, int]) + +###### raises: + +- Exception: If any of the required parameters for the free call strategy are missing. diff --git a/docs/payment_strategies/paidcall_payment_strategy.md b/docs/payment_strategies/paidcall_payment_strategy.md new file mode 100644 index 0000000..8dff3f9 --- /dev/null +++ b/docs/payment_strategies/paidcall_payment_strategy.md @@ -0,0 +1,108 @@ +## module: sdk.payment_strategies.paidcall_payment_strategy + +[Link](https://github.com/singnet/snet-sdk-python/blob/master/snet/sdk/payment_strategies/paidcall_payment_strategy.py) to GitHub + +Entities: +1. [PaidCallPaymentStrategy](#class-paidcallpaymentstrategy) + - [\_\_init\_\_](#__init__) + - [get_price](#get_price) + - [get_payment_metadata](#get_payment_metadata) + - [select_channel](#select_channel) + - [_has_sufficient_funds](#static-_has_sufficient_funds) + - [_is_valid](#static-_is_valid) + +### Class `PaidCallPaymentStrategy` + +extends: `PaymentStrategy` + +is extended by: - + +#### description + +The `PaidCallPaymentStrategy` class is a concrete implementation of the `PaymentStrategy` interface. +This is the simplest payment strategy among those presented. In it availability of channel, funds and +expiration are checked before each call and the payment itself is made each call. + +#### attributes + +- `block_offset` (int): Block offset. +- `call_allowance` (int): The amount of allowed calls. + +#### methods + +#### `__init__` + +Initializes a new instance of the class. + +###### args: + +- `block_offset` (int): Block offset. +- `call_allowance` (int): The amount of allowed calls. Defaults to 1. + +###### returns: + +- _None_ + +#### `get_price` + +Returns the price of the service call using service client. + +###### args: + +- `service_client` (ServiceClient): The service client object. + +###### returns: + +- The price of the service call. (int) + +#### `get_payment_metadata` + +Creates and returns the payment metadata for a service client with the field `snet-paument-type` equals to `escrow`. + +###### args: + +- `service_client` (ServiceClient): The service client object. + +###### returns: + +- The payment metadata. (list[tuple[str, Any]]) + +#### `select_channel` + +Retrieves the suitable payment channel from the MPE. Opens the channel, extends expiration +and adds funds id it is necessary. + +###### args: + +- `service_client` (ServiceClient): The service client object. + +###### returns: + +- The payment channel for the service calling. (PaymentChannel) + +#### static `_has_sufficient_funds` + +Checks whether the payment channel has the required amount of funds. + +###### args: + +- `channel` (PaymentChannel): The payment channel to check. +- `amount` (int): The amount of funds in cogs to check. + +###### returns: + +- True if the channel has enough funds, False otherwise. (bool) + +#### static `_is_valid` + +Checks if the payment channel expires later than it should. + +###### args: + +- `channel` (PaymentChannel): The payment channel to check. +- `expiry` (int): The expiration time in blocks to check. + +###### returns: + +- True if the channel has enough expiration, False otherwise. (bool) + diff --git a/docs/payment_strategies/payment_strategy.md b/docs/payment_strategies/payment_strategy.md new file mode 100644 index 0000000..c980c92 --- /dev/null +++ b/docs/payment_strategies/payment_strategy.md @@ -0,0 +1,45 @@ +## module: sdk.payment_strategies.payment_strategy + +[Link](https://github.com/singnet/snet-sdk-python/blob/master/snet/sdk/payment_strategies/payment_strategy.py) to GitHub + +Entities: +1. [PaymentStrategy](#class-paymentstrategy) + - [get_payment_metadata](#get_payment_metadata) + - [get_price](#get_price) + +### Abstract Class `PaymentStrategy` + +extends: `object` + +is extended by: `DefaultPaymentStrategy`, `DefaultPaymentStrategy`, `PaidCallPaymentStrategy`, `PrePaidPaymentStrategy` + +#### description + +Abstract base class for payment strategies. Defines the interface for organizing payment strategy. + +#### methods + +#### abstract `get_payment_metadata` + +Determines and returns payment metadata for a specified service client. + +###### args: + +- `service_client` (ServiceClient): The service client object. + +###### returns: + +- Payment metadata. (list[tuple[str, Any]]) + +#### abstract `get_price` + +Returns the price for calling a service using the provided client service. + +###### args: + +- `service_client` (ServiceClient): The service client object. + +###### returns: + +- Price of calling service in cogs. (int) + diff --git a/docs/payment_strategies/prepaid_payment_strategy.md b/docs/payment_strategies/prepaid_payment_strategy.md new file mode 100644 index 0000000..7e5094f --- /dev/null +++ b/docs/payment_strategies/prepaid_payment_strategy.md @@ -0,0 +1,126 @@ +## module: sdk.payment_strategies.prepaid_payment_strategy + +[Link](https://github.com/singnet/snet-sdk-python/blob/master/snet/sdk/payment_strategies/prepaid_payment_strategy.py) to GitHub + +Entities: +1. [PrePaidPaymentStrategy](#class-prepaidpaymentstrategy) + - [\_\_init\_\_](#__init__) + - [get_price](#get_price) + - [get_payment_metadata](#get_payment_metadata) + - [get_concurrency_token_and_channel](#get_concurrency_token_and_channel) + - [select_channel](#select_channel) + - [_has_sufficient_funds](#static-_has_sufficient_funds) + - [_is_valid](#static-_is_valid) + + +### Class `PrePaidPaymentStrategy` + +extends: `PaymentStrategy` + +is extended by: - + +#### description + +The `PrePaidPaymentStrategy` class is a concrete implementation of the `PaymentStrategy` interface. +The prepaid payment strategy is similar to the paid call strategy, but allows you to pay for several calls at once +and then make them. + +#### attributes + +- `concurrency_manager`: The `ConcurrencyManager` instance. +- `block_offset` (int): Block offset. +- `call_allowance` (int): The amount of allowed calls. + +#### methods + +#### `__init__` + +Initializes a new instance of the class. + +###### args: + +- `concurrency_manager`: The `ConcurrencyManager` instance. +- `block_offset` (int): Block offset. +- `call_allowance` (int): The amount of allowed calls. Defaults to 1. + +###### returns: + +- _None_ + +#### `get_price` + +Returns the price of the service calls using service client. + +###### args: + +- `service_client` (ServiceClient): The service client object. + +###### returns: + +- The price of the service call. (int) + +#### `get_payment_metadata` + +Creates and returns the payment metadata for a service client with the field `snet-paument-type` equals +to `prepaid-call`. + +###### args: + +- `service_client` (ServiceClient): The service client object. +- `channel` (PaymentChannel): The payment channel to make service call. + +###### returns: + +- The payment metadata. (list[tuple[str, Any]]) + +#### `get_concurrency_token_and_channel` + +Retrieves the concurrency token and channel from the payment strategy. + +###### args: + +- `service_client` (ServiceClient): The service client object. + +###### returns: + +- The concurrency token and channel. (tuple[str, PaymentChannel]) + +#### `select_channel` + +Retrieves the suitable payment channel from the MPE. Opens the channel, extends expiration +and adds funds if it is necessary. + +###### args: + +- `service_client` (ServiceClient): The service client object. + +###### returns: + +- The payment channel for the service calling. (PaymentChannel) + +#### static `_has_sufficient_funds` + +Checks whether the payment channel has the required amount of funds. + +###### args: + +- `channel` (PaymentChannel): The payment channel to check. +- `amount` (int): The amount of funds in cogs to check. + +###### returns: + +- True if the channel has enough funds, False otherwise. (bool) + +#### static `_is_valid` + +Checks if the payment channel expires later than it should. + +###### args: + +- `channel` (PaymentChannel): The payment channel to check. +- `expiry` (int): The expiration time in blocks to check. + +###### returns: + +- True if the channel has enough expiration, False otherwise. (bool) + diff --git a/docs/snet-sdk-python-documentation.md b/docs/snet-sdk-python-documentation.md new file mode 100644 index 0000000..d7b7692 --- /dev/null +++ b/docs/snet-sdk-python-documentation.md @@ -0,0 +1,43 @@ +# Welcome to snet-sdk-python's documentation! + +SingularityNET SDK for Python + +### Core concepts + +The SingularityNET SDK allows you to make calls to SingularityNET services programmatically from your application. +To communicate between clients and services, SingularityNET uses [gRPC](https://grpc.io/). +To handle payment of services, SingularityNET uses [Ethereum state channels](https://dev.singularitynet.io/docs/concepts/multi-party-escrow/). +The SingularityNET SDK abstracts and manages state channels with service providers on behalf of the user and handles authentication with the SingularityNET services. + +A getting started guide for the SNET SDK for Python is available [here](https://github.com/singnet/snet-sdk-python/blob/master/README.md). + +### Modules + +1. [\_\_init\_\_](main/init.md) +2. [account](main/account.md) +3. [service_client](main/service_client.md) +4. [concurrency_manager](main/concurrency_manager.md) +5. [config](main/config.md) +6. [client_lib_generator](main/client_lib_generator.md) +7. metadata_provider + 1. [metadata_provider](metadata_provider/metadata_provider.md) + 2. [ipfs_metadata_provider](metadata_provider/ipfs_metadata_provider.md) + 3. [service_metadata](metadata_provider/service_metadata.md) +8. mpe + 1. [mpe_contract](mpe/mpe_contract.md) + 2. [payment_channel](mpe/payment_channel.md) + 3. [payment_channel_provider](mpe/payment_channel_provider.md) +9. payment_strategies + 1. [payment_strategy](payment_strategies/payment_strategy.md) + 2. [default_payment_strategy](payment_strategies/default_payment_strategy.md) + 3. [freecall_payment_strategy](payment_strategies/freecall_payment_strategy.md) + 4. [paidcall_payment_strategy](payment_strategies/paidcall_payment_strategy.md) + 5. [prepaid_payment_strategy](payment_strategies/prepaid_payment_strategy.md) +10. utils + 1. [utils](utils/utils.md) + 2. [ipfs_utils](utils/ipfs_utils.md) +11. training + 1. [training](training/training.md) + + + diff --git a/docs/training/training.md b/docs/training/training.md new file mode 100644 index 0000000..0f946c7 --- /dev/null +++ b/docs/training/training.md @@ -0,0 +1,166 @@ +## module: sdk.training.training.py + +[Link](https://github.com/singnet/snet-sdk-python/blob/master/snet/sdk/training/training.py) to GitHub + +Entities: +1. [ModelMethodMessage](#class-modelmethodmessage) +2. [TrainingModel](#class-trainingmodel) + - [\_\_init\_\_](#__init__) + - [_invoke_model](#_invoke_model) + - [create_model](#create_model) + - [get_model_status](#get_model_status) + - [delete_model](#delete_model) + - [update_model_access](#update_model_access) + - [get_all_models](#get_all_models) + +### Class `ModelMethodMessage` + +extends: `Enum` + +is extended by: - + +#### description + +This is an `enum` that represents the available methods that can be called in the training grpc service. + +#### members + +- `CreateModel` (str): The method to create a new model. +- `GetModelStatus` (str): The method to get the status of a model. +- `UpdateModelAccess` (str): The method to update the access of a model. +- `DeleteModel` (str): The method to delete a model. +- `GetAllModels` (str): The method to get all models. + +### Class `TrainingModel` + +extends: - + +is extended by: - + +#### description + +This is a class that represents a training gRPC service. + +#### attributes + +- `training_pb2` (ModuleType): The gRPC service module. +- `training_pb2_grpc` (ModuleType): The gRPC service module. + +#### methods + +#### `__init__` + +Initializes a new instance of the class. Imports gRPC service modules. + +###### returns: + +- _None_ + +#### `_invoke_model` + +Invokes the model by establishing a gRPC channel and generating an authorization request. + +###### args: + +- `service_client` (ServiceClient): The client object for the service. +- `msg` (ModelMethodMessage): The message containing the method to be invoked. + +###### returns: + +- A tuple containing the authorization request and the gRPC channel. (tuple[AuthorizationDetails, grpc.Channel]) + +###### raises: + +- `ValueError`: If the scheme in the service metadata is not supported. + +#### `create_model` + +Calls the `create_model` method in the gRPC training service stub to create a new model. + +###### args: + +- `service_client` (ServiceClient): The client object for the service. +- `grpc_method_name` (str): The name of the gRPC method to be invoked. +- `model_name` (str): The name of the model to be created. +- `description` (str): A description of the model. Defaults to ''. +- `training_data_link` (str): A link to the training data. Defaults to ''. +- `grpc_service_name` (str): The name of the gRPC service. Defaults to 'service'. +- `is_publicly_accessible` (bool): Whether the model is publicly accessible. Defaults to False. +- `address_list` (list[str]): A list of addresses. Defaults to None. + +###### returns: + +- The response from the create model request. (Any) + +_Note_: Returns an exception if an error occurs during the create model request. + +#### `get_model_status` + +Calls the `get_model_status` method in the gRPC training service stub to get a model status. + +###### args: + +- `service_client` (ServiceClient): The client object for the service. +- `model_id` (str): The ID of the model whose status to be retrieved. + +###### returns: + +- The response from the get model status request. (Any) + +_Note_: Returns an exception if an error occurs during the get model status request. + +#### `delete_model` + +Calls the `delete_model` method in the gRPC training service stub to delete a model. + +###### args: + +- `service_client` (ServiceClient): The client object for the service. +- `model_id` (str): The ID of the model to be deleted. +- `grpc_service_name` (str): The name of the gRPC service. Defaults to 'service'. +- `grpc_method_name` (str): The name of the gRPC method to be invoked. + +###### returns: + +- The response from the delete model request. (Any) + +_Note_: Returns an exception if an error occurs during the delete model request. + +#### `update_model_access` + +Calls the `update_model_access` method in the gRPC training service stub to update the access of a model. + +###### args: + +- `service_client` (ServiceClient): The client object for the service. +- `model_id` (str): The ID of the model whose access to be updated. +- `grpc_method_name` (str): The name of the gRPC method to be invoked. +- `model_name` (str): The name of the model. +- `is_punlic` (bool): Whether the model is publicly accessible. +- `description` (str): A description of the model. +- `grpc_service_name` (str): The name of the gRPC service. Defaults to 'service'. +- `address_list` (list[str]): A list of addresses. + +###### returns: + +- The response from the update model access request. (Any) + +_Note_: Returns an exception if an error occurs during the update model access request. + +#### `get_all_models` + +Calls the `get_all_models` method in the gRPC training service stub to get all models. + +###### args: + +- `service_client` (ServiceClient): The client object for the service. +- `grpc_method_name` (str): The name of the gRPC method to be invoked. +- `grpc_service_name` (str): The name of the gRPC service. Defaults to 'service'. + +###### returns: + +- The response from the get all models request. (Any) + +_Note_: Returns an exception if an error occurs during the get all models request. + + diff --git a/docs/utils/ipfs_utils.md b/docs/utils/ipfs_utils.md new file mode 100644 index 0000000..62aaaef --- /dev/null +++ b/docs/utils/ipfs_utils.md @@ -0,0 +1,84 @@ +## module: sdk.utils.ipfs_utils + +[Link](https://github.com/singnet/snet-sdk-python/blob/master/snet/sdk/utils/ipfs_utils.py) to GitHub + +Entities: +1. [get_from_ipfs_and_checkhash](#function-get_from_ipfs_and_checkhash) +2. [bytesuri_to_hash](#function-bytesuri_to_hash) +3. [safe_extract_proto_from_ipfs](#function-safe_extract_proto_from_ipfs) +4. [get_ipfs_client](#function-get_ipfs_client) + + + +### Function `get_from_ipfs_and_checkhash` + +This function retrieves a file from IPFS and optionally verifies its integrity by +checking the hash. If `validate` is True, it manually parses the IPFS block, extracts the file data, and verifies +the hash using a multihash object. If the hash does not match, it raises an exception. If `validate` is False, +it simply retrieves the file data. + +###### args: + +- `ipfs_client` (ipfshttpclient.client.Client): The IPFS client instance. +- `ipfs_hash_base58` (Any): The base58-encoded IPFS hash of the file. +- `validate` (bool): A boolean indicating whether to validate the hash (default is True). + +###### returns: + +- The contents of the file retrieved from IPFS. (bytes) + +###### raises: + +- `Exception`: If the hash validation fails or if the IPFS hash is not a file. + +### Function `bytesuri_to_hash` + +Converts a bytes URI to a hash. + +###### args: + +- `s` (bytes): The bytes URI to convert. + +###### returns: + +- The hash extracted from the bytes URI. (str) + +###### raises: + +- `Exception`: If the input is not an IPFS URI. + +### Function `safe_extract_proto_from_ipfs` + +This function safely extracts a tar file from IPFS to a specified directory. It checks for potential security risks by: +- Ensuring the tar file does not contain directories +- Ensuring all contents are files +- Removing any existing files with the same name before extraction + +If any of these checks fail, it raises an exception. Otherwise, it extracts the tar file to the specified directory. + +###### args: + +- `ipfs_client` (ipfshttpclient.client.Client): The IPFS client instance. +- `ipfs_hash` (str): The IPFS hash of the tar file to extract. +- `protodir` (str): The directory to extract the tar file to. + +###### returns: + +- _None_ + +###### raises: + +- `Exception`: If the tarball contains directories or non-file entries. + +### Function `get_ipfs_client` + +Returns an IPFS client instance based on the provided configuration. + +###### args: + +- config (Config): The configuration object containing the IPFS endpoint. + +###### returns: + +- An IPFS client instance connected to the specified endpoint. (ipfshttpclient.client.Client) + diff --git a/docs/utils/utils.md b/docs/utils/utils.md new file mode 100644 index 0000000..e96a045 --- /dev/null +++ b/docs/utils/utils.md @@ -0,0 +1,140 @@ +## module: sdk.utils.utils + +[Link](https://github.com/singnet/snet-sdk-python/blob/master/snet/sdk/utils/utils.py) to GitHub + +Entities: +1. [safe_address_converter](#function-safe_address_converter) +2. [type_converter](#function-type_converter) +3. [bytes32_to_str](#function-bytes32_to_str) +4. [compile_proto](#function-compile_proto) +5. [is_valid_endpoint](#function-is_valid_endpoint) +6. [normalize_private_key](#function-normalize_private_key) +7. [get_address_from_private](#function-get_address_from_private) +8. [add_to_path](#class-add_to_path) +9. [find_file_by_keyword](#function-find_file_by_keyword) + + +### Function `safe_address_converter` + +Checks if the address is a valid checksum address and returns it, otherwise raises an exception. + +###### args: + +- `a` (Any): The address to check. + +###### returns: + +- The address if it is valid. (Any) + +###### raises: + +- `Exception`: If the address isn't a valid checksum address. + +### Function `type_converter + +Creates a function that converts a value to the specified type. + +###### args: + +- `t` (Any): The type to convert the value to. + +###### returns: + +- A function that converts the value to the specified type. (Any -> Any) + +### Function `bytes32_to_str` + +Converts a bytes32 value to a string. + +###### args: + +- `b` (bytes): The bytes32 value to convert. + +###### returns: + +- The string representation of the bytes32 value. (str) + +### Function `compile_proto` + +Compiles Protocol Buffer (protobuf) files into code for a specific target language. +Generated files as well as .proto files are stored in the `~/.snet` directory. + +###### args: + +- `entry_path` (Path): The path to the .proto file. +- `codegen_dir` (PurePath): The directory where the compiled code will be generated. +- `proto_file` (str): The name of the .proto file to compile. Defaults to `None`. +- `target_language` (str, optional): The target language for the compiled code. Defaults to "python". + +###### returns: + +- True if the compilation is successful, False otherwise. (bool) + +###### raises: + +- `Exception`: If the error occurs while performing the function. + +### Function `is_valid_endpoint` + +Checks if the given endpoint is valid. + +###### args: + +- `url` (str): The endpoint to check. + +###### returns: + +- True if the endpoint is valid, False otherwise. (bool) + +###### raises: + +- `ValueError`: If the error occurs while performing the function. + +### Function `normalize_private_key` + +Returns the normalized private key. + +###### args: + +- `private_key` (str): The private key in hex format to normalize. + +###### returns: + +- The normalized private key. (bytes) + +### Function `get_address_from_private` + +Returns the wallet address from the private key. + +###### args: + +- `private_key` (Any): The private key. + +###### returns: + +- The wallet address. (ChecksumAddress) + +### Class `add_to_path` + +`add_to_path` class is a _**context manager**_ that temporarily adds a given path to the system's `sys.path` list. +This allows for the import of modules or packages from that path. The `__enter__` method is called when the context +manager is entered, and it inserts the path at the beginning of sys.path. The `__exit__` method is called when the +context manager is exited, and it removes the path from sys.path. + +###### args: + +- `path` (str): The path to add to sys.path. + +### Function `find_file_by_keyword` + +Finds a file by keyword in the current directory and subdirectories. + +###### args: + +- `directory` (AnyStr | PathLike[AnyStr]): The directory to search in. +- `keyword` (AnyStr): The keyword to search for. + +###### returns: + +- The name of the file that contains the keyword, or `None` if no file is found. (AnyStr | None) + diff --git a/examples/calculator.py b/examples/calculator.py new file mode 100644 index 0000000..d9404ce --- /dev/null +++ b/examples/calculator.py @@ -0,0 +1,57 @@ +from snet import sdk + +config = sdk.config.Config(private_key="YOUR_PRIVATE_KEY", + eth_rpc_endpoint=f"https://sepolia.infura.io/v3/YOUR_INFURA_KEY", + concurrency=False, + force_update=False) + +operators = { + "+": "add", + "-": "sub", + "*": "mul", + "/": "div" +} + +snet_sdk = sdk.SnetSDK(config) +calc_client = snet_sdk.create_service_client(org_id="26072b8b6a0e448180f8c0e702ab6d2f", + service_id="Exampleservice", group_name="default_group") + + +def parse_expression(expression): + elements = list(expression.split()) + if len(elements) != 3: + raise Exception(f"Invalid expression '{expression}'. Three items required.") + + if elements[1] not in ["+", "-", "*", "/"]: + raise Exception(f"Invalid expression '{expression}'. Operation must be '+' or '-' or '*' or '/'.") + try: + a = float(elements[0]) + b = float(elements[2]) + except ValueError: + raise Exception(f"Invalid expression '{expression}'. Operands must be integers or floating point numbers.") + op = elements[1] + + return a, b, op + + +def main(): + print(""" +Welcome to the calculator powered by SingularityNET platform! +Please type the expression you want to calculate, e.g. 2 + 3. +Type 'exit' to exit the program.""") + while True: + expression = input("Calculator> ") + if expression == "exit": + break + try: + a, b, op = parse_expression(expression) + print(f"Calculating {a} {op} {b}...") + result = calc_client.call_rpc(operators[op], "Numbers", a=a, b=b) + print(f"{a} {op} {b} = {result}") + except Exception as e: + print(e) + + +if __name__ == "__main__": + main() + diff --git a/examples/console_app.py b/examples/console_app.py new file mode 100644 index 0000000..588bdd3 --- /dev/null +++ b/examples/console_app.py @@ -0,0 +1,393 @@ +""" +An example of how to use the SnetSDK to create a console application. +All the functionality of this application is based on the SnetSDK. + +It is assumed that there is an application provider (developer), who pays for all the +transactions and service calls. So, to run the application, you will need to change the values in 'config'. +""" + + +from snet import sdk + + +def list_organizations(): + """ + The function, which is called when the user enters the command 'organizations' in the main menu. + Prints the list of organization IDs related to the network specified in 'config'. + The list is got from the MPE contract using 'get_organization_list'. + """ + print("Organizations:") + print(*map(lambda x: '\t' + x, snet_sdk.get_organization_list()), sep="\n") + + +def list_services_for_org(): + """ + The function, which is called when the user enters the command 'services' in the main menu. + Prints the list of services IDs, related to the organization specified by the user. + The list is got from the MPE contract using 'get_organization_list'. + """ + org_id = input("Enter organization id: ").strip() + print("Services:") + print(*map(lambda x: '\t' + x, snet_sdk.get_services_list(org_id=org_id)), sep="\n") + + +def create_service_client(): + """ + The function, which is called when the user enters the command 'add' in the service menu. + Creates a service client, related to the service specified by the user, and adds it to the + list of initialized services. The creation occurs using 'create_service_client'. + """ + org_id = input("Enter organization id: ").strip() + service_id = input("Enter service id: ").strip() + group_name = input("Enter payment group name: ").strip() + + service = snet_sdk.create_service_client(org_id=org_id, service_id=service_id, group_name=group_name) + initialized_services.append(service) + + global active_service + if active_service is None: + active_service = service + + +def commands_help(): + """ + The function, which is called when the user enters the command 'help' in any menu. + Prints the list of available commands with descriptions depending on the active menu. + """ + global active_commands + print("Available commands:") + for command in active_commands.items(): + print(f'\t{command[0]} - {command[1][1]}') + + +def list_initialized_services(): + """ + The function, which is called when the user enters the command 'list' in the service menu. + Prints the list of initialized services including their organization ID, service ID and group name. + """ + print("INDEX ORGANIZATION_ID SERVICE_ID GROUP_NAME") + for index, service in enumerate(initialized_services): + print(f"{index} {service.org_id} {service.service_id} {service.group['group_name']}") + + +def switch_service(): + """ + The function, which is called when the user enters the command 'use' in the service menu. + Changes the active service to the one whose index the user specified. + """ + list_initialized_services() + index = int(input("Enter the index of one of the initialized services: ").strip()) + if index < len(initialized_services): + global active_service + active_service = initialized_services[index] + print(f"Switched to service with index {index}") + else: + print(f"Service with index {index} is not initialized!") + + +def call(): + """ + The function, which is called when the user enters the command 'call' in the service menu. + Calls the method specified by the user of the active service using `call_rpc` method. It gets data about the service + using the 'get_services_and_messages_info' and parses the resulting dict to display the correct names of the input + and output values to the user. + """ + global active_service + if active_service is None: + print("No initialized services!\n" + "Please enter 'service' to go to the service menu and then enter 'add' to add a service.") + return None + + method_name = input("Enter method name: ") + + services, messages = active_service.get_services_and_messages_info() + is_found = False + for service in services.items(): + for method in service[1]: + print(method[0], method_name) + if method[0] == method_name: + input_type = method[1] + output_type = method[2] + is_found = True + break + if is_found: + break + + if not is_found: + print(f"Method '{method_name}' is not found in service") + return None + + inputs = {var[1]: float(input(f"{var[1]}: ")) for var in messages[input_type]} + + print("Service calling...") + + result = active_service.call_rpc(method_name, input_type, **inputs) + outputs = {var[1]: getattr(result, var[1]) for var in messages[output_type]} + + print("Result:", *map(lambda x: f"{x[0]}: {x[1]}", outputs.items()), sep="\n") + + +def print_service_info(): + """ + The function, which is called when the user enters the command 'info' in the service menu. + Prints data (services, methods and services) of the active service. It gets data about the service using + 'get_services_and_messages_info_as_pretty_string'. + """ + global active_service + if active_service is None: + print("No initialized services!\n" + "Please enter 'service' to go to the service menu and then enter 'add' to add a service.") + return None + print(active_service.get_services_and_messages_info_as_pretty_string()) + + +def balance(): + """ + The function, which is called when the user enters the command 'balance' in the main menu. + Prints the balances of AGIX and MPE. It gets the balances using 'balance_of' and 'escrow_balance'. + """ + account_balance = snet_sdk.account.token_contract.functions.balanceOf(snet_sdk.account.address).call() + escrow_balance = snet_sdk.account.escrow_balance() + + print(f"AGIX balance: {account_balance}") + print(f"MPE balance: {escrow_balance}") + + +def deposit(): + """ + The function, which is called when the user enters the command 'deposit' in the main menu. + Deposits the user-specified amount of AGIX tokens in cogs into MPE contract using 'deposit_to_escrow_account'. + """ + amount = int(input("Enter amount of AGIX tokens in cogs to deposit into an MPE account: ")) + snet_sdk.account.deposit_to_escrow_account(amount) + + +def block_number(): + """ + The function, which is called when the user enters the command 'block' in the main menu. + Prints the current block number. It gets the block number using 'get_current_block_number'. + """ + if active_service is None: + print("No initialized services!\n" + "Please enter 'service' to go to the service menu and then enter 'add' to add a service.") + return None + print("Current block number: ", active_service.get_current_block_number()) + + +def update_channels(): + """ + The function, which is called when the user enters the command 'update' in the channel menu. + Updates the list of open channels stored in 'channels'. Gets the list of open channels using + 'load_open_channels' for each initialized service. + The specified method searches for channels through the blockchain, which is why it takes quite a long time + to work, so there is a warning for the user about this at the beginning. + """ + if active_service is None: + print("No initialized services!\n" + "Please enter 'service' to go to the service menu and then enter 'add' to add a service.") + return None + + is_continue = input("""Updating the channel list makes sense if the channel data has changed through other entry points. +This procedure may take several minutes. +Continue? (y/n): """).strip() == 'y' + if not is_continue: + return None + + print("Updating the channel list...") + global channels + channels.clear() + + for service in initialized_services: + load_channels = service.load_open_channels() + for channel in load_channels: + channels.append((channel, service.org_id, service.service_id, service.group['group_name'])) + + print("Channels updated! Enter 'list' to print the updated list.") + + +def open_channel(): + """ + The function, which is called when the user enters the command 'open' in the channel menu. + Opens a new channel for the active service. Checks the balance of the MPE contract and asks the user + if they want to deposit AGIX tokens into it if there isn't enough funds. Opens the channel using 'open_channel' + or 'deposit_and_open_channel' with the user-specified amount of AGIX tokens in cogs and expiration time. + """ + global active_service + global channels + additions = False + if active_service is None: + print("No initialized services! The channel can only be opened for the service!\n" + "Please enter 'service' to go to the service menu and then enter 'add' to add a service.") + return None + else: + is_continue = input("The new channel will be opened for the active service. Continue? (y/n): ").strip() == 'y' + if not is_continue: + return None + + amount = int(input("Enter amount of AGIX tokens in cogs to put into the channel: ").strip()) + + balance = snet_sdk.account.escrow_balance() + is_deposit = False + if balance < amount: + print(f"Insufficient balance!\n\tCurrent MPE balance: {balance}\n\tAmount to put: {amount}") + is_deposit = input("Would you like to deposit needed amount of AGIX tokens in advance? (y/n): ").strip() == 'y' + if not is_deposit: + print("Channel is not opened!") + return None + + expiration = int(input("Enter expiration time in blocks: ").strip()) + + if is_deposit: + channel = active_service.open_channel(amount=amount, expiration=expiration) + else: + channel = active_service.deposit_and_open_channel(amount=amount, expiration=expiration) + channels.append((channel, active_service.org_id, active_service.service_id, active_service.group['group_name'])) + + +def list_channels(): + """ + The function, which is called when the user enters the command 'list' in the channel menu. + Prints the list of open channels stored in 'channels'. + """ + global channels + print("ORGANIZATION_ID SERVICE_ID GROUP_NAME CHANNEL_ID AMOUNT EXPIRATION") + for channel in channels: + channel[0].sync_state() + print(channel[1], + channel[2], + channel[3], + channel[0].channel_id, + channel[0].state['available_amount'], + channel[0].state['expiration']) + + +def add_funds(): + """ + The function, which is called when the user enters the command 'add-funds' in the channel menu. + Adds funds to the channel. Finds the channel by its id specified by the user and adds the user-specified amount + of AGIX tokens in cogs to it using 'add_funds'. + """ + channel_id = int(input("Enter channel id: ").strip()) + exists = False + for channel in channels: + if channel[0].channel_id == channel_id: + amount = int(input("Enter amount of AGIX tokens in cogs to add to the channel: ").strip()) + channel[0].add_funds(amount) + exists = True + if not exists: + print(f"Channel with id {channel_id} is not found!") + + +def extend_expiration(): + """ + The function, which is called when the user enters the command 'extend-expiration' in the channel menu. + Extends expiration time of the channel. Finds the channel by its id specified by the user and Extends its + expiration time to a user-specified block using 'extend_expiration', after comparing it with the current + block number. + """ + channel_id = int(input("Enter channel id: ").strip()) + exists = False + for channel in channels: + if channel[0].channel_id == channel_id: + expiration = int(input("Enter new expiration time in blocks: ").strip()) + current_block = active_service.get_current_block_number() + if expiration < current_block: + print(f"Expiration time can't be less than current block ({current_block})!") + return None + channel[0].extend_expiration(expiration) + exists = True + if not exists: + print(f"Channel with id {channel_id} is not found!") + + +""" +SDK configuration that is configured by the application provider. +To run the application you need to change the 'private_key', 'eth_rpc_endpoint' and 'identity_name' values. +""" +config = sdk.config.Config(private_key="YOUR_PRIVATE_KEY", + eth_rpc_endpoint=f"https://sepolia.infura.io/v3/YOUR_INFURA_KEY", + concurrency=False, + force_update=False) + +snet_sdk = sdk.SnetSDK(config) # the 'SnetSDK' instance +initialized_services = [] # the list of initialized service clients +active_service: sdk.service_client.ServiceClient # the currently active service +channels = [] # the list of open channels + +""" +Commands available in the application with their descriptions and functions to call. +""" +commands = { + "main": { + "organizations": (list_organizations, "print a list of organization ids from Registry"), + "services": (list_services_for_org, "print a list of service ids for an organization from Registry"), + "balance": (balance, "print the account balance and the escrow balance"), + "deposit": (deposit, "deposit AGIX tokens into MPE"), + "block": (block_number, "print the current block number"), + "service": (lambda: None, "go to the services menu"), + "channel": (lambda: None, "go to the channels menu"), + "help": (commands_help, "print a list of available commands in the main menu"), + "exit": (lambda: exit(0), "exit the application") + }, + + "service": { + "add": (create_service_client, + "create a new service client. If it the first time, the new service becomes active"), + "use": (switch_service, "switch the active service"), + "call": (call, "call the active service method"), + "info": (print_service_info, "output services, methods and messages in a service"), + "list": (list_initialized_services, "print a list of initialized services"), + "help": (commands_help, "print a list of available commands in the services menu"), + "back": (lambda: None, "return to the main menu"), + "exit": (lambda: exit(0), "exit the application") + }, + + "channel": { + "update": (update_channels, "update a list of initialized payment channels"), + "list": (list_channels, "print a list of initialized payment channels"), + "open": (open_channel, "open a new payment channel"), + "add-funds": (add_funds, "add funds to a channel"), + "extend-expiration": (extend_expiration, "extend expiration of a channel"), + "help": (commands_help, "print a list of available commands in the channels menu"), + "back": (lambda: None, "return to the main menu"), + "exit": (lambda: exit(0), "exit the application") + } +} + +active_commands: dict = commands["main"] # the list of available commands in the active menu + + +def main(): + """ + The function, which is called when the application is started. + Manages global variables and calls the appropriate functions. + """ + global active_commands + + print(""" +Hello, welcome to the Snet SDK console application! +To use the application, type the name of the command you want to execute.""") + commands_help() + print("To print a list of available commands, type 'help'") + + prefix = ">>> " + while True: + command = input(prefix).strip() + if command in active_commands: + active_commands[command][0]() + else: + print(f"Command '{command}' is not found. Please try again.") + continue + + if command in ["back", "service", "channel"]: + if command == "back": + command = "main" + prefix = ">>> " + else: + prefix = command + " >>> " + active_commands = commands[command] + commands_help() + + +if __name__ == "__main__": + main() diff --git a/examples/examples_docs/calculator.md b/examples/examples_docs/calculator.md new file mode 100644 index 0000000..87fec3e --- /dev/null +++ b/examples/examples_docs/calculator.md @@ -0,0 +1,134 @@ +## Tutorial on developing a console calculator + +This is an example of how to use SingularityNET Python SDK to create a console calculator that works using a service +on the SingularityNET platform. + +### Description + +It is assumed that there is an application provider (developer), who pays for all the +transactions and service calls. + +So, the application must have the next console interface: + +```commandline +Welcome to the calculator powered by SingularityNET platform! +Please type the expression you want to calculate, e.g. 2 + 3. +Type 'exit' to exit the program. +Calculator> 34 * 4 +Calculating 34 * 4... +34 * 4 = 134 +Calculator> 103 - 82 +Calculating 103 - 82... +103 - 82 = 21 +Calculator> exit +``` + +### Development + +#### Install package + +Before the beginning we need to install `snet.sdk` package: + +```commandline +pip install snet.sdk +``` + +#### Configuration + +Firstly, we need to configure sdk and service client. So we create a config dict and then an sdk instance with +that config. + +_Note:_ don't forget to import `snet.sdk` package. + +```python +from snet import sdk + +config = sdk.config.Config(private_key="YOUR_PRIVATE_KEY", + eth_rpc_endpoint=f"https://sepolia.infura.io/v3/YOUR_INFURA_KEY", + concurrency=False, + force_update=False) + +snet_sdk = sdk.SnetSDK(config) +``` + +Here you need to set private values: `private_key`, `eth_rpc_endpoint`and possibly change some others. + +Calculator service is deployed on the sepolia network. To create a client of this service we need to pass `org_id`, +`service_id` and `group_name` to `create_service_client` method: + +```python +calc_client = snet_sdk.create_service_client(org_id="26072b8b6a0e448180f8c0e702ab6d2f", + service_id="Exampleservice", group_name="default_group") +``` + +#### User input parsing + +Secondly, we need to write a function that will process and parse user input. + +```python +def parse_expression(expression): + elements = list(expression.split()) + if len(elements) != 3: + raise Exception(f"Invalid expression '{expression}'. Three items required.") + + a = int(elements[0]) + b = int(elements[2]) + if elements[1] not in ["+", "-", "*", "/"]: + raise Exception(f"Invalid expression '{expression}'. Operation must be '+' or '-' or '*' or '/'") + elif not isinstance(a, (float, int)) or not isinstance(b, (float, int)): + raise Exception(f"Invalid expression '{expression}'. Operands must be integers or floating point numbers.") + op = elements[1] + + return a, b, op +``` + +This function splits the passed expression entered by the user into separate elements and checks their correctness. +In case of invalid input, exceptions are thrown, otherwise three elements of the required types are returned. + +#### Main cycle + +The calculator service accepts the name of the method on which the arithmetic operation depends. Therefore, we will +add a dictionary to match the operation symbol and the method name in the service. + +```python +operators = { + "+": "add", + "-": "sub", + "*": "mul", + "/": "div" +} +``` + +Now we can write the main function: + +```python +def main(): + print(""" +Welcome to the calculator powered by SingularityNET platform! +Please type the expression you want to calculate, e.g. 2 + 3. +Type 'exit' to exit the program.""") + while True: + expression = input("Calculator> ") + if expression == "exit": + break + try: + a, b, op = parse_expression(expression) + print(f"Calculating {a} {op} {b}...") + result = calc_client.call_rpc(operators[op], "Numbers", a=a, b=b) + print(f"{a} {op} {b} = {result}") + except Exception as e: + print(e) + + +if __name__ == "__main__": + main() +``` + +In an "infinite" loop, user input is read. If `exit` is entered, the program terminates. Otherwise, the expression +is parsed using the `parse_expression` function and, if no errors occur, its result is calculated using the previously +created instance of the ServiceClient class - `calc_client`, using `call_rpc` method. The result is then displayed +on the screen. + +The entire application code can be viewed at the +[link](https://github.com/Arondondon/snet-sdk-python/blob/depelopment-app-example/examples/calculator.py) to GitHub. + diff --git a/examples/examples_docs/console_app.md b/examples/examples_docs/console_app.md new file mode 100644 index 0000000..01970d5 --- /dev/null +++ b/examples/examples_docs/console_app.md @@ -0,0 +1,380 @@ +## Tutorial on developing a console application + +This is an example of how to use SingularityNET Python SDK to create a console application that uses all the +core functionality of the SDK. + +### Description + +It is assumed that there is an application provider (developer), who pays for all the +transactions and service calls. + +The application should have a main menu and a submenu where the user enters the command name. +The application should request additional parameters for a specific command after entering the command itself. + +So, the application must have the next console interface: + +```commandline +Hello, welcome to the Snet SDK console application! +To use the application, type the name of the command you want to execute. +Available commands: + organizations - print a list of organization ids from Registry + services - print a list of service ids for an organization from Registry + balance - print the account balance and the escrow balance + deposit - deposit AGIX tokens into MPE + block - print the current block number + service - go to the services menu + channel - go to the channels menu + help - print a list of available commands in the main menu + exit - exit the application +To print a list of available commands, type 'help' +>>> channel +Available commands: + update - update a list of initialized payment channels + list - print a list of initialized payment channels + open - open a new payment channel + add-funds - add funds to a channel + extend-expiration - extend expiration of a channel + help - print a list of available commands in the channels menu + back - return to the main menu + exit - exit the application +channel >>> back +Available commands: + organizations - print a list of organization ids from Registry + services - print a list of service ids for an organization from Registry + balance - print the account balance and the escrow balance + deposit - deposit AGIX tokens into MPE + block - print the current block number + service - go to the services menu + channel - go to the channels menu + help - print a list of available commands in the main menu + exit - exit the application +>>> services +Enter organization id: 26072b8b6a0e448180f8c0e702ab6d2f +Services: + Exampleservice +>>> exit +``` + +### Development + +#### Install package + +Before the beginning we need to install `snet.sdk` package: + +```commandline +pip install snet.sdk +``` + +#### Configuration + +Firstly, we need to configure sdk and service client. So we create a config dict and then an sdk instance with +that config. + +_Note:_ don't forget to import `snet.sdk` package. + +```python +from snet import sdk + +""" +SDK configuration that is configured by the application provider. +To run the application you need to change the 'private_key', 'eth_rpc_endpoint' and 'identity_name' values. +""" +config = sdk.config.Config(private_key="YOUR_PRIVATE_KEY", + eth_rpc_endpoint=f"https://sepolia.infura.io/v3/YOUR_INFURA_KEY", + concurrency=False, + force_update=False) + +snet_sdk = sdk.SnetSDK(config) # the 'SnetSDK' instance +``` + +Here you need to set private values: `private_key`, `eth_rpc_endpoint` and possibly change some others. + +#### Global variables + +The application will locally store created service clients as well as open payment channels for these services. +In addition, there must be an active service - the one for which methods are called, channels are opened, etc. + +```python +initialized_services = [] # the list of initialized service clients +active_service: sdk.service_client.ServiceClient # the currently active service +channels = [] # the list of open channels +``` + +The concept of the application is that when the user enters any command, the corresponding function should be called. +To implement this concept, we need a dict that will associate command names with the corresponding functions. + +```python +""" +Commands available in the application with their descriptions and functions to call. +""" +commands = { + "main": { + "organizations": (list_organizations, "print a list of organization ids from Registry"), + "services": (list_services_for_org, "print a list of service ids for an organization from Registry"), + "balance": (balance, "print the account balance and the escrow balance"), + "deposit": (deposit, "deposit AGIX tokens into MPE"), + "block": (block_number, "print the current block number"), + "service": (lambda: None, "go to the services menu"), + "channel": (lambda: None, "go to the channels menu"), + "help": (commands_help, "print a list of available commands in the main menu"), + "exit": (lambda: exit(0), "exit the application") + }, + + "service": { + "add": (create_service_client, + "create a new service client. If it the first time, the new service becomes active"), + "use": (switch_service, "switch the active service"), + "call": (call, "call the active service method"), + "info": (print_service_info, "output services, methods and messages in a service"), + "list": (list_initialized_services, "print a list of initialized services"), + "help": (commands_help, "print a list of available commands in the services menu"), + "back": (lambda: None, "return to the main menu"), + "exit": (lambda: exit(0), "exit the application") + }, + + "channel": { + "update": (update_channels, "update a list of initialized payment channels"), + "list": (list_channels, "print a list of initialized payment channels"), + "open": (open_channel, "open a new payment channel"), + "add-funds": (add_funds, "add funds to a channel"), + "extend-expiration": (extend_expiration, "extend expiration of a channel"), + "help": (commands_help, "print a list of available commands in the channels menu"), + "back": (lambda: None, "return to the main menu"), + "exit": (lambda: exit(0), "exit the application") + } +} +``` + +This dict is divided into three parts: the `main` part is responsible for the main menu, the `channel` part is +responsible for the channel submenu, and `service` is responsible for the service submenu. `commands` performs +several functions at once. It associates commands with their corresponding functions, stores descriptions for the +commands needed for the `help` command, and also defines the list of commands available in +the current menu. So one of the dict parts should be active to perform two last functions. + +```python +active_commands: dict = commands["main"] # the list of available commands in the active menu +``` + +`active_commands` is changed when changing menu. + +#### Main function + +```python +def main(): + """ + The function, which is called when the application is started. + Manages global variables and calls the appropriate functions. + """ + global active_commands + + print(""" +Hello, welcome to the Snet SDK console application! +To use the application, type the name of the command you want to execute.""") + commands_help() + print("To print a list of available commands, type 'help'") + + prefix = ">>> " + while True: + command = input(prefix).strip() + if command in active_commands: + active_commands[command][0]() + else: + print(f"Command '{command}' is not found. Please try again.") + continue + + if command in ["back", "service", "channel"]: + if command == "back": + command = "main" + prefix = ">>> " + else: + prefix = command + " >>> " + active_commands = commands[command] + commands_help() + + +if __name__ == "__main__": + main() + +``` + +The "main" function processes user input, calls the necessary functions, and also switches the menu (when the +corresponding command is entered) by changing the values of the "active_commands" and "prefix" variables. Of course, +all this happens in an "infinite" loop (until the "exit" command is called). + +#### Functions for commands + +There are lots of functions to implement, that can be viewed in `commands` dict. For example, `list_services_for_org`, +`deposit`, `create_service_client`, `call`, `open_channel`, etc. All these functions use SDK functionality and +global variables, and prompt the user for additional input if needed. Also some of them do some checks on user input +if necessary and possible. + +Not all functions will be described here, but the full program code with comments can be viewed at the +[link](https://github.com/Arondondon/snet-sdk-python/blob/depelopment-app-example/examples/console_app.py) to GitHub + +###### list_services_for_org + +The function, which is called when the user enters the command 'services' in the main menu. +Prints the list of services IDs, related to the organization specified by the user. +The list is got from the MPE contract using 'get_organization_list'. + +```python +def list_services_for_org(): + org_id = input("Enter organization id: ").strip() + print("Services:") + print(*map(lambda x: '\t' + x, snet_sdk.get_services_list(org_id=org_id)), sep="\n") +``` + +###### create_service_client + +The function, which is called when the user enters the command 'add' in the service menu. +Creates a service client, related to the service specified by the user, and adds it to the +list of initialized services. The creation occurs using 'create_service_client'. + +```python +def create_service_client(): + org_id = input("Enter organization id: ").strip() + service_id = input("Enter service id: ").strip() + group_name = input("Enter payment group name: ").strip() + + service = snet_sdk.create_service_client(org_id=org_id, service_id=service_id, group_name=group_name) + initialized_services.append(service) + + global active_service + if active_service is None: + active_service = service +``` + +###### commands_help + +The function, which is called when the user enters the command 'help' in any menu. +Prints the list of available commands with descriptions depending on the active menu. + +```python +def commands_help(): + global active_commands + print("Available commands:") + for command in active_commands.items(): + print(f'\t{command[0]} - {command[1][1]}') +``` + +###### call + +The function, which is called when the user enters the command 'call' in the service menu. +Calls the method specified by the user of the active service using `call_rpc` method. It gets data about the service +using the 'get_services_and_messages_info' and parses the resulting dict to display the correct names of the input +and output values to the user. + +```python +def call(): + global active_service + if active_service is None: + print("No initialized services!\n" + "Please enter 'service' to go to the service menu and then enter 'add' to add a service.") + return None + + method_name = input("Enter method name: ") + + services, messages = active_service.get_services_and_messages_info() + is_found = False + for service in services.items(): + for method in service[1]: + print(method[0], method_name) + if method[0] == method_name: + input_type = method[1] + output_type = method[2] + is_found = True + break + if is_found: + break + + if not is_found: + print(f"Method '{method_name}' is not found in service") + return None + + inputs = {var[1]: float(input(f"{var[1]}: ")) for var in messages[input_type]} + + print("Service calling...") + + result = active_service.call_rpc(method_name, input_type, **inputs) + outputs = {var[1]: getattr(result, var[1]) for var in messages[output_type]} + + print("Result:", *map(lambda x: f"{x[0]}: {x[1]}", outputs.items()), sep="\n") +``` + +###### update_channels + +The function, which is called when the user enters the command 'update' in the channel menu. +Updates the list of open channels stored in 'channels'. Gets the list of open channels using +'load_open_channels' for each initialized service. +The specified method searches for channels through the blockchain, which is why it takes quite a long time +to work, so there is a warning for the user about this at the beginning. + +```python +def update_channels(): + if active_service is None: + print("No initialized services!\n" + "Please enter 'service' to go to the service menu and then enter 'add' to add a service.") + return None + + is_continue = input("""Updating the channel list makes sense if the channel data has changed through other entry points. +This procedure may take several minutes. +Continue? (y/n): """).strip() == 'y' + if not is_continue: + return None + + print("Updating the channel list...") + global channels + channels.clear() + + for service in initialized_services: + load_channels = service.load_open_channels() + for channel in load_channels: + channels.append((channel, service.org_id, service.service_id, service.group['group_name'])) + + print("Channels updated! Enter 'list' to print the updated list.") +``` + +###### open_channel + +The function, which is called when the user enters the command 'open' in the channel menu. +Opens a new channel for the active service. Checks the balance of the MPE contract and asks the user +if they want to deposit AGIX tokens into it if there isn't enough funds. Opens the channel using 'open_channel' +or 'deposit_and_open_channel' with the user-specified amount of AGIX tokens in cogs and expiration time. + +```python +def open_channel(): + global active_service + global channels + additions = False + if active_service is None: + print("No initialized services! The channel can only be opened for the service!\n" + "Please enter 'service' to go to the service menu and then enter 'add' to add a service.") + return None + else: + is_continue = input("The new channel will be opened for the active service. Continue? (y/n): ").strip() == 'y' + if not is_continue: + return None + + amount = int(input("Enter amount of AGIX tokens in cogs to put into the channel: ").strip()) + + balance = snet_sdk.account.escrow_balance() + is_deposit = False + if balance < amount: + print(f"Insufficient balance!\n\tCurrent MPE balance: {balance}\n\tAmount to put: {amount}") + is_deposit = input("Would you like to deposit needed amount of AGIX tokens in advance? (y/n): ").strip() == 'y' + if not is_deposit: + print("Channel is not opened!") + return None + + expiration = int(input("Enter expiration time in blocks: ").strip()) + + if is_deposit: + channel = active_service.open_channel(amount=amount, expiration=expiration) + else: + channel = active_service.deposit_and_open_channel(amount=amount, expiration=expiration) + channels.append((channel, active_service.org_id, active_service.service_id, active_service.group['group_name'])) +``` + +The entire application code can be viewed at the +[link](https://github.com/Arondondon/snet-sdk-python/blob/depelopment-app-example/examples/console_app.py) to GitHub. + diff --git a/requirements.txt b/requirements.txt index 9c11871..218b126 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,6 +17,4 @@ argcomplete==3.1.2 grpcio-health-checking==1.59.0 jsonschema==4.0.0 eth-account==0.9.0 -snet.cli==2.1.4 -snet.contracts==0.1.1 -urllib3>=2.2.2 +snet.contracts==0.1.1 \ No newline at end of file diff --git a/snet/sdk/__init__.py b/snet/sdk/__init__.py index 0897b27..fd52bf2 100644 --- a/snet/sdk/__init__.py +++ b/snet/sdk/__init__.py @@ -14,10 +14,9 @@ from snet.sdk.metadata_provider.ipfs_metadata_provider import IPFSMetadataProvider from snet.sdk.payment_strategies.default_payment_strategy import DefaultPaymentStrategy -from snet.cli.commands.sdk_command import SDKCommand -from snet.cli.commands.commands import BlockchainCommand -from snet.cli.config import Config -from snet.cli.utils.utils import bytes32_to_str, type_converter +from snet.sdk.client_lib_generator import ClientLibGenerator +from snet.sdk.config import Config +from snet.sdk.utils.utils import bytes32_to_str, type_converter google.protobuf.internal.api_implementation.Type = lambda: 'python' @@ -26,12 +25,7 @@ _sym_db = _symbol_database.Default() _sym_db.RegisterMessage = lambda x: None - -from urllib.parse import urljoin - - import web3 -from rfc3986 import urlparse import ipfshttpclient from snet.sdk.service_client import ServiceClient @@ -40,32 +34,23 @@ from snet.contracts import get_contract_object -from snet.cli.metadata.service import mpe_service_metadata_from_json -from snet.cli.utils.ipfs_utils import bytesuri_to_hash, get_from_ipfs_and_checkhash -from snet.cli.utils.utils import find_file_by_keyword +from snet.sdk.metadata_provider.service_metadata import mpe_service_metadata_from_json +from snet.sdk.utils.ipfs_utils import bytesuri_to_hash, get_from_ipfs_and_checkhash +from snet.sdk.utils.utils import find_file_by_keyword ModuleName = NewType('ModuleName', str) ServiceStub = NewType('ServiceStub', Any) -class Arguments: - def __init__(self, org_id=None, service_id=None): - self.org_id = org_id - self.service_id = service_id - self.language = "python" - self.protodir = Path("~").expanduser().joinpath(".snet") - - class SnetSDK: """Base Snet SDK""" - def __init__(self, sdk_config, metadata_provider=None): + def __init__(self, sdk_config: Config, metadata_provider=None): self._sdk_config = sdk_config self._metadata_provider = metadata_provider # Instantiate Ethereum client - eth_rpc_endpoint = self._sdk_config.get("eth_rpc_endpoint", - "https://mainnet.infura.io/v3/e7732e1f679e461b9bb4da5653ac3fc2") + eth_rpc_endpoint = self._sdk_config["eth_rpc_endpoint"] eth_rpc_request_kwargs = self._sdk_config.get("eth_rpc_request_kwargs") provider = web3.HTTPProvider(endpoint_uri=eth_rpc_endpoint, request_kwargs=eth_rpc_request_kwargs) @@ -80,7 +65,7 @@ def __init__(self, sdk_config, metadata_provider=None): self.mpe_contract = MPEContract(self.web3, _mpe_contract_address) # Instantiate IPFS client - ipfs_endpoint = self._sdk_config.get("default_ipfs_endpoint", "/dns/ipfs.singularitynet.io/tcp/80/") + ipfs_endpoint = self._sdk_config["ipfs_endpoint"] self.ipfs_client = ipfshttpclient.connect(ipfs_endpoint) # Get Registry contract address from config if specified; mostly for local testing @@ -92,30 +77,6 @@ def __init__(self, sdk_config, metadata_provider=None): self.account = Account(self.web3, sdk_config, self.mpe_contract) - global_config = Config(sdk_config=sdk_config) - self.setup_config(global_config) - - def setup_config(self, config: Config) -> None: - out_f = sys.stdout - network = self._sdk_config.get("network", None) - identity_name = self._sdk_config.get("identity_name", None) - # Checking for an empty network - if network and config["session"]["network"] != network: - config.set_session_network(network, out_f) - if identity_name: - self.set_session_identity(identity_name, config, out_f) - elif len(config.get_all_identities_names()) > 0: - if "identity" not in config["session"] or config["session"]["identity"] == "": - raise Exception("identity_name is not passed or selected") - - def set_session_identity(self, identity_name: str, config: Config, out_f): - if identity_name not in config.get_all_identities_names(): - identity = config.setup_identity() - config.add_identity(identity_name, identity, out_f) - config.set_session_identity(identity_name, out_f) - elif config["session"]["identity"] != identity_name: - config.set_session_identity(identity_name, out_f) - def create_service_client(self, org_id: str, service_id: str, group_name=None, payment_channel_management_strategy=None, free_call_auth_token_bin=None, @@ -123,20 +84,19 @@ def create_service_client(self, org_id: str, service_id: str, group_name=None, options=None, concurrent_calls=1): - # Create and instance of the Config object, so we can create an instance of SDKCommand - sdk_config_object = Config(sdk_config=self._sdk_config) - sdk = SDKCommand(sdk_config_object, args=Arguments(org_id, service_id)) + # Create and instance of the Config object, so we can create an instance of ClientLibGenerator + lib_generator = ClientLibGenerator(self._sdk_config, self.registry_contract, org_id, service_id) # Download the proto file and generate stubs if needed force_update = self._sdk_config.get('force_update', False) if force_update: - sdk.generate_client_library() + lib_generator.generate_client_library() else: path_to_pb_files = self.get_path_to_pb_files(org_id, service_id) pb_2_file_name = find_file_by_keyword(path_to_pb_files, keyword="pb2.py") pb_2_grpc_file_name = find_file_by_keyword(path_to_pb_files, keyword="pb2_grpc.py") if not pb_2_file_name or not pb_2_grpc_file_name: - sdk.generate_client_library() + lib_generator.generate_client_library() if payment_channel_management_strategy is None: payment_channel_management_strategy = DefaultPaymentStrategy(concurrent_calls) @@ -223,21 +183,16 @@ def _get_service_group_details(self, service_metadata, group_name): return self._get_group_by_group_name(service_metadata, group_name) def get_organization_list(self) -> list: - global_config = Config(sdk_config=self._sdk_config) - blockchain_command = BlockchainCommand(config=global_config, args=Arguments()) - org_list = blockchain_command.call_contract_command( - "Registry", "listOrganizations", []) + org_list = self.registry_contract.functions.listOrganizations().call() organization_list = [] for idx, org_id in enumerate(org_list): organization_list.append(bytes32_to_str(org_id)) return organization_list def get_services_list(self, org_id: str) -> list: - global_config = Config(sdk_config=self._sdk_config) - blockchain_command = BlockchainCommand(config=global_config, args=Arguments()) - (found, org_service_list) = blockchain_command.call_contract_command("Registry", - "listServicesForOrganization", - [type_converter("bytes32")(org_id)]) + found, org_service_list = self.registry_contract.functions.listServicesForOrganization( + type_converter("bytes32")(org_id) + ).call() if not found: raise Exception(f"Organization with id={org_id} doesn't exist!") org_service_list = list(map(bytes32_to_str, org_service_list)) diff --git a/snet/sdk/account.py b/snet/sdk/account.py index d77cc9b..df71493 100644 --- a/snet/sdk/account.py +++ b/snet/sdk/account.py @@ -1,6 +1,6 @@ import json -from snet.cli.utils.utils import get_address_from_private, normalize_private_key +from snet.sdk.utils.utils import get_address_from_private, normalize_private_key from snet.contracts import get_contract_object DEFAULT_GAS = 300000 diff --git a/snet/sdk/client_lib_generator.py b/snet/sdk/client_lib_generator.py new file mode 100644 index 0000000..8623162 --- /dev/null +++ b/snet/sdk/client_lib_generator.py @@ -0,0 +1,70 @@ +import os +from pathlib import Path, PurePath + +from snet.sdk.utils import ipfs_utils +from snet.sdk.utils.utils import compile_proto, type_converter +from snet.sdk.metadata_provider.service_metadata import mpe_service_metadata_from_json + + +class ClientLibGenerator: + + def __init__(self, sdk_config, registry_contract, org_id, service_id): + self.sdk_config = sdk_config + self.registry_contract = registry_contract + self.org_id = org_id + self.service_id = service_id + self.language = "python" + self.protodir = Path("~").expanduser().joinpath(".snet") + + def generate_client_library(self): + + if os.path.isabs(self.protodir): + client_libraries_base_dir_path = PurePath(self.protodir) + else: + cur_dir_path = PurePath(os.getcwd()) + client_libraries_base_dir_path = cur_dir_path.joinpath(self.protodir) + + os.makedirs(client_libraries_base_dir_path, exist_ok=True) + + # Create service client libraries path + library_language = self.language + library_org_id = self.org_id + library_service_id = self.service_id + + library_dir_path = client_libraries_base_dir_path.joinpath(library_org_id, + library_service_id, + library_language) + + try: + metadata = self._get_service_metadata_from_registry() + model_ipfs_hash = metadata["model_ipfs_hash"] + + # Receive proto files + ipfs_utils.safe_extract_proto_from_ipfs(ipfs_utils.get_ipfs_client(self.sdk_config), + model_ipfs_hash, library_dir_path) + + # Compile proto files + compile_proto(Path(library_dir_path), library_dir_path, target_language=self.language) + + print(f'client libraries for service with id "{library_service_id}" in org with id "{library_org_id}" ' + f'generated at {library_dir_path}') + except Exception as e: + print(e) + + def _get_service_metadata_from_registry(self): + rez = self._get_service_registration() + metadata_hash = ipfs_utils.bytesuri_to_hash(rez["metadataURI"]) + metadata = ipfs_utils.get_from_ipfs_and_checkhash(ipfs_utils.get_ipfs_client(self.sdk_config), metadata_hash) + metadata = metadata.decode("utf-8") + metadata = mpe_service_metadata_from_json(metadata) + return metadata + + def _get_service_registration(self): + params = [type_converter("bytes32")(self.org_id), type_converter("bytes32")(self.service_id)] + rez = self.registry_contract.functions.getServiceRegistrationById(*params).call() + if not rez[0]: + raise Exception("Cannot find Service with id=%s in Organization with id=%s" % ( + self.service_id, self.org_id)) + return {"metadataURI": rez[2]} + + diff --git a/snet/sdk/concurrency_manager.py b/snet/sdk/concurrency_manager.py index 8348396..6c2a29a 100644 --- a/snet/sdk/concurrency_manager.py +++ b/snet/sdk/concurrency_manager.py @@ -3,7 +3,7 @@ import grpc import web3 -from snet.cli.utils.utils import RESOURCES_PATH, add_to_path +from snet.sdk.utils.utils import RESOURCES_PATH, add_to_path class ConcurrencyManager: diff --git a/snet/sdk/config.py b/snet/sdk/config.py new file mode 100644 index 0000000..eff168f --- /dev/null +++ b/snet/sdk/config.py @@ -0,0 +1,37 @@ + + +class Config: + def __init__(self, + private_key, + eth_rpc_endpoint, + wallet_index=0, + ipfs_endpoint=None, + concurrency=True, + force_update=False, + mpe_contract_address=None, + token_contract_address=None, + registry_contract_address=None, + signer_private_key=None): + self.__config = { + "private_key": private_key, + "eth_rpc_endpoint": eth_rpc_endpoint, + "wallet_index": wallet_index, + "ipfs_endpoint": ipfs_endpoint if ipfs_endpoint else "/dns/ipfs.singularitynet.io/tcp/80/", + "concurrency": concurrency, + "force_update": force_update, + "mpe_contract_address": mpe_contract_address, + "token_contract_address": token_contract_address, + "registry_contract_address": registry_contract_address, + "signer_private_key": signer_private_key + } + + def __getitem__(self, key): + return self.__config[key] + + def get(self, key, default=None): + return self.__config.get(key, default) + + def get_ipfs_endpoint(self): + return self["ipfs_endpoint"] + + diff --git a/snet/sdk/metadata_provider/ipfs_metadata_provider.py b/snet/sdk/metadata_provider/ipfs_metadata_provider.py index 4f1446f..a1c7067 100644 --- a/snet/sdk/metadata_provider/ipfs_metadata_provider.py +++ b/snet/sdk/metadata_provider/ipfs_metadata_provider.py @@ -1,8 +1,8 @@ import json import web3 -from snet.cli.metadata.service import mpe_service_metadata_from_json -from snet.cli.utils.ipfs_utils import bytesuri_to_hash, get_from_ipfs_and_checkhash +from snet.sdk.metadata_provider.service_metadata import mpe_service_metadata_from_json +from snet.sdk.utils.ipfs_utils import bytesuri_to_hash, get_from_ipfs_and_checkhash class IPFSMetadataProvider(object): diff --git a/snet/sdk/metadata_provider/service_metadata.py b/snet/sdk/metadata_provider/service_metadata.py new file mode 100644 index 0000000..1772e6e --- /dev/null +++ b/snet/sdk/metadata_provider/service_metadata.py @@ -0,0 +1,545 @@ +""" +Functions for manipulating service metadata + +Metadata format: +---------------------------------------------------- +version - used to track format changes (current version is 1) +display_name - Display name of the service +encoding - Service encoding (proto or json) +service_type - Service type (grpc, jsonrpc or process) +service_description - Service description (arbitrary field) +payment_expiration_threshold - Service will reject payments with expiration less + than current_block + payment_expiration_threshold. + This field should be used by the client with caution. + Client should not accept arbitrary payment_expiration_threshold +model_ipfs_hash - IPFS HASH to the .tar archive of protobuf service specification +mpe_address - Address of MultiPartyEscrow contract. + Client should use it exclusively for cross-checking of mpe_address, + (because service can attack via mpe_address) + Daemon can use it directly if authenticity of metadata is confirmed +pricing {} - Pricing model + Possible pricing models: + 1. Fixed price + price_model - "fixed_price" + price_in_cogs - unique fixed price in cogs for all method (1 AGIX = 10^8 cogs) + (other pricing models can be easily supported) +groups [] - group is the number of endpoints which shares same payment channel; + grouping strategy is defined by service provider; + for example service provider can use region name as group name + group_name - unique name of the group (human readable) + group_id - unique id of the group (random 32 byte string in base64 encoding) + payment_address - Ethereum address to recieve payments +endpoints[] - address in the off-chain network to provide a service + group_name + endpoint - unique endpoint identifier (ip:port) + +assets {} - asset type and its ipfs value/values +""" + +import re +import json +import base64 + +from collections import defaultdict +from enum import Enum + +from snet.sdk.utils.utils import is_valid_endpoint + + +# Supported Asset types +class AssetType(Enum): + HERO_IMAGE = "hero_image" + IMAGES = "images" + DOCUMENTATION = "documentation" + TERMS_OF_USE = "terms_of_use" + + @staticmethod + def is_single_value(asset_type): + if (asset_type == AssetType.HERO_IMAGE.value or asset_type == AssetType.DOCUMENTATION.value + or asset_type == AssetType.TERMS_OF_USE.value): + return True + + +# TODO: we should use some standard solution here +class MPEServiceMetadata: + + def __init__(self): + """ init with modelIPFSHash """ + self.m = {"version": 1, + "display_name": "", + "encoding": "grpc", # grpc by default + "service_type": "grpc", # grpc by default + # one week by default (15 sec block, 24*60*60*7/15) + "model_ipfs_hash": "", + "mpe_address": "", + "groups": [], + "assets": {}, + "media": [], + "tags": [] + } + + def set_simple_field(self, f, v): + if f != "display_name" and f != "encoding" and f != "model_ipfs_hash" and f != "mpe_address" and \ + f != "service_type" and f != "payment_expiration_threshold" and f != "service_description": + raise Exception("unknown field in MPEServiceMetadata") + self.m[f] = v + + def set_fixed_price_in_cogs(self, group_name, price): + if type(price) != int: + raise Exception("Price should have int type") + + if not self.is_group_name_exists(group_name): + raise Exception("the group %s is not present" % str(group_name)) + + for group in self.m["groups"]: + if group["group_name"] == group_name: + is_fixed_price_enabled = False + # default=True it will change when we will go live with method level pricing + if "pricing" in group: + for pricing in group['pricing']: + if pricing["price_model"] == "fixed_price": + is_fixed_price_enabled = True + pricing["price_in_cogs"] = price + if not is_fixed_price_enabled: + group["pricing"].append({"price_model": "fixed_price", + "price_in_cogs": price, "default": True}) + else: + group["pricing"] = [{"price_model": "fixed_price", + "price_in_cogs": price, "default": True}] + + def set_method_price_in_cogs(self, group_name, package_name, service_name, method, price): + if type(price) != int: + raise Exception("Price should have int type") + + if not self.is_group_name_exists(group_name): + raise Exception("the group %s is not present" % str(group_name)) + + groups = self.m["groups"] + for group in groups: + if group["group_name"] == group_name: + + service_name = service_name + package_name = package_name + method_pricing = {"method_name": method, + "price_in_cogs": price} + pricings = [] + + if 'pricings' in group: + pricings = group["pricings"] + + fixed_price_method_model_exist = False + for pricing in pricings: + if pricing['price_model'] == 'fixed_price_per_method': + fixed_price_method_model_exist = True + + if 'details' in pricing: + fixed_price_method_pricing_for_service_exist = False + for detail in pricing['details']: + + if detail['service_name'] == service_name: + # adding new method pricing for existing service + fixed_price_method_pricing_for_service_exist = True + detail['method_pricing'].append( + method_pricing) + + if not fixed_price_method_pricing_for_service_exist: + # pricing for new method for new service + pricing['details'].append({"service_name": service_name, + "method_pricing": [method_pricing]}) + else: + pricing['details'] = [{"service_name": service_name, + "method_pricing": [method_pricing]}] + + if not fixed_price_method_model_exist: + fixed_price_per_method = {"package_name": package_name, + "price_model": "fixed_price_per_method", + "details": [ + {"service_name": service_name, "method_pricing": [method_pricing]}]} + group['pricings'] = [fixed_price_per_method] + + def add_group(self, group_name): + """ Return new group_id in base64 """ + if self.is_group_name_exists(group_name): + raise Exception("the group \"%s\" is already present" % + str(group_name)) + + self.m["groups"] += [{"group_name": group_name}] + + def remove_group(self, group_name): + for group in self.m["groups"]: + if group["group_name"] == group_name: + self.m["groups"].remove(group) + + def get_tags(self): + tags = [] + if "tags" in self.m: + tags = self.m["tags"] + return tags + + def add_tag(self, tag_name): + if not "tags" in self.m: + self.m["tags"] = [] + + if tag_name in self.m["tags"]: + print(f"The tag {str(tag_name)} is already present") + return + self.m["tags"] += [tag_name] + + def remove_tag(self, tag_name): + if not "tags" in self.m: + self.m["tags"] = [] + + if tag_name not in self.m["tags"]: + print(f"The tag {str(tag_name)} is not found") + return + self.m["tags"].remove(tag_name) + + def add_asset(self, asset_ipfs_hash, asset_type): + # Check if we need to validation if same asset type is added twice if we need to add it or replace the existing one + + if 'assets' not in self.m: + self.m['assets'] = {} + + # hero image will contain the single value + if AssetType.is_single_value(asset_type): + self.m['assets'][asset_type] = asset_ipfs_hash + + # images can contain multiple value + elif asset_type == AssetType.IMAGES.value: + if asset_type in self.m['assets']: + self.m['assets'][asset_type].append(asset_ipfs_hash) + else: + self.m['assets'][asset_type] = [asset_ipfs_hash] + else: + raise Exception("Invalid asset type %s" % asset_type) + + def remove_all_assets(self): + self.m['assets'] = {} + + def remove_asset(self, asset_type): + if 'assets' in self.m: + if AssetType.is_single_value(asset_type): + self.m['assets'][asset_type] = "" + elif asset_type == AssetType.IMAGES.value: + self.m['assets'][asset_type] = [] + else: + raise Exception("Invalid asset type %s" % asset_type) + + def add_endpoint_to_group(self, group_name, endpoint): + if re.match("^\w+://", endpoint) is None: + # TODO: Default to https when our tutorials show setting up a ssl certificate as well + endpoint = 'http://' + endpoint + if not is_valid_endpoint(endpoint): + raise Exception("Endpoint is not a valid URL") + if not self.is_group_name_exists(group_name): + raise Exception("the group %s is not present" % str(group_name)) + if endpoint in self.get_all_endpoints_for_group(group_name): + raise Exception("the endpoint %s is already present" % + str(endpoint)) + + groups = self.m["groups"] + for group in groups: + if group["group_name"] == group_name: + if 'endpoints' in group: + group['endpoints'].append(endpoint) + else: + group['endpoints'] = [endpoint] + + def remove_all_endpoints_for_group(self, group_name): + if not self.is_group_name_exists(group_name): + raise Exception("Group name does not exist %s", group_name) + + groups = self.m["groups"] + for group in groups: + if group["group_name"] == group_name: + group["endpoints"] = [] + + def is_group_name_exists(self, group_name): + """ check if group with given name is already exists """ + groups = self.m["groups"] + for g in groups: + if g["group_name"] == group_name: + return True + return False + + def get_group_by_group_id(self, group_id): + """ return group with given group_id (return None if it doesn't exist) """ + group_id_base64 = base64.b64encode(group_id).decode('ascii') + groups = self.m["groups"] + for g in groups: + if g["group_id"] == group_id_base64: + return g + return None + + def set_free_calls_for_group(self, group_name, free_calls): + groups = self.m["groups"] + for g in groups: + if g["group_name"] == group_name: + g["free_calls"] = free_calls + + def set_freecall_signer_address(self, group_name, signer_address): + groups = self.m["groups"] + for g in groups: + if g["group_name"] == group_name: + g["free_call_signer_address"] = signer_address + + def get_json(self): + return json.dumps(self.m) + + def get_json_pretty(self): + return json.dumps(self.m, indent=4) + + def set_from_json(self, j): + # TODO: we probaly should check the consistensy of loaded json here + # check that it contains required fields + self.m = json.loads(j) + if not "tags" in self.m: + self.m["tags"] = [] + + def load(self, file_name): + with open(file_name) as f: + self.set_from_json(f.read()) + + def save_pretty(self, file_name): + with open(file_name, 'w') as f: + f.write(self.get_json_pretty()) + + def __getitem__(self, key): + return self.m[key] + + def __contains__(self, key): + return key in self.m + + def get_group_name_nonetrick(self, group_name=None): + """ In all getter function in case of single payment group, group_name can be None """ + groups = self.m["groups"] + if len(groups) == 0: + raise Exception("Cannot find any groups in metadata") + if not group_name: + if len(groups) > 1: + raise Exception( + "We have more than one payment group in metadata, so group_name should be specified") + return groups[0]["group_name"] + return group_name + + def get_group(self, group_name=None): + group_name = self.get_group_name_nonetrick(group_name) + for g in self.m["groups"]: + if g["group_name"] == group_name: + return g + raise Exception('Cannot find group "%s" in metadata' % group_name) + + def get_group_id_base64(self, group_name=None): + return self.get_group(group_name)["group_id"] + + def get_group_id(self, group_name=None): + return base64.b64decode(self.get_group_id_base64(group_name)) + + def get_payment_address(self, group_name=None): + return self.get_group(group_name)["payment_address"] + + def add_daemon_address_to_group(self, group_name, daemon_address): + groups = self.m["groups"] + if not self.is_group_name_exists(group_name): + raise Exception('Cannot find group "%s" in metadata' % group_name) + for group in groups: + if group["group_name"] == group_name: + if 'daemon_addresses' in group: + group['daemon_addresses'].append(daemon_address) + else: + group['daemon_addresses'] = [daemon_address] + + def remove_all_daemon_addresses_for_group(self, group_name): + groups = self.m["groups"] + if not self.is_group_name_exists(group_name): + raise Exception('Cannot find group "%s" in metadata' % group_name) + for group in groups: + if group["group_name"] == group_name: + group["daemon_addresses"] = [] + + def get_all_endpoints_for_group(self, group_name): + for group in self.m["groups"]: + if group["group_name"] == group_name: + if "endpoints" in group: + return group["endpoints"] + return [] + + def get_all_group_endpoints(self): + group_endpoints = {} + for group in self.m["groups"]: + if "endpoints" in group: + group_endpoints[group["group_name"]] = group['endpoints'] + return group_endpoints + + def get_all_endpoints_with_group_name(self): + endpts_with_grp = defaultdict(list) + for e in self.m["endpoints"]: + endpts_with_grp[e['group_name']].append(e['endpoint']) + return endpts_with_grp + + def get_endpoints_for_group(self, group_name=None): + group_name = self.get_group_name_nonetrick(group_name) + return [e["endpoint"] for e in self.m["endpoints"] if e["group_name"] == group_name] + + def add_contributor(self, name, email_id): + if "contributors" in self.m: + contributors = self.m["contributors"] + else: + contributors = [] + + contributors.append( + { + "name": name, + "email_id": email_id + } + ) + self.m["contributors"] = contributors + + def remove_contributor_by_email(self, email_id): + self.m["contributors"] = [ + contributor for contributor in self.m["contributors"] if contributor["email_id"] != email_id + ] + + def group_init(self, group_name): + """Required values for creating a new payment group. + + Args: + group_name: If org contains only 1 payment group -> default_group, ask user for other groups otherwise. + + Raises: + ValueError: User enters non-integer value for `fixed_price.` + Exception: User enters same endpoints. + """ + self.add_group(group_name) + while True: + try: + fixed_price = int(input("Set fixed price: ")) + except ValueError: + print("Enter a valid integer.") + else: + self.set_fixed_price_in_cogs(group_name, fixed_price) + break + while True: + try: + endpoints = input("Add endpoints as comma separated values: ").split(',') + if endpoints[0] == "": + print("Endpoints required.") + else: + for endpoint in endpoints: + self.add_endpoint_to_group(group_name, endpoint.strip()) + break + except Exception as e: + print(e) + while True: + daemon_addresses = input("Add daemon addresses as comma separated values: ").split(',') + if daemon_addresses[0] == "": + print("Daemon address required.") + else: + for daemon_address in daemon_addresses: + self.add_daemon_address_to_group(group_name, daemon_address.strip()) + break + if input('Free calls included? [y/n] ').lower() == 'y': + self.set_free_calls_for_group(group_name, int(input('free calls: (15) ') or 15)) + self.set_freecall_signer_address(group_name, input('free call signer address: ')) + + def add_media(self, url, media_type, hero_img=False): + """Add new individual media to service metadata.""" + if 'media' not in self.m: + self.m['media'] = [] + individual_media = {} + if hero_img: + assert (media_type == 'image'), f"{media_type.upper()} media-type cannot be a hero-image." + assert (not self._is_asset_type_exists()), "Hero-image already exists (only 1 unique hero-image allowed.)" + individual_media['asset_type'] = AssetType.HERO_IMAGE.value # Dependency with AssetType, fix if obsolete + if len(self.m['media']) == 0: + individual_media['order'] = 1 + else: + individual_media['order'] = self.m['media'][-1]['order'] + 1 + individual_media['url'] = url + individual_media['file_type'] = media_type + if media_type == 'image': + individual_media['alt_text'] = 'hover_on_the_image_text' + else: + individual_media['alt_text'] = 'hover_on_the_video_url' + self.m['media'].append(individual_media) + + def remove_media(self, order): + """Remove individual media from service metadata using unique order key.""" + assert (len(self.m['media']) > 0), "No media content to remove." + assert (order > 0), "Order of individual media starts from 1." + del_position = -1 + for i in range(len(self.m['media'])): + if order == self.m['media'][i]['order']: + del self.m['media'][i] + del_position = i + break + if del_position == -1: + raise Exception(f"Media with order: {order} not found.") + for i in range(del_position, len(self.m['media'])): + self.m['media'][i]['order'] -= 1 + + def remove_all_media(self): + """Remove all individual media from metadata.""" + self.m['media'].clear() + + def swap_media_order(self, move_from, move_to): + """Swap orders of two different media given their individual orders (move_from, move_to).""" + assert (len(self.m['media']) + 1 > move_from > 0), f"Order {move_from} out of bounds." + assert (len(self.m['media']) + 1 > move_to > 0), f"Order {move_to} out of bounds." + self.m['media'][move_to - 1], self.m['media'][move_from - 1] = self.m['media'][move_from - 1], self.m['media'][ + move_to - 1] + self.m['media'][move_to - 1]['order'], self.m['media'][move_from - 1]['order'] = self.m['media'][move_from - 1][ + 'order'], \ + self.m['media'][move_to - 1][ + 'order'] + + def change_media_order(self): + """Mini REPL to change order of all individual media""" + order_range = range(1, len(self.m['media']) + 1) + available_orders = list(order_range) + for individual_media in self.m['media']: + print(f"File Type: {individual_media['file_type']}, Current Order: {individual_media['order']}") + while True: + try: + new_order = int(input(f"Enter new order for {individual_media['url']}: ")) + except ValueError: + print("Error: Order entered not a number. Try again.") + else: + if new_order in available_orders: + individual_media['order'] = new_order + available_orders.remove(new_order) + break + elif new_order not in order_range: + print( + f"Media array contains only {len(self.m['media'])} items. Enter order between [{order_range.start}, {order_range.stop - 1}]") + else: + print(f"Order already taken. Available orders: {available_orders}") + self.m['media'].sort(key=lambda x: x['order']) + + def _is_asset_type_exists(self): + """Return boolean on whether asset type already exists""" + media = self.m['media'] + for individual_media in media: + if 'asset_type' in individual_media: + return True + return False + + def add_description(self): + if 'service_description' not in self.m: + self.m['service_description'] = { + "url": input("user guide url: "), + "long_description": input("service long description: "), + "short_description": input("service short description: ") + } + + +def load_mpe_service_metadata(f): + metadata = MPEServiceMetadata() + metadata.load(f) + return metadata + + +def mpe_service_metadata_from_json(j): + metadata = MPEServiceMetadata() + metadata.set_from_json(j) + return metadata diff --git a/snet/sdk/mpe/payment_channel.py b/snet/sdk/mpe/payment_channel.py index c13f6f3..ead629e 100644 --- a/snet/sdk/mpe/payment_channel.py +++ b/snet/sdk/mpe/payment_channel.py @@ -2,8 +2,7 @@ import importlib from eth_account.messages import defunct_hash_message -from snet.cli.utils.utils import RESOURCES_PATH, add_to_path - +from snet.sdk.utils.utils import RESOURCES_PATH, add_to_path class PaymentChannel: def __init__(self, channel_id, w3, account, payment_channel_state_service_client, mpe_contract): diff --git a/snet/sdk/payment.py b/snet/sdk/payment.py deleted file mode 100644 index fcb4219..0000000 --- a/snet/sdk/payment.py +++ /dev/null @@ -1,6 +0,0 @@ -class Payment(object): - - def to_metadata(self): - pass - - diff --git a/snet/sdk/payment_strategies/default_payment_strategy.py b/snet/sdk/payment_strategies/default_payment_strategy.py index 63203f6..d8582d7 100644 --- a/snet/sdk/payment_strategies/default_payment_strategy.py +++ b/snet/sdk/payment_strategies/default_payment_strategy.py @@ -2,7 +2,7 @@ from snet.sdk.payment_strategies.freecall_payment_strategy import FreeCallPaymentStrategy from snet.sdk.payment_strategies.paidcall_payment_strategy import PaidCallPaymentStrategy from snet.sdk.payment_strategies.prepaid_payment_strategy import PrePaidPaymentStrategy -from snet.sdk.payment_strategies.payment_staregy import PaymentStrategy +from snet.sdk.payment_strategies.payment_strategy import PaymentStrategy class DefaultPaymentStrategy(PaymentStrategy): diff --git a/snet/sdk/payment_strategies/freecall_payment_strategy.py b/snet/sdk/payment_strategies/freecall_payment_strategy.py index 4649fea..aae70b6 100644 --- a/snet/sdk/payment_strategies/freecall_payment_strategy.py +++ b/snet/sdk/payment_strategies/freecall_payment_strategy.py @@ -3,10 +3,10 @@ import grpc import web3 -from snet.cli.resources.root_certificate import certificate -from snet.cli.utils.utils import RESOURCES_PATH, add_to_path +from snet.sdk.resources.root_certificate import certificate +from snet.sdk.utils.utils import RESOURCES_PATH, add_to_path -from snet.sdk.payment_strategies.payment_staregy import PaymentStrategy +from snet.sdk.payment_strategies.payment_strategy import PaymentStrategy class FreeCallPaymentStrategy(PaymentStrategy): diff --git a/snet/sdk/payment_strategies/paidcall_payment_strategy.py b/snet/sdk/payment_strategies/paidcall_payment_strategy.py index 5903dba..8acd44b 100644 --- a/snet/sdk/payment_strategies/paidcall_payment_strategy.py +++ b/snet/sdk/payment_strategies/paidcall_payment_strategy.py @@ -1,5 +1,5 @@ import web3 -from snet.sdk.payment_strategies.payment_staregy import PaymentStrategy +from snet.sdk.payment_strategies.payment_strategy import PaymentStrategy class PaidCallPaymentStrategy(PaymentStrategy): diff --git a/snet/sdk/payment_strategies/payment_staregy.py b/snet/sdk/payment_strategies/payment_strategy.py similarity index 100% rename from snet/sdk/payment_strategies/payment_staregy.py rename to snet/sdk/payment_strategies/payment_strategy.py diff --git a/snet/sdk/payment_strategies/prepaid_payment_strategy.py b/snet/sdk/payment_strategies/prepaid_payment_strategy.py index b786170..aaaf3b3 100644 --- a/snet/sdk/payment_strategies/prepaid_payment_strategy.py +++ b/snet/sdk/payment_strategies/prepaid_payment_strategy.py @@ -1,4 +1,4 @@ -from snet.sdk.payment_strategies.payment_staregy import PaymentStrategy +from snet.sdk.payment_strategies.payment_strategy import PaymentStrategy class PrePaidPaymentStrategy(PaymentStrategy): diff --git a/snet/sdk/resources/package.json b/snet/sdk/resources/package.json new file mode 100644 index 0000000..15db610 --- /dev/null +++ b/snet/sdk/resources/package.json @@ -0,0 +1,5 @@ +{ + "dependencies": { + "grpc-tools": "1.9.0" + } +} diff --git a/snet/sdk/resources/proto/control_service.proto b/snet/sdk/resources/proto/control_service.proto new file mode 100644 index 0000000..efd301a --- /dev/null +++ b/snet/sdk/resources/proto/control_service.proto @@ -0,0 +1,55 @@ +syntax = "proto3"; + +package escrow; + +service ProviderControlService { + + //get list of all unclaimed "payments". + //in PaymentsSignatureReply signatures MUST be omited + //if signature field is present then response should be considered as invalid + rpc GetListUnclaimed(GetPaymentsListRequest) returns (PaymentsListReply) {} + + //get list of all payments in progress + rpc GetListInProgress(GetPaymentsListRequest) returns (PaymentsListReply) {} + + //initilize claim for specific channel + rpc StartClaim(StartClaimRequest) returns (PaymentReply) {} +} + + +message GetPaymentsListRequest { + //address of MultiPartyEscrow contract + string mpe_address = 1; + //current block number (signature will be valid only for short time around this block number) + uint64 current_block = 2; + //signature of the following message: + //for GetListUnclaimed ("__list_unclaimed", mpe_address, current_block_number) + //for GetListInProgress ("__list_in_progress", mpe_address, current_block_number) + bytes signature = 3; +} + +message StartClaimRequest { + //address of MultiPartyEscrow contract + string mpe_address = 1; + //channel_id contains id of the channel which state is requested. + bytes channel_id = 2; + //signature of the following message ("__start_claim", mpe_address, channel_id, channel_nonce) + bytes signature = 3; +} + +message PaymentReply { + bytes channel_id = 1; + + bytes channel_nonce = 2; + + bytes signed_amount = 3; + + //this filed must be OMITED in GetListUnclaimed request + bytes signature = 4; +} + +message PaymentsListReply { + repeated PaymentReply payments = 1; +} + + diff --git a/snet/sdk/resources/proto/control_service_pb2.py b/snet/sdk/resources/proto/control_service_pb2.py new file mode 100644 index 0000000..43b685a --- /dev/null +++ b/snet/sdk/resources/proto/control_service_pb2.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: control_service.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x63ontrol_service.proto\x12\x06\x65scrow\"W\n\x16GetPaymentsListRequest\x12\x13\n\x0bmpe_address\x18\x01 \x01(\t\x12\x15\n\rcurrent_block\x18\x02 \x01(\x04\x12\x11\n\tsignature\x18\x03 \x01(\x0c\"O\n\x11StartClaimRequest\x12\x13\n\x0bmpe_address\x18\x01 \x01(\t\x12\x12\n\nchannel_id\x18\x02 \x01(\x0c\x12\x11\n\tsignature\x18\x03 \x01(\x0c\"c\n\x0cPaymentReply\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\x15\n\rchannel_nonce\x18\x02 \x01(\x0c\x12\x15\n\rsigned_amount\x18\x03 \x01(\x0c\x12\x11\n\tsignature\x18\x04 \x01(\x0c\";\n\x11PaymentsListReply\x12&\n\x08payments\x18\x01 \x03(\x0b\x32\x14.escrow.PaymentReply2\xfc\x01\n\x16ProviderControlService\x12O\n\x10GetListUnclaimed\x12\x1e.escrow.GetPaymentsListRequest\x1a\x19.escrow.PaymentsListReply\"\x00\x12P\n\x11GetListInProgress\x12\x1e.escrow.GetPaymentsListRequest\x1a\x19.escrow.PaymentsListReply\"\x00\x12?\n\nStartClaim\x12\x19.escrow.StartClaimRequest\x1a\x14.escrow.PaymentReply\"\x00\x62\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'control_service_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + _globals['_GETPAYMENTSLISTREQUEST']._serialized_start=33 + _globals['_GETPAYMENTSLISTREQUEST']._serialized_end=120 + _globals['_STARTCLAIMREQUEST']._serialized_start=122 + _globals['_STARTCLAIMREQUEST']._serialized_end=201 + _globals['_PAYMENTREPLY']._serialized_start=203 + _globals['_PAYMENTREPLY']._serialized_end=302 + _globals['_PAYMENTSLISTREPLY']._serialized_start=304 + _globals['_PAYMENTSLISTREPLY']._serialized_end=363 + _globals['_PROVIDERCONTROLSERVICE']._serialized_start=366 + _globals['_PROVIDERCONTROLSERVICE']._serialized_end=618 +# @@protoc_insertion_point(module_scope) diff --git a/snet/sdk/resources/proto/control_service_pb2_grpc.py b/snet/sdk/resources/proto/control_service_pb2_grpc.py new file mode 100644 index 0000000..818e476 --- /dev/null +++ b/snet/sdk/resources/proto/control_service_pb2_grpc.py @@ -0,0 +1,137 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +import control_service_pb2 as control__service__pb2 + + +class ProviderControlServiceStub(object): + """Missing associated documentation comment in .proto file.""" + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.GetListUnclaimed = channel.unary_unary( + '/escrow.ProviderControlService/GetListUnclaimed', + request_serializer=control__service__pb2.GetPaymentsListRequest.SerializeToString, + response_deserializer=control__service__pb2.PaymentsListReply.FromString, + ) + self.GetListInProgress = channel.unary_unary( + '/escrow.ProviderControlService/GetListInProgress', + request_serializer=control__service__pb2.GetPaymentsListRequest.SerializeToString, + response_deserializer=control__service__pb2.PaymentsListReply.FromString, + ) + self.StartClaim = channel.unary_unary( + '/escrow.ProviderControlService/StartClaim', + request_serializer=control__service__pb2.StartClaimRequest.SerializeToString, + response_deserializer=control__service__pb2.PaymentReply.FromString, + ) + + +class ProviderControlServiceServicer(object): + """Missing associated documentation comment in .proto file.""" + + def GetListUnclaimed(self, request, context): + """get list of all unclaimed "payments". + in PaymentsSignatureReply signatures MUST be omited + if signature field is present then response should be considered as invalid + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetListInProgress(self, request, context): + """get list of all payments in progress + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def StartClaim(self, request, context): + """initilize claim for specific channel + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_ProviderControlServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'GetListUnclaimed': grpc.unary_unary_rpc_method_handler( + servicer.GetListUnclaimed, + request_deserializer=control__service__pb2.GetPaymentsListRequest.FromString, + response_serializer=control__service__pb2.PaymentsListReply.SerializeToString, + ), + 'GetListInProgress': grpc.unary_unary_rpc_method_handler( + servicer.GetListInProgress, + request_deserializer=control__service__pb2.GetPaymentsListRequest.FromString, + response_serializer=control__service__pb2.PaymentsListReply.SerializeToString, + ), + 'StartClaim': grpc.unary_unary_rpc_method_handler( + servicer.StartClaim, + request_deserializer=control__service__pb2.StartClaimRequest.FromString, + response_serializer=control__service__pb2.PaymentReply.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'escrow.ProviderControlService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class ProviderControlService(object): + """Missing associated documentation comment in .proto file.""" + + @staticmethod + def GetListUnclaimed(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/escrow.ProviderControlService/GetListUnclaimed', + control__service__pb2.GetPaymentsListRequest.SerializeToString, + control__service__pb2.PaymentsListReply.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetListInProgress(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/escrow.ProviderControlService/GetListInProgress', + control__service__pb2.GetPaymentsListRequest.SerializeToString, + control__service__pb2.PaymentsListReply.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def StartClaim(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/escrow.ProviderControlService/StartClaim', + control__service__pb2.StartClaimRequest.SerializeToString, + control__service__pb2.PaymentReply.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/snet/sdk/resources/proto/merckledag.proto b/snet/sdk/resources/proto/merckledag.proto new file mode 100644 index 0000000..5af078a --- /dev/null +++ b/snet/sdk/resources/proto/merckledag.proto @@ -0,0 +1,17 @@ +syntax = "proto2"; +// An IPFS MerkleDAG Link +message MerkleLink { + required bytes Hash = 1; // multihash of the target object + required string Name = 2; // utf string name + required uint64 Tsize = 3; // cumulative size of target object + + // user extensions start at 50 +} + +// An IPFS MerkleDAG Node +message MerkleNode { + repeated MerkleLink Links = 2; // refs to other objects + required bytes Data = 1; // opaque user data + + // user extensions start at 50 +} \ No newline at end of file diff --git a/snet/sdk/resources/proto/merckledag_pb2.py b/snet/sdk/resources/proto/merckledag_pb2.py new file mode 100644 index 0000000..c47ebb5 --- /dev/null +++ b/snet/sdk/resources/proto/merckledag_pb2.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: merckledag.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x10merckledag.proto\"7\n\nMerkleLink\x12\x0c\n\x04Hash\x18\x01 \x02(\x0c\x12\x0c\n\x04Name\x18\x02 \x02(\t\x12\r\n\x05Tsize\x18\x03 \x02(\x04\"6\n\nMerkleNode\x12\x1a\n\x05Links\x18\x02 \x03(\x0b\x32\x0b.MerkleLink\x12\x0c\n\x04\x44\x61ta\x18\x01 \x02(\x0c') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'merckledag_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + _globals['_MERKLELINK']._serialized_start=20 + _globals['_MERKLELINK']._serialized_end=75 + _globals['_MERKLENODE']._serialized_start=77 + _globals['_MERKLENODE']._serialized_end=131 +# @@protoc_insertion_point(module_scope) diff --git a/snet/sdk/resources/proto/merckledag_pb2_grpc.py b/snet/sdk/resources/proto/merckledag_pb2_grpc.py new file mode 100644 index 0000000..2daafff --- /dev/null +++ b/snet/sdk/resources/proto/merckledag_pb2_grpc.py @@ -0,0 +1,4 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + diff --git a/snet/sdk/resources/proto/state_service.proto b/snet/sdk/resources/proto/state_service.proto new file mode 100644 index 0000000..a2ce9aa --- /dev/null +++ b/snet/sdk/resources/proto/state_service.proto @@ -0,0 +1,81 @@ +syntax = "proto3"; + +package escrow; + +option java_package = "io.singularitynet.daemon.escrow"; + +// PaymentChannelStateService contains methods to get the MultiPartyEscrow +// payment channel state. +// channel_id, channel_nonce, value and amount fields below in fact are +// Solidity uint256 values. Which are big-endian integers, see +// https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#formal-specification-of-the-encoding +// These values may be or may be not padded by zeros, service supports both +// options. +service PaymentChannelStateService { + // GetChannelState method returns a channel state by channel id. + rpc GetChannelState(ChannelStateRequest) returns (ChannelStateReply) {} +} + +// ChanelStateRequest is a request for channel state. +message ChannelStateRequest { + // channel_id contains id of the channel which state is requested. + bytes channel_id = 1; + + // signature is a client signature of the message which contains + // channel_id. It is used for client authorization. + bytes signature = 2; + + //current block number (signature will be valid only for short time around this block number) + uint64 current_block = 3; +} + +// ChannelStateReply message contains a latest channel state. current_nonce and +// current_value fields can be different from ones stored in the blockchain if +// server started withdrawing funds froms channel but transaction is still not +// finished. +message ChannelStateReply { + // current_nonce is a latest nonce of the payment channel. + bytes current_nonce = 1; + + // current_signed_amount is a last amount which were signed by client with current_nonce + //it could be absent if none message was signed with current_nonce + bytes current_signed_amount = 2; + + // current_signature is a last signature sent by client with current_nonce + // it could be absent if none message was signed with current nonce + bytes current_signature = 3; + + // last amount which was signed by client with nonce=current_nonce - 1 + bytes old_nonce_signed_amount = 4; + + // last signature sent by client with nonce = current_nonce - 1 + bytes old_nonce_signature = 5; + } + +//Used to determine free calls available for a given user. +service FreeCallStateService { + rpc GetFreeCallsAvailable(FreeCallStateRequest) returns (FreeCallStateReply) {} +} + +message FreeCallStateRequest { + //Has the user email id + string user_id = 1; + //signer-token = (user@mail, user-public-key, token_issue_date), this is generated my Market place Dapp + //to leverage free calls from SDK/ snet-cli, you will need this signer-token to be downloaded from Dapp + bytes token_for_free_call = 2; + //Token expiration date in Block number + uint64 token_expiry_date_block = 3 ; + //Signature is made up of the below, user signs with the private key corresponding with the public key used to generate the authorized token + //free-call-metadata = ("__prefix_free_trial",user_id,organization_id,service_id,group_id,current_block,authorized_token) + bytes signature = 4; + //current block number (signature will be valid only for short time around this block number) + uint64 current_block = 5; + +} + +message FreeCallStateReply { + //Has the user email id + string user_id = 1; + //Balance number of free calls available + uint64 free_calls_available = 2; +} diff --git a/snet/sdk/resources/proto/state_service_pb2.py b/snet/sdk/resources/proto/state_service_pb2.py new file mode 100644 index 0000000..d298f8a --- /dev/null +++ b/snet/sdk/resources/proto/state_service_pb2.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: state_service.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x13state_service.proto\x12\x06\x65scrow\"S\n\x13\x43hannelStateRequest\x12\x12\n\nchannel_id\x18\x01 \x01(\x0c\x12\x11\n\tsignature\x18\x02 \x01(\x0c\x12\x15\n\rcurrent_block\x18\x03 \x01(\x04\"\xa2\x01\n\x11\x43hannelStateReply\x12\x15\n\rcurrent_nonce\x18\x01 \x01(\x0c\x12\x1d\n\x15\x63urrent_signed_amount\x18\x02 \x01(\x0c\x12\x19\n\x11\x63urrent_signature\x18\x03 \x01(\x0c\x12\x1f\n\x17old_nonce_signed_amount\x18\x04 \x01(\x0c\x12\x1b\n\x13old_nonce_signature\x18\x05 \x01(\x0c\"\x8f\x01\n\x14\x46reeCallStateRequest\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12\x1b\n\x13token_for_free_call\x18\x02 \x01(\x0c\x12\x1f\n\x17token_expiry_date_block\x18\x03 \x01(\x04\x12\x11\n\tsignature\x18\x04 \x01(\x0c\x12\x15\n\rcurrent_block\x18\x05 \x01(\x04\"C\n\x12\x46reeCallStateReply\x12\x0f\n\x07user_id\x18\x01 \x01(\t\x12\x1c\n\x14\x66ree_calls_available\x18\x02 \x01(\x04\x32i\n\x1aPaymentChannelStateService\x12K\n\x0fGetChannelState\x12\x1b.escrow.ChannelStateRequest\x1a\x19.escrow.ChannelStateReply\"\x00\x32k\n\x14\x46reeCallStateService\x12S\n\x15GetFreeCallsAvailable\x12\x1c.escrow.FreeCallStateRequest\x1a\x1a.escrow.FreeCallStateReply\"\x00\x42!\n\x1fio.singularitynet.daemon.escrowb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'state_service_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + DESCRIPTOR._serialized_options = b'\n\037io.singularitynet.daemon.escrow' + _globals['_CHANNELSTATEREQUEST']._serialized_start=31 + _globals['_CHANNELSTATEREQUEST']._serialized_end=114 + _globals['_CHANNELSTATEREPLY']._serialized_start=117 + _globals['_CHANNELSTATEREPLY']._serialized_end=279 + _globals['_FREECALLSTATEREQUEST']._serialized_start=282 + _globals['_FREECALLSTATEREQUEST']._serialized_end=425 + _globals['_FREECALLSTATEREPLY']._serialized_start=427 + _globals['_FREECALLSTATEREPLY']._serialized_end=494 + _globals['_PAYMENTCHANNELSTATESERVICE']._serialized_start=496 + _globals['_PAYMENTCHANNELSTATESERVICE']._serialized_end=601 + _globals['_FREECALLSTATESERVICE']._serialized_start=603 + _globals['_FREECALLSTATESERVICE']._serialized_end=710 +# @@protoc_insertion_point(module_scope) diff --git a/snet/sdk/resources/proto/state_service_pb2_grpc.py b/snet/sdk/resources/proto/state_service_pb2_grpc.py new file mode 100644 index 0000000..977dbd7 --- /dev/null +++ b/snet/sdk/resources/proto/state_service_pb2_grpc.py @@ -0,0 +1,152 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +import state_service_pb2 as state__service__pb2 + + +class PaymentChannelStateServiceStub(object): + """PaymentChannelStateService contains methods to get the MultiPartyEscrow + payment channel state. + channel_id, channel_nonce, value and amount fields below in fact are + Solidity uint256 values. Which are big-endian integers, see + https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#formal-specification-of-the-encoding + These values may be or may be not padded by zeros, service supports both + options. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.GetChannelState = channel.unary_unary( + '/escrow.PaymentChannelStateService/GetChannelState', + request_serializer=state__service__pb2.ChannelStateRequest.SerializeToString, + response_deserializer=state__service__pb2.ChannelStateReply.FromString, + ) + + +class PaymentChannelStateServiceServicer(object): + """PaymentChannelStateService contains methods to get the MultiPartyEscrow + payment channel state. + channel_id, channel_nonce, value and amount fields below in fact are + Solidity uint256 values. Which are big-endian integers, see + https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#formal-specification-of-the-encoding + These values may be or may be not padded by zeros, service supports both + options. + """ + + def GetChannelState(self, request, context): + """GetChannelState method returns a channel state by channel id. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_PaymentChannelStateServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'GetChannelState': grpc.unary_unary_rpc_method_handler( + servicer.GetChannelState, + request_deserializer=state__service__pb2.ChannelStateRequest.FromString, + response_serializer=state__service__pb2.ChannelStateReply.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'escrow.PaymentChannelStateService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class PaymentChannelStateService(object): + """PaymentChannelStateService contains methods to get the MultiPartyEscrow + payment channel state. + channel_id, channel_nonce, value and amount fields below in fact are + Solidity uint256 values. Which are big-endian integers, see + https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI#formal-specification-of-the-encoding + These values may be or may be not padded by zeros, service supports both + options. + """ + + @staticmethod + def GetChannelState(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/escrow.PaymentChannelStateService/GetChannelState', + state__service__pb2.ChannelStateRequest.SerializeToString, + state__service__pb2.ChannelStateReply.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + +class FreeCallStateServiceStub(object): + """Used to determine free calls available for a given user. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.GetFreeCallsAvailable = channel.unary_unary( + '/escrow.FreeCallStateService/GetFreeCallsAvailable', + request_serializer=state__service__pb2.FreeCallStateRequest.SerializeToString, + response_deserializer=state__service__pb2.FreeCallStateReply.FromString, + ) + + +class FreeCallStateServiceServicer(object): + """Used to determine free calls available for a given user. + """ + + def GetFreeCallsAvailable(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_FreeCallStateServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'GetFreeCallsAvailable': grpc.unary_unary_rpc_method_handler( + servicer.GetFreeCallsAvailable, + request_deserializer=state__service__pb2.FreeCallStateRequest.FromString, + response_serializer=state__service__pb2.FreeCallStateReply.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'escrow.FreeCallStateService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class FreeCallStateService(object): + """Used to determine free calls available for a given user. + """ + + @staticmethod + def GetFreeCallsAvailable(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/escrow.FreeCallStateService/GetFreeCallsAvailable', + state__service__pb2.FreeCallStateRequest.SerializeToString, + state__service__pb2.FreeCallStateReply.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/snet/sdk/resources/proto/token_service.proto b/snet/sdk/resources/proto/token_service.proto new file mode 100644 index 0000000..33a6656 --- /dev/null +++ b/snet/sdk/resources/proto/token_service.proto @@ -0,0 +1,63 @@ +syntax = "proto3"; + +package escrow; + +option java_package = "io.singularitynet.daemon.escrow"; +//It is expected that the user would call the GetChannelState to Determine the Current state of the Channel +//Based on the usage forecast, the user/client will have to sign for an amount L + U , where L is the last amount Signed +//and U is the amount based on expected usage. +//Please be aware that the Signing up an amount upfront ( Pre Paid) does come with a risk and hence the +//user must exercise caution on the amount signed specially with new service providers. +//If there is no need of making concurrent calls then you may consider pay per mode. +//Using a Token, the Client can now make concurrent calls, which was not supported previously with the pay per mode. +//However the pay per mode is a lot secure than the pre-paid mode. +service TokenService { + // GetToken method checks the Signature sent and returns a Token + // 1) The Signature is valid and has to be signed in the below format + //"__MPE_claim_message"+MpeContractAddress+ChannelID+ChannelNonce+SignedAmount + //Signature is to let the Service Provider make a claim + // 2) Signed amount >= Last amount Signed. + // if Signed amount == Last Signed amount , then check if planned_amount < used_amount + // if Signed amount > Last Signed amount , then update the planned amount = Signed Amount + // GetToken method in a way behaves as a renew Token too!. + rpc GetToken(TokenRequest) returns (TokenReply) {} + + + +} + +// TokenRequest is a request for getting a valid token. +message TokenRequest { + // channel_id contains id of the channel which state is requested. + uint64 channel_id = 1; + // current_nonce is a latest nonce of the payment channel. + uint64 current_nonce = 2; + //signed_amount is the amount signed by client with current_nonce + uint64 signed_amount = 3; + // Signature is a client signature of the message which contains 2 parts + //Part 1 : MPE Signature "__MPE_claim_message"+MpeContractAddress+ChannelID+ChannelNonce+SignedAmount + //Part 2 : Current Block Number + bytes signature = 4; + //current block number (signature will be valid only for short time around this block number) + uint64 current_block = 5; + + bytes claim_signature = 6; + +} + +// TokenReply message contains a latest channel state. current_nonce and +message TokenReply { + // current_nonce is a latest nonce of the payment channel. + uint64 channel_id = 1; + + //it could be absent if none message was signed with current_nonce + string token = 2; + + //If the client / user chooses to sign upfront , the planned amount in cogs will be indicative of this. + uint64 planned_amount = 3; + + //If the client / user chooses to sign upfront , the used amount in cogs will be indicative of how much of the + //planned amount has actually been used. + uint64 used_amount = 4; + +} diff --git a/snet/sdk/resources/proto/token_service_pb2.py b/snet/sdk/resources/proto/token_service_pb2.py new file mode 100644 index 0000000..038ca7f --- /dev/null +++ b/snet/sdk/resources/proto/token_service_pb2.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: token_service.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x13token_service.proto\x12\x06\x65scrow\"\x93\x01\n\x0cTokenRequest\x12\x12\n\nchannel_id\x18\x01 \x01(\x04\x12\x15\n\rcurrent_nonce\x18\x02 \x01(\x04\x12\x15\n\rsigned_amount\x18\x03 \x01(\x04\x12\x11\n\tsignature\x18\x04 \x01(\x0c\x12\x15\n\rcurrent_block\x18\x05 \x01(\x04\x12\x17\n\x0f\x63laim_signature\x18\x06 \x01(\x0c\"\\\n\nTokenReply\x12\x12\n\nchannel_id\x18\x01 \x01(\x04\x12\r\n\x05token\x18\x02 \x01(\t\x12\x16\n\x0eplanned_amount\x18\x03 \x01(\x04\x12\x13\n\x0bused_amount\x18\x04 \x01(\x04\x32\x46\n\x0cTokenService\x12\x36\n\x08GetToken\x12\x14.escrow.TokenRequest\x1a\x12.escrow.TokenReply\"\x00\x42!\n\x1fio.singularitynet.daemon.escrowb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'token_service_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + DESCRIPTOR._serialized_options = b'\n\037io.singularitynet.daemon.escrow' + _globals['_TOKENREQUEST']._serialized_start=32 + _globals['_TOKENREQUEST']._serialized_end=179 + _globals['_TOKENREPLY']._serialized_start=181 + _globals['_TOKENREPLY']._serialized_end=273 + _globals['_TOKENSERVICE']._serialized_start=275 + _globals['_TOKENSERVICE']._serialized_end=345 +# @@protoc_insertion_point(module_scope) diff --git a/snet/sdk/resources/proto/token_service_pb2_grpc.py b/snet/sdk/resources/proto/token_service_pb2_grpc.py new file mode 100644 index 0000000..dd1bc73 --- /dev/null +++ b/snet/sdk/resources/proto/token_service_pb2_grpc.py @@ -0,0 +1,98 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +import token_service_pb2 as token__service__pb2 + + +class TokenServiceStub(object): + """It is expected that the user would call the GetChannelState to Determine the Current state of the Channel + Based on the usage forecast, the user/client will have to sign for an amount L + U , where L is the last amount Signed + and U is the amount based on expected usage. + Please be aware that the Signing up an amount upfront ( Pre Paid) does come with a risk and hence the + user must exercise caution on the amount signed specially with new service providers. + If there is no need of making concurrent calls then you may consider pay per mode. + Using a Token, the Client can now make concurrent calls, which was not supported previously with the pay per mode. + However the pay per mode is a lot secure than the pre-paid mode. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.GetToken = channel.unary_unary( + '/escrow.TokenService/GetToken', + request_serializer=token__service__pb2.TokenRequest.SerializeToString, + response_deserializer=token__service__pb2.TokenReply.FromString, + ) + + +class TokenServiceServicer(object): + """It is expected that the user would call the GetChannelState to Determine the Current state of the Channel + Based on the usage forecast, the user/client will have to sign for an amount L + U , where L is the last amount Signed + and U is the amount based on expected usage. + Please be aware that the Signing up an amount upfront ( Pre Paid) does come with a risk and hence the + user must exercise caution on the amount signed specially with new service providers. + If there is no need of making concurrent calls then you may consider pay per mode. + Using a Token, the Client can now make concurrent calls, which was not supported previously with the pay per mode. + However the pay per mode is a lot secure than the pre-paid mode. + """ + + def GetToken(self, request, context): + """GetToken method checks the Signature sent and returns a Token + 1) The Signature is valid and has to be signed in the below format + "__MPE_claim_message"+MpeContractAddress+ChannelID+ChannelNonce+SignedAmount + Signature is to let the Service Provider make a claim + 2) Signed amount >= Last amount Signed. + if Signed amount == Last Signed amount , then check if planned_amount < used_amount + if Signed amount > Last Signed amount , then update the planned amount = Signed Amount + GetToken method in a way behaves as a renew Token too!. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_TokenServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'GetToken': grpc.unary_unary_rpc_method_handler( + servicer.GetToken, + request_deserializer=token__service__pb2.TokenRequest.FromString, + response_serializer=token__service__pb2.TokenReply.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'escrow.TokenService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class TokenService(object): + """It is expected that the user would call the GetChannelState to Determine the Current state of the Channel + Based on the usage forecast, the user/client will have to sign for an amount L + U , where L is the last amount Signed + and U is the amount based on expected usage. + Please be aware that the Signing up an amount upfront ( Pre Paid) does come with a risk and hence the + user must exercise caution on the amount signed specially with new service providers. + If there is no need of making concurrent calls then you may consider pay per mode. + Using a Token, the Client can now make concurrent calls, which was not supported previously with the pay per mode. + However the pay per mode is a lot secure than the pre-paid mode. + """ + + @staticmethod + def GetToken(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/escrow.TokenService/GetToken', + token__service__pb2.TokenRequest.SerializeToString, + token__service__pb2.TokenReply.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/snet/sdk/resources/proto/training.proto b/snet/sdk/resources/proto/training.proto new file mode 100644 index 0000000..86b3074 --- /dev/null +++ b/snet/sdk/resources/proto/training.proto @@ -0,0 +1,112 @@ +syntax = "proto3"; +import "google/protobuf/descriptor.proto"; +package training; +option go_package = "../training"; +//Please note that the AI developers need to provide a server implementation of the gprc server of this proto. +message ModelDetails { + //This Id will be generated when you invoke the create_model method and hence doesnt need to be filled when you + //invoke the create model + string model_id = 1; + //define the training method name + string grpc_method_name = 2; + //define the grpc service name , under which the method is defined + string grpc_service_name = 3; + string description = 4; + + string status = 6; + string updated_date = 7; + //List of all the addresses that will have access to this model + repeated string address_list = 8; + // this is optional + string training_data_link = 9; + string model_name = 10; + + + string organization_id = 11; + string service_id = 12 ; + string group_id = 13; + + //set this to true if you want your model to be used by other AI consumers + bool is_publicly_accessible = 14; + +} + +message AuthorizationDetails { + uint64 current_block = 1; + //Signer can fill in any message here + string message = 2; + //signature of the following message: + //("user specified message", user_address, current_block_number) + bytes signature = 3; + string signer_address = 4; + +} + +enum Status { + CREATED = 0; + IN_PROGRESS = 1; + ERRORED = 2; + COMPLETED = 3; + DELETED = 4; +} + +message CreateModelRequest { + AuthorizationDetails authorization = 1; + ModelDetails model_details = 2; +} + +//the signer address will get to know all the models associated with this address. +message AccessibleModelsRequest { + string grpc_method_name = 1; + string grpc_service_name = 2; + AuthorizationDetails authorization = 3; +} + +message AccessibleModelsResponse { + repeated ModelDetails list_of_models = 1; +} + +message ModelDetailsRequest { + ModelDetails model_details = 1 ; + AuthorizationDetails authorization = 2; +} + +//helps determine which service end point to call for model training +//format is of type "packageName/serviceName/MethodName", Example :"/example_service.Calculator/estimate_add" +//Daemon will invoke the model training end point , when the below method option is specified +message TrainingMethodOption { + string trainingMethodIndicator = 1; +} + +extend google.protobuf.MethodOptions { + TrainingMethodOption my_method_option = 9999197; +} + +message UpdateModelRequest { + ModelDetails update_model_details = 1 ; + AuthorizationDetails authorization = 2; +} + + +message ModelDetailsResponse { + Status status = 1; + ModelDetails model_details = 2; + +} + +service Model { + + // The AI developer needs to Implement this service and Daemon will call these + // There will be no cost borne by the consumer in calling these methods, + // Pricing will apply when you actually call the training methods defined. + // AI consumer will call all these methods + rpc create_model(CreateModelRequest) returns (ModelDetailsResponse) {} + rpc delete_model(UpdateModelRequest) returns (ModelDetailsResponse) {} + rpc get_model_status(ModelDetailsRequest) returns (ModelDetailsResponse) {} + + // Daemon will implement , however the AI developer should skip implementing these and just provide dummy code. + rpc update_model_access(UpdateModelRequest) returns (ModelDetailsResponse) {} + rpc get_all_models(AccessibleModelsRequest) returns (AccessibleModelsResponse) {} + + +} \ No newline at end of file diff --git a/snet/sdk/resources/proto/training_pb2.py b/snet/sdk/resources/proto/training_pb2.py new file mode 100644 index 0000000..735e256 --- /dev/null +++ b/snet/sdk/resources/proto/training_pb2.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: training.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0etraining.proto\x12\x08training\x1a google/protobuf/descriptor.proto\"\xb5\x02\n\x0cModelDetails\x12\x10\n\x08model_id\x18\x01 \x01(\t\x12\x18\n\x10grpc_method_name\x18\x02 \x01(\t\x12\x19\n\x11grpc_service_name\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t\x12\x0e\n\x06status\x18\x06 \x01(\t\x12\x14\n\x0cupdated_date\x18\x07 \x01(\t\x12\x14\n\x0c\x61\x64\x64ress_list\x18\x08 \x03(\t\x12\x1a\n\x12training_data_link\x18\t \x01(\t\x12\x12\n\nmodel_name\x18\n \x01(\t\x12\x17\n\x0forganization_id\x18\x0b \x01(\t\x12\x12\n\nservice_id\x18\x0c \x01(\t\x12\x10\n\x08group_id\x18\r \x01(\t\x12\x1e\n\x16is_publicly_accessible\x18\x0e \x01(\x08\"i\n\x14\x41uthorizationDetails\x12\x15\n\rcurrent_block\x18\x01 \x01(\x04\x12\x0f\n\x07message\x18\x02 \x01(\t\x12\x11\n\tsignature\x18\x03 \x01(\x0c\x12\x16\n\x0esigner_address\x18\x04 \x01(\t\"z\n\x12\x43reateModelRequest\x12\x35\n\rauthorization\x18\x01 \x01(\x0b\x32\x1e.training.AuthorizationDetails\x12-\n\rmodel_details\x18\x02 \x01(\x0b\x32\x16.training.ModelDetails\"\x85\x01\n\x17\x41\x63\x63\x65ssibleModelsRequest\x12\x18\n\x10grpc_method_name\x18\x01 \x01(\t\x12\x19\n\x11grpc_service_name\x18\x02 \x01(\t\x12\x35\n\rauthorization\x18\x03 \x01(\x0b\x32\x1e.training.AuthorizationDetails\"J\n\x18\x41\x63\x63\x65ssibleModelsResponse\x12.\n\x0elist_of_models\x18\x01 \x03(\x0b\x32\x16.training.ModelDetails\"{\n\x13ModelDetailsRequest\x12-\n\rmodel_details\x18\x01 \x01(\x0b\x32\x16.training.ModelDetails\x12\x35\n\rauthorization\x18\x02 \x01(\x0b\x32\x1e.training.AuthorizationDetails\"7\n\x14TrainingMethodOption\x12\x1f\n\x17trainingMethodIndicator\x18\x01 \x01(\t\"\x81\x01\n\x12UpdateModelRequest\x12\x34\n\x14update_model_details\x18\x01 \x01(\x0b\x32\x16.training.ModelDetails\x12\x35\n\rauthorization\x18\x02 \x01(\x0b\x32\x1e.training.AuthorizationDetails\"g\n\x14ModelDetailsResponse\x12 \n\x06status\x18\x01 \x01(\x0e\x32\x10.training.Status\x12-\n\rmodel_details\x18\x02 \x01(\x0b\x32\x16.training.ModelDetails*O\n\x06Status\x12\x0b\n\x07\x43REATED\x10\x00\x12\x0f\n\x0bIN_PROGRESS\x10\x01\x12\x0b\n\x07\x45RRORED\x10\x02\x12\r\n\tCOMPLETED\x10\x03\x12\x0b\n\x07\x44\x45LETED\x10\x04\x32\xae\x03\n\x05Model\x12N\n\x0c\x63reate_model\x12\x1c.training.CreateModelRequest\x1a\x1e.training.ModelDetailsResponse\"\x00\x12N\n\x0c\x64\x65lete_model\x12\x1c.training.UpdateModelRequest\x1a\x1e.training.ModelDetailsResponse\"\x00\x12S\n\x10get_model_status\x12\x1d.training.ModelDetailsRequest\x1a\x1e.training.ModelDetailsResponse\"\x00\x12U\n\x13update_model_access\x12\x1c.training.UpdateModelRequest\x1a\x1e.training.ModelDetailsResponse\"\x00\x12Y\n\x0eget_all_models\x12!.training.AccessibleModelsRequest\x1a\".training.AccessibleModelsResponse\"\x00:[\n\x10my_method_option\x12\x1e.google.protobuf.MethodOptions\x18\xdd\xa6\xe2\x04 \x01(\x0b\x32\x1e.training.TrainingMethodOptionB\rZ\x0b../trainingb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'training_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + DESCRIPTOR._serialized_options = b'Z\013../training' + _globals['_STATUS']._serialized_start=1236 + _globals['_STATUS']._serialized_end=1315 + _globals['_MODELDETAILS']._serialized_start=63 + _globals['_MODELDETAILS']._serialized_end=372 + _globals['_AUTHORIZATIONDETAILS']._serialized_start=374 + _globals['_AUTHORIZATIONDETAILS']._serialized_end=479 + _globals['_CREATEMODELREQUEST']._serialized_start=481 + _globals['_CREATEMODELREQUEST']._serialized_end=603 + _globals['_ACCESSIBLEMODELSREQUEST']._serialized_start=606 + _globals['_ACCESSIBLEMODELSREQUEST']._serialized_end=739 + _globals['_ACCESSIBLEMODELSRESPONSE']._serialized_start=741 + _globals['_ACCESSIBLEMODELSRESPONSE']._serialized_end=815 + _globals['_MODELDETAILSREQUEST']._serialized_start=817 + _globals['_MODELDETAILSREQUEST']._serialized_end=940 + _globals['_TRAININGMETHODOPTION']._serialized_start=942 + _globals['_TRAININGMETHODOPTION']._serialized_end=997 + _globals['_UPDATEMODELREQUEST']._serialized_start=1000 + _globals['_UPDATEMODELREQUEST']._serialized_end=1129 + _globals['_MODELDETAILSRESPONSE']._serialized_start=1131 + _globals['_MODELDETAILSRESPONSE']._serialized_end=1234 + _globals['_MODEL']._serialized_start=1318 + _globals['_MODEL']._serialized_end=1748 +# @@protoc_insertion_point(module_scope) diff --git a/snet/sdk/resources/proto/training_pb2_grpc.py b/snet/sdk/resources/proto/training_pb2_grpc.py new file mode 100644 index 0000000..51ccf27 --- /dev/null +++ b/snet/sdk/resources/proto/training_pb2_grpc.py @@ -0,0 +1,203 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +import training_pb2 as training__pb2 + + +class ModelStub(object): + """Missing associated documentation comment in .proto file.""" + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.create_model = channel.unary_unary( + '/training.Model/create_model', + request_serializer=training__pb2.CreateModelRequest.SerializeToString, + response_deserializer=training__pb2.ModelDetailsResponse.FromString, + ) + self.delete_model = channel.unary_unary( + '/training.Model/delete_model', + request_serializer=training__pb2.UpdateModelRequest.SerializeToString, + response_deserializer=training__pb2.ModelDetailsResponse.FromString, + ) + self.get_model_status = channel.unary_unary( + '/training.Model/get_model_status', + request_serializer=training__pb2.ModelDetailsRequest.SerializeToString, + response_deserializer=training__pb2.ModelDetailsResponse.FromString, + ) + self.update_model_access = channel.unary_unary( + '/training.Model/update_model_access', + request_serializer=training__pb2.UpdateModelRequest.SerializeToString, + response_deserializer=training__pb2.ModelDetailsResponse.FromString, + ) + self.get_all_models = channel.unary_unary( + '/training.Model/get_all_models', + request_serializer=training__pb2.AccessibleModelsRequest.SerializeToString, + response_deserializer=training__pb2.AccessibleModelsResponse.FromString, + ) + + +class ModelServicer(object): + """Missing associated documentation comment in .proto file.""" + + def create_model(self, request, context): + """The AI developer needs to Implement this service and Daemon will call these + There will be no cost borne by the consumer in calling these methods, + Pricing will apply when you actually call the training methods defined. + AI consumer will call all these methods + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def delete_model(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def get_model_status(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def update_model_access(self, request, context): + """Daemon will implement , however the AI developer should skip implementing these and just provide dummy code. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def get_all_models(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_ModelServicer_to_server(servicer, server): + rpc_method_handlers = { + 'create_model': grpc.unary_unary_rpc_method_handler( + servicer.create_model, + request_deserializer=training__pb2.CreateModelRequest.FromString, + response_serializer=training__pb2.ModelDetailsResponse.SerializeToString, + ), + 'delete_model': grpc.unary_unary_rpc_method_handler( + servicer.delete_model, + request_deserializer=training__pb2.UpdateModelRequest.FromString, + response_serializer=training__pb2.ModelDetailsResponse.SerializeToString, + ), + 'get_model_status': grpc.unary_unary_rpc_method_handler( + servicer.get_model_status, + request_deserializer=training__pb2.ModelDetailsRequest.FromString, + response_serializer=training__pb2.ModelDetailsResponse.SerializeToString, + ), + 'update_model_access': grpc.unary_unary_rpc_method_handler( + servicer.update_model_access, + request_deserializer=training__pb2.UpdateModelRequest.FromString, + response_serializer=training__pb2.ModelDetailsResponse.SerializeToString, + ), + 'get_all_models': grpc.unary_unary_rpc_method_handler( + servicer.get_all_models, + request_deserializer=training__pb2.AccessibleModelsRequest.FromString, + response_serializer=training__pb2.AccessibleModelsResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'training.Model', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class Model(object): + """Missing associated documentation comment in .proto file.""" + + @staticmethod + def create_model(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/training.Model/create_model', + training__pb2.CreateModelRequest.SerializeToString, + training__pb2.ModelDetailsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def delete_model(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/training.Model/delete_model', + training__pb2.UpdateModelRequest.SerializeToString, + training__pb2.ModelDetailsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def get_model_status(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/training.Model/get_model_status', + training__pb2.ModelDetailsRequest.SerializeToString, + training__pb2.ModelDetailsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def update_model_access(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/training.Model/update_model_access', + training__pb2.UpdateModelRequest.SerializeToString, + training__pb2.ModelDetailsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def get_all_models(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/training.Model/get_all_models', + training__pb2.AccessibleModelsRequest.SerializeToString, + training__pb2.AccessibleModelsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/snet/sdk/resources/proto/unixfs.proto b/snet/sdk/resources/proto/unixfs.proto new file mode 100644 index 0000000..c190079 --- /dev/null +++ b/snet/sdk/resources/proto/unixfs.proto @@ -0,0 +1,25 @@ +syntax = "proto2"; +package unixfs.pb; + +message Data { + enum DataType { + Raw = 0; + Directory = 1; + File = 2; + Metadata = 3; + Symlink = 4; + HAMTShard = 5; + } + + required DataType Type = 1; + optional bytes Data = 2; + optional uint64 filesize = 3; + repeated uint64 blocksizes = 4; + + optional uint64 hashType = 5; + optional uint64 fanout = 6; +} + +message Metadata { + optional string MimeType = 1; +} \ No newline at end of file diff --git a/snet/sdk/resources/proto/unixfs_pb2.py b/snet/sdk/resources/proto/unixfs_pb2.py new file mode 100644 index 0000000..394f454 --- /dev/null +++ b/snet/sdk/resources/proto/unixfs_pb2.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: unixfs.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0cunixfs.proto\x12\tunixfs.pb\"\xdc\x01\n\x04\x44\x61ta\x12&\n\x04Type\x18\x01 \x02(\x0e\x32\x18.unixfs.pb.Data.DataType\x12\x0c\n\x04\x44\x61ta\x18\x02 \x01(\x0c\x12\x10\n\x08\x66ilesize\x18\x03 \x01(\x04\x12\x12\n\nblocksizes\x18\x04 \x03(\x04\x12\x10\n\x08hashType\x18\x05 \x01(\x04\x12\x0e\n\x06\x66\x61nout\x18\x06 \x01(\x04\"V\n\x08\x44\x61taType\x12\x07\n\x03Raw\x10\x00\x12\r\n\tDirectory\x10\x01\x12\x08\n\x04\x46ile\x10\x02\x12\x0c\n\x08Metadata\x10\x03\x12\x0b\n\x07Symlink\x10\x04\x12\r\n\tHAMTShard\x10\x05\"\x1c\n\x08Metadata\x12\x10\n\x08MimeType\x18\x01 \x01(\t') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'unixfs_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + _globals['_DATA']._serialized_start=28 + _globals['_DATA']._serialized_end=248 + _globals['_DATA_DATATYPE']._serialized_start=162 + _globals['_DATA_DATATYPE']._serialized_end=248 + _globals['_METADATA']._serialized_start=250 + _globals['_METADATA']._serialized_end=278 +# @@protoc_insertion_point(module_scope) diff --git a/snet/sdk/resources/proto/unixfs_pb2_grpc.py b/snet/sdk/resources/proto/unixfs_pb2_grpc.py new file mode 100644 index 0000000..2daafff --- /dev/null +++ b/snet/sdk/resources/proto/unixfs_pb2_grpc.py @@ -0,0 +1,4 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + diff --git a/snet/sdk/resources/root_certificate.py b/snet/sdk/resources/root_certificate.py new file mode 100644 index 0000000..eb383d3 --- /dev/null +++ b/snet/sdk/resources/root_certificate.py @@ -0,0 +1 @@ +certificate = b'# This Source Code Form is subject to the terms of the Mozilla Public\r\n# License, v. 2.0. If a copy of the MPL was not distributed with this\r\n# file, You can obtain one at http://mozilla.org/MPL/2.0/.\r\n\r\n# Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA\r\n# Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA\r\n# Label: "GlobalSign Root CA"\r\n# Serial: 4835703278459707669005204\r\n# MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a\r\n# SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c\r\n# SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99\r\n-----BEGIN CERTIFICATE-----\r\nMIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG\r\nA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv\r\nb3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw\r\nMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i\r\nYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT\r\naWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ\r\njc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp\r\nxy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp\r\n1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG\r\nsnUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ\r\nU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8\r\n9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E\r\nBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B\r\nAQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz\r\nyj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE\r\n38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP\r\nAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad\r\nDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME\r\nHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2\r\n# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2\r\n# Label: "GlobalSign Root CA - R2"\r\n# Serial: 4835703278459682885658125\r\n# MD5 Fingerprint: 94:14:77:7e:3e:5e:fd:8f:30:bd:41:b0:cf:e7:d0:30\r\n# SHA1 Fingerprint: 75:e0:ab:b6:13:85:12:27:1c:04:f8:5f:dd:de:38:e4:b7:24:2e:fe\r\n# SHA256 Fingerprint: ca:42:dd:41:74:5f:d0:b8:1e:b9:02:36:2c:f9:d8:bf:71:9d:a1:bd:1b:1e:fc:94:6f:5b:4c:99:f4:2c:1b:9e\r\n-----BEGIN CERTIFICATE-----\r\nMIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G\r\nA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp\r\nZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1\r\nMDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG\r\nA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI\r\nhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL\r\nv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8\r\neoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq\r\ntTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd\r\nC9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa\r\nzq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB\r\nmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH\r\nV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n\r\nbG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG\r\n3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs\r\nJ0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO\r\n291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS\r\not+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd\r\nAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7\r\nTBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited\r\n# Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited\r\n# Label: "Entrust.net Premium 2048 Secure Server CA"\r\n# Serial: 946069240\r\n# MD5 Fingerprint: ee:29:31:bc:32:7e:9a:e6:e8:b5:f7:51:b4:34:71:90\r\n# SHA1 Fingerprint: 50:30:06:09:1d:97:d4:f5:ae:39:f7:cb:e7:92:7d:7d:65:2d:34:31\r\n# SHA256 Fingerprint: 6d:c4:71:72:e0:1c:bc:b0:bf:62:58:0d:89:5f:e2:b8:ac:9a:d4:f8:73:80:1e:0c:10:b9:c8:37:d2:1e:b1:77\r\n-----BEGIN CERTIFICATE-----\r\nMIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML\r\nRW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp\r\nbmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5\r\nIEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp\r\nZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3\r\nMjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3\r\nLmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp\r\nYWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG\r\nA1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp\r\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq\r\nK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe\r\nsYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX\r\nMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT\r\nXTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/\r\nHoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH\r\n4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV\r\nHQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub\r\nj1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo\r\nU8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf\r\nzX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b\r\nu/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+\r\nbYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er\r\nfF6adulZkMV8gzURZVE=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust\r\n# Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust\r\n# Label: "Baltimore CyberTrust Root"\r\n# Serial: 33554617\r\n# MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4\r\n# SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74\r\n# SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb\r\n-----BEGIN CERTIFICATE-----\r\nMIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ\r\nRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD\r\nVQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX\r\nDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y\r\nZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy\r\nVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr\r\nmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr\r\nIZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK\r\nmpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu\r\nXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy\r\ndc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye\r\njl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1\r\nBE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3\r\nDQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92\r\n9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx\r\njkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0\r\nEpn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz\r\nksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS\r\nR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.\r\n# Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.\r\n# Label: "Entrust Root Certification Authority"\r\n# Serial: 1164660820\r\n# MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4\r\n# SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9\r\n# SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c\r\n-----BEGIN CERTIFICATE-----\r\nMIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC\r\nVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0\r\nLm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW\r\nKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl\r\ncnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw\r\nNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw\r\nNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy\r\nZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV\r\nBAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ\r\nKoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo\r\nNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4\r\n4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9\r\nKlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI\r\nrb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi\r\n94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB\r\nsDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi\r\ngA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo\r\nkORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE\r\nvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA\r\nA4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t\r\nO1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua\r\nAGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP\r\n9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/\r\neu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m\r\n0vdXcDazv/wor3ElhVsT/h5/WrQ8\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=AAA Certificate Services O=Comodo CA Limited\r\n# Subject: CN=AAA Certificate Services O=Comodo CA Limited\r\n# Label: "Comodo AAA Services root"\r\n# Serial: 1\r\n# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0\r\n# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49\r\n# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4\r\n-----BEGIN CERTIFICATE-----\r\nMIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb\r\nMBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow\r\nGAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj\r\nYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL\r\nMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\r\nBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM\r\nGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP\r\nADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua\r\nBtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe\r\n3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4\r\nYgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR\r\nrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm\r\nez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU\r\noBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF\r\nMAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v\r\nQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t\r\nb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF\r\nAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q\r\nGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz\r\nRt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2\r\nG9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi\r\nl2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3\r\nsmPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=QuoVadis Root CA 2 O=QuoVadis Limited\r\n# Subject: CN=QuoVadis Root CA 2 O=QuoVadis Limited\r\n# Label: "QuoVadis Root CA 2"\r\n# Serial: 1289\r\n# MD5 Fingerprint: 5e:39:7b:dd:f8:ba:ec:82:e9:ac:62:ba:0c:54:00:2b\r\n# SHA1 Fingerprint: ca:3a:fb:cf:12:40:36:4b:44:b2:16:20:88:80:48:39:19:93:7c:f7\r\n# SHA256 Fingerprint: 85:a0:dd:7d:d7:20:ad:b7:ff:05:f8:3d:54:2b:20:9d:c7:ff:45:28:f7:d6:77:b1:83:89:fe:a5:e5:c4:9e:86\r\n-----BEGIN CERTIFICATE-----\r\n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\r\n8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=QuoVadis Root CA 3 O=QuoVadis Limited\r\n# Subject: CN=QuoVadis Root CA 3 O=QuoVadis Limited\r\n# Label: "QuoVadis Root CA 3"\r\n# Serial: 1478\r\n# MD5 Fingerprint: 31:85:3c:62:94:97:63:b9:aa:fd:89:4e:af:6f:e0:cf\r\n# SHA1 Fingerprint: 1f:49:14:f7:d8:74:95:1d:dd:ae:02:c0:be:fd:3a:2d:82:75:51:85\r\n# SHA256 Fingerprint: 18:f1:fc:7f:20:5d:f8:ad:dd:eb:7f:e0:07:dd:57:e3:af:37:5a:9c:4d:8d:73:54:6b:f4:f1:fe:d1:e1:8d:35\r\n-----BEGIN CERTIFICATE-----\r\nMIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x\r\nGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv\r\nb3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV\r\nBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W\r\nYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM\r\nV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB\r\n4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr\r\nH556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd\r\n8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv\r\nvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT\r\nmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe\r\nbtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc\r\nT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt\r\nWAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ\r\nc6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A\r\n4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD\r\nVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG\r\nCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0\r\naXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0\r\naWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu\r\ndC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw\r\nczALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G\r\nA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC\r\nTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg\r\nUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0\r\n7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem\r\nd1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd\r\n+LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B\r\n4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN\r\nt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x\r\nDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57\r\nk8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s\r\nzHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j\r\nWy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT\r\nmJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK\r\n4SVhM7JZG+Ju1zdXtg2pEto=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: O=SECOM Trust.net OU=Security Communication RootCA1\r\n# Subject: O=SECOM Trust.net OU=Security Communication RootCA1\r\n# Label: "Security Communication Root CA"\r\n# Serial: 0\r\n# MD5 Fingerprint: f1:bc:63:6a:54:e0:b5:27:f5:cd:e7:1a:e3:4d:6e:4a\r\n# SHA1 Fingerprint: 36:b1:2b:49:f9:81:9e:d7:4c:9e:bc:38:0f:c6:56:8f:5d:ac:b2:f7\r\n# SHA256 Fingerprint: e7:5e:72:ed:9f:56:0e:ec:6e:b4:80:00:73:a4:3f:c3:ad:19:19:5a:39:22:82:01:78:95:97:4a:99:02:6b:6c\r\n-----BEGIN CERTIFICATE-----\r\nMIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY\r\nMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t\r\ndW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5\r\nWjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD\r\nVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3\r\nDQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8\r\n9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ\r\nDKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9\r\nMs+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N\r\nQV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ\r\nxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G\r\nA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T\r\nAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG\r\nkl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr\r\nUj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5\r\nBw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU\r\nJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot\r\nRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com\r\n# Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com\r\n# Label: "XRamp Global CA Root"\r\n# Serial: 107108908803651509692980124233745014957\r\n# MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1\r\n# SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6\r\n# SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2\r\n-----BEGIN CERTIFICATE-----\r\nMIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB\r\ngjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk\r\nMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY\r\nUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx\r\nNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3\r\ndy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy\r\ndmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB\r\ndXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6\r\n38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP\r\nKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q\r\nDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4\r\nqEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa\r\nJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi\r\nPvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P\r\nBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs\r\njVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0\r\neS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD\r\nggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR\r\nvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt\r\nqZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa\r\nIR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy\r\ni6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ\r\nO+7ETPTsJ3xCwnR8gooJybQDJbw=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority\r\n# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority\r\n# Label: "Go Daddy Class 2 CA"\r\n# Serial: 0\r\n# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67\r\n# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4\r\n# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4\r\n-----BEGIN CERTIFICATE-----\r\nMIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh\r\nMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE\r\nYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3\r\nMDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo\r\nZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg\r\nMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN\r\nADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA\r\nPVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w\r\nwdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi\r\nEqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY\r\navx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+\r\nYihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE\r\nsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h\r\n/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5\r\nIEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj\r\nYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD\r\nggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy\r\nOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P\r\nTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ\r\nHmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER\r\ndEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf\r\nReYNnyicsbkqWletNw+vHX/bvZ8=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority\r\n# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority\r\n# Label: "Starfield Class 2 CA"\r\n# Serial: 0\r\n# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24\r\n# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a\r\n# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58\r\n-----BEGIN CERTIFICATE-----\r\nMIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl\r\nMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp\r\nU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw\r\nNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE\r\nChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp\r\nZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3\r\nDQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf\r\n8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN\r\n+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0\r\nX9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa\r\nK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA\r\n1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G\r\nA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR\r\nzt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0\r\nYXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD\r\nbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w\r\nDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3\r\nL7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D\r\neruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl\r\nxy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp\r\nVSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY\r\nWQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com\r\n# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com\r\n# Label: "DigiCert Assured ID Root CA"\r\n# Serial: 17154717934120587862167794914071425081\r\n# MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72\r\n# SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43\r\n# SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c\r\n-----BEGIN CERTIFICATE-----\r\nMIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl\r\nMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\r\nd3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv\r\nb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG\r\nEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl\r\ncnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi\r\nMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c\r\nJpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP\r\nmDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+\r\nwRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4\r\nVYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/\r\nAUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB\r\nAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW\r\nBBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun\r\npyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC\r\ndWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf\r\nfwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm\r\nNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx\r\nH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe\r\n+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com\r\n# Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com\r\n# Label: "DigiCert Global Root CA"\r\n# Serial: 10944719598952040374951832963794454346\r\n# MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e\r\n# SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36\r\n# SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61\r\n-----BEGIN CERTIFICATE-----\r\nMIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh\r\nMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\r\nd3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\r\nQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT\r\nMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\r\nb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG\r\n9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB\r\nCSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97\r\nnh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt\r\n43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P\r\nT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4\r\ngdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO\r\nBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR\r\nTLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw\r\nDQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr\r\nhMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg\r\n06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF\r\nPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls\r\nYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk\r\nCAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com\r\n# Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com\r\n# Label: "DigiCert High Assurance EV Root CA"\r\n# Serial: 3553400076410547919724730734378100087\r\n# MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a\r\n# SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25\r\n# SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf\r\n-----BEGIN CERTIFICATE-----\r\nMIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs\r\nMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\r\nd3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j\r\nZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL\r\nMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3\r\nLmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug\r\nRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm\r\n+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW\r\nPNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM\r\nxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB\r\nIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3\r\nhzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg\r\nEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF\r\nMAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA\r\nFLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec\r\nnzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z\r\neM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF\r\nhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2\r\nYzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe\r\nvEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep\r\n+OkuE6N36B9K\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG\r\n# Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG\r\n# Label: "SwissSign Gold CA - G2"\r\n# Serial: 13492815561806991280\r\n# MD5 Fingerprint: 24:77:d9:a8:91:d1:3b:fa:88:2d:c2:ff:f8:cd:33:93\r\n# SHA1 Fingerprint: d8:c5:38:8a:b7:30:1b:1b:6e:d4:7a:e6:45:25:3a:6f:9f:1a:27:61\r\n# SHA256 Fingerprint: 62:dd:0b:e9:b9:f5:0a:16:3e:a0:f8:e7:5c:05:3b:1e:ca:57:ea:55:c8:68:8f:64:7c:68:81:f2:c8:35:7b:95\r\n-----BEGIN CERTIFICATE-----\r\n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\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=SwissSign Silver CA - G2 O=SwissSign AG\r\n# Subject: CN=SwissSign Silver CA - G2 O=SwissSign AG\r\n# Label: "SwissSign Silver CA - G2"\r\n# Serial: 5700383053117599563\r\n# MD5 Fingerprint: e0:06:a1:c9:7d:cf:c9:fc:0d:c0:56:75:96:d8:62:13\r\n# SHA1 Fingerprint: 9b:aa:e5:9f:56:ee:21:cb:43:5a:be:25:93:df:a7:f0:40:d1:1d:cb\r\n# SHA256 Fingerprint: be:6c:4d:a2:bb:b9:ba:59:b6:f3:93:97:68:37:42:46:c3:c0:05:99:3f:a9:8f:02:0d:1d:ed:be:d4:8a:81:d5\r\n-----BEGIN CERTIFICATE-----\r\n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\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=SecureTrust CA O=SecureTrust Corporation\r\n# Subject: CN=SecureTrust CA O=SecureTrust Corporation\r\n# Label: "SecureTrust CA"\r\n# Serial: 17199774589125277788362757014266862032\r\n# MD5 Fingerprint: dc:32:c3:a7:6d:25:57:c7:68:09:9d:ea:2d:a9:a2:d1\r\n# SHA1 Fingerprint: 87:82:c6:c3:04:35:3b:cf:d2:96:92:d2:59:3e:7d:44:d9:34:ff:11\r\n# SHA256 Fingerprint: f1:c1:b5:0a:e5:a2:0d:d8:03:0e:c9:f6:bc:24:82:3d:d3:67:b5:25:57:59:b4:e7:1b:61:fc:e9:f7:37:5d:73\r\n-----BEGIN CERTIFICATE-----\r\nMIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI\r\nMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x\r\nFzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz\r\nMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv\r\ncnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN\r\nAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz\r\nZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO\r\n0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao\r\nwW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj\r\n7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS\r\n8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT\r\nBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB\r\n/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg\r\nJYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC\r\nNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3\r\n6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/\r\n3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm\r\nD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS\r\nCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR\r\n3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Secure Global CA O=SecureTrust Corporation\r\n# Subject: CN=Secure Global CA O=SecureTrust Corporation\r\n# Label: "Secure Global CA"\r\n# Serial: 9751836167731051554232119481456978597\r\n# MD5 Fingerprint: cf:f4:27:0d:d4:ed:dc:65:16:49:6d:3d:da:bf:6e:de\r\n# SHA1 Fingerprint: 3a:44:73:5a:e5:81:90:1f:24:86:61:46:1e:3b:9c:c4:5f:f5:3a:1b\r\n# SHA256 Fingerprint: 42:00:f5:04:3a:c8:59:0e:bb:52:7d:20:9e:d1:50:30:29:fb:cb:d4:1c:a1:b5:06:ec:27:f1:5a:de:7d:ac:69\r\n-----BEGIN CERTIFICATE-----\r\nMIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK\r\nMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x\r\nGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx\r\nMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg\r\nQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG\r\nSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ\r\niQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa\r\n/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ\r\njnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI\r\nHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7\r\nsFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w\r\ngZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF\r\nMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw\r\nKaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG\r\nAQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L\r\nURYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO\r\nH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm\r\nI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY\r\niNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc\r\nf8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited\r\n# Subject: CN=COMODO Certification Authority O=COMODO CA Limited\r\n# Label: "COMODO Certification Authority"\r\n# Serial: 104350513648249232941998508985834464573\r\n# MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75\r\n# SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b\r\n# SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66\r\n-----BEGIN CERTIFICATE-----\r\nMIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB\r\ngTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G\r\nA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV\r\nBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw\r\nMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl\r\nYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P\r\nRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0\r\naG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3\r\nUcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI\r\n2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8\r\nQ5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp\r\n+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+\r\nDT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O\r\nnKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW\r\n/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g\r\nPKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u\r\nQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY\r\nSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv\r\nIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/\r\nRxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4\r\nzJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd\r\nBA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB\r\nZQ==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C.\r\n# Subject: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C.\r\n# Label: "Network Solutions Certificate Authority"\r\n# Serial: 116697915152937497490437556386812487904\r\n# MD5 Fingerprint: d3:f3:a6:16:c0:fa:6b:1d:59:b1:2d:96:4d:0e:11:2e\r\n# SHA1 Fingerprint: 74:f8:a3:c3:ef:e7:b3:90:06:4b:83:90:3c:21:64:60:20:e5:df:ce\r\n# SHA256 Fingerprint: 15:f0:ba:00:a3:ac:7a:f3:ac:88:4c:07:2b:10:11:a0:77:bd:77:c0:97:f4:01:64:b2:f8:59:8a:bd:83:86:0c\r\n-----BEGIN CERTIFICATE-----\r\nMIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi\r\nMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu\r\nMTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp\r\ndHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV\r\nUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO\r\nZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG\r\nSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz\r\nc7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP\r\nOCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl\r\nmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF\r\nBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4\r\nqY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw\r\ngZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB\r\nBjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu\r\nbmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp\r\ndHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8\r\n6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/\r\nh1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH\r\n/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv\r\nwKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN\r\npGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited\r\n# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited\r\n# Label: "COMODO ECC Certification Authority"\r\n# Serial: 41578283867086692638256921589707938090\r\n# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23\r\n# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11\r\n# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7\r\n-----BEGIN CERTIFICATE-----\r\nMIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL\r\nMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\r\nBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT\r\nIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw\r\nMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy\r\nZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N\r\nT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv\r\nbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR\r\nFtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J\r\ncfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW\r\nBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/\r\nBAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm\r\nfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv\r\nGDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Certigna O=Dhimyotis\r\n# Subject: CN=Certigna O=Dhimyotis\r\n# Label: "Certigna"\r\n# Serial: 18364802974209362175\r\n# MD5 Fingerprint: ab:57:a6:5b:7d:42:82:19:b5:d8:58:26:28:5e:fd:ff\r\n# SHA1 Fingerprint: b1:2e:13:63:45:86:a4:6f:1a:b2:60:68:37:58:2d:c4:ac:fd:94:97\r\n# SHA256 Fingerprint: e3:b6:a2:db:2e:d7:ce:48:84:2f:7a:c5:32:41:c7:b7:1d:54:14:4b:fb:40:c1:1f:3f:1d:0b:42:f5:ee:a1:2d\r\n-----BEGIN CERTIFICATE-----\r\nMIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV\r\nBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X\r\nDTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ\r\nBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3\r\nDQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4\r\nQCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny\r\ngQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw\r\nzBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q\r\n130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2\r\nJsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw\r\nDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw\r\nZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT\r\nAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj\r\nAQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG\r\n9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h\r\nbV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc\r\nfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu\r\nHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w\r\nt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw\r\nWyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc\r\n# Subject: CN=Cybertrust Global Root O=Cybertrust, Inc\r\n# Label: "Cybertrust Global Root"\r\n# Serial: 4835703278459682877484360\r\n# MD5 Fingerprint: 72:e4:4a:87:e3:69:40:80:77:ea:bc:e3:f4:ff:f0:e1\r\n# SHA1 Fingerprint: 5f:43:e5:b1:bf:f8:78:8c:ac:1c:c7:ca:4a:9a:c6:22:2b:cc:34:c6\r\n# SHA256 Fingerprint: 96:0a:df:00:63:e9:63:56:75:0c:29:65:dd:0a:08:67:da:0b:9c:bd:6e:77:71:4a:ea:fb:23:49:ab:39:3d:a3\r\n-----BEGIN CERTIFICATE-----\r\nMIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG\r\nA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh\r\nbCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE\r\nChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS\r\nb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5\r\n7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS\r\nJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y\r\nHLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP\r\nt3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz\r\nFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY\r\nXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/\r\nMB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw\r\nhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js\r\nMB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA\r\nA4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj\r\nWqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx\r\nXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o\r\nomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc\r\nA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW\r\nWL1WMRJOEcgh4LMRkWXbtKaIOM5V\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority\r\n# Subject: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority\r\n# Label: "ePKI Root Certification Authority"\r\n# Serial: 28956088682735189655030529057352760477\r\n# MD5 Fingerprint: 1b:2e:00:ca:26:06:90:3d:ad:fe:6f:15:68:d3:6b:b3\r\n# SHA1 Fingerprint: 67:65:0d:f1:7e:8e:7e:5b:82:40:a4:f4:56:4b:cf:e2:3d:69:c6:f0\r\n# SHA256 Fingerprint: c0:a6:f4:dc:63:a2:4b:fd:cf:54:ef:2a:6a:08:2a:0a:72:de:35:80:3e:2f:f5:ff:52:7a:e5:d8:72:06:df:d5\r\n-----BEGIN CERTIFICATE-----\r\n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\r\nhNQ+IIX3Sj0rnP0qCglN6oH4EZw=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: O=certSIGN OU=certSIGN ROOT CA\r\n# Subject: O=certSIGN OU=certSIGN ROOT CA\r\n# Label: "certSIGN ROOT CA"\r\n# Serial: 35210227249154\r\n# MD5 Fingerprint: 18:98:c0:d6:e9:3a:fc:f9:b0:f5:0c:f7:4b:01:44:17\r\n# SHA1 Fingerprint: fa:b7:ee:36:97:26:62:fb:2d:b0:2a:f6:bf:03:fd:e8:7c:4b:2f:9b\r\n# SHA256 Fingerprint: ea:a9:62:c4:fa:4a:6b:af:eb:e4:15:19:6d:35:1c:cd:88:8d:4f:53:f3:fa:8a:e6:d7:c4:66:a9:4e:60:42:bb\r\n-----BEGIN CERTIFICATE-----\r\nMIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT\r\nAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD\r\nQTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP\r\nMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC\r\nASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do\r\n0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ\r\nUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d\r\nRdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ\r\nOA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv\r\nJoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C\r\nAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O\r\nBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ\r\nLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY\r\nMnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ\r\n44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I\r\nJd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw\r\ni/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN\r\n9u6wWk5JRFRYX0KD\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=NetLock Arany (Class Gold) F\xc5\x91tan\xc3\xbas\xc3\xadtv\xc3\xa1ny O=NetLock Kft. OU=Tan\xc3\xbas\xc3\xadtv\xc3\xa1nykiad\xc3\xb3k (Certification Services)\r\n# Subject: CN=NetLock Arany (Class Gold) F\xc5\x91tan\xc3\xbas\xc3\xadtv\xc3\xa1ny O=NetLock Kft. OU=Tan\xc3\xbas\xc3\xadtv\xc3\xa1nykiad\xc3\xb3k (Certification Services)\r\n# Label: "NetLock Arany (Class Gold) F\xc5\x91tan\xc3\xbas\xc3\xadtv\xc3\xa1ny"\r\n# Serial: 80544274841616\r\n# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88\r\n# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91\r\n# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98\r\n-----BEGIN CERTIFICATE-----\r\nMIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG\r\nEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3\r\nMDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl\r\ncnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR\r\ndGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB\r\npzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM\r\nb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm\r\naWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz\r\nIEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A\r\nMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT\r\nlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz\r\nAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5\r\nVA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG\r\nILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2\r\nBJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG\r\nAQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M\r\nU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh\r\nbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C\r\n+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC\r\nbLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F\r\nuLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2\r\nXjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post\r\n# Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post\r\n# Label: "Hongkong Post Root CA 1"\r\n# Serial: 1000\r\n# MD5 Fingerprint: a8:0d:6f:39:78:b9:43:6d:77:42:6d:98:5a:cc:23:ca\r\n# SHA1 Fingerprint: d6:da:a8:20:8d:09:d2:15:4d:24:b5:2f:cb:34:6e:b2:58:b2:8a:58\r\n# SHA256 Fingerprint: f9:e6:7d:33:6c:51:00:2a:c0:54:c6:32:02:2d:66:dd:a2:e7:e3:ff:f1:0a:d0:61:ed:31:d8:bb:b4:10:cf:b2\r\n-----BEGIN CERTIFICATE-----\r\nMIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx\r\nFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg\r\nUm9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG\r\nA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr\r\nb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\r\nAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ\r\njVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn\r\nPzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh\r\nZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9\r\nnnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h\r\nq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED\r\nMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC\r\nmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3\r\n7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB\r\noiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs\r\nEhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO\r\nfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi\r\nAmvZWg==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc.\r\n# Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc.\r\n# Label: "SecureSign RootCA11"\r\n# Serial: 1\r\n# MD5 Fingerprint: b7:52:74:e2:92:b4:80:93:f2:75:e4:cc:d7:f2:ea:26\r\n# SHA1 Fingerprint: 3b:c4:9f:48:f8:f3:73:a0:9c:1e:bd:f8:5b:b1:c3:65:c7:d8:11:b3\r\n# SHA256 Fingerprint: bf:0f:ee:fb:9e:3a:58:1a:d5:f9:e9:db:75:89:98:57:43:d2:61:08:5c:4d:31:4f:6f:5d:72:59:aa:42:16:12\r\n-----BEGIN CERTIFICATE-----\r\nMIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr\r\nMCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG\r\nA1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0\r\nMDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp\r\nY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD\r\nQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz\r\ni1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8\r\nh9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV\r\nMdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9\r\nUK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni\r\n8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC\r\nh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD\r\nVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB\r\nAKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm\r\nKbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ\r\nX5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr\r\nQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5\r\npPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN\r\nQSdJQO7e5iNEOdyhIta6A/I=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd.\r\n# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd.\r\n# Label: "Microsec e-Szigno Root CA 2009"\r\n# Serial: 14014712776195784473\r\n# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1\r\n# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e\r\n# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78\r\n-----BEGIN CERTIFICATE-----\r\nMIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD\r\nVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0\r\nZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G\r\nCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y\r\nOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx\r\nFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp\r\nZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o\r\ndTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP\r\nkd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc\r\ncbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U\r\nfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7\r\nN4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC\r\nxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1\r\n+rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G\r\nA1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM\r\nPcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG\r\nSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h\r\nmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk\r\nddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775\r\ntyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c\r\n2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t\r\nHMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3\r\n# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3\r\n# Label: "GlobalSign Root CA - R3"\r\n# Serial: 4835703278459759426209954\r\n# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28\r\n# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad\r\n# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b\r\n-----BEGIN CERTIFICATE-----\r\nMIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G\r\nA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp\r\nZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4\r\nMTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG\r\nA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI\r\nhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8\r\nRgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT\r\ngHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm\r\nKPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd\r\nQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ\r\nXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw\r\nDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o\r\nLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU\r\nRUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp\r\njjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK\r\n6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX\r\nmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs\r\nMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH\r\nWD9f\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068\r\n# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068\r\n# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068"\r\n# Serial: 6047274297262753887\r\n# MD5 Fingerprint: 73:3a:74:7a:ec:bb:a3:96:a6:c2:e4:e2:c8:9b:c0:c3\r\n# SHA1 Fingerprint: ae:c5:fb:3f:c8:e1:bf:c4:e5:4f:03:07:5a:9a:e8:00:b7:f7:b6:fa\r\n# SHA256 Fingerprint: 04:04:80:28:bf:1f:28:64:d4:8f:9a:d4:d8:32:94:36:6a:82:88:56:55:3f:3b:14:30:3f:90:14:7f:5d:40:ef\r\n-----BEGIN CERTIFICATE-----\r\n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\r\njLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Izenpe.com O=IZENPE S.A.\r\n# Subject: CN=Izenpe.com O=IZENPE S.A.\r\n# Label: "Izenpe.com"\r\n# Serial: 917563065490389241595536686991402621\r\n# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73\r\n# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19\r\n# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f\r\n-----BEGIN CERTIFICATE-----\r\n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\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.\r\n# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.\r\n# Label: "Go Daddy Root Certificate Authority - G2"\r\n# Serial: 0\r\n# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01\r\n# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b\r\n# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da\r\n-----BEGIN CERTIFICATE-----\r\nMIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx\r\nEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT\r\nEUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp\r\nZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz\r\nNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH\r\nEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE\r\nAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw\r\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD\r\nE6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH\r\n/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy\r\nDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh\r\nGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR\r\ntDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA\r\nAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE\r\nFDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX\r\nWWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu\r\n9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr\r\ngIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo\r\n2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO\r\nLPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI\r\n4uJEvlz36hz1\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.\r\n# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.\r\n# Label: "Starfield Root Certificate Authority - G2"\r\n# Serial: 0\r\n# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96\r\n# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e\r\n# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5\r\n-----BEGIN CERTIFICATE-----\r\nMIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx\r\nEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT\r\nHFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs\r\nZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw\r\nMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6\r\nb25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj\r\naG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp\r\nY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\r\nggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg\r\nnLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1\r\nHOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N\r\nHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN\r\ndloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0\r\nHZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO\r\nBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G\r\nCSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU\r\nsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3\r\n4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg\r\n8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K\r\npL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1\r\nmMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc.\r\n# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc.\r\n# Label: "Starfield Services Root Certificate Authority - G2"\r\n# Serial: 0\r\n# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2\r\n# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f\r\n# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5\r\n-----BEGIN CERTIFICATE-----\r\nMIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx\r\nEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT\r\nHFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs\r\nZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5\r\nMDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD\r\nVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy\r\nZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy\r\ndmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI\r\nhvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p\r\nOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2\r\n8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K\r\nTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe\r\nhRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk\r\n6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw\r\nDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q\r\nAdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI\r\nbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB\r\nve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z\r\nqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd\r\niEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn\r\n0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN\r\nsSi6\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=AffirmTrust Commercial O=AffirmTrust\r\n# Subject: CN=AffirmTrust Commercial O=AffirmTrust\r\n# Label: "AffirmTrust Commercial"\r\n# Serial: 8608355977964138876\r\n# MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7\r\n# SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7\r\n# SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7\r\n-----BEGIN CERTIFICATE-----\r\nMIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE\r\nBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz\r\ndCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL\r\nMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp\r\ncm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\r\nAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP\r\nHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr\r\nba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL\r\nMeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1\r\nyHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr\r\nVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/\r\nnx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ\r\nKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG\r\nXUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj\r\nvbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt\r\nZ8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g\r\nN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC\r\nnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=AffirmTrust Networking O=AffirmTrust\r\n# Subject: CN=AffirmTrust Networking O=AffirmTrust\r\n# Label: "AffirmTrust Networking"\r\n# Serial: 8957382827206547757\r\n# MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f\r\n# SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f\r\n# SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b\r\n-----BEGIN CERTIFICATE-----\r\nMIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE\r\nBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz\r\ndCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL\r\nMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp\r\ncm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\r\nAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y\r\nYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua\r\nkCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL\r\nQESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp\r\n6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG\r\nyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i\r\nQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ\r\nKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO\r\ntDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu\r\nQY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ\r\nLgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u\r\nolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48\r\nx3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=AffirmTrust Premium O=AffirmTrust\r\n# Subject: CN=AffirmTrust Premium O=AffirmTrust\r\n# Label: "AffirmTrust Premium"\r\n# Serial: 7893706540734352110\r\n# MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57\r\n# SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27\r\n# SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a\r\n-----BEGIN CERTIFICATE-----\r\nMIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE\r\nBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz\r\ndCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG\r\nA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U\r\ncnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf\r\nqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ\r\nJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ\r\n+jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS\r\ns8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5\r\nHMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7\r\n70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG\r\nV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S\r\nqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S\r\n5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia\r\nC1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX\r\nOwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE\r\nFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/\r\nBAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2\r\nKI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg\r\nNt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B\r\n8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ\r\nMKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc\r\n0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ\r\nu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF\r\nu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH\r\nYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8\r\nGKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO\r\nRtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e\r\nKeC2uAloGRwYQw==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust\r\n# Subject: CN=AffirmTrust Premium ECC O=AffirmTrust\r\n# Label: "AffirmTrust Premium ECC"\r\n# Serial: 8401224907861490260\r\n# MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d\r\n# SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb\r\n# SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23\r\n-----BEGIN CERTIFICATE-----\r\nMIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC\r\nVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ\r\ncmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ\r\nBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt\r\nVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D\r\n0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9\r\nss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G\r\nA1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G\r\nA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs\r\naobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I\r\nflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority\r\n# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority\r\n# Label: "Certum Trusted Network CA"\r\n# Serial: 279744\r\n# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78\r\n# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e\r\n# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e\r\n-----BEGIN CERTIFICATE-----\r\nMIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM\r\nMSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D\r\nZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU\r\ncnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3\r\nWjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg\r\nUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw\r\nIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B\r\nAQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH\r\nUV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM\r\nTXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU\r\nBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM\r\nkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x\r\nAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV\r\nHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV\r\nHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y\r\nsHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL\r\nI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8\r\nJ9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY\r\nVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI\r\n03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA\r\n# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA\r\n# Label: "TWCA Root Certification Authority"\r\n# Serial: 1\r\n# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79\r\n# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48\r\n# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44\r\n-----BEGIN CERTIFICATE-----\r\nMIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES\r\nMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU\r\nV0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz\r\nWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO\r\nLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm\r\naWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\r\nAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE\r\nAcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH\r\nK3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX\r\nRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z\r\nrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx\r\n3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV\r\nHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq\r\nhkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC\r\nMErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls\r\nXebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D\r\nlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn\r\naspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ\r\nYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2\r\n# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2\r\n# Label: "Security Communication RootCA2"\r\n# Serial: 0\r\n# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43\r\n# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74\r\n# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6\r\n-----BEGIN CERTIFICATE-----\r\nMIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl\r\nMCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe\r\nU2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX\r\nDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy\r\ndXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj\r\nYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV\r\nOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr\r\nzbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM\r\nVAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ\r\nhNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO\r\nojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw\r\nawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs\r\nOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3\r\nDQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF\r\ncoJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc\r\nokgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8\r\nt/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy\r\n1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/\r\nSjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=EC-ACC O=Agencia Catalana de Certificacio (NIF Q-0801176-I) OU=Serveis Publics de Certificacio/Vegeu https://www.catcert.net/verarrel (c)03/Jerarquia Entitats de Certificacio Catalanes\r\n# Subject: CN=EC-ACC O=Agencia Catalana de Certificacio (NIF Q-0801176-I) OU=Serveis Publics de Certificacio/Vegeu https://www.catcert.net/verarrel (c)03/Jerarquia Entitats de Certificacio Catalanes\r\n# Label: "EC-ACC"\r\n# Serial: -23701579247955709139626555126524820479\r\n# MD5 Fingerprint: eb:f5:9d:29:0d:61:f9:42:1f:7c:c2:ba:6d:e3:15:09\r\n# SHA1 Fingerprint: 28:90:3a:63:5b:52:80:fa:e6:77:4c:0b:6d:a7:d6:ba:a6:4a:f2:e8\r\n# SHA256 Fingerprint: 88:49:7f:01:60:2f:31:54:24:6a:e2:8c:4d:5a:ef:10:f1:d8:7e:bb:76:62:6f:4a:e0:b7:f9:5b:a7:96:87:99\r\n-----BEGIN CERTIFICATE-----\r\nMIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB\r\n8zELMAkGA1UEBhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2Vy\r\ndGlmaWNhY2lvIChOSUYgUS0wODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1\r\nYmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYDVQQLEyxWZWdldSBodHRwczovL3d3\r\ndy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UECxMsSmVyYXJxdWlh\r\nIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMTBkVD\r\nLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQG\r\nEwJFUzE7MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8g\r\nKE5JRiBRLTA4MDExNzYtSSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBD\r\nZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZlZ2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQu\r\nbmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJhcnF1aWEgRW50aXRhdHMg\r\nZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUNDMIIBIjAN\r\nBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R\r\n85iKw5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm\r\n4CgPukLjbo73FCeTae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaV\r\nHMf5NLWUhdWZXqBIoH7nF2W4onW4HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNd\r\nQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0aE9jD2z3Il3rucO2n5nzbcc8t\r\nlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw0JDnJwIDAQAB\r\no4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E\r\nBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4\r\nopvpXY0wfwYDVR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBo\r\ndHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidW\r\nZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAwDQYJKoZIhvcN\r\nAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJlF7W2u++AVtd0x7Y\r\n/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNaAl6k\r\nSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhy\r\nRp/7SNVel+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOS\r\nAgu+TGbrIP65y7WZf+a2E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xl\r\nnJ2lYJU6Un/10asIbvPuW/mIPX64b24D5EI=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority\r\n# Subject: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority\r\n# Label: "Hellenic Academic and Research Institutions RootCA 2011"\r\n# Serial: 0\r\n# MD5 Fingerprint: 73:9f:4c:4b:73:5b:79:e9:fa:ba:1c:ef:6e:cb:d5:c9\r\n# SHA1 Fingerprint: fe:45:65:9b:79:03:5b:98:a1:61:b5:51:2e:ac:da:58:09:48:22:4d\r\n# SHA256 Fingerprint: bc:10:4f:15:a4:8b:e7:09:dc:a5:42:a7:e1:d4:b9:df:6f:05:45:27:e8:02:ea:a9:2d:59:54:44:25:8a:fe:71\r\n-----BEGIN CERTIFICATE-----\r\nMIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix\r\nRDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1\r\ndGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p\r\nYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw\r\nNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK\r\nEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl\r\ncnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl\r\nc2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB\r\nBQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz\r\ndYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ\r\nfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns\r\nbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD\r\n75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP\r\nFEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV\r\nHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp\r\n5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu\r\nb3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA\r\nA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p\r\n6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8\r\nTqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7\r\ndIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys\r\nNnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI\r\nl7WdmplNsDz4SgCbZN2fOUvRJ9e4\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967\r\n# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967\r\n# Label: "Actalis Authentication Root CA"\r\n# Serial: 6271844772424770508\r\n# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6\r\n# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac\r\n# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66\r\n-----BEGIN CERTIFICATE-----\r\nMIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE\r\nBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w\r\nMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290\r\nIENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC\r\nSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1\r\nODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB\r\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv\r\nUTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX\r\n4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9\r\nKK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/\r\ngCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb\r\nrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ\r\n51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F\r\nbe8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe\r\nKF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F\r\nv6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn\r\nfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7\r\njPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz\r\nezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt\r\nifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL\r\ne3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70\r\njsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz\r\nWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V\r\nSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j\r\npwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX\r\nX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok\r\nfcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R\r\nK4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU\r\nZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU\r\nLysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT\r\nLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327\r\n# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327\r\n# Label: "Buypass Class 2 Root CA"\r\n# Serial: 2\r\n# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29\r\n# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99\r\n# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48\r\n-----BEGIN CERTIFICATE-----\r\nMIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd\r\nMBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg\r\nQ2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow\r\nTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw\r\nHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB\r\nBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr\r\n6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV\r\nL4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91\r\n1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx\r\nMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ\r\nQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB\r\narcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr\r\nUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi\r\nFRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS\r\nP/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN\r\n9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP\r\nAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz\r\nuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h\r\n9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s\r\nA20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t\r\nOluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo\r\n+fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7\r\nKcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2\r\nDISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us\r\nH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ\r\nI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7\r\n5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h\r\n3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz\r\nY11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327\r\n# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327\r\n# Label: "Buypass Class 3 Root CA"\r\n# Serial: 2\r\n# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec\r\n# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57\r\n# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d\r\n-----BEGIN CERTIFICATE-----\r\nMIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd\r\nMBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg\r\nQ2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow\r\nTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw\r\nHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB\r\nBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y\r\nZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E\r\nN3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9\r\ntznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX\r\n0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c\r\n/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X\r\nKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY\r\nzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS\r\nO1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D\r\n34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP\r\nK9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3\r\nAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv\r\nTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj\r\nQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV\r\ncSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS\r\nIGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2\r\nHJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa\r\nO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv\r\n033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u\r\ndmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE\r\nkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41\r\n3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD\r\nu79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq\r\n4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center\r\n# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center\r\n# Label: "T-TeleSec GlobalRoot Class 3"\r\n# Serial: 1\r\n# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef\r\n# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1\r\n# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd\r\n-----BEGIN CERTIFICATE-----\r\nMIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx\r\nKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd\r\nBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl\r\nYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1\r\nOTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy\r\naXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50\r\nZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G\r\nCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN\r\n8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/\r\nRLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4\r\nhqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5\r\nZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM\r\nEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj\r\nQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1\r\nA/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy\r\nWL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ\r\n1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30\r\n6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT\r\n91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml\r\ne9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p\r\nTpPDpFQUWw==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH\r\n# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH\r\n# Label: "D-TRUST Root Class 3 CA 2 2009"\r\n# Serial: 623603\r\n# MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f\r\n# SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0\r\n# SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1\r\n-----BEGIN CERTIFICATE-----\r\nMIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF\r\nMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD\r\nbGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha\r\nME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM\r\nHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB\r\nBQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03\r\nUAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42\r\ntSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R\r\nySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM\r\nlFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp\r\n/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G\r\nA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G\r\nA1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj\r\ndG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy\r\nMENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl\r\ncmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js\r\nL2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL\r\nBQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni\r\nacfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0\r\no3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K\r\nzCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8\r\nPIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y\r\nJohw1+qRzT65ysCQblrGXnRl11z+o+I=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH\r\n# Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH\r\n# Label: "D-TRUST Root Class 3 CA 2 EV 2009"\r\n# Serial: 623604\r\n# MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6\r\n# SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83\r\n# SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81\r\n-----BEGIN CERTIFICATE-----\r\nMIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF\r\nMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD\r\nbGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw\r\nNDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV\r\nBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI\r\nhvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn\r\nljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0\r\n3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z\r\nqQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR\r\np75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8\r\nHgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw\r\nggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea\r\nHNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw\r\nOi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh\r\nc3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E\r\nRT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt\r\ndHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku\r\nY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp\r\n3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05\r\nnsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF\r\nCSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na\r\nxpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX\r\nKVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=CA Disig Root R2 O=Disig a.s.\r\n# Subject: CN=CA Disig Root R2 O=Disig a.s.\r\n# Label: "CA Disig Root R2"\r\n# Serial: 10572350602393338211\r\n# MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03\r\n# SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71\r\n# SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03\r\n-----BEGIN CERTIFICATE-----\r\nMIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV\r\nBAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu\r\nMRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy\r\nMDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx\r\nEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw\r\nggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe\r\nNcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH\r\nPWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I\r\nx2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe\r\nQTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR\r\nyyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO\r\nQG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912\r\nH9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ\r\nQfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD\r\ni/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs\r\nnLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1\r\nrqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud\r\nDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI\r\nhvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM\r\ntCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf\r\nGopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb\r\nlvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka\r\n+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal\r\nTFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i\r\nnSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3\r\ngzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr\r\nG5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os\r\nzMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x\r\nL4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV\r\n# Subject: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV\r\n# Label: "ACCVRAIZ1"\r\n# Serial: 6828503384748696800\r\n# MD5 Fingerprint: d0:a0:5a:ee:05:b6:09:94:21:a1:7d:f1:b2:29:82:02\r\n# SHA1 Fingerprint: 93:05:7a:88:15:c6:4f:ce:88:2f:fa:91:16:52:28:78:bc:53:64:17\r\n# SHA256 Fingerprint: 9a:6e:c0:12:e1:a7:da:9d:be:34:19:4d:47:8a:d7:c0:db:18:22:fb:07:1d:f1:29:81:49:6e:d1:04:38:41:13\r\n-----BEGIN CERTIFICATE-----\r\nMIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE\r\nAwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw\r\nCQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ\r\nBgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND\r\nVjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb\r\nqau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY\r\nHtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo\r\nG2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA\r\nlHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr\r\nIA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/\r\n0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH\r\nk6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47\r\n4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO\r\nm3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa\r\ncXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl\r\nuUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI\r\nKwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls\r\nZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG\r\nAQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2\r\nVuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT\r\nVfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG\r\nCCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA\r\ncgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA\r\nQwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA\r\n7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA\r\ncgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA\r\nQwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA\r\nczAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu\r\naHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt\r\naW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud\r\nDwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF\r\nBQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp\r\nD70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU\r\nJyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m\r\nAM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD\r\nvV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms\r\ntn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH\r\n7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h\r\nI6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA\r\nh1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF\r\nd3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H\r\npPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA\r\n# Subject: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA\r\n# Label: "TWCA Global Root CA"\r\n# Serial: 3262\r\n# MD5 Fingerprint: f9:03:7e:cf:e6:9e:3c:73:7a:2a:90:07:69:ff:2b:96\r\n# SHA1 Fingerprint: 9c:bb:48:53:f6:a4:f6:d3:52:a4:e8:32:52:55:60:13:f5:ad:af:65\r\n# SHA256 Fingerprint: 59:76:90:07:f7:68:5d:0f:cd:50:87:2f:9f:95:d5:75:5a:5b:2b:45:7d:81:f3:69:2b:61:0a:98:67:2f:0e:1b\r\n-----BEGIN CERTIFICATE-----\r\nMIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx\r\nEjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT\r\nVFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5\r\nNTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT\r\nB1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG\r\nSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF\r\n10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz\r\n0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh\r\nMBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH\r\nzIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc\r\n46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2\r\nyKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi\r\nlaLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP\r\noA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA\r\nBDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE\r\nqYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm\r\n4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB\r\n/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL\r\n1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn\r\nLhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF\r\nH6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo\r\nRI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+\r\nnile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh\r\n15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW\r\n6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW\r\nnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j\r\nwa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz\r\naGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy\r\nKwbQBM0=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=TeliaSonera Root CA v1 O=TeliaSonera\r\n# Subject: CN=TeliaSonera Root CA v1 O=TeliaSonera\r\n# Label: "TeliaSonera Root CA v1"\r\n# Serial: 199041966741090107964904287217786801558\r\n# MD5 Fingerprint: 37:41:49:1b:18:56:9a:26:f5:ad:c2:66:fb:40:a5:4c\r\n# SHA1 Fingerprint: 43:13:bb:96:f1:d5:86:9b:c1:4e:6a:92:f6:cf:f6:34:69:87:82:37\r\n# SHA256 Fingerprint: dd:69:36:fe:21:f8:f0:77:c1:23:a1:a5:21:c1:22:24:f7:22:55:b7:3e:03:a7:26:06:93:e8:a2:4b:0f:a3:89\r\n-----BEGIN CERTIFICATE-----\r\nMIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw\r\nNzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv\r\nb3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD\r\nVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2\r\nMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F\r\nVRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1\r\n7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X\r\nZ75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+\r\n/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs\r\n81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm\r\ndtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe\r\nOh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu\r\nsDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4\r\npgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs\r\nslESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ\r\narMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD\r\nVR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG\r\n9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl\r\ndxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx\r\n0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj\r\nTQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed\r\nY2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7\r\nQ4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI\r\nOylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7\r\nvVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW\r\nt88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn\r\nHL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx\r\nSK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=E-Tugra Certification Authority O=E-Tu\xc4\x9fra EBG Bili\xc5\x9fim Teknolojileri ve Hizmetleri A.\xc5\x9e. OU=E-Tugra Sertifikasyon Merkezi\r\n# Subject: CN=E-Tugra Certification Authority O=E-Tu\xc4\x9fra EBG Bili\xc5\x9fim Teknolojileri ve Hizmetleri A.\xc5\x9e. OU=E-Tugra Sertifikasyon Merkezi\r\n# Label: "E-Tugra Certification Authority"\r\n# Serial: 7667447206703254355\r\n# MD5 Fingerprint: b8:a1:03:63:b0:bd:21:71:70:8a:6f:13:3a:bb:79:49\r\n# SHA1 Fingerprint: 51:c6:e7:08:49:06:6e:f3:92:d4:5c:a0:0d:6d:a3:62:8f:c3:52:39\r\n# SHA256 Fingerprint: b0:bf:d5:2b:b0:d7:d9:bd:92:bf:5d:4d:c1:3d:a2:55:c0:2c:54:2f:37:83:65:ea:89:39:11:f5:5e:55:f2:3c\r\n-----BEGIN CERTIFICATE-----\r\nMIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV\r\nBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC\r\naWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV\r\nBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1\r\nZ3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz\r\nMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+\r\nBgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp\r\nem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN\r\nZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5\r\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY\r\nB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH\r\nD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF\r\nQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo\r\nq1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D\r\nk14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH\r\nfC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut\r\ndEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM\r\nti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8\r\nzLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn\r\nrFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX\r\nU8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6\r\nJyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5\r\nXPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF\r\nNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR\r\nHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY\r\nGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c\r\n77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3\r\n+GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK\r\nvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6\r\nFiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl\r\nyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P\r\nAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD\r\ny4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d\r\nNL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center\r\n# Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center\r\n# Label: "T-TeleSec GlobalRoot Class 2"\r\n# Serial: 1\r\n# MD5 Fingerprint: 2b:9b:9e:e4:7b:6c:1f:00:72:1a:cc:c1:77:79:df:6a\r\n# SHA1 Fingerprint: 59:0d:2d:7d:88:4f:40:2e:61:7e:a5:62:32:17:65:cf:17:d8:94:e9\r\n# SHA256 Fingerprint: 91:e2:f5:78:8d:58:10:eb:a7:ba:58:73:7d:e1:54:8a:8e:ca:cd:01:45:98:bc:0b:14:3e:04:1b:17:05:25:52\r\n-----BEGIN CERTIFICATE-----\r\nMIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx\r\nKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd\r\nBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl\r\nYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1\r\nOTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy\r\naXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50\r\nZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G\r\nCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd\r\nAqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC\r\nFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi\r\n1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq\r\njnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ\r\nwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj\r\nQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/\r\nWSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy\r\nNsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC\r\nuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw\r\nIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6\r\ng1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN\r\n9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP\r\nBSeOE6Fuwg==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Atos TrustedRoot 2011 O=Atos\r\n# Subject: CN=Atos TrustedRoot 2011 O=Atos\r\n# Label: "Atos TrustedRoot 2011"\r\n# Serial: 6643877497813316402\r\n# MD5 Fingerprint: ae:b9:c4:32:4b:ac:7f:5d:66:cc:77:94:bb:2a:77:56\r\n# SHA1 Fingerprint: 2b:b1:f5:3e:55:0c:1d:c5:f1:d4:e6:b7:6a:46:4b:55:06:02:ac:21\r\n# SHA256 Fingerprint: f3:56:be:a2:44:b7:a9:1e:b3:5d:53:ca:9a:d7:86:4a:ce:01:8e:2d:35:d5:f8:f9:6d:df:68:a6:f4:1a:a4:74\r\n-----BEGIN CERTIFICATE-----\r\nMIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE\r\nAwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG\r\nEwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM\r\nFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC\r\nREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp\r\nNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM\r\nVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+\r\nSZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ\r\n4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L\r\ncp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi\r\neowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV\r\nHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG\r\nA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3\r\nDQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j\r\nvZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP\r\nDpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc\r\nmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D\r\nlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv\r\nKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited\r\n# Subject: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited\r\n# Label: "QuoVadis Root CA 1 G3"\r\n# Serial: 687049649626669250736271037606554624078720034195\r\n# MD5 Fingerprint: a4:bc:5b:3f:fe:37:9a:fa:64:f0:e2:fa:05:3d:0b:ab\r\n# SHA1 Fingerprint: 1b:8e:ea:57:96:29:1a:c9:39:ea:b8:0a:81:1a:73:73:c0:93:79:67\r\n# SHA256 Fingerprint: 8a:86:6f:d1:b2:76:b5:7e:57:8e:92:1c:65:82:8a:2b:ed:58:e9:f2:f2:88:05:41:34:b7:f1:f4:bf:c9:cc:74\r\n-----BEGIN CERTIFICATE-----\r\nMIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL\r\nBQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc\r\nBgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00\r\nMjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM\r\naW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG\r\nSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV\r\nwedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe\r\nrNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341\r\n68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh\r\n4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp\r\nUhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o\r\nabw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc\r\n3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G\r\nKubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt\r\nhfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO\r\nTk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt\r\nzCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB\r\nBjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD\r\nggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC\r\nMTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2\r\ncDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN\r\nqXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5\r\nYCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv\r\nb2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2\r\n8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k\r\nNSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj\r\nZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp\r\nq1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt\r\nnh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited\r\n# Subject: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited\r\n# Label: "QuoVadis Root CA 2 G3"\r\n# Serial: 390156079458959257446133169266079962026824725800\r\n# MD5 Fingerprint: af:0c:86:6e:bf:40:2d:7f:0b:3e:12:50:ba:12:3d:06\r\n# SHA1 Fingerprint: 09:3c:61:f3:8b:8b:dc:7d:55:df:75:38:02:05:00:e1:25:f5:c8:36\r\n# SHA256 Fingerprint: 8f:e4:fb:0a:f9:3a:4d:0d:67:db:0b:eb:b2:3e:37:c7:1b:f3:25:dc:bc:dd:24:0e:a0:4d:af:58:b4:7e:18:40\r\n-----BEGIN CERTIFICATE-----\r\nMIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL\r\nBQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc\r\nBgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00\r\nMjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM\r\naW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG\r\nSIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf\r\nqq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW\r\nn4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym\r\nc5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+\r\nO7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1\r\no9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j\r\nIaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq\r\nIcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz\r\n8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh\r\nvNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l\r\n7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG\r\ncC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB\r\nBjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD\r\nggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66\r\nAarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC\r\nroijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga\r\nW/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n\r\nlv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE\r\n+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV\r\ncsaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd\r\ndbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg\r\nKCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM\r\nHVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4\r\nWSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited\r\n# Subject: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited\r\n# Label: "QuoVadis Root CA 3 G3"\r\n# Serial: 268090761170461462463995952157327242137089239581\r\n# MD5 Fingerprint: df:7d:b9:ad:54:6f:68:a1:df:89:57:03:97:43:b0:d7\r\n# SHA1 Fingerprint: 48:12:bd:92:3c:a8:c4:39:06:e7:30:6d:27:96:e6:a4:cf:22:2e:7d\r\n# SHA256 Fingerprint: 88:ef:81:de:20:2e:b0:18:45:2e:43:f8:64:72:5c:ea:5f:bd:1f:c2:d9:d2:05:73:07:09:c5:d8:b8:69:0f:46\r\n-----BEGIN CERTIFICATE-----\r\nMIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL\r\nBQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc\r\nBgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00\r\nMjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM\r\naW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG\r\nSIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR\r\n/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu\r\nFoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR\r\nU7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c\r\nra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR\r\nFHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k\r\nA9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw\r\neyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl\r\nsSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp\r\nVzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q\r\nA4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+\r\nydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB\r\nBjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD\r\nggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px\r\nKGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI\r\nFUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv\r\noxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg\r\nu/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP\r\n0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf\r\n3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl\r\n8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+\r\nDhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN\r\nPlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/\r\nywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com\r\n# Subject: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com\r\n# Label: "DigiCert Assured ID Root G2"\r\n# Serial: 15385348160840213938643033620894905419\r\n# MD5 Fingerprint: 92:38:b9:f8:63:24:82:65:2c:57:33:e6:fe:81:8f:9d\r\n# SHA1 Fingerprint: a1:4b:48:d9:43:ee:0a:0e:40:90:4f:3c:e0:a4:c0:91:93:51:5d:3f\r\n# SHA256 Fingerprint: 7d:05:eb:b6:82:33:9f:8c:94:51:ee:09:4e:eb:fe:fa:79:53:a1:14:ed:b2:f4:49:49:45:2f:ab:7d:2f:c1:85\r\n-----BEGIN CERTIFICATE-----\r\nMIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl\r\nMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\r\nd3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv\r\nb3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG\r\nEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl\r\ncnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi\r\nMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA\r\nn61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc\r\nbiJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp\r\nEgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA\r\nbx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu\r\nYjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB\r\nAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW\r\nBBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI\r\nQW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I\r\n0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni\r\nlmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9\r\nB5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv\r\nON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo\r\nIhNzbM8m9Yop5w==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com\r\n# Subject: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com\r\n# Label: "DigiCert Assured ID Root G3"\r\n# Serial: 15459312981008553731928384953135426796\r\n# MD5 Fingerprint: 7c:7f:65:31:0c:81:df:8d:ba:3e:99:e2:5c:ad:6e:fb\r\n# SHA1 Fingerprint: f5:17:a2:4f:9a:48:c6:c9:f8:a2:00:26:9f:dc:0f:48:2c:ab:30:89\r\n# SHA256 Fingerprint: 7e:37:cb:8b:4c:47:09:0c:ab:36:55:1b:a6:f4:5d:b8:40:68:0f:ba:16:6a:95:2d:b1:00:71:7f:43:05:3f:c2\r\n-----BEGIN CERTIFICATE-----\r\nMIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw\r\nCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu\r\nZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg\r\nRzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV\r\nUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu\r\nY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq\r\nhkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf\r\nZn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q\r\nRSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/\r\nBAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD\r\nAwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY\r\nJjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv\r\n6pZjamVFkpUBtA==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com\r\n# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com\r\n# Label: "DigiCert Global Root G2"\r\n# Serial: 4293743540046975378534879503202253541\r\n# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44\r\n# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4\r\n# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f\r\n-----BEGIN CERTIFICATE-----\r\nMIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh\r\nMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\r\nd3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH\r\nMjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT\r\nMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\r\nb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG\r\n9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI\r\n2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx\r\n1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ\r\nq2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz\r\ntCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ\r\nvIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP\r\nBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV\r\n5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY\r\n1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4\r\nNeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG\r\nFdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91\r\n8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe\r\npLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl\r\nMrY=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com\r\n# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com\r\n# Label: "DigiCert Global Root G3"\r\n# Serial: 7089244469030293291760083333884364146\r\n# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca\r\n# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e\r\n# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0\r\n-----BEGIN CERTIFICATE-----\r\nMIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw\r\nCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu\r\nZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe\r\nFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw\r\nEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x\r\nIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF\r\nK4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG\r\nfp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO\r\nZ9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd\r\nBgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx\r\nAK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/\r\noAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8\r\nsycX\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com\r\n# Subject: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com\r\n# Label: "DigiCert Trusted Root G4"\r\n# Serial: 7451500558977370777930084869016614236\r\n# MD5 Fingerprint: 78:f2:fc:aa:60:1f:2f:b4:eb:c9:37:ba:53:2e:75:49\r\n# SHA1 Fingerprint: dd:fb:16:cd:49:31:c9:73:a2:03:7d:3f:c8:3a:4d:7d:77:5d:05:e4\r\n# SHA256 Fingerprint: 55:2f:7b:dc:f1:a7:af:9e:6c:e6:72:01:7f:4f:12:ab:f7:72:40:c7:8e:76:1a:c2:03:d1:d9:d2:0a:c8:99:88\r\n-----BEGIN CERTIFICATE-----\r\n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\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited\r\n# Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited\r\n# Label: "COMODO RSA Certification Authority"\r\n# Serial: 101909084537582093308941363524873193117\r\n# MD5 Fingerprint: 1b:31:b0:71:40:36:cc:14:36:91:ad:c4:3e:fd:ec:18\r\n# SHA1 Fingerprint: af:e5:d2:44:a8:d1:19:42:30:ff:47:9f:e2:f8:97:bb:cd:7a:8c:b4\r\n# SHA256 Fingerprint: 52:f0:e1:c4:e5:8e:c6:29:29:1b:60:31:7f:07:46:71:b8:5d:7e:a8:0d:5b:07:27:34:63:53:4b:32:b4:02:34\r\n-----BEGIN CERTIFICATE-----\r\nMIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB\r\nhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G\r\nA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV\r\nBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5\r\nMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT\r\nEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR\r\nQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh\r\ndGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR\r\n6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X\r\npz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC\r\n9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV\r\n/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf\r\nZd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z\r\n+pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w\r\nqP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah\r\nSL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC\r\nu9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf\r\nFobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq\r\ncrxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E\r\nFgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB\r\n/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl\r\nwFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM\r\n4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV\r\n2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna\r\nFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ\r\nCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK\r\nboHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke\r\njkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL\r\nS0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb\r\nQOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl\r\n0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB\r\nNVOFBkpdn627G190\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network\r\n# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network\r\n# Label: "USERTrust RSA Certification Authority"\r\n# Serial: 2645093764781058787591871645665788717\r\n# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5\r\n# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e\r\n# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2\r\n-----BEGIN CERTIFICATE-----\r\nMIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB\r\niDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl\r\ncnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV\r\nBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw\r\nMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV\r\nBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU\r\naGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy\r\ndGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK\r\nAoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B\r\n3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY\r\ntJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/\r\nFp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2\r\nVN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT\r\n79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6\r\nc0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT\r\nYo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l\r\nc6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee\r\nUB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE\r\nHg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd\r\nBgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G\r\nA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF\r\nUp/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO\r\nVWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3\r\nATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs\r\n8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR\r\niQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze\r\nSf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ\r\nXHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/\r\nqS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB\r\nVXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB\r\nL6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG\r\njjxDah2nGN59PRbxYvnKkKj9\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=USERTrust ECC Certification Authority O=The USERTRUST Network\r\n# Subject: CN=USERTrust ECC Certification Authority O=The USERTRUST Network\r\n# Label: "USERTrust ECC Certification Authority"\r\n# Serial: 123013823720199481456569720443997572134\r\n# MD5 Fingerprint: fa:68:bc:d9:b5:7f:ad:fd:c9:1d:06:83:28:cc:24:c1\r\n# SHA1 Fingerprint: d1:cb:ca:5d:b2:d5:2a:7f:69:3b:67:4d:e5:f0:5a:1d:0c:95:7d:f0\r\n# SHA256 Fingerprint: 4f:f4:60:d5:4b:9c:86:da:bf:bc:fc:57:12:e0:40:0d:2b:ed:3f:bc:4d:4f:bd:aa:86:e0:6a:dc:d2:a9:ad:7a\r\n-----BEGIN CERTIFICATE-----\r\nMIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL\r\nMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl\r\neSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT\r\nJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx\r\nMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT\r\nCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg\r\nVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm\r\naWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo\r\nI+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng\r\no4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G\r\nA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD\r\nVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB\r\nzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW\r\nRNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4\r\n# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4\r\n# Label: "GlobalSign ECC Root CA - R4"\r\n# Serial: 14367148294922964480859022125800977897474\r\n# MD5 Fingerprint: 20:f0:27:68:d1:7e:a0:9d:0e:e6:2a:ca:df:5c:89:8e\r\n# SHA1 Fingerprint: 69:69:56:2e:40:80:f4:24:a1:e7:19:9f:14:ba:f3:ee:58:ab:6a:bb\r\n# SHA256 Fingerprint: be:c9:49:11:c2:95:56:76:db:6c:0a:55:09:86:d7:6e:3b:a0:05:66:7c:44:2c:97:62:b4:fb:b7:73:de:22:8c\r\n-----BEGIN CERTIFICATE-----\r\nMIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk\r\nMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH\r\nbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX\r\nDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD\r\nQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu\r\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ\r\nFspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw\r\nDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F\r\nuOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX\r\nkPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs\r\newv4n4Q=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5\r\n# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5\r\n# Label: "GlobalSign ECC Root CA - R5"\r\n# Serial: 32785792099990507226680698011560947931244\r\n# MD5 Fingerprint: 9f:ad:3b:1c:02:1e:8a:ba:17:74:38:81:0c:a2:bc:08\r\n# SHA1 Fingerprint: 1f:24:c6:30:cd:a4:18:ef:20:69:ff:ad:4f:dd:5f:46:3a:1b:69:aa\r\n# SHA256 Fingerprint: 17:9f:bc:14:8a:3d:d0:0f:d2:4e:a1:34:58:cc:43:bf:a7:f5:9c:81:82:d7:83:a5:13:f6:eb:ec:10:0c:89:24\r\n-----BEGIN CERTIFICATE-----\r\nMIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk\r\nMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH\r\nbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX\r\nDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD\r\nQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu\r\nMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc\r\n8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke\r\nhOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD\r\nVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI\r\nKoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg\r\n515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO\r\nxwy8p2Fp8fc74SrL+SvzZpA3\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden\r\n# Subject: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden\r\n# Label: "Staat der Nederlanden EV Root CA"\r\n# Serial: 10000013\r\n# MD5 Fingerprint: fc:06:af:7b:e8:1a:f1:9a:b4:e8:d2:70:1f:c0:f5:ba\r\n# SHA1 Fingerprint: 76:e2:7e:c1:4f:db:82:c1:c0:a6:75:b5:05:be:3d:29:b4:ed:db:bb\r\n# SHA256 Fingerprint: 4d:24:91:41:4c:fe:95:67:46:ec:4c:ef:a6:cf:6f:72:e2:8a:13:29:43:2f:9d:8a:90:7a:c4:cb:5d:ad:c1:5a\r\n-----BEGIN CERTIFICATE-----\r\nMIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO\r\nTDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh\r\ndCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y\r\nMjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg\r\nTmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS\r\nb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS\r\nM4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC\r\nUiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d\r\nZ//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p\r\nrfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l\r\npJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb\r\nj5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC\r\nKFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS\r\n/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X\r\ncgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH\r\n1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP\r\npx9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB\r\n/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7\r\nMA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI\r\neK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u\r\n2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS\r\nv4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC\r\nwPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy\r\nCqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e\r\nvTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6\r\nZ2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa\r\nGl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL\r\neG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8\r\nFVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc\r\n7uzXLg==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=IdenTrust Commercial Root CA 1 O=IdenTrust\r\n# Subject: CN=IdenTrust Commercial Root CA 1 O=IdenTrust\r\n# Label: "IdenTrust Commercial Root CA 1"\r\n# Serial: 13298821034946342390520003877796839426\r\n# MD5 Fingerprint: b3:3e:77:73:75:ee:a0:d3:e3:7e:49:63:49:59:bb:c7\r\n# SHA1 Fingerprint: df:71:7e:aa:4a:d9:4e:c9:55:84:99:60:2d:48:de:5f:bc:f0:3a:25\r\n# SHA256 Fingerprint: 5d:56:49:9b:e4:d2:e0:8b:cf:ca:d0:8a:3e:38:72:3d:50:50:3b:de:70:69:48:e4:2f:55:60:30:19:e5:28:ae\r\n-----BEGIN CERTIFICATE-----\r\nMIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK\r\nMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu\r\nVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw\r\nMTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw\r\nJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG\r\nSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT\r\n3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU\r\n+ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp\r\nS0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1\r\nbVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi\r\nT0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL\r\nvYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK\r\nVsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK\r\ndHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT\r\nc+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv\r\nl7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N\r\niGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB\r\n/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD\r\nggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH\r\n6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt\r\nLRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93\r\nnAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3\r\n+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK\r\nW2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT\r\nAwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq\r\nl1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG\r\n4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ\r\nmUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A\r\n7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust\r\n# Subject: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust\r\n# Label: "IdenTrust Public Sector Root CA 1"\r\n# Serial: 13298821034946342390521976156843933698\r\n# MD5 Fingerprint: 37:06:a5:b0:fc:89:9d:ba:f4:6b:8c:1a:64:cd:d5:ba\r\n# SHA1 Fingerprint: ba:29:41:60:77:98:3f:f4:f3:ef:f2:31:05:3b:2e:ea:6d:4d:45:fd\r\n# SHA256 Fingerprint: 30:d0:89:5a:9a:44:8a:26:20:91:63:55:22:d1:f5:20:10:b5:86:7a:ca:e1:2c:78:ef:95:8f:d4:f4:38:9f:2f\r\n-----BEGIN CERTIFICATE-----\r\nMIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN\r\nMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu\r\nVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN\r\nMzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0\r\nMSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi\r\nMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7\r\nekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy\r\nRBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS\r\nbdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF\r\n/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R\r\n3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw\r\nEUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy\r\n9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V\r\nGxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ\r\n2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV\r\nWaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD\r\nW/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/\r\nBAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN\r\nAQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj\r\nt2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV\r\nDRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9\r\nTaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G\r\nlwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW\r\nmhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df\r\nWN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5\r\n+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ\r\ntshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA\r\nGaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv\r\n8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only\r\n# Subject: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only\r\n# Label: "Entrust Root Certification Authority - G2"\r\n# Serial: 1246989352\r\n# MD5 Fingerprint: 4b:e2:c9:91:96:65:0c:f4:0e:5a:93:92:a0:0a:fe:b2\r\n# SHA1 Fingerprint: 8c:f4:27:fd:79:0c:3a:d1:66:06:8d:e8:1e:57:ef:bb:93:22:72:d4\r\n# SHA256 Fingerprint: 43:df:57:74:b0:3e:7f:ef:5f:e4:0d:93:1a:7b:ed:f1:bb:2e:6b:42:73:8c:4e:6d:38:41:10:3d:3a:a7:f3:39\r\n-----BEGIN CERTIFICATE-----\r\nMIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC\r\nVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50\r\ncnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs\r\nIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz\r\ndCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy\r\nNTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu\r\ndHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt\r\ndGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0\r\naG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj\r\nYXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\r\nAoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T\r\nRU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN\r\ncCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW\r\nwcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1\r\nU1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0\r\njaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP\r\nBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN\r\nBgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/\r\njTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ\r\nRkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v\r\n1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R\r\nnAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH\r\nVHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only\r\n# Subject: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only\r\n# Label: "Entrust Root Certification Authority - EC1"\r\n# Serial: 51543124481930649114116133369\r\n# MD5 Fingerprint: b6:7e:1d:f0:58:c5:49:6c:24:3b:3d:ed:98:18:ed:bc\r\n# SHA1 Fingerprint: 20:d8:06:40:df:9b:25:f5:12:25:3a:11:ea:f7:59:8a:eb:14:b5:47\r\n# SHA256 Fingerprint: 02:ed:0e:b2:8c:14:da:45:16:5c:56:67:91:70:0d:64:51:d7:fb:56:f0:b2:ab:1d:3b:8e:b0:70:e5:6e:df:f5\r\n-----BEGIN CERTIFICATE-----\r\nMIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG\r\nA1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3\r\nd3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu\r\ndHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq\r\nRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy\r\nMTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD\r\nVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0\r\nL2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g\r\nZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD\r\nZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi\r\nA2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt\r\nByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH\r\nBz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O\r\nBBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC\r\nR98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX\r\nhTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=CFCA EV ROOT O=China Financial Certification Authority\r\n# Subject: CN=CFCA EV ROOT O=China Financial Certification Authority\r\n# Label: "CFCA EV ROOT"\r\n# Serial: 407555286\r\n# MD5 Fingerprint: 74:e1:b6:ed:26:7a:7a:44:30:33:94:ab:7b:27:81:30\r\n# SHA1 Fingerprint: e2:b8:29:4b:55:84:ab:6b:58:c2:90:46:6c:ac:3f:b8:39:8f:84:83\r\n# SHA256 Fingerprint: 5c:c3:d7:8e:4e:1d:5e:45:54:7a:04:e6:87:3e:64:f9:0c:f9:53:6d:1c:cc:2e:f8:00:f3:55:c4:c5:fd:70:fd\r\n-----BEGIN CERTIFICATE-----\r\nMIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD\r\nTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y\r\naXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx\r\nMjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j\r\naWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP\r\nT1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03\r\nsQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL\r\nTIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5\r\n/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp\r\n7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz\r\nEpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt\r\nhxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP\r\na931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot\r\naK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg\r\nTnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV\r\nPKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv\r\ncWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL\r\ntbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd\r\nBgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB\r\nACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT\r\nej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL\r\njOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS\r\nESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy\r\nP5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19\r\nxIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d\r\nCi77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN\r\n5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe\r\n/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z\r\nAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ\r\n5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed\r\n# Subject: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed\r\n# Label: "OISTE WISeKey Global Root GB CA"\r\n# Serial: 157768595616588414422159278966750757568\r\n# MD5 Fingerprint: a4:eb:b9:61:28:2e:b7:2f:98:b0:35:26:90:99:51:1d\r\n# SHA1 Fingerprint: 0f:f9:40:76:18:d3:d7:6a:4b:98:f0:a8:35:9e:0c:fd:27:ac:cc:ed\r\n# SHA256 Fingerprint: 6b:9c:08:e8:6e:b0:f7:67:cf:ad:65:cd:98:b6:21:49:e5:49:4a:67:f5:84:5e:7b:d1:ed:01:9f:27:b8:6b:d6\r\n-----BEGIN CERTIFICATE-----\r\nMIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt\r\nMQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg\r\nRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i\r\nYWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x\r\nCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG\r\nb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh\r\nbCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3\r\nHEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx\r\nWuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX\r\n1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk\r\nu7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P\r\n99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r\r\nM2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw\r\nAwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB\r\nBAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh\r\ncViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5\r\ngSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO\r\nZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf\r\naPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic\r\nNc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A.\r\n# Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A.\r\n# Label: "SZAFIR ROOT CA2"\r\n# Serial: 357043034767186914217277344587386743377558296292\r\n# MD5 Fingerprint: 11:64:c1:89:b0:24:b1:8c:b1:07:7e:89:9e:51:9e:99\r\n# SHA1 Fingerprint: e2:52:fa:95:3f:ed:db:24:60:bd:6e:28:f3:9c:cc:cf:5e:b3:3f:de\r\n# SHA256 Fingerprint: a1:33:9d:33:28:1a:0b:56:e5:57:d3:d3:2b:1c:e7:f9:36:7e:b0:94:bd:5f:a7:2a:7e:50:04:c8:de:d7:ca:fe\r\n-----BEGIN CERTIFICATE-----\r\nMIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL\r\nBQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6\r\nZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw\r\nNzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L\r\ncmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg\r\nUk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN\r\nQLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT\r\n3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw\r\n3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6\r\n3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5\r\nBSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN\r\nXGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD\r\nAgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF\r\nAAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw\r\n8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG\r\nnXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP\r\noky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy\r\nd05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg\r\nLvWpCz/UXeHPhJ/iGcJfitYgHuNztw==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority\r\n# Subject: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority\r\n# Label: "Certum Trusted Network CA 2"\r\n# Serial: 44979900017204383099463764357512596969\r\n# MD5 Fingerprint: 6d:46:9e:d9:25:6d:08:23:5b:5e:74:7d:1e:27:db:f2\r\n# SHA1 Fingerprint: d3:dd:48:3e:2b:bf:4c:05:e8:af:10:f5:fa:76:26:cf:d3:dc:30:92\r\n# SHA256 Fingerprint: b6:76:f2:ed:da:e8:77:5c:d3:6c:b0:f6:3c:d1:d4:60:39:61:f4:9e:62:65:ba:01:3a:2f:03:07:b6:d0:b8:04\r\n-----BEGIN CERTIFICATE-----\r\nMIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB\r\ngDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu\r\nQS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG\r\nA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz\r\nOTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ\r\nVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp\r\nZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3\r\nb3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA\r\nDGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn\r\n0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB\r\nOJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE\r\nfktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E\r\nSv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m\r\no130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i\r\nsx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW\r\nOZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez\r\nTv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS\r\nadgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n\r\n3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD\r\nAQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC\r\nAQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ\r\nF/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf\r\nCVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29\r\nXN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm\r\ndjWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/\r\nWjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb\r\nAoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq\r\nP/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko\r\nb7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj\r\nXALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P\r\n5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi\r\nDrW5viSP\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority\r\n# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority\r\n# Label: "Hellenic Academic and Research Institutions RootCA 2015"\r\n# Serial: 0\r\n# MD5 Fingerprint: ca:ff:e2:db:03:d9:cb:4b:e9:0f:ad:84:fd:7b:18:ce\r\n# SHA1 Fingerprint: 01:0c:06:95:a6:98:19:14:ff:bf:5f:c6:b0:b6:95:ea:29:e9:12:a6\r\n# SHA256 Fingerprint: a0:40:92:9a:02:ce:53:b4:ac:f4:f2:ff:c6:98:1c:e4:49:6f:75:5e:6d:45:fe:0b:2a:69:2b:cd:52:52:3f:36\r\n-----BEGIN CERTIFICATE-----\r\nMIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix\r\nDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k\r\nIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT\r\nN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v\r\ndENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG\r\nA1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh\r\nZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx\r\nQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1\r\ndGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC\r\nAQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA\r\n4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0\r\nAoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10\r\n4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C\r\nojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV\r\n9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD\r\ngfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6\r\nY5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq\r\nNhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko\r\nLfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc\r\nBw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV\r\nHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd\r\nctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I\r\nXtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI\r\nM4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot\r\n9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V\r\nZ5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea\r\nj8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh\r\nX9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ\r\nl033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf\r\nbzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4\r\npcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK\r\ne7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0\r\nvm9qp/UsQu0yrbYhnr68\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority\r\n# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority\r\n# Label: "Hellenic Academic and Research Institutions ECC RootCA 2015"\r\n# Serial: 0\r\n# MD5 Fingerprint: 81:e5:b4:17:eb:c2:f5:e1:4b:0d:41:7b:49:92:fe:ef\r\n# SHA1 Fingerprint: 9f:f1:71:8d:92:d5:9a:f3:7d:74:97:b4:bc:6f:84:68:0b:ba:b6:66\r\n# SHA256 Fingerprint: 44:b5:45:aa:8a:25:e6:5a:73:ca:15:dc:27:fc:36:d2:4c:1c:b9:95:3a:06:65:39:b1:15:82:dc:48:7b:48:33\r\n-----BEGIN CERTIFICATE-----\r\nMIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN\r\nBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl\r\nc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl\r\nbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv\r\nb3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ\r\nBgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj\r\nYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5\r\nMUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0\r\ndXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg\r\nQehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa\r\njq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC\r\nMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi\r\nC4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep\r\nlSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof\r\nTUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=ISRG Root X1 O=Internet Security Research Group\r\n# Subject: CN=ISRG Root X1 O=Internet Security Research Group\r\n# Label: "ISRG Root X1"\r\n# Serial: 172886928669790476064670243504169061120\r\n# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e\r\n# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8\r\n# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6\r\n-----BEGIN CERTIFICATE-----\r\nMIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw\r\nTzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh\r\ncmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4\r\nWhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu\r\nZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY\r\nMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc\r\nh77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+\r\n0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U\r\nA5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW\r\nT8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH\r\nB5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC\r\nB5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv\r\nKBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn\r\nOlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn\r\njh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw\r\nqHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI\r\nrU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV\r\nHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq\r\nhkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL\r\nubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ\r\n3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK\r\nNFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5\r\nORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur\r\nTkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC\r\njNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc\r\noyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq\r\n4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA\r\nmRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d\r\nemyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: O=FNMT-RCM OU=AC RAIZ FNMT-RCM\r\n# Subject: O=FNMT-RCM OU=AC RAIZ FNMT-RCM\r\n# Label: "AC RAIZ FNMT-RCM"\r\n# Serial: 485876308206448804701554682760554759\r\n# MD5 Fingerprint: e2:09:04:b4:d3:bd:d1:a0:14:fd:1a:d2:47:c4:57:1d\r\n# SHA1 Fingerprint: ec:50:35:07:b2:15:c4:95:62:19:e2:a8:9a:5b:42:99:2c:4c:2c:20\r\n# SHA256 Fingerprint: eb:c5:57:0c:29:01:8c:4d:67:b1:aa:12:7b:af:12:f7:03:b4:61:1e:bc:17:b7:da:b5:57:38:94:17:9b:93:fa\r\n-----BEGIN CERTIFICATE-----\r\nMIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx\r\nCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ\r\nWiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ\r\nBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG\r\nTk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/\r\nyBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf\r\nBBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz\r\nWHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF\r\ntBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z\r\n374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC\r\nIfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL\r\nmbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7\r\nwk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS\r\nMKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2\r\nZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet\r\nUqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw\r\nAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H\r\nYJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3\r\nLmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD\r\nnFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1\r\nRXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM\r\nLVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf\r\n77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N\r\nJpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm\r\nfZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp\r\n6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp\r\n1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B\r\n9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok\r\nRqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv\r\nuu8wd+RU4riEmViAqhOLUTpPSPaLtrM=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Amazon Root CA 1 O=Amazon\r\n# Subject: CN=Amazon Root CA 1 O=Amazon\r\n# Label: "Amazon Root CA 1"\r\n# Serial: 143266978916655856878034712317230054538369994\r\n# MD5 Fingerprint: 43:c6:bf:ae:ec:fe:ad:2f:18:c6:88:68:30:fc:c8:e6\r\n# SHA1 Fingerprint: 8d:a7:f9:65:ec:5e:fc:37:91:0f:1c:6e:59:fd:c1:cc:6a:6e:de:16\r\n# SHA256 Fingerprint: 8e:cd:e6:88:4f:3d:87:b1:12:5b:a3:1a:c3:fc:b1:3d:70:16:de:7f:57:cc:90:4f:e1:cb:97:c6:ae:98:19:6e\r\n-----BEGIN CERTIFICATE-----\r\nMIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF\r\nADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\r\nb24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL\r\nMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv\r\nb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj\r\nca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM\r\n9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw\r\nIFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6\r\nVOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L\r\n93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm\r\njgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\r\nAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA\r\nA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI\r\nU5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs\r\nN+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv\r\no/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU\r\n5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy\r\nrqXRfboQnoZsG4q5WTP468SQvvG5\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Amazon Root CA 2 O=Amazon\r\n# Subject: CN=Amazon Root CA 2 O=Amazon\r\n# Label: "Amazon Root CA 2"\r\n# Serial: 143266982885963551818349160658925006970653239\r\n# MD5 Fingerprint: c8:e5:8d:ce:a8:42:e2:7a:c0:2a:5c:7c:9e:26:bf:66\r\n# SHA1 Fingerprint: 5a:8c:ef:45:d7:a6:98:59:76:7a:8c:8b:44:96:b5:78:cf:47:4b:1a\r\n# SHA256 Fingerprint: 1b:a5:b2:aa:8c:65:40:1a:82:96:01:18:f8:0b:ec:4f:62:30:4d:83:ce:c4:71:3a:19:c3:9c:01:1e:a4:6d:b4\r\n-----BEGIN CERTIFICATE-----\r\nMIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF\r\nADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\r\nb24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL\r\nMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv\r\nb3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK\r\ngXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ\r\nW0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg\r\n1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K\r\n8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r\r\n2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me\r\nz/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR\r\n8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj\r\nmUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz\r\n7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6\r\n+XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI\r\n0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB\r\nAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm\r\nUjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2\r\nLIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY\r\n+gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS\r\nk5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl\r\n7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm\r\nbtmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl\r\nurR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+\r\nfUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63\r\nn749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE\r\n76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H\r\n9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT\r\n4PsJYGw=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Amazon Root CA 3 O=Amazon\r\n# Subject: CN=Amazon Root CA 3 O=Amazon\r\n# Label: "Amazon Root CA 3"\r\n# Serial: 143266986699090766294700635381230934788665930\r\n# MD5 Fingerprint: a0:d4:ef:0b:f7:b5:d8:49:95:2a:ec:f5:c4:fc:81:87\r\n# SHA1 Fingerprint: 0d:44:dd:8c:3c:8c:1a:1a:58:75:64:81:e9:0f:2e:2a:ff:b3:d2:6e\r\n# SHA256 Fingerprint: 18:ce:6c:fe:7b:f1:4e:60:b2:e3:47:b8:df:e8:68:cb:31:d0:2e:bb:3a:da:27:15:69:f5:03:43:b4:6d:b3:a4\r\n-----BEGIN CERTIFICATE-----\r\nMIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5\r\nMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g\r\nUm9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG\r\nA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg\r\nQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl\r\nui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j\r\nQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr\r\nttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr\r\nBqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM\r\nYyRIHN8wfdVoOw==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Amazon Root CA 4 O=Amazon\r\n# Subject: CN=Amazon Root CA 4 O=Amazon\r\n# Label: "Amazon Root CA 4"\r\n# Serial: 143266989758080763974105200630763877849284878\r\n# MD5 Fingerprint: 89:bc:27:d5:eb:17:8d:06:6a:69:d5:fd:89:47:b4:cd\r\n# SHA1 Fingerprint: f6:10:84:07:d6:f8:bb:67:98:0c:c2:e2:44:c2:eb:ae:1c:ef:63:be\r\n# SHA256 Fingerprint: e3:5d:28:41:9e:d0:20:25:cf:a6:90:38:cd:62:39:62:45:8d:a5:c6:95:fb:de:a3:c2:2b:0b:fb:25:89:70:92\r\n-----BEGIN CERTIFICATE-----\r\nMIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5\r\nMQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g\r\nUm9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG\r\nA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg\r\nQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi\r\n9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk\r\nM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB\r\n/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB\r\nMAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw\r\nCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW\r\n1KyLa2tJElMzrdfkviT8tQp21KW8EA==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM\r\n# Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM\r\n# Label: "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1"\r\n# Serial: 1\r\n# MD5 Fingerprint: dc:00:81:dc:69:2f:3e:2f:b0:3b:f6:3d:5a:91:8e:49\r\n# SHA1 Fingerprint: 31:43:64:9b:ec:ce:27:ec:ed:3a:3f:0b:8f:0d:e4:e8:91:dd:ee:ca\r\n# SHA256 Fingerprint: 46:ed:c3:68:90:46:d5:3a:45:3f:b3:10:4a:b8:0d:ca:ec:65:8b:26:60:ea:16:29:dd:7e:86:79:90:64:87:16\r\n-----BEGIN CERTIFICATE-----\r\nMIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx\r\nGDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp\r\nbXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w\r\nKwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0\r\nBgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy\r\ndW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG\r\nEwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll\r\nIEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU\r\nQUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT\r\nTTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg\r\nLSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7\r\na9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr\r\nLqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr\r\nN3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X\r\nYacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/\r\niSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f\r\nAJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH\r\nV8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL\r\nBQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh\r\nAHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf\r\nIPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4\r\nlzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c\r\n8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf\r\nlo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD.\r\n# Subject: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD.\r\n# Label: "GDCA TrustAUTH R5 ROOT"\r\n# Serial: 9009899650740120186\r\n# MD5 Fingerprint: 63:cc:d9:3d:34:35:5c:6f:53:a3:e2:08:70:48:1f:b4\r\n# SHA1 Fingerprint: 0f:36:38:5b:81:1a:25:c3:9b:31:4e:83:ca:e9:34:66:70:cc:74:b4\r\n# SHA256 Fingerprint: bf:ff:8f:d0:44:33:48:7d:6a:8a:a6:0c:1a:29:76:7a:9f:c2:bb:b0:5e:42:0f:71:3a:13:b9:92:89:1d:38:93\r\n-----BEGIN CERTIFICATE-----\r\nMIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE\r\nBhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ\r\nIENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0\r\nMTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV\r\nBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w\r\nHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF\r\nAAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj\r\nDp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj\r\nTnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u\r\nKU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj\r\nqcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm\r\nMUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12\r\nZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP\r\nzgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk\r\nL30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC\r\njGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA\r\nHQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC\r\nAwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB\r\n/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg\r\np8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm\r\nDRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5\r\nCOmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry\r\nL3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf\r\nJWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg\r\nIHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io\r\n2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV\r\n09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ\r\nXR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq\r\nT8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe\r\nMTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority\r\n# Subject: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority\r\n# Label: "TrustCor RootCert CA-1"\r\n# Serial: 15752444095811006489\r\n# MD5 Fingerprint: 6e:85:f1:dc:1a:00:d3:22:d5:b2:b2:ac:6b:37:05:45\r\n# SHA1 Fingerprint: ff:bd:cd:e7:82:c8:43:5e:3c:6f:26:86:5c:ca:a8:3a:45:5b:c3:0a\r\n# SHA256 Fingerprint: d4:0e:9c:86:cd:8f:e4:68:c1:77:69:59:f4:9e:a7:74:fa:54:86:84:b6:c4:06:f3:90:92:61:f4:dc:e2:57:5c\r\n-----BEGIN CERTIFICATE-----\r\nMIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYD\r\nVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk\r\nMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U\r\ncnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29y\r\nIFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkxMjMxMTcyMzE2WjCB\r\npDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFuYW1h\r\nIENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUG\r\nA1UECwweVHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZU\r\ncnVzdENvciBSb290Q2VydCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\r\nCgKCAQEAv463leLCJhJrMxnHQFgKq1mqjQCj/IDHUHuO1CAmujIS2CNUSSUQIpid\r\nRtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4pQa81QBeCQryJ3pS/C3V\r\nseq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0JEsq1pme\r\n9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CV\r\nEY4hgLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorW\r\nhnAbJN7+KIor0Gqw/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/\r\nDeOxCbeKyKsZn3MzUOcwHwYDVR0jBBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcw\r\nDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD\r\nggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5mDo4Nvu7Zp5I\r\n/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf\r\nke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZ\r\nyonnMlo2HD6CqFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djts\r\nL1Ac59v2Z3kf9YKVmgenFK+P3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdN\r\nzl/HHk484IkzlQsPpTLWPFp5LBk=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority\r\n# Subject: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority\r\n# Label: "TrustCor RootCert CA-2"\r\n# Serial: 2711694510199101698\r\n# MD5 Fingerprint: a2:e1:f8:18:0b:ba:45:d5:c7:41:2a:bb:37:52:45:64\r\n# SHA1 Fingerprint: b8:be:6d:cb:56:f1:55:b9:63:d4:12:ca:4e:06:34:c7:94:b2:1c:c0\r\n# SHA256 Fingerprint: 07:53:e9:40:37:8c:1b:d5:e3:83:6e:39:5d:ae:a5:cb:83:9e:50:46:f1:bd:0e:ae:19:51:cf:10:fe:c7:c9:65\r\n-----BEGIN CERTIFICATE-----\r\nMIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNV\r\nBAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw\r\nIgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy\r\ndXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEfMB0GA1UEAwwWVHJ1c3RDb3Ig\r\nUm9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEyMzExNzI2MzlaMIGk\r\nMQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEg\r\nQ2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYD\r\nVQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRy\r\ndXN0Q29yIFJvb3RDZXJ0IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK\r\nAoICAQCnIG7CKqJiJJWQdsg4foDSq8GbZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+\r\nQVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9NkRvRUqdw6VC0xK5mC8tkq\r\n1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1oYxOdqHp\r\n2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nK\r\nDOObXUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hape\r\naz6LMvYHL1cEksr1/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF\r\n3wP+TfSvPd9cW436cOGlfifHhi5qjxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88\r\noWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQPeSghYA2FFn3XVDjxklb9tTNM\r\ng9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+CtgrKAmrhQhJ8Z3\r\nmjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh\r\n8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAd\r\nBgNVHQ4EFgQU2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6U\r\nnrybPZx9mCAZ5YwwYrIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw\r\nDQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/hOsh80QA9z+LqBrWyOrsGS2h60COX\r\ndKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnpkpfbsEZC89NiqpX+\r\nMWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv2wnL\r\n/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RX\r\nCI/hOWB3S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYa\r\nZH9bDTMJBzN7Bj8RpFxwPIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW\r\n2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dvDDqPys/cA8GiCcjl/YBeyGBCARsaU1q7\r\nN6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYURpFHmygk71dSTlxCnKr3\r\nSewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANExdqtvArB\r\nAs8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp\r\n5KeXRKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu\r\n1uwJ\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority\r\n# Subject: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority\r\n# Label: "TrustCor ECA-1"\r\n# Serial: 9548242946988625984\r\n# MD5 Fingerprint: 27:92:23:1d:0a:f5:40:7c:e9:e6:6b:9d:d8:f5:e7:6c\r\n# SHA1 Fingerprint: 58:d1:df:95:95:67:6b:63:c0:f0:5b:1c:17:4d:8b:84:0b:c8:78:bd\r\n# SHA256 Fingerprint: 5a:88:5d:b1:9c:01:d9:12:c5:75:93:88:93:8c:af:bb:df:03:1a:b2:d4:8e:91:ee:15:58:9b:42:97:1d:03:9c\r\n-----BEGIN CERTIFICATE-----\r\nMIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD\r\nVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk\r\nMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U\r\ncnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFzAVBgNVBAMMDlRydXN0Q29y\r\nIEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3MjgwN1owgZwxCzAJBgNV\r\nBAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw\r\nIgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy\r\ndXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3Ig\r\nRUNBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb\r\n3w9U73NjKYKtR8aja+3+XzP4Q1HpGjORMRegdMTUpwHmspI+ap3tDvl0mEDTPwOA\r\nBoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23xFUfJ3zSCNV2HykVh0A5\r\n3ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmcp0yJF4Ou\r\nowReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/\r\nwZ0+fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZF\r\nZtS6mFjBAgMBAAGjYzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAf\r\nBgNVHSMEGDAWgBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/\r\nMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEABT41XBVwm8nHc2Fv\r\ncivUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u/ukZMjgDfxT2\r\nAHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F\r\nhcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50\r\nsoIipX1TH0XsJ5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BI\r\nWJZpTdwHjFGTot+fDz2LYLSCjaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1Wi\r\ntJ/X5g==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=SSL.com Root Certification Authority RSA O=SSL Corporation\r\n# Subject: CN=SSL.com Root Certification Authority RSA O=SSL Corporation\r\n# Label: "SSL.com Root Certification Authority RSA"\r\n# Serial: 8875640296558310041\r\n# MD5 Fingerprint: 86:69:12:c0:70:f1:ec:ac:ac:c2:d5:bc:a5:5b:a1:29\r\n# SHA1 Fingerprint: b7:ab:33:08:d1:ea:44:77:ba:14:80:12:5a:6f:bd:a9:36:49:0c:bb\r\n# SHA256 Fingerprint: 85:66:6a:56:2e:e0:be:5c:e9:25:c1:d8:89:0a:6f:76:a8:7e:c1:6d:4d:7d:5f:29:ea:74:19:cf:20:12:3b:69\r\n-----BEGIN CERTIFICATE-----\r\nMIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE\r\nBhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK\r\nDA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp\r\nY2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz\r\nOTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv\r\ndXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv\r\nbSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN\r\nAQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R\r\nxFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX\r\nqhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC\r\nC52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3\r\n6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh\r\n/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF\r\nYD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E\r\nJNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc\r\nUS4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8\r\nZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm\r\n+Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi\r\nM+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV\r\nHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G\r\nA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV\r\ncpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc\r\nHadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs\r\nPgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/\r\nq5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0\r\ncuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr\r\na6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I\r\nH37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y\r\nK9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu\r\nnLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf\r\noYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY\r\nIc2wBlX7Jz9TkHCpBB5XJ7k=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=SSL.com Root Certification Authority ECC O=SSL Corporation\r\n# Subject: CN=SSL.com Root Certification Authority ECC O=SSL Corporation\r\n# Label: "SSL.com Root Certification Authority ECC"\r\n# Serial: 8495723813297216424\r\n# MD5 Fingerprint: 2e:da:e4:39:7f:9c:8f:37:d1:70:9f:26:17:51:3a:8e\r\n# SHA1 Fingerprint: c3:19:7c:39:24:e6:54:af:1b:c4:ab:20:95:7a:e2:c3:0e:13:02:6a\r\n# SHA256 Fingerprint: 34:17:bb:06:cc:60:07:da:1b:96:1c:92:0b:8a:b4:ce:3f:ad:82:0e:4a:a3:0b:9a:cb:c4:a7:4e:bd:ce:bc:65\r\n-----BEGIN CERTIFICATE-----\r\nMIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC\r\nVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T\r\nU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0\r\naW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz\r\nWjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0\r\nb24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS\r\nb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB\r\nBAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI\r\n7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg\r\nCemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud\r\nEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD\r\nVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T\r\nkdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+\r\ngA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation\r\n# Subject: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation\r\n# Label: "SSL.com EV Root Certification Authority RSA R2"\r\n# Serial: 6248227494352943350\r\n# MD5 Fingerprint: e1:1e:31:58:1a:ae:54:53:02:f6:17:6a:11:7b:4d:95\r\n# SHA1 Fingerprint: 74:3a:f0:52:9b:d0:32:a0:f4:4a:83:cd:d4:ba:a9:7b:7c:2e:c4:9a\r\n# SHA256 Fingerprint: 2e:7b:f1:6c:c2:24:85:a7:bb:e2:aa:86:96:75:07:61:b0:ae:39:be:3b:2f:e9:d0:cc:6d:4e:f7:34:91:42:5c\r\n-----BEGIN CERTIFICATE-----\r\nMIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV\r\nBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE\r\nCgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy\r\ndGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy\r\nMDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G\r\nA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD\r\nDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy\r\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq\r\nM0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf\r\nOePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa\r\n4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9\r\nHSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR\r\naZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA\r\nb9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ\r\nGp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV\r\nPWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO\r\npgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu\r\nUDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY\r\nMBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV\r\nHSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4\r\n9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW\r\ns47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5\r\nSm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg\r\ncLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM\r\n79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz\r\n/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt\r\nll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm\r\nKf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK\r\nQbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ\r\nw/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi\r\nS9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07\r\nmKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation\r\n# Subject: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation\r\n# Label: "SSL.com EV Root Certification Authority ECC"\r\n# Serial: 3182246526754555285\r\n# MD5 Fingerprint: 59:53:22:65:83:42:01:54:c0:ce:42:b9:5a:7c:f2:90\r\n# SHA1 Fingerprint: 4c:dd:51:a3:d1:f5:20:32:14:b0:c6:c5:32:23:03:91:c7:46:42:6d\r\n# SHA256 Fingerprint: 22:a2:c1:f7:bd:ed:70:4c:c1:e7:01:b5:f4:08:c3:10:88:0f:e9:56:b5:de:2a:4a:44:f9:9c:87:3a:25:a7:c8\r\n-----BEGIN CERTIFICATE-----\r\nMIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC\r\nVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T\r\nU0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp\r\nY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx\r\nNTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv\r\ndXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv\r\nbSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49\r\nAgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA\r\nVIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku\r\nWnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP\r\nMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX\r\n5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ\r\nytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg\r\nh5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6\r\n# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6\r\n# Label: "GlobalSign Root CA - R6"\r\n# Serial: 1417766617973444989252670301619537\r\n# MD5 Fingerprint: 4f:dd:07:e4:d4:22:64:39:1e:0c:37:42:ea:d1:c6:ae\r\n# SHA1 Fingerprint: 80:94:64:0e:b5:a7:a1:ca:11:9c:1f:dd:d5:9f:81:02:63:a7:fb:d1\r\n# SHA256 Fingerprint: 2c:ab:ea:fe:37:d0:6c:a2:2a:ba:73:91:c0:03:3d:25:98:29:52:c4:53:64:73:49:76:3a:3a:b5:ad:6c:cf:69\r\n-----BEGIN CERTIFICATE-----\r\nMIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg\r\nMB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh\r\nbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx\r\nMjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET\r\nMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI\r\nxutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k\r\nZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD\r\naNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw\r\nLnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw\r\n1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX\r\nk7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2\r\nSXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h\r\nbguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n\r\nWUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY\r\nrZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce\r\nMgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD\r\nAQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu\r\nbAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN\r\nnsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt\r\nIxg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61\r\n55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj\r\nvUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf\r\ncDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz\r\noHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp\r\nnOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs\r\npA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v\r\nJJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R\r\n8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4\r\n5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed\r\n# Subject: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed\r\n# Label: "OISTE WISeKey Global Root GC CA"\r\n# Serial: 44084345621038548146064804565436152554\r\n# MD5 Fingerprint: a9:d6:b9:2d:2f:93:64:f8:a5:69:ca:91:e9:68:07:23\r\n# SHA1 Fingerprint: e0:11:84:5e:34:de:be:88:81:b9:9c:f6:16:26:d1:96:1f:c3:b9:31\r\n# SHA256 Fingerprint: 85:60:f9:1c:36:24:da:ba:95:70:b5:fe:a0:db:e3:6f:f1:1a:83:23:be:94:86:85:4f:b3:f3:4a:55:71:19:8d\r\n-----BEGIN CERTIFICATE-----\r\nMIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw\r\nCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91\r\nbmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg\r\nUm9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ\r\nBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu\r\nZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS\r\nb290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni\r\neUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W\r\np2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E\r\nBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T\r\nrYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV\r\n57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg\r\nMgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=GTS Root R1 O=Google Trust Services LLC\r\n# Subject: CN=GTS Root R1 O=Google Trust Services LLC\r\n# Label: "GTS Root R1"\r\n# Serial: 146587175971765017618439757810265552097\r\n# MD5 Fingerprint: 82:1a:ef:d4:d2:4a:f2:9f:e2:3d:97:06:14:70:72:85\r\n# SHA1 Fingerprint: e1:c9:50:e6:ef:22:f8:4c:56:45:72:8b:92:20:60:d7:d5:a7:a3:e8\r\n# SHA256 Fingerprint: 2a:57:54:71:e3:13:40:bc:21:58:1c:bd:2c:f1:3e:15:84:63:20:3e:ce:94:bc:f9:d3:cc:19:6b:f0:9a:54:72\r\n-----BEGIN CERTIFICATE-----\r\nMIIFWjCCA0KgAwIBAgIQbkepxUtHDA3sM9CJuRz04TANBgkqhkiG9w0BAQwFADBH\r\nMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM\r\nQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy\r\nMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl\r\ncnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEB\r\nAQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM\r\nf/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vX\r\nmX7wCl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7\r\nzUjwTcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0P\r\nfyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtc\r\nvfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4\r\nZor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUsp\r\nzBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOO\r\nRc92wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYW\r\nk70paDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+\r\nDVrNVjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgF\r\nlQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV\r\nHQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBADiW\r\nCu49tJYeX++dnAsznyvgyv3SjgofQXSlfKqE1OXyHuY3UjKcC9FhHb8owbZEKTV1\r\nd5iyfNm9dKyKaOOpMQkpAWBz40d8U6iQSifvS9efk+eCNs6aaAyC58/UEBZvXw6Z\r\nXPYfcX3v73svfuo21pdwCxXu11xWajOl40k4DLh9+42FpLFZXvRq4d2h9mREruZR\r\ngyFmxhE+885H7pwoHyXa/6xmld01D1zvICxi/ZG6qcz8WpyTgYMpl0p8WnK0OdC3\r\nd8t5/Wk6kjftbjhlRn7pYL15iJdfOBL07q9bgsiG1eGZbYwE8na6SfZu6W0eX6Dv\r\nJ4J2QPim01hcDyxC2kLGe4g0x8HYRZvBPsVhHdljUEn2NIVq4BjFbkerQUIpm/Zg\r\nDdIx02OYI5NaAIFItO/Nis3Jz5nu2Z6qNuFoS3FJFDYoOj0dzpqPJeaAcWErtXvM\r\n+SUWgeExX6GjfhaknBZqlxi9dnKlC54dNuYvoS++cJEPqOba+MSSQGwlfnuzCdyy\r\nF62ARPBopY+Udf90WuioAnwMCeKpSwughQtiue+hMZL77/ZRBIls6Kl0obsXs7X9\r\nSQ98POyDGCBDTtWTurQ0sR8WNh8M5mQ5Fkzc4P4dyKliPUDqysU0ArSuiYgzNdws\r\nE3PYJ/HQcu51OyLemGhmW/HGY0dVHLqlCFF1pkgl\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=GTS Root R2 O=Google Trust Services LLC\r\n# Subject: CN=GTS Root R2 O=Google Trust Services LLC\r\n# Label: "GTS Root R2"\r\n# Serial: 146587176055767053814479386953112547951\r\n# MD5 Fingerprint: 44:ed:9a:0e:a4:09:3b:00:f2:ae:4c:a3:c6:61:b0:8b\r\n# SHA1 Fingerprint: d2:73:96:2a:2a:5e:39:9f:73:3f:e1:c7:1e:64:3f:03:38:34:fc:4d\r\n# SHA256 Fingerprint: c4:5d:7b:b0:8e:6d:67:e6:2e:42:35:11:0b:56:4e:5f:78:fd:92:ef:05:8c:84:0a:ea:4e:64:55:d7:58:5c:60\r\n-----BEGIN CERTIFICATE-----\r\nMIIFWjCCA0KgAwIBAgIQbkepxlqz5yDFMJo/aFLybzANBgkqhkiG9w0BAQwFADBH\r\nMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM\r\nQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIy\r\nMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNl\r\ncnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEB\r\nAQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv\r\nCvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3Kg\r\nGjSY6Dlo7JUle3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9Bu\r\nXvAuMC6C/Pq8tBcKSOWIm8Wba96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOd\r\nre7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS+LFjKBC4swm4VndAoiaYecb+3yXu\r\nPuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7MkogwTZq9TwtImoS1\r\nmKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJGr61K\r\n8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqj\r\nx5RWIr9qS34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsR\r\nnTKaG73VululycslaVNVJ1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0\r\nkzCqgc7dGtxRcw1PcOnlthYhGXmy5okLdWTK1au8CcEYof/UVKGFPP0UJAOyh9Ok\r\ntwIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV\r\nHQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQADggIBALZp\r\n8KZ3/p7uC4Gt4cCpx/k1HUCCq+YEtN/L9x0Pg/B+E02NjO7jMyLDOfxA325BS0JT\r\nvhaI8dI4XsRomRyYUpOM52jtG2pzegVATX9lO9ZY8c6DR2Dj/5epnGB3GFW1fgiT\r\nz9D2PGcDFWEJ+YF59exTpJ/JjwGLc8R3dtyDovUMSRqodt6Sm2T4syzFJ9MHwAiA\r\npJiS4wGWAqoC7o87xdFtCjMwc3i5T1QWvwsHoaRc5svJXISPD+AVdyx+Jn7axEvb\r\npxZ3B7DNdehyQtaVhJ2Gg/LkkM0JR9SLA3DaWsYDQvTtN6LwG1BUSw7YhN4ZKJmB\r\nR64JGz9I0cNv4rBgF/XuIwKl2gBbbZCr7qLpGzvpx0QnRY5rn/WkhLx3+WuXrD5R\r\nRaIRpsyF7gpo8j5QOHokYh4XIDdtak23CZvJ/KRY9bb7nE4Yu5UC56GtmwfuNmsk\r\n0jmGwZODUNKBRqhfYlcsu2xkiAhu7xNUX90txGdj08+JN7+dIPT7eoOboB6BAFDC\r\n5AwiWVIQ7UNWhwD4FFKnHYuTjKJNRn8nxnGbJN7k2oaLDX5rIMHAnuFl2GqjpuiF\r\nizoHCBy69Y9Vmhh1fuXsgWbRIXOhNUQLgD1bnF5vKheW0YMjiGZt5obicDIvUiLn\r\nyOd/xCxgXS/Dr55FBcOEArf9LAhST4Ldo/DUhgkC\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=GTS Root R3 O=Google Trust Services LLC\r\n# Subject: CN=GTS Root R3 O=Google Trust Services LLC\r\n# Label: "GTS Root R3"\r\n# Serial: 146587176140553309517047991083707763997\r\n# MD5 Fingerprint: 1a:79:5b:6b:04:52:9c:5d:c7:74:33:1b:25:9a:f9:25\r\n# SHA1 Fingerprint: 30:d4:24:6f:07:ff:db:91:89:8a:0b:e9:49:66:11:eb:8c:5e:46:e5\r\n# SHA256 Fingerprint: 15:d5:b8:77:46:19:ea:7d:54:ce:1c:a6:d0:b0:c4:03:e0:37:a9:17:f1:31:e8:a0:4e:1e:6b:7a:71:ba:bc:e5\r\n-----BEGIN CERTIFICATE-----\r\nMIICDDCCAZGgAwIBAgIQbkepx2ypcyRAiQ8DVd2NHTAKBggqhkjOPQQDAzBHMQsw\r\nCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU\r\nMBIGA1UEAxMLR1RTIFJvb3QgUjMwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw\r\nMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp\r\nY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjOPQIBBgUrgQQA\r\nIgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout\r\n736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2A\r\nDDL24CejQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud\r\nDgQWBBTB8Sa6oC2uhYHP0/EqEr24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEAgFuk\r\nfCPAlaUs3L6JbyO5o91lAFJekazInXJ0glMLfalAvWhgxeG4VDvBNhcl2MG9AjEA\r\nnjWSdIUlUfUk7GRSJFClH9voy8l27OyCbvWFGFPouOOaKaqW04MjyaR7YbPMAuhd\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=GTS Root R4 O=Google Trust Services LLC\r\n# Subject: CN=GTS Root R4 O=Google Trust Services LLC\r\n# Label: "GTS Root R4"\r\n# Serial: 146587176229350439916519468929765261721\r\n# MD5 Fingerprint: 5d:b6:6a:c4:60:17:24:6a:1a:99:a8:4b:ee:5e:b4:26\r\n# SHA1 Fingerprint: 2a:1d:60:27:d9:4a:b1:0a:1c:4d:91:5c:cd:33:a0:cb:3e:2d:54:cb\r\n# SHA256 Fingerprint: 71:cc:a5:39:1f:9e:79:4b:04:80:25:30:b3:63:e1:21:da:8a:30:43:bb:26:66:2f:ea:4d:ca:7f:c9:51:a4:bd\r\n-----BEGIN CERTIFICATE-----\r\nMIICCjCCAZGgAwIBAgIQbkepyIuUtui7OyrYorLBmTAKBggqhkjOPQQDAzBHMQsw\r\nCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU\r\nMBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw\r\nMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp\r\nY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQA\r\nIgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu\r\nhXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/l\r\nxKvRHYqjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud\r\nDgQWBBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNnADBkAjBqUFJ0\r\nCMRw3J5QdCHojXohw0+WbhXRIjVhLfoIN+4Zba3bssx9BzT1YBkstTTZbyACMANx\r\nsbqjYAuG7ZoIapVon+Kz4ZNkfF6Tpt95LY2F45TPI11xzPKwTdb+mciUqXWi4w==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=UCA Global G2 Root O=UniTrust\r\n# Subject: CN=UCA Global G2 Root O=UniTrust\r\n# Label: "UCA Global G2 Root"\r\n# Serial: 124779693093741543919145257850076631279\r\n# MD5 Fingerprint: 80:fe:f0:c4:4a:f0:5c:62:32:9f:1c:ba:78:a9:50:f8\r\n# SHA1 Fingerprint: 28:f9:78:16:19:7a:ff:18:25:18:aa:44:fe:c1:a0:ce:5c:b6:4c:8a\r\n# SHA256 Fingerprint: 9b:ea:11:c9:76:fe:01:47:64:c1:be:56:a6:f9:14:b5:a5:60:31:7a:bd:99:88:39:33:82:e5:16:1a:a0:49:3c\r\n-----BEGIN CERTIFICATE-----\r\nMIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9\r\nMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBH\r\nbG9iYWwgRzIgUm9vdDAeFw0xNjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0x\r\nCzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlUcnVzdDEbMBkGA1UEAwwSVUNBIEds\r\nb2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxeYr\r\nb3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmToni9\r\nkmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzm\r\nVHqUwCoV8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/R\r\nVogvGjqNO7uCEeBHANBSh6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDc\r\nC/Vkw85DvG1xudLeJ1uK6NjGruFZfc8oLTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIj\r\ntm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/R+zvWr9LesGtOxdQXGLY\r\nD0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBeKW4bHAyv\r\nj5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6Dl\r\nNaBa4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6\r\niIis7nCs+dwp4wwcOxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznP\r\nO6Q0ibd5Ei9Hxeepl2n8pndntd978XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/\r\nBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFIHEjMz15DD/pQwIX4wV\r\nZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo5sOASD0Ee/oj\r\nL3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5\r\n1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl\r\n1qnN3e92mI0ADs0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oU\r\nb3n09tDh05S60FdRvScFDcH9yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LV\r\nPtateJLbXDzz2K36uGt/xDYotgIVilQsnLAXc47QN6MUPJiVAAwpBVueSUmxX8fj\r\ny88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHojhJi6IjMtX9Gl8Cb\r\nEGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZkbxqg\r\nDMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI\r\n+Vg7RE+xygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGy\r\nYiGqhkCyLmTTX8jjfhFnRR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bX\r\nUB+K+wb1whnw0A==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=UCA Extended Validation Root O=UniTrust\r\n# Subject: CN=UCA Extended Validation Root O=UniTrust\r\n# Label: "UCA Extended Validation Root"\r\n# Serial: 106100277556486529736699587978573607008\r\n# MD5 Fingerprint: a1:f3:5f:43:c6:34:9b:da:bf:8c:7e:05:53:ad:96:e2\r\n# SHA1 Fingerprint: a3:a1:b0:6f:24:61:23:4a:e3:36:a5:c2:37:fc:a6:ff:dd:f0:d7:3a\r\n# SHA256 Fingerprint: d4:3a:f9:b3:54:73:75:5c:96:84:fc:06:d7:d8:cb:70:ee:5c:28:e7:73:fb:29:4e:b4:1e:e7:17:22:92:4d:24\r\n-----BEGIN CERTIFICATE-----\r\nMIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBH\r\nMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBF\r\neHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMx\r\nMDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNV\r\nBAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIiMA0GCSqGSIb3DQEB\r\nAQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrsiWog\r\nD4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvS\r\nsPGP2KxFRv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aop\r\nO2z6+I9tTcg1367r3CTueUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dk\r\nsHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR59mzLC52LqGj3n5qiAno8geK+LLNEOfi\r\nc0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH0mK1lTnj8/FtDw5lhIpj\r\nVMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KRel7sFsLz\r\nKuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/\r\nTuDvB0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41G\r\nsx2VYVdWf6/wFlthWG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs\r\n1+lvK9JKBZP8nm9rZ/+I8U6laUpSNwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQD\r\nfwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS3H5aBZ8eNJr34RQwDwYDVR0T\r\nAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggIBADaN\r\nl8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR\r\nap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQ\r\nVBcZEhrxH9cMaVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5\r\nc6sq1WnIeJEmMX3ixzDx/BR4dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp\r\n4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb+7lsq+KePRXBOy5nAliRn+/4Qh8s\r\nt2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOWF3sGPjLtx7dCvHaj\r\n2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwiGpWO\r\nvpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2C\r\nxR9GUeOcGMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmx\r\ncmtpzyKEC2IPrNkZAJSidjzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbM\r\nfjKaiJUINlK73nZfdklJrX+9ZSCyycErdhh2n1ax\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036\r\n# Subject: CN=Certigna Root CA O=Dhimyotis OU=0002 48146308100036\r\n# Label: "Certigna Root CA"\r\n# Serial: 269714418870597844693661054334862075617\r\n# MD5 Fingerprint: 0e:5c:30:62:27:eb:5b:bc:d7:ae:62:ba:e9:d5:df:77\r\n# SHA1 Fingerprint: 2d:0d:52:14:ff:9e:ad:99:24:01:74:20:47:6e:6c:85:27:27:f5:43\r\n# SHA256 Fingerprint: d4:8d:3d:23:ee:db:50:a4:59:e5:51:97:60:1c:27:77:4b:9d:7b:18:c9:4d:5a:05:95:11:a1:02:50:b9:31:68\r\n-----BEGIN CERTIFICATE-----\r\nMIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAw\r\nWjELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAw\r\nMiA0ODE0NjMwODEwMDAzNjEZMBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0x\r\nMzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjdaMFoxCzAJBgNVBAYTAkZSMRIwEAYD\r\nVQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYzMDgxMDAwMzYxGTAX\r\nBgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw\r\nggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sO\r\nty3tRQgXstmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9M\r\nCiBtnyN6tMbaLOQdLNyzKNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPu\r\nI9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8JXrJhFwLrN1CTivngqIkicuQstDuI7pm\r\nTLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16XdG+RCYyKfHx9WzMfgIh\r\nC59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq4NYKpkDf\r\nePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3Yz\r\nIoejwpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWT\r\nCo/1VTp2lc5ZmIoJlXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1k\r\nJWumIWmbat10TWuXekG9qxf5kBdIjzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5\r\nhwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp//TBt2dzhauH8XwIDAQABo4IB\r\nGjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE\r\nFBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of\r\n1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczov\r\nL3d3d3cuY2VydGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilo\r\ndHRwOi8vY3JsLmNlcnRpZ25hLmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYr\r\naHR0cDovL2NybC5kaGlteW90aXMuY29tL2NlcnRpZ25hcm9vdGNhLmNybDANBgkq\r\nhkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOItOoldaDgvUSILSo3L\r\n6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxPTGRG\r\nHVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH6\r\n0BGM+RFq7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncB\r\nlA2c5uk5jR+mUYyZDDl34bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdi\r\no2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1\r\ngPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS6Cvu5zHbugRqh5jnxV/v\r\nfaci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaYtlu3zM63\r\nNwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayh\r\njWZSaX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw\r\n3kAP+HwV96LOPNdeE4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI\r\n# Subject: CN=emSign Root CA - G1 O=eMudhra Technologies Limited OU=emSign PKI\r\n# Label: "emSign Root CA - G1"\r\n# Serial: 235931866688319308814040\r\n# MD5 Fingerprint: 9c:42:84:57:dd:cb:0b:a7:2e:95:ad:b6:f3:da:bc:ac\r\n# SHA1 Fingerprint: 8a:c7:ad:8f:73:ac:4e:c1:b5:75:4d:a5:40:f4:fc:cf:7c:b5:8e:8c\r\n# SHA256 Fingerprint: 40:f6:af:03:46:a9:9a:a1:cd:1d:55:5a:4e:9c:ce:62:c7:f9:63:46:03:ee:40:66:15:83:3d:c8:c8:d0:03:67\r\n-----BEGIN CERTIFICATE-----\r\nMIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYD\r\nVQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBU\r\nZWNobm9sb2dpZXMgTGltaXRlZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBH\r\nMTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgxODMwMDBaMGcxCzAJBgNVBAYTAklO\r\nMRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVkaHJhIFRlY2hub2xv\r\nZ2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIBIjAN\r\nBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQz\r\nf2N4aLTNLnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO\r\n8oG0x5ZOrRkVUkr+PHB1cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aq\r\nd7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHWDV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhM\r\ntTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ6DqS0hdW5TUaQBw+jSzt\r\nOd9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrHhQIDAQAB\r\no0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQD\r\nAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31x\r\nPaOfG1vR2vjTnGs2vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjM\r\nwiI/aTvFthUvozXGaCocV685743QNcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6d\r\nGNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q+Mri/Tm3R7nrft8EI6/6nAYH\r\n6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeihU80Bv2noWgby\r\nRQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx\r\niN66zB+Afko=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI\r\n# Subject: CN=emSign ECC Root CA - G3 O=eMudhra Technologies Limited OU=emSign PKI\r\n# Label: "emSign ECC Root CA - G3"\r\n# Serial: 287880440101571086945156\r\n# MD5 Fingerprint: ce:0b:72:d1:9f:88:8e:d0:50:03:e8:e3:b8:8b:67:40\r\n# SHA1 Fingerprint: 30:43:fa:4f:f2:57:dc:a0:c3:80:ee:2e:58:ea:78:b2:3f:e6:bb:c1\r\n# SHA256 Fingerprint: 86:a1:ec:ba:08:9c:4a:8d:3b:be:27:34:c6:12:ba:34:1d:81:3e:04:3c:f9:e8:a8:62:cd:5c:57:a3:6b:be:6b\r\n-----BEGIN CERTIFICATE-----\r\nMIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQG\r\nEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNo\r\nbm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g\r\nRzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4MTgzMDAwWjBrMQswCQYDVQQGEwJJ\r\nTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9s\r\nb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMw\r\ndjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0\r\nWXTsuwYc58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xyS\r\nfvalY8L1X44uT6EYGQIrMgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuB\r\nzhccLikenEhjQjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggq\r\nhkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+DCBeQyh+KTOgNG3qxrdWB\r\nCUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7jHvrZQnD\r\n+JbNR6iC8hZVdyR+EhCVBCyj\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI\r\n# Subject: CN=emSign Root CA - C1 O=eMudhra Inc OU=emSign PKI\r\n# Label: "emSign Root CA - C1"\r\n# Serial: 825510296613316004955058\r\n# MD5 Fingerprint: d8:e3:5d:01:21:fa:78:5a:b0:df:ba:d2:ee:2a:5f:68\r\n# SHA1 Fingerprint: e7:2e:f1:df:fc:b2:09:28:cf:5d:d4:d5:67:37:b1:51:cb:86:4f:01\r\n# SHA256 Fingerprint: 12:56:09:aa:30:1d:a0:a2:49:b9:7a:82:39:cb:6a:34:21:6f:44:dc:ac:9f:39:54:b1:42:92:f2:e8:c8:60:8f\r\n-----BEGIN CERTIFICATE-----\r\nMIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkG\r\nA1UEBhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEg\r\nSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAw\r\nMFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln\r\nbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNpZ24gUm9v\r\ndCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+upufGZ\r\nBczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZ\r\nHdPIWoU/Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH\r\n3DspVpNqs8FqOp099cGXOFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvH\r\nGPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4VI5b2P/AgNBbeCsbEBEV5f6f9vtKppa+c\r\nxSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleoomslMuoaJuvimUnzYnu3Yy1\r\naylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+XJGFehiq\r\nTbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL\r\nBQADggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87\r\n/kOXSTKZEhVb3xEp/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4\r\nkqNPEjE2NuLe/gDEo2APJ62gsIq1NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrG\r\nYQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9wC68AivTxEDkigcxHpvOJpkT\r\n+xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQBmIMMMAVSKeo\r\nWXzhriKi4gp6D/piq1JM4fHfyr6DDUI=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI\r\n# Subject: CN=emSign ECC Root CA - C3 O=eMudhra Inc OU=emSign PKI\r\n# Label: "emSign ECC Root CA - C3"\r\n# Serial: 582948710642506000014504\r\n# MD5 Fingerprint: 3e:53:b3:a3:81:ee:d7:10:f8:d3:b0:1d:17:92:f5:d5\r\n# SHA1 Fingerprint: b6:af:43:c2:9b:81:53:7d:f6:ef:6b:c3:1f:1f:60:15:0c:ee:48:66\r\n# SHA256 Fingerprint: bc:4d:80:9b:15:18:9d:78:db:3e:1d:8c:f4:f9:72:6a:79:5d:a1:64:3c:a5:f1:35:8e:1d:db:0e:dc:0d:7e:b3\r\n-----BEGIN CERTIFICATE-----\r\nMIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQG\r\nEwJVUzETMBEGA1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMx\r\nIDAeBgNVBAMTF2VtU2lnbiBFQ0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAw\r\nMFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UEBhMCVVMxEzARBgNVBAsTCmVtU2ln\r\nbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQDExdlbVNpZ24gRUND\r\nIFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd6bci\r\nMK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4Ojavti\r\nsIGJAnB9SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0O\r\nBBYEFPtaSNCAIEDyqOkAB2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMB\r\nAf8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQC02C8Cif22TGK6Q04ThHK1rt0c\r\n3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwUZOR8loMRnLDRWmFLpg9J\r\n0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Hongkong Post Root CA 3 O=Hongkong Post\r\n# Subject: CN=Hongkong Post Root CA 3 O=Hongkong Post\r\n# Label: "Hongkong Post Root CA 3"\r\n# Serial: 46170865288971385588281144162979347873371282084\r\n# MD5 Fingerprint: 11:fc:9f:bd:73:30:02:8a:fd:3f:f3:58:b9:cb:20:f0\r\n# SHA1 Fingerprint: 58:a2:d0:ec:20:52:81:5b:c1:f3:f8:64:02:24:4e:c2:8e:02:4b:02\r\n# SHA256 Fingerprint: 5a:2f:c0:3f:0c:83:b0:90:bb:fa:40:60:4b:09:88:44:6c:76:36:18:3d:f9:84:6e:17:10:1a:44:7f:b8:ef:d6\r\n-----BEGIN CERTIFICATE-----\r\n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\r\nmpv0\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only\r\n# Subject: CN=Entrust Root Certification Authority - G4 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2015 Entrust, Inc. - for authorized use only\r\n# Label: "Entrust Root Certification Authority - G4"\r\n# Serial: 289383649854506086828220374796556676440\r\n# MD5 Fingerprint: 89:53:f1:83:23:b7:7c:8e:05:f1:8c:71:38:4e:1f:88\r\n# SHA1 Fingerprint: 14:88:4e:86:26:37:b0:26:af:59:62:5c:40:77:ec:35:29:ba:96:01\r\n# SHA256 Fingerprint: db:35:17:d1:f6:73:2a:2d:5a:b9:7c:53:3e:c7:07:79:ee:32:70:a6:2f:b4:ac:42:38:37:24:60:e6:f0:1e:88\r\n-----BEGIN CERTIFICATE-----\r\nMIIGSzCCBDOgAwIBAgIRANm1Q3+vqTkPAAAAAFVlrVgwDQYJKoZIhvcNAQELBQAw\r\ngb4xCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQL\r\nEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykg\r\nMjAxNSBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAw\r\nBgNVBAMTKUVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0\r\nMB4XDTE1MDUyNzExMTExNloXDTM3MTIyNzExNDExNlowgb4xCzAJBgNVBAYTAlVT\r\nMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1\r\nc3QubmV0L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxNSBFbnRydXN0LCBJ\r\nbmMuIC0gZm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMjAwBgNVBAMTKUVudHJ1c3Qg\r\nUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEc0MIICIjANBgkqhkiG9w0B\r\nAQEFAAOCAg8AMIICCgKCAgEAsewsQu7i0TD/pZJH4i3DumSXbcr3DbVZwbPLqGgZ\r\n2K+EbTBwXX7zLtJTmeH+H17ZSK9dE43b/2MzTdMAArzE+NEGCJR5WIoV3imz/f3E\r\nT+iq4qA7ec2/a0My3dl0ELn39GjUu9CH1apLiipvKgS1sqbHoHrmSKvS0VnM1n4j\r\n5pds8ELl3FFLFUHtSUrJ3hCX1nbB76W1NhSXNdh4IjVS70O92yfbYVaCNNzLiGAM\r\nC1rlLAHGVK/XqsEQe9IFWrhAnoanw5CGAlZSCXqc0ieCU0plUmr1POeo8pyvi73T\r\nDtTUXm6Hnmo9RR3RXRv06QqsYJn7ibT/mCzPfB3pAqoEmh643IhuJbNsZvc8kPNX\r\nwbMv9W3y+8qh+CmdRouzavbmZwe+LGcKKh9asj5XxNMhIWNlUpEbsZmOeX7m640A\r\n2Vqq6nPopIICR5b+W45UYaPrL0swsIsjdXJ8ITzI9vF01Bx7owVV7rtNOzK+mndm\r\nnqxpkCIHH2E6lr7lmk/MBTwoWdPBDFSoWWG9yHJM6Nyfh3+9nEg2XpWjDrk4JFX8\r\ndWbrAuMINClKxuMrLzOg2qOGpRKX/YAr2hRC45K9PvJdXmd0LhyIRyk0X+IyqJwl\r\nN4y6mACXi0mWHv0liqzc2thddG5msP9E36EYxr5ILzeUePiVSj9/E15dWf10hkNj\r\nc0kCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD\r\nVR0OBBYEFJ84xFYjwznooHFs6FRM5Og6sb9nMA0GCSqGSIb3DQEBCwUAA4ICAQAS\r\n5UKme4sPDORGpbZgQIeMJX6tuGguW8ZAdjwD+MlZ9POrYs4QjbRaZIxowLByQzTS\r\nGwv2LFPSypBLhmb8qoMi9IsabyZIrHZ3CL/FmFz0Jomee8O5ZDIBf9PD3Vht7LGr\r\nhFV0d4QEJ1JrhkzO3bll/9bGXp+aEJlLdWr+aumXIOTkdnrG0CSqkM0gkLpHZPt/\r\nB7NTeLUKYvJzQ85BK4FqLoUWlFPUa19yIqtRLULVAJyZv967lDtX/Zr1hstWO1uI\r\nAeV8KEsD+UmDfLJ/fOPtjqF/YFOOVZ1QNBIPt5d7bIdKROf1beyAN/BYGW5KaHbw\r\nH5Lk6rWS02FREAutp9lfx1/cH6NcjKF+m7ee01ZvZl4HliDtC3T7Zk6LERXpgUl+\r\nb7DUUH8i119lAg2m9IUe2K4GS0qn0jFmwvjO5QimpAKWRGhXxNUzzxkvFMSUHHuk\r\n2fCfDrGA4tGeEWSpiBE6doLlYsKA2KSD7ZPvfC+QsDJMlhVoSFLUmQjAJOgc47Ol\r\nIQ6SwJAfzyBfyjs4x7dtOvPmRLgOMWuIjnDrnBdSqEGULoe256YSxXXfW8AKbnuk\r\n5F6G+TaU33fD6Q3AOfF5u0aOq0NZJ7cguyPpVkAh7DE9ZapD8j3fcEThuk0mEDuY\r\nn/PIjhs4ViFqUZPTkcpG2om3PVODLAgfi49T3f+sHw==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation\r\n# Subject: CN=Microsoft ECC Root Certificate Authority 2017 O=Microsoft Corporation\r\n# Label: "Microsoft ECC Root Certificate Authority 2017"\r\n# Serial: 136839042543790627607696632466672567020\r\n# MD5 Fingerprint: dd:a1:03:e6:4a:93:10:d1:bf:f0:19:42:cb:fe:ed:67\r\n# SHA1 Fingerprint: 99:9a:64:c3:7f:f4:7d:9f:ab:95:f1:47:69:89:14:60:ee:c4:c3:c5\r\n# SHA256 Fingerprint: 35:8d:f3:9d:76:4a:f9:e1:b7:66:e9:c9:72:df:35:2e:e1:5c:fa:c2:27:af:6a:d1:d7:0e:8e:4a:6e:dc:ba:02\r\n-----BEGIN CERTIFICATE-----\r\nMIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQsw\r\nCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYD\r\nVQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIw\r\nMTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4MjMxNjA0WjBlMQswCQYDVQQGEwJV\r\nUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNy\r\nb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQBgcq\r\nhkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZR\r\nogPZnZH6thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYb\r\nhGBKia/teQ87zvH2RPUBeMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8E\r\nBTADAQH/MB0GA1UdDgQWBBTIy5lycFIM+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3\r\nFQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlfXu5gKcs68tvWMoQZP3zV\r\nL8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaReNtUjGUB\r\niudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation\r\n# Subject: CN=Microsoft RSA Root Certificate Authority 2017 O=Microsoft Corporation\r\n# Label: "Microsoft RSA Root Certificate Authority 2017"\r\n# Serial: 40975477897264996090493496164228220339\r\n# MD5 Fingerprint: 10:ff:00:ff:cf:c9:f8:c7:7a:c0:ee:35:8e:c9:0f:47\r\n# SHA1 Fingerprint: 73:a5:e6:4a:3b:ff:83:16:ff:0e:dc:cc:61:8a:90:6e:4e:ae:4d:74\r\n# SHA256 Fingerprint: c7:41:f7:0f:4b:2a:8d:88:bf:2e:71:c1:41:22:ef:53:ef:10:eb:a0:cf:a5:e6:4c:fa:20:f4:18:85:30:73:e0\r\n-----BEGIN CERTIFICATE-----\r\nMIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBl\r\nMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw\r\nNAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5\r\nIDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIwNzE4MjMwMDIzWjBlMQswCQYDVQQG\r\nEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1N\r\naWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwggIi\r\nMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZ\r\nNt9GkMml7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0\r\nZdDMbRnMlfl7rEqUrQ7eS0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1\r\nHLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw71VdyvD/IybLeS2v4I2wDwAW9lcfNcztm\r\ngGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+dkC0zVJhUXAoP8XFWvLJ\r\njEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49FyGcohJUc\r\naDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaG\r\nYaRSMLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6\r\nW6IYZVcSn2i51BVrlMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4K\r\nUGsTuqwPN1q3ErWQgR5WrlcihtnJ0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH\r\n+FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJClTUFLkqqNfs+avNJVgyeY+Q\r\nW5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/\r\nBAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC\r\nNxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZC\r\nLgLNFgVZJ8og6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OC\r\ngMNPOsduET/m4xaRhPtthH80dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6\r\ntZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk+ONVFT24bcMKpBLBaYVu32TxU5nh\r\nSnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex/2kskZGT4d9Mozd2\r\nTaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDyAmH3\r\npvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGR\r\nxpl/j8nWZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiApp\r\nGWSZI1b7rCoucL5mxAyE7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9\r\ndOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKTc0QWbej09+CVgI+WXTik9KveCjCHk9hN\r\nAHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D5KbvtwEwXlGjefVwaaZB\r\nRA+GsCyRxj3qrg+E\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=e-Szigno Root CA 2017 O=Microsec Ltd.\r\n# Subject: CN=e-Szigno Root CA 2017 O=Microsec Ltd.\r\n# Label: "e-Szigno Root CA 2017"\r\n# Serial: 411379200276854331539784714\r\n# MD5 Fingerprint: de:1f:f6:9e:84:ae:a7:b4:21:ce:1e:58:7d:d1:84:98\r\n# SHA1 Fingerprint: 89:d4:83:03:4f:9e:9a:48:80:5f:72:37:d4:a9:a6:ef:cb:7c:1f:d1\r\n# SHA256 Fingerprint: be:b0:0b:30:83:9b:9b:c3:2c:32:e4:44:79:05:95:06:41:f2:64:21:b1:5e:d0:89:19:8b:51:8a:e2:ea:1b:99\r\n-----BEGIN CERTIFICATE-----\r\nMIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNV\r\nBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRk\r\nLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJv\r\nb3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZaFw00MjA4MjIxMjA3MDZaMHExCzAJ\r\nBgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMg\r\nTHRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25v\r\nIFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtv\r\nxie+RJCxs1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+H\r\nWyx7xf58etqjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G\r\nA1UdDgQWBBSHERUI0arBeAyxr87GyZDvvzAEwDAfBgNVHSMEGDAWgBSHERUI0arB\r\neAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEAtVfd14pVCzbhhkT61Nlo\r\njbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxOsvxyqltZ\r\n+efcMQ==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: O=CERTSIGN SA OU=certSIGN ROOT CA G2\r\n# Subject: O=CERTSIGN SA OU=certSIGN ROOT CA G2\r\n# Label: "certSIGN Root CA G2"\r\n# Serial: 313609486401300475190\r\n# MD5 Fingerprint: 8c:f1:75:8a:c6:19:cf:94:b7:f7:65:20:87:c3:97:c7\r\n# SHA1 Fingerprint: 26:f9:93:b4:ed:3d:28:27:b0:b9:4b:a7:e9:15:1d:a3:8d:92:e5:32\r\n# SHA256 Fingerprint: 65:7c:fe:2f:a7:3f:aa:38:46:25:71:f3:32:a2:36:3a:46:fc:e7:02:09:51:71:07:02:cd:fb:b6:ee:da:33:05\r\n-----BEGIN CERTIFICATE-----\r\nMIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNV\r\nBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04g\r\nUk9PVCBDQSBHMjAeFw0xNzAyMDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJ\r\nBgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJ\r\nR04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDF\r\ndRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05N0Iw\r\nvlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZ\r\nuIt4ImfkabBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhp\r\nn+Sc8CnTXPnGFiWeI8MgwT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKs\r\ncpc/I1mbySKEwQdPzH/iV8oScLumZfNpdWO9lfsbl83kqK/20U6o2YpxJM02PbyW\r\nxPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91QqhngLjYl/rNUssuHLoPj1P\r\nrCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732jcZZroiF\r\nDsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fx\r\nDTvf95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgy\r\nLcsUDFDYg2WD7rlcz8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6C\r\neWRgKRM+o/1Pcmqr4tTluCRVLERLiohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB\r\n/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSCIS1mxteg4BXrzkwJ\r\nd8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOBywaK8SJJ6ejq\r\nkX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC\r\nb6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQl\r\nqiCA2ClV9+BB/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0\r\nOJD7uNGzcgbJceaBxXntC6Z58hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+c\r\nNywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5BiKDUyUM/FHE5r7iOZULJK2v0ZXk\r\nltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklWatKcsWMy5WHgUyIO\r\npwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tUSxfj\r\n03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZk\r\nPuXaTH4MNMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE\r\n1LlSVHJ7liXMvGnjSG4N0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MX\r\nQRBdJ3NghVdJIgc=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc.\r\n# Subject: CN=Trustwave Global Certification Authority O=Trustwave Holdings, Inc.\r\n# Label: "Trustwave Global Certification Authority"\r\n# Serial: 1846098327275375458322922162\r\n# MD5 Fingerprint: f8:1c:18:2d:2f:ba:5f:6d:a1:6c:bc:c7:ab:91:c7:0e\r\n# SHA1 Fingerprint: 2f:8f:36:4f:e1:58:97:44:21:59:87:a5:2a:9a:d0:69:95:26:7f:b5\r\n# SHA256 Fingerprint: 97:55:20:15:f5:dd:fc:3c:87:88:c0:06:94:45:55:40:88:94:45:00:84:f1:00:86:70:86:bc:1a:2b:b5:8d:c8\r\n-----BEGIN CERTIFICATE-----\r\nMIIF2jCCA8KgAwIBAgIMBfcOhtpJ80Y1LrqyMA0GCSqGSIb3DQEBCwUAMIGIMQsw\r\nCQYDVQQGEwJVUzERMA8GA1UECAwISWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28x\r\nITAfBgNVBAoMGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1\r\nc3R3YXZlIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMx\r\nOTM0MTJaFw00MjA4MjMxOTM0MTJaMIGIMQswCQYDVQQGEwJVUzERMA8GA1UECAwI\r\nSWxsaW5vaXMxEDAOBgNVBAcMB0NoaWNhZ28xITAfBgNVBAoMGFRydXN0d2F2ZSBI\r\nb2xkaW5ncywgSW5jLjExMC8GA1UEAwwoVHJ1c3R3YXZlIEdsb2JhbCBDZXJ0aWZp\r\nY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB\r\nALldUShLPDeS0YLOvR29zd24q88KPuFd5dyqCblXAj7mY2Hf8g+CY66j96xz0Xzn\r\nswuvCAAJWX/NKSqIk4cXGIDtiLK0thAfLdZfVaITXdHG6wZWiYj+rDKd/VzDBcdu\r\n7oaJuogDnXIhhpCujwOl3J+IKMujkkkP7NAP4m1ET4BqstTnoApTAbqOl5F2brz8\r\n1Ws25kCI1nsvXwXoLG0R8+eyvpJETNKXpP7ScoFDB5zpET71ixpZfR9oWN0EACyW\r\n80OzfpgZdNmcc9kYvkHHNHnZ9GLCQ7mzJ7Aiy/k9UscwR7PJPrhq4ufogXBeQotP\r\nJqX+OsIgbrv4Fo7NDKm0G2x2EOFYeUY+VM6AqFcJNykbmROPDMjWLBz7BegIlT1l\r\nRtzuzWniTY+HKE40Cz7PFNm73bZQmq131BnW2hqIyE4bJ3XYsgjxroMwuREOzYfw\r\nhI0Vcnyh78zyiGG69Gm7DIwLdVcEuE4qFC49DxweMqZiNu5m4iK4BUBjECLzMx10\r\ncoos9TkpoNPnG4CELcU9402x/RpvumUHO1jsQkUm+9jaJXLE9gCxInm943xZYkqc\r\nBW89zubWR2OZxiRvchLIrH+QtAuRcOi35hYQcRfO3gZPSEF9NUqjifLJS3tBEW1n\r\ntwiYTOURGa5CgNz7kAXU+FDKvuStx8KU1xad5hePrzb7AgMBAAGjQjBAMA8GA1Ud\r\nEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJngGWcNYtt2s9o9uFvo/ULSMQ6HMA4GA1Ud\r\nDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAmHNw4rDT7TnsTGDZqRKGFx6W\r\n0OhUKDtkLSGm+J1WE2pIPU/HPinbbViDVD2HfSMF1OQc3Og4ZYbFdada2zUFvXfe\r\nuyk3QAUHw5RSn8pk3fEbK9xGChACMf1KaA0HZJDmHvUqoai7PF35owgLEQzxPy0Q\r\nlG/+4jSHg9bP5Rs1bdID4bANqKCqRieCNqcVtgimQlRXtpla4gt5kNdXElE1GYhB\r\naCXUNxeEFfsBctyV3lImIJgm4nb1J2/6ADtKYdkNy1GTKv0WBpanI5ojSP5RvbbE\r\nsLFUzt5sQa0WZ37b/TjNuThOssFgy50X31ieemKyJo90lZvkWx3SD92YHJtZuSPT\r\nMaCm/zjdzyBP6VhWOmfD0faZmZ26NraAL4hHT4a/RDqA5Dccprrql5gR0IRiR2Qe\r\nqu5AvzSxnI9O4fKSTx+O856X3vOmeWqJcU9LJxdI/uz0UA9PSX3MReO9ekDFQdxh\r\nVicGaeVyQYHTtgGJoC86cnn+OjC/QezHYj6RS8fZMXZC+fc8Y+wmjHMMfRod6qh8\r\nh6jCJ3zhM0EPz8/8AKAigJ5Kp28AsEFFtyLKaEjFQqKu3R3y4G5OBVixwJAWKqQ9\r\nEEC+j2Jjg6mcgn0tAumDMHzLJ8n9HmYAsC7TIS+OMxZsmO0QqAfWzJPP29FpHOTK\r\nyeC2nOnOcXHebD8WpHk=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc.\r\n# Subject: CN=Trustwave Global ECC P256 Certification Authority O=Trustwave Holdings, Inc.\r\n# Label: "Trustwave Global ECC P256 Certification Authority"\r\n# Serial: 4151900041497450638097112925\r\n# MD5 Fingerprint: 5b:44:e3:8d:5d:36:86:26:e8:0d:05:d2:59:a7:83:54\r\n# SHA1 Fingerprint: b4:90:82:dd:45:0c:be:8b:5b:b1:66:d3:e2:a4:08:26:cd:ed:42:cf\r\n# SHA256 Fingerprint: 94:5b:bc:82:5e:a5:54:f4:89:d1:fd:51:a7:3d:df:2e:a6:24:ac:70:19:a0:52:05:22:5c:22:a7:8c:cf:a8:b4\r\n-----BEGIN CERTIFICATE-----\r\nMIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYD\r\nVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf\r\nBgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3\r\nYXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x\r\nNzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYDVQQGEwJVUzERMA8G\r\nA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0\r\nd2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF\r\nQ0MgUDI1NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqG\r\nSM49AwEHA0IABH77bOYj43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoN\r\nFWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqmP62jQzBBMA8GA1UdEwEB/wQFMAMBAf8w\r\nDwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt0UrrdaVKEJmzsaGLSvcw\r\nCgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjzRM4q3wgh\r\nDDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc.\r\n# Subject: CN=Trustwave Global ECC P384 Certification Authority O=Trustwave Holdings, Inc.\r\n# Label: "Trustwave Global ECC P384 Certification Authority"\r\n# Serial: 2704997926503831671788816187\r\n# MD5 Fingerprint: ea:cf:60:c4:3b:b9:15:29:40:a1:97:ed:78:27:93:d6\r\n# SHA1 Fingerprint: e7:f3:a3:c8:cf:6f:c3:04:2e:6d:0e:67:32:c5:9e:68:95:0d:5e:d2\r\n# SHA256 Fingerprint: 55:90:38:59:c8:c0:c3:eb:b8:75:9e:ce:4e:25:57:22:5f:f5:75:8b:bd:38:eb:d4:82:76:60:1e:1b:d5:80:97\r\n-----BEGIN CERTIFICATE-----\r\nMIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYD\r\nVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAf\r\nBgNVBAoTGFRydXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3\r\nYXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0x\r\nNzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYDVQQGEwJVUzERMA8G\r\nA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0\r\nd2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBF\r\nQ0MgUDM4NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuB\r\nBAAiA2IABGvaDXU1CDFHBa5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJ\r\nj9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr/TklZvFe/oyujUF5nQlgziip04pt89ZF\r\n1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNVHQ8BAf8EBQMDBwYAMB0G\r\nA1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNnADBkAjA3\r\nAZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsC\r\nMGclCrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVu\r\nSw==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp.\r\n# Subject: CN=NAVER Global Root Certification Authority O=NAVER BUSINESS PLATFORM Corp.\r\n# Label: "NAVER Global Root Certification Authority"\r\n# Serial: 9013692873798656336226253319739695165984492813\r\n# MD5 Fingerprint: c8:7e:41:f6:25:3b:f5:09:b3:17:e8:46:3d:bf:d0:9b\r\n# SHA1 Fingerprint: 8f:6b:f2:a9:27:4a:da:14:a0:c4:f4:8e:61:27:f9:c0:1e:78:5d:d1\r\n# SHA256 Fingerprint: 88:f4:38:dc:f8:ff:d1:fa:8f:42:91:15:ff:e5:f8:2a:e1:e0:6e:0c:70:c3:75:fa:ad:71:7b:34:a4:9e:72:65\r\n-----BEGIN CERTIFICATE-----\r\n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\r\n9XXeifdy\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres\r\n# Subject: CN=AC RAIZ FNMT-RCM SERVIDORES SEGUROS O=FNMT-RCM OU=Ceres\r\n# Label: "AC RAIZ FNMT-RCM SERVIDORES SEGUROS"\r\n# Serial: 131542671362353147877283741781055151509\r\n# MD5 Fingerprint: 19:36:9c:52:03:2f:d2:d1:bb:23:cc:dd:1e:12:55:bb\r\n# SHA1 Fingerprint: 62:ff:d9:9e:c0:65:0d:03:ce:75:93:d2:ed:3f:2d:32:c9:e3:e5:4a\r\n# SHA256 Fingerprint: 55:41:53:b1:3d:2c:f9:dd:b7:53:bf:be:1a:4e:0a:e0:8d:0a:a4:18:70:58:fe:60:a2:b8:62:b2:e4:b8:7b:cb\r\n-----BEGIN CERTIFICATE-----\r\nMIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQsw\r\nCQYDVQQGEwJFUzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgw\r\nFgYDVQRhDA9WQVRFUy1RMjgyNjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1S\r\nQ00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4MTIyMDA5MzczM1oXDTQzMTIyMDA5\r\nMzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQtUkNNMQ4wDAYDVQQL\r\nDAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNBQyBS\r\nQUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuB\r\nBAAiA2IABPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LH\r\nsbI6GA60XYyzZl2hNPk2LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oK\r\nUm8BA06Oi6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD\r\nVR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqGSM49BAMDA2kAMGYCMQCu\r\nSuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoDzBOQn5IC\r\nMQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJy\r\nv+c=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=GlobalSign Root R46 O=GlobalSign nv-sa\r\n# Subject: CN=GlobalSign Root R46 O=GlobalSign nv-sa\r\n# Label: "GlobalSign Root R46"\r\n# Serial: 1552617688466950547958867513931858518042577\r\n# MD5 Fingerprint: c4:14:30:e4:fa:66:43:94:2a:6a:1b:24:5f:19:d0:ef\r\n# SHA1 Fingerprint: 53:a2:b0:4b:ca:6b:d6:45:e6:39:8a:8e:c4:0d:d2:bf:77:c3:a2:90\r\n# SHA256 Fingerprint: 4f:a3:12:6d:8d:3a:11:d1:c4:85:5a:4f:80:7c:ba:d6:cf:91:9d:3a:5a:88:b0:3b:ea:2c:63:72:d9:3c:40:c9\r\n-----BEGIN CERTIFICATE-----\r\nMIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUA\r\nMEYxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYD\r\nVQQDExNHbG9iYWxTaWduIFJvb3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMy\r\nMDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYt\r\nc2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEB\r\nAQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08EsCVeJ\r\nOaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQG\r\nvGIFAha/r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud\r\n316HCkD7rRlr+/fKYIje2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo\r\n0q3v84RLHIf8E6M6cqJaESvWJ3En7YEtbWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSE\r\ny132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvjK8Cd+RTyG/FWaha/LIWF\r\nzXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD412lPFzYE\r\n+cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCN\r\nI/onccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzs\r\nx2sZy/N78CsHpdlseVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqa\r\nByFrgY/bxFn63iLABJzjqls2k+g9vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC\r\n4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV\r\nHQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEMBQADggIBAHx4\r\n7PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg\r\nJuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti\r\n2kM3S+LGteWygxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIk\r\npnnpHs6i58FZFZ8d4kuaPp92CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRF\r\nFRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZmOUdkLG5NrmJ7v2B0GbhWrJKsFjLt\r\nrWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qqJZ4d16GLuc1CLgSk\r\nZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwyeqiv5\r\nu+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP\r\n4vkYxboznxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6\r\nN3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3\r\nvouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=GlobalSign Root E46 O=GlobalSign nv-sa\r\n# Subject: CN=GlobalSign Root E46 O=GlobalSign nv-sa\r\n# Label: "GlobalSign Root E46"\r\n# Serial: 1552617690338932563915843282459653771421763\r\n# MD5 Fingerprint: b5:b8:66:ed:de:08:83:e3:c9:e2:01:34:06:ac:51:6f\r\n# SHA1 Fingerprint: 39:b4:6c:d5:fe:80:06:eb:e2:2f:4a:bb:08:33:a0:af:db:b9:dd:84\r\n# SHA256 Fingerprint: cb:b9:c4:4d:84:b8:04:3e:10:50:ea:31:a6:9f:51:49:55:d7:bf:d2:e2:c6:b4:93:01:01:9a:d6:1d:9f:50:58\r\n-----BEGIN CERTIFICATE-----\r\nMIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYx\r\nCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQD\r\nExNHbG9iYWxTaWduIFJvb3QgRTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAw\r\nMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2Ex\r\nHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUrgQQA\r\nIgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkBjtjq\r\nR+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGdd\r\nyXqBPCCjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud\r\nDgQWBBQxCpCPtsad0kRLgLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ\r\n7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZkvLtoURMMA/cVi4RguYv/Uo7njLwcAjA8\r\n+RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+CAezNIm8BZ/3Hobui3A=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=GLOBALTRUST 2020 O=e-commerce monitoring GmbH\r\n# Subject: CN=GLOBALTRUST 2020 O=e-commerce monitoring GmbH\r\n# Label: "GLOBALTRUST 2020"\r\n# Serial: 109160994242082918454945253\r\n# MD5 Fingerprint: 8a:c7:6f:cb:6d:e3:cc:a2:f1:7c:83:fa:0e:78:d7:e8\r\n# SHA1 Fingerprint: d0:67:c1:13:51:01:0c:aa:d0:c7:6a:65:37:31:16:26:4f:53:71:a2\r\n# SHA256 Fingerprint: 9a:29:6a:51:82:d1:d4:51:a2:e3:7f:43:9b:74:da:af:a2:67:52:33:29:f9:0f:9a:0d:20:07:c3:34:e2:3c:9a\r\n-----BEGIN CERTIFICATE-----\r\nMIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkG\r\nA1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkw\r\nFwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYx\r\nMDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAhBgNVBAoTGmUtY29tbWVyY2UgbW9u\r\naXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAyMDIwMIICIjANBgkq\r\nhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWiD59b\r\nRatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9Z\r\nYybNpyrOVPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3\r\nQWPKzv9pj2gOlTblzLmMCcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPw\r\nyJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCmfecqQjuCgGOlYx8ZzHyyZqjC0203b+J+\r\nBlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKAA1GqtH6qRNdDYfOiaxaJ\r\nSaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9ORJitHHmkH\r\nr96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj0\r\n4KlGDfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9Me\r\ndKZssCz3AwyIDMvUclOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIw\r\nq7ejMZdnrY8XD2zHc+0klGvIg5rQmjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2\r\nnKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\r\nAQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1UdIwQYMBaAFNwu\r\nH9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA\r\nVC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJC\r\nXtzoRlgHNQIw4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd\r\n6IwPS3BD0IL/qMy/pJTAvoe9iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf\r\n+I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS8cE54+X1+NZK3TTN+2/BT+MAi1bi\r\nkvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2HcqtbepBEX4tdJP7\r\nwry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxSvTOB\r\nTI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6C\r\nMUO+1918oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn\r\n4rnvyOL2NSl6dPrFf4IFYqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+I\r\naFvowdlxfv1k7/9nR4hYJS8+hge9+6jlgqispdNpQ80xiEmEU5LAsTkbOYMBMMTy\r\nqfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg==\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz\r\n# Subject: CN=ANF Secure Server Root CA O=ANF Autoridad de Certificacion OU=ANF CA Raiz\r\n# Label: "ANF Secure Server Root CA"\r\n# Serial: 996390341000653745\r\n# MD5 Fingerprint: 26:a6:44:5a:d9:af:4e:2f:b2:1d:b6:65:b0:4e:e8:96\r\n# SHA1 Fingerprint: 5b:6e:68:d0:cc:15:b6:a0:5f:1e:c1:5f:ae:02:fc:6b:2f:5d:6f:74\r\n# SHA256 Fingerprint: fb:8f:ec:75:91:69:b9:10:6b:1e:51:16:44:c6:18:c5:13:04:37:3f:6c:06:43:08:8d:8b:ef:fd:1b:99:75:99\r\n-----BEGIN CERTIFICATE-----\r\n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\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority\r\n# Subject: CN=Certum EC-384 CA O=Asseco Data Systems S.A. OU=Certum Certification Authority\r\n# Label: "Certum EC-384 CA"\r\n# Serial: 160250656287871593594747141429395092468\r\n# MD5 Fingerprint: b6:65:b3:96:60:97:12:a1:ec:4e:e1:3d:a3:c6:c9:f1\r\n# SHA1 Fingerprint: f3:3e:78:3c:ac:df:f4:a2:cc:ac:67:55:69:56:d7:e5:16:3c:e1:ed\r\n# SHA256 Fingerprint: 6b:32:80:85:62:53:18:aa:50:d1:73:c9:8d:8b:da:09:d5:7e:27:41:3d:11:4c:f7:87:a0:f5:d0:6c:03:0c:f6\r\n-----BEGIN CERTIFICATE-----\r\nMIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQsw\r\nCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScw\r\nJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMT\r\nEENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2MDcyNDU0WhcNNDMwMzI2MDcyNDU0\r\nWjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBT\r\nLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGTAX\r\nBgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATE\r\nKI6rGFtqvm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7Tm\r\nFy8as10CW4kjPMIRBSqniBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68Kj\r\nQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI0GZnQkdjrzife81r1HfS+8\r\nEF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjADVS2m5hjEfO/J\r\nUG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0QoSZ/6vn\r\nnvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority\r\n# Subject: CN=Certum Trusted Root CA O=Asseco Data Systems S.A. OU=Certum Certification Authority\r\n# Label: "Certum Trusted Root CA"\r\n# Serial: 40870380103424195783807378461123655149\r\n# MD5 Fingerprint: 51:e1:c2:e7:fe:4c:84:af:59:0e:2f:f4:54:6f:ea:29\r\n# SHA1 Fingerprint: c8:83:44:c0:18:ae:9f:cc:f1:87:b7:8f:22:d1:c5:d7:45:84:ba:e5\r\n# SHA256 Fingerprint: fe:76:96:57:38:55:77:3e:37:a9:5e:7a:d4:d9:cc:96:c3:01:57:c1:5d:31:76:5b:a9:b1:57:04:e1:ae:78:fd\r\n-----BEGIN CERTIFICATE-----\r\n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\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique\r\n# Subject: CN=TunTrust Root CA O=Agence Nationale de Certification Electronique\r\n# Label: "TunTrust Root CA"\r\n# Serial: 108534058042236574382096126452369648152337120275\r\n# MD5 Fingerprint: 85:13:b9:90:5b:36:5c:b6:5e:b8:5a:f8:e0:31:57:b4\r\n# SHA1 Fingerprint: cf:e9:70:84:0f:e0:73:0f:9d:f6:0c:7f:2c:4b:ee:20:46:34:9c:bb\r\n# SHA256 Fingerprint: 2e:44:10:2a:b5:8c:b8:54:19:45:1c:8e:19:d9:ac:f3:66:2c:af:bc:61:4b:6a:53:96:0a:30:f7:d0:e2:eb:41\r\n-----BEGIN CERTIFICATE-----\r\nMIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQEL\r\nBQAwYTELMAkGA1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUg\r\nQ2VydGlmaWNhdGlvbiBFbGVjdHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJv\r\nb3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQwNDI2MDg1NzU2WjBhMQswCQYDVQQG\r\nEwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBDZXJ0aWZpY2F0aW9u\r\nIEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIwDQYJ\r\nKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZ\r\nn56eY+hz2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd\r\n2JQDoOw05TDENX37Jk0bbjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgF\r\nVwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZ\r\nGoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAdgjH8KcwAWJeRTIAAHDOF\r\nli/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViWVSHbhlnU\r\nr8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2\r\neY8fTpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIb\r\nMlEsPvLfe/ZdeikZjuXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISg\r\njwBUFfyRbVinljvrS5YnzWuioYasDXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB\r\n7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwSVXAkPcvCFDVDXSdOvsC9qnyW\r\n5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI04Y+oXNZtPdE\r\nITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0\r\n90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+z\r\nxiD2BkewhpMl0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYu\r\nQEkHDVneixCwSQXi/5E/S7fdAo74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4\r\nFstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRYYdZ2vyJ/0Adqp2RT8JeNnYA/u8EH\r\n22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJpadbGNjHh/PqAulxP\r\nxOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65xxBzn\r\ndFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5\r\nXc0yGYuPjCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7b\r\nnV2UqL1g52KAdoGDDIzMMEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQ\r\nCvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9zZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZH\r\nu/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3rAZ3r2OvEhJn7wAzMMujj\r\nd9qDRIueVSjAi1jTkD5OGwDxFa2DK5o=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA\r\n# Subject: CN=HARICA TLS RSA Root CA 2021 O=Hellenic Academic and Research Institutions CA\r\n# Label: "HARICA TLS RSA Root CA 2021"\r\n# Serial: 76817823531813593706434026085292783742\r\n# MD5 Fingerprint: 65:47:9b:58:86:dd:2c:f0:fc:a2:84:1f:1e:96:c4:91\r\n# SHA1 Fingerprint: 02:2d:05:82:fa:88:ce:14:0c:06:79:de:7f:14:10:e9:45:d7:a5:6d\r\n# SHA256 Fingerprint: d9:5d:0e:8e:da:79:52:5b:f9:be:b1:1b:14:d2:10:0d:32:94:98:5f:0c:62:d9:fa:bd:9c:d9:99:ec:cb:7b:1d\r\n-----BEGIN CERTIFICATE-----\r\n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\r\n63ZTGI0RmLo=\r\n-----END CERTIFICATE-----\r\n\r\n# Issuer: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA\r\n# Subject: CN=HARICA TLS ECC Root CA 2021 O=Hellenic Academic and Research Institutions CA\r\n# Label: "HARICA TLS ECC Root CA 2021"\r\n# Serial: 137515985548005187474074462014555733966\r\n# MD5 Fingerprint: ae:f7:4c:e5:66:35:d1:b7:9b:8c:22:93:74:d3:4b:b0\r\n# SHA1 Fingerprint: bc:b0:c1:9d:e9:98:92:70:19:38:57:e9:8d:a7:b4:5d:6e:ee:01:48\r\n# SHA256 Fingerprint: 3f:99:cc:47:4a:cf:ce:4d:fe:d5:87:94:66:5e:47:8d:15:47:73:9f:2e:78:0f:1b:b4:ca:9b:13:30:97:d4:01\r\n-----BEGIN CERTIFICATE-----\r\nMIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQsw\r\nCQYDVQQGEwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2Vh\r\ncmNoIEluc3RpdHV0aW9ucyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9v\r\ndCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoXDTQ1MDIxMzExMDEwOVowbDELMAkG\r\nA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj\r\naCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJvb3Qg\r\nQ0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7\r\nKKrxcm1lAEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9Y\r\nSTHMmE5gEYd103KUkE+bECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUw\r\nAwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQD\r\nAgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAircJRQO9gcS3ujwLEXQNw\r\nSaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/QwCZ61IygN\r\nnxS2PFOiTAZpffpskcYqSUXm7LcT4Tps\r\n-----END CERTIFICATE-----' \ No newline at end of file diff --git a/snet/sdk/service_client.py b/snet/sdk/service_client.py index bc6034a..7a4b59f 100644 --- a/snet/sdk/service_client.py +++ b/snet/sdk/service_client.py @@ -9,8 +9,8 @@ import web3 from eth_account.messages import defunct_hash_message from rfc3986 import urlparse -from snet.cli.resources.root_certificate import certificate -from snet.cli.utils.utils import RESOURCES_PATH, add_to_path, find_file_by_keyword +from snet.sdk.resources.root_certificate import certificate +from snet.sdk.utils.utils import RESOURCES_PATH, add_to_path, find_file_by_keyword import snet.sdk.generic_client_interceptor as generic_client_interceptor from snet.sdk.mpe.payment_channel_provider import PaymentChannelProvider @@ -123,8 +123,8 @@ def load_open_channels(self): group_id = base64.b64decode(str(self.group["group_id"])) new_payment_channels = self.payment_channel_provider.get_past_open_channels(self.account, payment_address, group_id, self.last_read_block) - self.payment_channels = self.payment_channels + self._filter_existing_channels_from_new_payment_channels( - new_payment_channels) + self.payment_channels = self.payment_channels + \ + self._filter_existing_channels_from_new_payment_channels(new_payment_channels) self.last_read_block = current_block_number return self.payment_channels diff --git a/snet/sdk/training/training.py b/snet/sdk/training/training.py index 67a5e74..c5ede80 100644 --- a/snet/sdk/training/training.py +++ b/snet/sdk/training/training.py @@ -5,8 +5,8 @@ import grpc import web3 -from snet.cli.resources.root_certificate import certificate -from snet.cli.utils.utils import add_to_path, RESOURCES_PATH +from snet.sdk.resources.root_certificate import certificate +from snet.sdk.utils.utils import add_to_path, RESOURCES_PATH # for local debug @@ -62,15 +62,16 @@ def _invoke_model(self, service_client, msg: ModelMethodMessage): # params from AI-service: status, model_id # params pass to daemon: grpc_service_name, grpc_method_name, address_list, # description, model_name, training_data_link, is_public_accessible - def create_model(self, service_client, grpc_method_name: str, model_name: str, - description: str = '', + def create_model(self, service_client, grpc_method_name: str, + model_name: str, description: str = '', training_data_link: str = '', grpc_service_name='service', is_publicly_accessible=False, address_list: list[str] = None): if address_list is None: address_list = [] try: auth_req, channel = self._invoke_model(service_client, ModelMethodMessage.CreateModel) - model_details = self.training_pb2.ModelDetails(grpc_method_name=grpc_method_name, description=description, + model_details = self.training_pb2.ModelDetails(grpc_method_name=grpc_method_name, + description=description, training_data_link=training_data_link, grpc_service_name=grpc_service_name, model_name=model_name, address_list=address_list, @@ -89,7 +90,8 @@ def get_model_status(self, service_client, model_id: str, grpc_method_name: str, try: auth_req, channel = self._invoke_model(service_client, ModelMethodMessage.GetModelStatus) model_details = self.training_pb2.ModelDetails(grpc_method_name=grpc_method_name, - grpc_service_name=grpc_service_name, model_id=str(model_id)) + grpc_service_name=grpc_service_name, + model_id=str(model_id)) stub = self.training_pb2_grpc.ModelStub(channel) response = stub.get_model_status( self.training_pb2.ModelDetailsRequest(authorization=auth_req, model_details=model_details)) @@ -100,12 +102,13 @@ def get_model_status(self, service_client, model_id: str, grpc_method_name: str, # params from AI-service: status # params to daemon: grpc_service_name, grpc_method_name, model_id - def delete_model(self, service_client, model_id: str, grpc_method_name: str, - grpc_service_name='service'): + def delete_model(self, service_client, model_id: str, + grpc_method_name: str, grpc_service_name='service'): try: auth_req, channel = self._invoke_model(service_client, ModelMethodMessage.DeleteModel) model_details = self.training_pb2.ModelDetails(grpc_method_name=grpc_method_name, - grpc_service_name=grpc_service_name, model_id=str(model_id)) + grpc_service_name=grpc_service_name, + model_id=str(model_id)) stub = self.training_pb2_grpc.ModelStub(channel) response = stub.delete_model( self.training_pb2.UpdateModelRequest(authorization=auth_req, update_model_details=model_details)) @@ -119,13 +122,16 @@ def delete_model(self, service_client, model_id: str, grpc_method_name: str, # all params required def update_model_access(self, service_client, model_id: str, grpc_method_name: str, model_name: str, is_public: bool, - description: str, grpc_service_name: str = 'service', address_list: list[str] = None): + description: str, grpc_service_name: str = 'service', + address_list: list[str] = None): try: auth_req, channel = self._invoke_model(service_client, ModelMethodMessage.UpdateModelAccess) - model_details = self.training_pb2.ModelDetails(grpc_method_name=grpc_method_name, description=description, + model_details = self.training_pb2.ModelDetails(grpc_method_name=grpc_method_name, + description=description, grpc_service_name=grpc_service_name, address_list=address_list, - is_publicly_accessible=is_public, model_name=model_name, + is_publicly_accessible=is_public, + model_name=model_name, model_id=str(model_id)) stub = self.training_pb2_grpc.ModelStub(channel) response = stub.update_model_access( @@ -142,9 +148,10 @@ def get_all_models(self, service_client, grpc_method_name: str, grpc_service_nam auth_req, channel = self._invoke_model(service_client, ModelMethodMessage.GetAllModels) stub = self.training_pb2_grpc.ModelStub(channel) response = stub.get_all_models( - self.training_pb2.AccessibleModelsRequest(authorization=auth_req, grpc_service_name=grpc_service_name, + self.training_pb2.AccessibleModelsRequest(authorization=auth_req, + grpc_service_name=grpc_service_name, grpc_method_name=grpc_method_name)) return response except Exception as e: print("Exception: ", e) - return e \ No newline at end of file + return e diff --git a/snet/sdk/utils/__init__.py b/snet/sdk/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/snet/sdk/utils/ipfs_utils.py b/snet/sdk/utils/ipfs_utils.py new file mode 100644 index 0000000..4e18c95 --- /dev/null +++ b/snet/sdk/utils/ipfs_utils.py @@ -0,0 +1,78 @@ +""" Utilities related to ipfs """ +import tarfile +import io +import os + +import base58 +import ipfshttpclient +import multihash + + +def get_from_ipfs_and_checkhash(ipfs_client, ipfs_hash_base58, validate=True): + """ + Get file from ipfs + We must check the hash becasue we cannot believe that ipfs_client wasn't been compromise + """ + if validate: + from snet.sdk.resources.proto.unixfs_pb2 import Data + from snet.sdk.resources.proto.merckledag_pb2 import MerkleNode + + # No nice Python library to parse ipfs blocks, so do it ourselves. + block_data = ipfs_client.block.get(ipfs_hash_base58) + mn = MerkleNode() + mn.ParseFromString(block_data) + unixfs_data = Data() + unixfs_data.ParseFromString(mn.Data) + assert unixfs_data.Type == unixfs_data.DataType.Value( + 'File'), "IPFS hash must be a file" + data = unixfs_data.Data + + # multihash has a badly registered base58 codec, overwrite it... + multihash.CodecReg.register( + 'base58', base58.b58encode, base58.b58decode) + # create a multihash object from our ipfs hash + mh = multihash.decode(ipfs_hash_base58.encode('ascii'), 'base58') + + # Convenience method lets us directly use a multihash to verify data + if not mh.verify(block_data): + raise Exception("IPFS hash mismatch with data") + else: + data = ipfs_client.cat(ipfs_hash_base58) + return data + + +def bytesuri_to_hash(s): + s = s.rstrip(b"\0").decode('ascii') + if not s.startswith("ipfs://"): + raise Exception("We support only ipfs uri in Registry") + return s[7:] + + +def safe_extract_proto_from_ipfs(ipfs_client, ipfs_hash, protodir): + """ + Tar files might be dangerous (see https://bugs.python.org/issue21109, + and https://docs.python.org/3/library/tarfile.html, TarFile.extractall warning) + we extract only simple files + """ + spec_tar = get_from_ipfs_and_checkhash(ipfs_client, ipfs_hash) + with tarfile.open(fileobj=io.BytesIO(spec_tar)) as f: + for m in f.getmembers(): + if os.path.dirname(m.name) != "": + raise Exception( + "tarball has directories. We do not support it.") + if not m.isfile(): + raise Exception( + "tarball contains %s which is not a file" % m.name) + fullname = os.path.join(protodir, m.name) + if os.path.exists(fullname): + os.remove(fullname) + print("%s removed." % fullname) + # now it is safe to call extractall + f.extractall(protodir) + + +def get_ipfs_client(config): + ipfs_endpoint = config.get_ipfs_endpoint() + return ipfshttpclient.connect(ipfs_endpoint) + + diff --git a/snet/sdk/utils/utils.py b/snet/sdk/utils/utils.py new file mode 100644 index 0000000..ebb7cc1 --- /dev/null +++ b/snet/sdk/utils/utils.py @@ -0,0 +1,147 @@ +import json +import os +import subprocess +import sys +import importlib.resources +from urllib.parse import urlparse +from pathlib import Path, PurePath + +import web3 +from grpc_tools.protoc import main as protoc + +from snet import sdk + +RESOURCES_PATH = PurePath(os.path.dirname(sdk.__file__)).joinpath("resources") + + +def safe_address_converter(a): + if not web3.Web3.is_checksum_address(a): + raise Exception("%s is not is not a valid Ethereum checksum address" % a) + return a + + +def type_converter(t): + if t.endswith("[]"): + return lambda x: list(map(type_converter(t.replace("[]", "")), json.loads(x))) + else: + if "int" in t: + return lambda x: web3.Web3.to_int(text=x) + elif "bytes32" in t: + return lambda x: web3.Web3.to_bytes(text=x).ljust(32, b"\0") if not x.startswith( + "0x") else web3.Web3.to_bytes(hexstr=x).ljust(32, b"\0") + elif "byte" in t: + return lambda x: web3.Web3.to_bytes(text=x) if not x.startswith("0x") else web3.Web3.to_bytes(hexstr=x) + elif "address" in t: + return safe_address_converter + else: + return str + + +def bytes32_to_str(b): + return b.rstrip(b"\0").decode("utf-8") + + +def compile_proto(entry_path, codegen_dir, proto_file=None, target_language="python"): + try: + if not os.path.exists(codegen_dir): + os.makedirs(codegen_dir) + proto_include = importlib.resources.files('grpc_tools') / '_proto' + + compiler_args = [ + "-I{}".format(entry_path), + "-I{}".format(proto_include) + ] + + if target_language == "python": + compiler_args.insert(0, "protoc") + compiler_args.append("--python_out={}".format(codegen_dir)) + compiler_args.append("--grpc_python_out={}".format(codegen_dir)) + compiler = protoc + elif target_language == "nodejs": + protoc_node_compiler_path = Path( + RESOURCES_PATH.joinpath("node_modules").joinpath("grpc-tools").joinpath("bin").joinpath( + "protoc.js")).absolute() + grpc_node_plugin_path = Path( + RESOURCES_PATH.joinpath("node_modules").joinpath("grpc-tools").joinpath("bin").joinpath( + "grpc_node_plugin")).resolve() + if not os.path.isfile(protoc_node_compiler_path) or not os.path.isfile(grpc_node_plugin_path): + print("Missing required node.js protoc compiler. Retrieving from npm...") + subprocess.run(["npm", "install"], cwd=RESOURCES_PATH) + compiler_args.append("--js_out=import_style=commonjs,binary:{}".format(codegen_dir)) + compiler_args.append("--grpc_out={}".format(codegen_dir)) + compiler_args.append("--plugin=protoc-gen-grpc={}".format(grpc_node_plugin_path)) + compiler = lambda args: subprocess.run([str(protoc_node_compiler_path)] + args) + + if proto_file: + compiler_args.append(str(proto_file)) + else: + compiler_args.extend([str(p) for p in entry_path.glob("**/*.proto")]) + + if not compiler(compiler_args): + return True + else: + return False + + except Exception as e: + print(e) + return False + + +def is_valid_endpoint(url): + """ + Just ensures the url has a scheme (http/https), and a net location (IP or domain name). + Can make more advanced or do on-network tests if needed, but this is really just to catch obvious errors. + >>> is_valid_endpoint("https://34.216.72.29:6206") + True + >>> is_valid_endpoint("blahblah") + False + >>> is_valid_endpoint("blah://34.216.72.29") + False + >>> is_valid_endpoint("http://34.216.72.29:%%%") + False + >>> is_valid_endpoint("http://192.168.0.2:9999") + True + """ + try: + result = urlparse(url) + if result.port: + _port = int(result.port) + return ( + all([result.scheme, result.netloc]) and + result.scheme in ['http', 'https'] + ) + except ValueError: + return False + + +def normalize_private_key(private_key): + if private_key.startswith("0x"): + private_key = bytes(bytearray.fromhex(private_key[2:])) + else: + private_key = bytes(bytearray.fromhex(private_key)) + return private_key + + +def get_address_from_private(private_key): + return web3.Account.from_key(private_key).address + + +class add_to_path: + def __init__(self, path): + self.path = path + + def __enter__(self): + sys.path.insert(0, self.path) + + def __exit__(self, exc_type, exc_value, traceback): + try: + sys.path.remove(self.path) + except ValueError: + pass + + +def find_file_by_keyword(directory, keyword): + for root, dirs, files in os.walk(directory): + for file in files: + if keyword in file: + return file diff --git a/testcases/functional_tests/test_sdk_client.py b/testcases/functional_tests/test_sdk_client.py index 6a3069d..4028ab9 100644 --- a/testcases/functional_tests/test_sdk_client.py +++ b/testcases/functional_tests/test_sdk_client.py @@ -23,15 +23,10 @@ def tearDown(self): def get_test_service_data(): - config = { - "private_key": os.environ['SNET_TEST_WALLET_PRIVATE_KEY'], - "eth_rpc_endpoint": f"https://sepolia.infura.io/v3/{os.environ['SNET_TEST_INFURA_KEY']}", - "concurrency": False, - "identity_name": "test", - "identity_type": "key", - "network": "sepolia", - "force_update": False - } + config = sdk.config.Config(private_key=os.environ['SNET_TEST_WALLET_PRIVATE_KEY'], + eth_rpc_endpoint=f"https://sepolia.infura.io/v3/{os.environ['SNET_TEST_INFURA_KEY']}", + concurrency=False, + force_update=False) snet_sdk = sdk.SnetSDK(config) diff --git a/version.py b/version.py index a5cfdf5..dcbfb52 100644 --- a/version.py +++ b/version.py @@ -1 +1 @@ -__version__ = "3.4.1" +__version__ = "3.5.0"