diff --git a/.gitignore b/.gitignore
index eac73b6c..9b2b39ad 100644
--- a/.gitignore
+++ b/.gitignore
@@ -196,7 +196,7 @@ Setup/outlook_addin_with_keyring-cache/
# ==========================
-# Enable Build folder for Nuget packages
+# Enable Build folder for Nuget packages
# ==========================
!Nuget/*/build/
@@ -206,13 +206,14 @@ Setup/outlook_addin_with_keyring-cache/
# Config files
# ==========================
-SDK/Source/Virgil.SDK.Tests/App.config
-SDK/Source/Virgil.SDK.Tests/App_Prod.config
-SDK/Source/Virgil.SDK.Tests/App_Stg.config
-
+SDK/Source/Virgil.SDK.Tests.Shared/App.config
+SDK/Source/Virgil.SDK.Tests.Shared/App_Prod.config
+SDK/Source/Virgil.SDK.Tests.Shared/App_Stg.config
+SDK/Source/.vs/
Nuget/__pycache__
Nuget/output
+.idea/
# ==========================
# MacOS
@@ -221,3 +222,16 @@ Nuget/output
*.DS_Store
/doc/
myresults.xml
+/docs/
+
+#============================
+vs external project for c# 2.0
+#============================
+SDK/Source/Virgil.SDK.Shared/Crypto/Crypto.csproj
+SDK/Source/Virgil.SDK.Shared/Crypto/Crypto.sln
+SDK/Source/Virgil.SDK.Shared/Crypto/app.config
+SDK/Source/Virgil.SDK.Shared/Crypto/packages.config
+app.config
+app-prod.config
+# Studio
+*.userprefs
diff --git a/LICENSE.md b/LICENSE.md
index 6348eb78..099be9b0 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,4 +1,7 @@
-# Copyright 2017 Virgil Security
+The BSD 3-Clause License (BSD)
+
+Copyright (c) 2018, Virgil Security, Inc.
+All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
diff --git a/Nuget/CryptoLib/Package.nuspec b/Nuget/CryptoLib/Package.nuspec
index c4d99eed..94fb79e1 100644
--- a/Nuget/CryptoLib/Package.nuspec
+++ b/Nuget/CryptoLib/Package.nuspec
@@ -28,7 +28,7 @@
https://avatars0.githubusercontent.com/u/9740508
false
http://opensource.org/licenses/Apache-2.0
- © 2016 Virgil Security, Inc.
+ © 2018 Virgil Security, Inc.
diff --git a/Nuget/virgil-crypto-api.py b/Nuget/virgil-crypto-api.py
new file mode 100644
index 00000000..fc702539
--- /dev/null
+++ b/Nuget/virgil-crypto-api.py
@@ -0,0 +1,9 @@
+import msbuilder
+
+proj = r'..\SDK\Source\Virgil.CryptoApi\Virgil.CryptoAPI.csproj'
+spec = r'..\SDK\Source\Virgil.CryptoApi\Virgil.CryptoAPI.spec'
+output = r'.\output'
+
+builder = msbuilder.MsBuilder()
+builder.build(proj)
+builder.pack(proj, output)
\ No newline at end of file
diff --git a/Nuget/virgil-crypto-impl.py b/Nuget/virgil-crypto-impl.py
new file mode 100644
index 00000000..7f5de7f8
--- /dev/null
+++ b/Nuget/virgil-crypto-impl.py
@@ -0,0 +1,9 @@
+import msbuilder
+
+proj = r'..\..\virgil-sdk-crypto-net\Virgil.CryptoImpl\Virgil.CryptoImpl.csproj'
+spec = r'..\..\virgil-sdk-crypto-net\Virgil.CryptoImpl\Virgil.CryptoImpl.nuspec'
+output = r'.\output'
+
+builder = msbuilder.MsBuilder()
+builder.build(proj)
+builder.pack(proj, output)
\ No newline at end of file
diff --git a/Nuget/virgil-sdk-contracts.py b/Nuget/virgil-sdk-contracts.py
deleted file mode 100644
index 1c820172..00000000
--- a/Nuget/virgil-sdk-contracts.py
+++ /dev/null
@@ -1,8 +0,0 @@
-import msbuilder
-
-proj = r'..\SDK\Source\Virgil.SDK.Contracts\Virgil.SDK.Contracts.csproj'
-output = r'.\output'
-
-builder = msbuilder.MsBuilder()
-builder.build(proj)
-builder.pack(proj, output)
\ No newline at end of file
diff --git a/Nuget/virgil-sdk.py b/Nuget/virgil-sdk.py
index c028c7b9..2bc99a6e 100644
--- a/Nuget/virgil-sdk.py
+++ b/Nuget/virgil-sdk.py
@@ -1,6 +1,8 @@
import msbuilder
proj = r'..\SDK\Source\Virgil.SDK.NetFx\Virgil.SDK.NetFx.csproj'
+spec = r'..\SDK\Source\Virgil.SDK.NetFx\Virgil.SDK.NetFx.nuspec'
+nuget = r'C:\Users\Vasilina\Documents\projects\sdk-net2\virgil-sdk-net\SDK\Source\.nuget\NuGet.exe'
output = r'.\output'
builder = msbuilder.MsBuilder()
diff --git a/README.md b/README.md
index a44a2120..3346400d 100644
--- a/README.md
+++ b/README.md
@@ -1,121 +1,146 @@
-# Virgil Security .NET/C# SDK
+# Virgil Security .NET/C# SDK
[](https://ci.appveyor.com/project/unlim-it/virgil-sdk-net/branch/release) [](https://www.nuget.org/packages/Virgil.SDK/)
+[](https://github.com/VirgilSecurity/virgil/blob/master/LICENSE)
+
+
+[Introduction](#installation) | [SDK Features](#sdk-features) | [Installation](#installation) | [Usage Examples](#usage-examples) | [Docs](#docs) | [Support](#support)
-[Installation](#installation) | [Encryption Example](#encryption-example) | [Initialization](#initialization) | [Documentation](#documentation) | [Reference API][_reference_api] | [Support](#support)
[Virgil Security](https://virgilsecurity.com) provides a set of APIs for adding security to any application. In a few simple steps you can encrypt communication, securely store data, provide passwordless login, and ensure data integrity.
-For a full overview head over to our .NET/C# [Get Started][_getstarted] guides.
+The Virgil SDK allows developers to get up and running with Virgil API quickly and add full end-to-end security to their existing digital solutions to become HIPAA and GDPR compliant and more.
-## Installation
+## SDK Features
+- communicate with [Virgil Cards Service][_cards_service]
+- manage users' Public Keys
+- store private keys in secure local storage
+- use Virgil [Crypto library][_virgil_crypto]
+- use your own Crypto
-The Virgil .NET SDK is provided as a package named *Virgil.SDK*. The package is distributed via NuGet package management system.
-The package is available for .NET Framework 4.5 and newer.
-Installing the package
+## Installation
-1. Use NuGet Package Manager (Tools -> Library Package Manager -> Package Manager Console)
-2. Run `PM> Install-Package Virgil.SDK`
+The Virgil .NET SDK is provided as a package named Virgil.SDK. The package is distributed via [NuGet package](https://docs.microsoft.com/en-us/nuget/quickstart/use-a-package) management system.
-__Next:__ [Get Started with the .NET/C# SDK][_getstarted].
+The package is available for .NET Framework 4.5 and newer.
-## Encryption Example
+Installing the package using Package Manager Console:
-Virgil Security makes it super easy to add encryption to any application. With our SDK you create a public [__Virgil Card__][_guide_virgil_cards] for every one of your users and devices. With these in place you can easily encrypt any data in the client.
+```bash
+Run PM> Install-Package Virgil.SDK
+```
-```csharp
-// find Alice's card(s)
-var aliceCards = await virgil.Cards.FindAsync("alice");
+## Usage Examples
-// encrypt the message using Alice's cards
-var message = "Hello Alice!";
-var encryptedMessage = aliceCards.Encrypt(message);
+#### Generate and publish user's Cards with Public Keys inside on Cards Service
+Use the following lines of code to create and publish a user's Card with Public Key inside on Virgil Cards Service:
-// transmit the message with your preferred technology
-this.TransmitMessage(encryptedMessage.ToString(StringEncoding.Base64));
-```
+```cs
+using Virgil.CryptoImpl;
+using Virgil.SDK;
-The receiving user then uses their stored __private key__ to decrypt the message.
+var crypto = new VirgilCrypto();
+// generate a key pair
+var keyPair = crypto.GenerateKeys();
-```csharp
-// load Alice's Key from storage.
-var aliceKey = virgil.Keys.Load("alice_key_1", "mypassword");
+// save a private key into key storage
+privateKeyStorage.Store(keyPair.PrivateKey, "Alice");
-// decrypt the message using the key
-var originalMessage = aliceKey.Decrypt(transferData).ToString();
+// publish user's on the Cards Service
+var card = await cardManager.PublishCardAsync(
+ new CardParams()
+ {
+ PublicKey = keyPair.PublicKey,
+ PrivateKey = keyPair.PrivateKey,
+ });
```
-__Next:__ To [get you properly started][_guide_encryption] you'll need to know how to create and store Virgil Cards. Our [Get Started guide][_guide_encryption] will get you there all the way.
+#### Sign then encrypt data
+
+Virgil SDK lets you use a user's Private key and his or her Cards to sign, then encrypt any kind of data.
-__Also:__ [Encrypted communication][_getstarted_encryption] is just one of the few things our SDK can do. Have a look at our guides on [Encrypted Storage][_getstarted_storage], [Data Integrity][_getstarted_data_integrity] and [Passwordless Login][_getstarted_passwordless_login] for more information.
+In the following example, we load a Private Key from a customized Key Storage and get recipient's Card from the Virgil Cards Services. Recipient's Card contains a Public Key on which we will encrypt the data and verify a signature.
-## Initialization
+```cs
+using Virgil.CryptoImpl;
+using Virgil.SDK;
-To use this SDK you need to [sign up for an account](https://developer.virgilsecurity.com/account/signup) and create your first __application__. Make sure to save the __app id__, __private key__ and it's __password__. After this, create an __application token__ for your application to make authenticated requests from your clients.
+// prepare a message
+var messageToEncrypt = "Hello, Bob!";
+var dataToEncrypt = Bytes.FromString(messageToEncrypt);
-To initialize the SDK on the client side you will only need the __access token__ you created.
+// prepare a user's private key
+var (alicePrivateKey, alicePrivateKeyAdditionalData) = privateKeyStorage.Load("Alice");
-```csharp
-var virgil = new VirgilApi("[ACCESS_TOKEN]");
+// using cardManager search for Bob's cards on Cards Service
+var cards = await cardManager.SearchCardsAsync("Bob");
+var bobRelevantCardsPublicKeys = cards.Select(x => x.PublicKey).ToArray();
+
+// sign a message with a private key then encrypt using Bob's public keys
+var encryptedData = crypto.SignThenEncrypt(dataToEncrypt, alicePrivateKey, bobRelevantCardsPublicKeys);
```
-> __Note:__ this client will have limited capabilities. For example, it will be able to generate new __Cards__ but it will need a server-side client to transmit these to Virgil.
+#### Decrypt then verify data
+Once the Users receive the signed and encrypted message, they can decrypt it with their own Private Key and verify signature with a Sender's Card:
+
+```cs
+using Virgil.CryptoImpl;
+using Virgil.SDK;
-To initialize the SDK on the server side we will need the __access token__, __app id__ and the __App Key__ you created on the [Developer Dashboard](https://developer.virgilsecurity.com/account/dashboard).
+// prepare a user's private key
+var (bobPrivateKey, bobPrivateKeyAdditionalData) = privateKeyStorage.Load("Bob");
-```csharp
-var context = new VirgilApiContext
-{
- AccessToken = "[YOUR_ACCESS_TOKEN_HERE]",
- Credentials = new AppCredentials
- {
- AppId = "[YOUR_APP_ID_HERE]",
- AppKeyData = VirgilBuffer.FromFile("[YOUR_APP_KEY_PATH_HERE]"),
- AppKeyPassword = "[YOUR_APP_KEY_PASSWORD_HERE]"
- }
-};
+// using cardManager search for Alice's cards on Cards Service
+var cards = await cardManager.SearchCardsAsync("Alice");
+var aliceRelevantCardsPublicKeys = cards.Select(x => x.PublicKey).ToArray();
-var virgil = new VirgilApi(context);
+// decrypt with a private key and verify using one of Alice's public keys
+var decryptedData = crypto.DecryptThenVerify(encryptedData, bobPrivateKey, aliceRelevantCardsPublicKeys);
```
-Next: [Learn more about our the different ways of initializing the .NET/C# SDK][_guide_initialization] in our documentation.
+## Docs
+Virgil Security has a powerful set of APIs, and the documentation below can get you started today.
-## Documentation
+In order to use the Virgil SDK with your application, you will need to first configure your application. By default, the SDK will attempt to look for Virgil-specific settings in your application but you can change it during SDK configuration.
-Virgil Security has a powerful set of APIs, and the documentation is there to get you started today.
+* [Configure the SDK][_configure_sdk] documentation
+ * [Setup authentication][_setup_authentication] to make API calls to Virgil Services
+ * [Setup Card Manager][_card_manager] to manage user's Public Keys
+ * [Setup Card Verifier][_card_verifier] to verify signatures inside of user's Card
+ * [Setup Key storage][_key_storage] to store Private Keys
+ * [Setup your own Crypto library][_own_crypto] inside of the SDK
+* [More usage examples][_more_examples]
+ * [Create & publish a Card][_create_card] that has a Public Key on Virgil Cards Service
+ * [Search user's Card by user's identity][_search_card]
+ * [Get user's Card by its ID][_get_card]
+ * [Use Card for crypto operations][_use_card]
+* [Reference API][_reference_api]
-* [Get Started][_getstarted_root] documentation
- * [Initialize the SDK][_initialize_root]
- * [Encrypted storage][_getstarted_storage]
- * [Encrypted communication][_getstarted_encryption]
- * [Data integrity][_getstarted_data_integrity]
- * [Passwordless login][_getstarted_passwordless_login]
-* [Guides][_guides]
- * [Virgil Cards][_guide_virgil_cards]
- * [Virgil Keys][_guide_virgil_keys]
-* [Reference API][_reference_api]
## License
This library is released under the [3-clause BSD License](LICENSE.md).
## Support
-
-Our developer support team is here to help you. You can find us on [Twitter](https://twitter.com/virgilsecurity) and [email](support).
-
-[support]: mailto:support@virgilsecurity.com
-[_getstarted_root]: https://developer.virgilsecurity.com/docs/cs/get-started
-[_getstarted]: https://developer.virgilsecurity.com/docs/cs/guides
-[_getstarted_encryption]: https://developer.virgilsecurity.com/docs/cs/get-started/encrypted-communication
-[_getstarted_storage]: https://developer.virgilsecurity.com/docs/cs/get-started/encrypted-storage
-[_getstarted_data_integrity]: https://developer.virgilsecurity.com/docs/cs/get-started/data-integrity
-[_getstarted_passwordless_login]: https://developer.virgilsecurity.com/docs/cs/get-started/passwordless-authentication
-[_guides]: https://developer.virgilsecurity.com/docs/cs/guides
-[_guide_initialization]: https://developer.virgilsecurity.com/docs/cs/guides/settings/install-sdk
-[_guide_virgil_cards]: https://developer.virgilsecurity.com/docs/cs/guides/virgil-card/creating
-[_guide_virgil_keys]: https://developer.virgilsecurity.com/docs/cs/guides/virgil-key/generating
-[_guide_encryption]: https://developer.virgilsecurity.com/docs/cs/guides/encryption/encrypting
-[_initialize_root]: https://developer.virgilsecurity.com/docs/cs/guides/settings/initialize-sdk-on-client
-[_reference_api]: http://virgilsecurity.github.io/virgil-sdk-net/
+Our developer support team is here to help you.
+
+You can find us on [Twitter](https://twitter.com/VirgilSecurity) or send us email support@VirgilSecurity.com.
+
+Also, get extra help from our support team on [Slack](https://join.slack.com/t/VirgilSecurity/shared_invite/enQtMjg4MDE4ODM3ODA4LTc2OWQwOTQ3YjNhNTQ0ZjJiZDc2NjkzYjYxNTI0YzhmNTY2ZDliMGJjYWQ5YmZiOGU5ZWEzNmJiMWZhYWVmYTM).
+
+[_virgil_crypto]: https://github.com/VirgilSecurity/virgil-sdk-crypto-net
+[_cards_service]: https://developer.virgilsecurity.com/docs/api-reference/card-service/v5
+[_use_card]: https://developer.virgilsecurity.com/docs/cs/how-to/public-key-management/use-card-for-crypto-operation
+[_get_card]: https://developer.virgilsecurity.com/docs/cs/how-to/public-key-management/get-card
+[_search_card]: https://developer.virgilsecurity.com/docs/cs/how-to/public-key-management/search-card
+[_create_card]: https://developer.virgilsecurity.com/docs/cs/how-to/public-key-management/create-card
+[_own_crypto]: https://developer.virgilsecurity.com/docs/cs/how-to/setup/setup-own-crypto-library
+[_key_storage]: https://developer.virgilsecurity.com/docs/cs/how-to/setup/setup-key-storage
+[_card_verifier]: https://developer.virgilsecurity.com/docs/cs/how-to/setup/setup-card-verifier
+[_card_manager]: https://developer.virgilsecurity.com/docs/cs/how-to/setup/setup-card-manager
+[_setup_authentication]: https://developer.virgilsecurity.com/docs/cs/how-to/setup/setup-authentication
+[_reference_api]: https://developer.virgilsecurity.com/docs/api-reference
+[_configure_sdk]: https://developer.virgilsecurity.com/docs/how-to#sdk-configuration
+[_more_examples]: https://developer.virgilsecurity.com/docs/how-to#public-key-management
diff --git a/SDK/Source/.nuget/NuGet.Config b/SDK/Source/.nuget/NuGet.Config
index 67f8ea04..308b678b 100644
--- a/SDK/Source/.nuget/NuGet.Config
+++ b/SDK/Source/.nuget/NuGet.Config
@@ -1,6 +1,6 @@
-
+
-
\ No newline at end of file
+
diff --git a/SDK/Source/.nuget/NuGet.targets b/SDK/Source/.nuget/NuGet.targets
index 3f8c37b2..4a8b70f0 100644
--- a/SDK/Source/.nuget/NuGet.targets
+++ b/SDK/Source/.nuget/NuGet.targets
@@ -126,11 +126,9 @@
-
+
\ No newline at end of file
diff --git a/SDK/Source/.vs/config/applicationhost.config b/SDK/Source/.vs/config/applicationhost.config
deleted file mode 100644
index a1c32495..00000000
--- a/SDK/Source/.vs/config/applicationhost.config
+++ /dev/null
@@ -1,1038 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/SDK/Source/Virgil.CryptoApi/IAccessTokenSigner.cs b/SDK/Source/Virgil.CryptoApi/IAccessTokenSigner.cs
new file mode 100644
index 00000000..d4b8d470
--- /dev/null
+++ b/SDK/Source/Virgil.CryptoApi/IAccessTokenSigner.cs
@@ -0,0 +1,72 @@
+#region Copyright (C) Virgil Security Inc.
+// Copyright (C) 2015-2018 Virgil Security Inc.
+//
+// Lead Maintainer: Virgil Security Inc.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// (1) Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// (2) Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+//
+// (3) Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+namespace Virgil.CryptoAPI
+{
+ ///
+ /// The provides interface
+ /// to sign access token and verify its signature using and .
+ ///
+ public interface IAccessTokenSigner
+ {
+ ///
+ /// Represents used signature algorithm.
+ ///
+ ///
+ string GetAlgorithm();
+
+ ///
+ /// Generates the digital signature for the specified using
+ /// the specified
+ ///
+ /// The material representation bytes of access token
+ /// for which to compute the signature.
+ /// The private key
+ /// The digital signature for the material representation bytes of access token.
+ byte[] GenerateTokenSignature(byte[] tokenBytes, IPrivateKey privateKey);
+
+ ///
+ /// Verifies that a digital signature is valid by checking the and
+ /// provided and .
+ ///
+ /// The material representation bytes of access token
+ /// for which the has been generated.
+ /// The digital signature for the
+ /// The public key
+ /// True if signature is valid, False otherwise.
+ bool VerifyTokenSignature(byte[] signature, byte[] tokenBytes, IPublicKey publicKey);
+ }
+}
\ No newline at end of file
diff --git a/SDK/Source/Virgil.CryptoApi/ICardCrypto.cs b/SDK/Source/Virgil.CryptoApi/ICardCrypto.cs
new file mode 100644
index 00000000..8d1a6bd6
--- /dev/null
+++ b/SDK/Source/Virgil.CryptoApi/ICardCrypto.cs
@@ -0,0 +1,87 @@
+#region Copyright (C) Virgil Security Inc.
+// Copyright (C) 2015-2018 Virgil Security Inc.
+//
+// Lead Maintainer: Virgil Security Inc.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// (1) Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// (2) Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+//
+// (3) Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+namespace Virgil.CryptoAPI
+{
+ ///
+ /// The interface defines a list of methods that provide a signature
+ /// generation and signature verification methods.
+ ///
+ public interface ICardCrypto
+ {
+ ///
+ /// Generates the digital signature for the specified using
+ /// the specified
+ ///
+ /// The input data for which to compute the signature.
+ /// The private key
+ /// The digital signature for the specified data.
+ byte[] GenerateSignature(byte[] inputBytes, IPrivateKey privateKey);
+
+ ///
+ /// Verifies that a digital signature is valid by checking the and
+ /// provided and .
+ ///
+ /// The input data for which the
+ /// has been generated.
+ /// The digital signature for the
+ /// The public key
+ /// True if signature is valid, False otherwise.
+ bool VerifySignature(byte[] signature, byte[] inputBytes, IPublicKey publicKey);
+
+ ///
+ /// Generates the fingerprint(512-bit hash) for the specified .
+ ///
+ /// The input data for which to compute the fingerprint.
+ /// The fingerprint for specified data.
+ byte[] GenerateSHA512(byte[] inputBytes);
+
+ ///
+ /// Imports the public key from its material representation.
+ ///
+ /// The public key material representation bytes.
+ /// The instance of imported
+ /// from .
+ IPublicKey ImportPublicKey(byte[] publicKeyBytes);
+
+ ///
+ /// Exports the provided into material representation bytes.
+ ///
+ /// The public key
+ /// The public key material representation bytes.
+ byte[] ExportPublicKey(IPublicKey publicKey);
+ }
+}
diff --git a/SDK/Source/Virgil.SDK.Contracts/Cryptography/IPrivateKey.cs b/SDK/Source/Virgil.CryptoApi/IPrivateKey.cs
similarity index 92%
rename from SDK/Source/Virgil.SDK.Contracts/Cryptography/IPrivateKey.cs
rename to SDK/Source/Virgil.CryptoApi/IPrivateKey.cs
index cc1088dd..0b826d68 100644
--- a/SDK/Source/Virgil.SDK.Contracts/Cryptography/IPrivateKey.cs
+++ b/SDK/Source/Virgil.CryptoApi/IPrivateKey.cs
@@ -1,5 +1,5 @@
#region Copyright (C) Virgil Security Inc.
-// Copyright (C) 2015-2016 Virgil Security Inc.
+// Copyright (C) 2015-2018 Virgil Security Inc.
//
// Lead Maintainer: Virgil Security Inc.
//
@@ -34,11 +34,11 @@
// POSSIBILITY OF SUCH DAMAGE.
#endregion
-namespace Virgil.SDK.Cryptography
+namespace Virgil.CryptoAPI
{
///
- /// The object represents an opaque reference to keying material
- /// that is managed by the agent.
+ /// The object represents an opaque reference to
+ /// keying material that is managed by the agent.
///
public interface IPrivateKey
{
diff --git a/SDK/Source/Virgil.CryptoApi/IPrivateKeyExporter.cs b/SDK/Source/Virgil.CryptoApi/IPrivateKeyExporter.cs
new file mode 100644
index 00000000..ca58cf8b
--- /dev/null
+++ b/SDK/Source/Virgil.CryptoApi/IPrivateKeyExporter.cs
@@ -0,0 +1,64 @@
+#region Copyright (C) Virgil Security Inc.
+// Copyright (C) 2015-2018 Virgil Security Inc.
+//
+// Lead Maintainer: Virgil Security Inc.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// (1) Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// (2) Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+//
+// (3) Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+
+namespace Virgil.CryptoAPI
+{
+
+ ///
+ /// The provides interface
+ /// to export into its material representation bytes and
+ /// import from its material representation bytes.
+ ///
+ public interface IPrivateKeyExporter
+ {
+ ///
+ /// Exports the provided into material representation bytes.
+ ///
+ /// The private key.
+ /// The private key material representation bytes.
+ byte[] ExportPrivatekey(IPrivateKey privateKey);
+
+
+ ///
+ /// Imports the private key from its material representation.
+ ///
+ /// The private key material representation bytes.
+ /// The instance of imported
+ /// from .
+ IPrivateKey ImportPrivateKey(byte[] privateKeyBytes);
+ }
+}
diff --git a/SDK/Source/Virgil.SDK.Contracts/Cryptography/IPublicKey.cs b/SDK/Source/Virgil.CryptoApi/IPublicKey.cs
similarity index 92%
rename from SDK/Source/Virgil.SDK.Contracts/Cryptography/IPublicKey.cs
rename to SDK/Source/Virgil.CryptoApi/IPublicKey.cs
index 94956158..62487351 100644
--- a/SDK/Source/Virgil.SDK.Contracts/Cryptography/IPublicKey.cs
+++ b/SDK/Source/Virgil.CryptoApi/IPublicKey.cs
@@ -1,5 +1,5 @@
#region Copyright (C) Virgil Security Inc.
-// Copyright (C) 2015-2016 Virgil Security Inc.
+// Copyright (C) 2015-2018 Virgil Security Inc.
//
// Lead Maintainer: Virgil Security Inc.
//
@@ -34,11 +34,11 @@
// POSSIBILITY OF SUCH DAMAGE.
#endregion
-namespace Virgil.SDK.Cryptography
+namespace Virgil.CryptoAPI
{
///
- /// The object represents an opaque reference to keying material
- /// that is managed by the agent.
+ /// The object represents an opaque reference to
+ /// keying material that is managed by the agent.
///
public interface IPublicKey
{
diff --git a/SDK/Source/Virgil.CryptoApi/Properties/AssemblyInfo.cs b/SDK/Source/Virgil.CryptoApi/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..2b266b32
--- /dev/null
+++ b/SDK/Source/Virgil.CryptoApi/Properties/AssemblyInfo.cs
@@ -0,0 +1,26 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes.
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle("Virgil.CryptoAPI")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
diff --git a/SDK/Source/Virgil.CryptoApi/Virgil.CryptoAPI.nuspec b/SDK/Source/Virgil.CryptoApi/Virgil.CryptoAPI.nuspec
new file mode 100644
index 00000000..8cb0e273
--- /dev/null
+++ b/SDK/Source/Virgil.CryptoApi/Virgil.CryptoAPI.nuspec
@@ -0,0 +1,39 @@
+
+
+
+ Virgil.CryptoAPI
+ $version$
+ Virgil.CryptoAPI
+ Virgil Security, Inc
+ Virgil Security, Inc
+ Virgil.CryptoAPI provides the required interfaces to Virgil.SDK.
+
+
+
+Virgil Security allows for every developer can build cryptographic features including end-to-end encryption, passwordless authentication, and cryptographic verification of data, devices, and identities into their products, with no cryptographic training. Virgil SDK simplifies their work with Virgil Security services(keys management and identities validation) and Crypto Library(modern algorithms with crypto agility).
+
+Docs - https://developer.virgilsecurity.com/docs/cs
+Source - https://github.com/VirgilSecurity/virgil-sdk-net
+
+Supported Platforms:
+ - .NET Framework 4.5+
+ - ASP.NET Core 1.0+
+ - Windows 8+
+ - Windows Phone 8.1+
+ - Windows Phone Silverlight 8+
+ - Xamarin.Android
+ - Xamarin.iOS
+ - Xamarin.iOS (Classic)
+
+ en-US
+ https://virgilsecurity.com/
+ https://avatars0.githubusercontent.com/u/9740508
+ false
+ http://opensource.org/licenses/Apache-2.0
+ © 2018 Virgil Security, Inc.
+
+
+
+ PKI, Cryptography, Cross Platform
+
+
\ No newline at end of file
diff --git a/SDK/Source/Virgil.CryptoApi/Virgil.CryptoApi.csproj b/SDK/Source/Virgil.CryptoApi/Virgil.CryptoApi.csproj
new file mode 100644
index 00000000..ee41317e
--- /dev/null
+++ b/SDK/Source/Virgil.CryptoApi/Virgil.CryptoApi.csproj
@@ -0,0 +1,39 @@
+
+
+
+ Debug
+ AnyCPU
+ {BCC9EB08-9768-413E-A69D-FE45699F213D}
+ {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ true
+ Library
+ Virgil.CryptoApi
+ Virgil.CryptoApi
+ v4.5
+ Profile111
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+
+
+ true
+ bin\Release
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SDK/Source/Virgil.SDK.Contracts/Exceptions/KeyEntryAlreadyExistsException.cs b/SDK/Source/Virgil.SDK.Contracts/Exceptions/KeyEntryAlreadyExistsException.cs
deleted file mode 100644
index 35913fcc..00000000
--- a/SDK/Source/Virgil.SDK.Contracts/Exceptions/KeyEntryAlreadyExistsException.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-namespace Virgil.SDK.Exceptions
-{
- ///
- /// The exception that is thrown when an key is already exists.
- ///
- public class KeyEntryAlreadyExistsException : KeyStorageException
- {
- ///
- /// Initializes a new instance of the class.
- ///
- public KeyEntryAlreadyExistsException() : base("Key with specified name is already exists.")
- {
- }
- }
-}
\ No newline at end of file
diff --git a/SDK/Source/Virgil.SDK.Contracts/Exceptions/KeyEntryNotFoundException.cs b/SDK/Source/Virgil.SDK.Contracts/Exceptions/KeyEntryNotFoundException.cs
deleted file mode 100644
index ba59dd1b..00000000
--- a/SDK/Source/Virgil.SDK.Contracts/Exceptions/KeyEntryNotFoundException.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-namespace Virgil.SDK.Exceptions
-{
- ///
- /// The exception that is thrown when an key is not found.
- ///
- public class KeyEntryNotFoundException : KeyStorageException
- {
- ///
- /// Initializes a new instance of the class.
- ///
- public KeyEntryNotFoundException() : base("Key with specified name is not found.")
- {
- }
- }
-}
\ No newline at end of file
diff --git a/SDK/Source/Virgil.SDK.Contracts/Exceptions/SignatureIsNotValidException.cs b/SDK/Source/Virgil.SDK.Contracts/Exceptions/SignatureIsNotValidException.cs
deleted file mode 100644
index 3ace57ab..00000000
--- a/SDK/Source/Virgil.SDK.Contracts/Exceptions/SignatureIsNotValidException.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace Virgil.SDK.Exceptions
-{
- public class SignatureIsNotValidException : CryptoException
- {
- ///
- /// Initializes a new instance of the class.
- ///
- public SignatureIsNotValidException() : base("Digital signature is not valid")
- {
- }
- }
-}
\ No newline at end of file
diff --git a/SDK/Source/Virgil.SDK.Contracts/Exceptions/VirgilException.cs b/SDK/Source/Virgil.SDK.Contracts/Exceptions/VirgilException.cs
deleted file mode 100644
index f9b49523..00000000
--- a/SDK/Source/Virgil.SDK.Contracts/Exceptions/VirgilException.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-namespace Virgil.SDK.Exceptions
-{
- using System;
-
- ///
- /// Represents errors occurred during interaction with SDK components.
- ///
- public class VirgilException : Exception
- {
- public VirgilException(string message) : base(message)
- {
- }
- }
-}
\ No newline at end of file
diff --git a/SDK/Source/Virgil.SDK.Contracts/Virgil.SDK.Contracts.csproj b/SDK/Source/Virgil.SDK.Contracts/Virgil.SDK.Contracts.csproj
index ef2bd3d3..9337882d 100644
--- a/SDK/Source/Virgil.SDK.Contracts/Virgil.SDK.Contracts.csproj
+++ b/SDK/Source/Virgil.SDK.Contracts/Virgil.SDK.Contracts.csproj
@@ -38,19 +38,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/SDK/Source/Virgil.SDK.Droid/Virgil.SDK.Droid.csproj.bak b/SDK/Source/Virgil.SDK.Droid/Virgil.SDK.Droid.csproj.bak
new file mode 100644
index 00000000..3b211df5
--- /dev/null
+++ b/SDK/Source/Virgil.SDK.Droid/Virgil.SDK.Droid.csproj.bak
@@ -0,0 +1,88 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {6B9CE116-871B-4294-AA8E-64DE316AA79A}
+ {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Library
+ Properties
+ Virgil.SDK
+ Virgil.SDK
+ 512
+ Resources\Resource.Designer.cs
+ Off
+ True
+ v6.0
+
+
+
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\packages\Virgil.Crypto.2.2.3\lib\monoandroid\Virgil.Crypto.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {bcc9eb08-9768-413e-a69d-fe45699f213d}
+ Virgil.CryptoApi
+
+
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+
+
+
\ No newline at end of file
diff --git a/SDK/Source/Virgil.SDK.Droid/packages.config b/SDK/Source/Virgil.SDK.Droid/packages.config
new file mode 100644
index 00000000..d2dd5600
--- /dev/null
+++ b/SDK/Source/Virgil.SDK.Droid/packages.config
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SDK/Source/Virgil.SDK.Mac/AppSettings.cs b/SDK/Source/Virgil.SDK.Mac/AppSettings.cs
new file mode 100644
index 00000000..6a2a5363
--- /dev/null
+++ b/SDK/Source/Virgil.SDK.Mac/AppSettings.cs
@@ -0,0 +1,40 @@
+using System.Collections.Generic;
+using System.Configuration;
+using System.IO;
+using Newtonsoft.Json;
+using Virgil.SDK.Common;
+
+namespace Virgil.SDK.Tests
+{
+ public class AppSettings
+ {
+ static AppSettings(){
+ var cryptoTestData = File.ReadAllText("TestData/crypto_compatibility_data.json");
+ AppSettings.CryptoCompatibilityData = cryptoTestData;
+
+ }
+
+ public static string AppId = ConfigurationManager.AppSettings["virgil:AppID"];
+ public static string AccounId = ConfigurationManager.AppSettings["virgil:AccountID"];
+ public static string AppPrivateKeyPassword = ConfigurationManager.AppSettings["virgil:AppKeyPassword"];
+ public static string ApiPublicKeyId = ConfigurationManager.AppSettings["virgil:AccessPublicKeyId"];
+ public static string ApiPrivateKeyBase64 = ConfigurationManager.AppSettings["virgil:AccessPrivateKeyBase64"];
+ public static string ServiceCardId = ConfigurationManager.AppSettings["virgil:ServiceCardId"];
+ public static string ServicePublicKeyPemBase64 = ConfigurationManager.AppSettings["virgil:ServicePublicKeyPemBase64"];
+ public static string ServicePublicKeyDerBase64 = ConfigurationManager.AppSettings["virgil:ServicePublicKeyDerBase64"];
+ public static string CryptoCompatibilityData = "";
+ public static string OutputTestDataPath = ConfigurationManager.AppSettings["test:OutputDataPath"];
+ public static string CardsServiceAddress = ConfigurationManager.AppSettings["virgil:CardsServicesAddressV5"];
+
+ public static string PrivateKeySTC31_1 = ConfigurationManager.AppSettings["test:PrivateKeySTC31_1"];
+ public static string PrivateKeySTC31_2 = ConfigurationManager.AppSettings["test:PrivateKeySTC31_2"];
+ public static string PublicKeySTC32 = ConfigurationManager.AppSettings["test:PublicKeySTC32"];
+
+ public static string ImportedAccessPublicKeyId = ConfigurationManager.AppSettings["test:ImportedAccessPublicKeyId"];
+ public static string ImportedAccessPublicKey = ConfigurationManager.AppSettings["test:ImportedAccessPublicKey"];
+
+ public static string PredefinedPrivateKeyBase64 = ConfigurationManager.AppSettings["test:PredefinedPrivateKeyBase64"];
+
+ public static string ImportedJwt = ConfigurationManager.AppSettings["test:ImportedJwt"];
+ }
+}
diff --git a/SDK/Source/Virgil.SDK.Mac/Exceptions/DuplicateKeyException.cs b/SDK/Source/Virgil.SDK.Mac/Exceptions/DuplicateKeyException.cs
new file mode 100644
index 00000000..c9a08be2
--- /dev/null
+++ b/SDK/Source/Virgil.SDK.Mac/Exceptions/DuplicateKeyException.cs
@@ -0,0 +1,13 @@
+namespace Virgil.SDK.Storage.Exceptions
+{
+ ///
+ /// The exception that is thrown when an key already exists.
+ ///
+ public class DuplicateKeyException : SecureStorageException
+ {
+ public DuplicateKeyException(string key)
+ : base($"Specified key '{key}' is already exists in the secure storage.")
+ {
+ }
+ }
+}
diff --git a/SDK/Source/Virgil.SDK.Mac/Exceptions/KeyNotFoundException.cs b/SDK/Source/Virgil.SDK.Mac/Exceptions/KeyNotFoundException.cs
new file mode 100644
index 00000000..03f6e5fe
--- /dev/null
+++ b/SDK/Source/Virgil.SDK.Mac/Exceptions/KeyNotFoundException.cs
@@ -0,0 +1,13 @@
+namespace Virgil.SDK.Storage.Exceptions
+{
+ ///
+ /// The exception that is thrown when the key doesn't exist.
+ ///
+ public class KeyNotFoundException : SecureStorageException
+ {
+ public KeyNotFoundException(string key)
+ : base($"Specified key '{key}' doesn't exist in the secure storage.")
+ {
+ }
+ }
+}
diff --git a/SDK/Source/Virgil.SDK.Mac/Exceptions/SecureStorageException.cs b/SDK/Source/Virgil.SDK.Mac/Exceptions/SecureStorageException.cs
new file mode 100644
index 00000000..c0ba2a49
--- /dev/null
+++ b/SDK/Source/Virgil.SDK.Mac/Exceptions/SecureStorageException.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace Virgil.SDK.Storage.Exceptions
+{
+ public class SecureStorageException : Exception
+ {
+ public SecureStorageException(string message) : base(message)
+ {
+ }
+ }
+}
diff --git a/SDK/Source/Virgil.SDK.Mac/Properties/AssemblyInfo.cs b/SDK/Source/Virgil.SDK.Mac/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..e30f3eac
--- /dev/null
+++ b/SDK/Source/Virgil.SDK.Mac/Properties/AssemblyInfo.cs
@@ -0,0 +1,26 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes.
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle("Virgil.SDK.Mac")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("${AuthorCopyright}")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
diff --git a/SDK/Source/Virgil.SDK.Mac/SecureStorage.cs b/SDK/Source/Virgil.SDK.Mac/SecureStorage.cs
new file mode 100644
index 00000000..f11dbc5e
--- /dev/null
+++ b/SDK/Source/Virgil.SDK.Mac/SecureStorage.cs
@@ -0,0 +1,156 @@
+using System;
+using Foundation;
+using Security;
+using Virgil.SDK.Storage;
+using Virgil.SDK.Storage.Exceptions;
+
+namespace Virgil.SDK.Storage
+{
+ public class SecureStorage
+ {
+ ///
+ /// Storage identity
+ ///
+ public static string StorageIdentity = "Virgil.SecureStorage";
+
+ ///
+ /// Constructor
+ ///
+ public SecureStorage()
+ {
+ if (string.IsNullOrWhiteSpace(StorageIdentity))
+ {
+ throw new SecureStorageException("StorageIdentity can't be empty");
+ }
+ }
+
+ ///
+ /// Stores the key data to the given alias.
+ ///
+ /// The alias.
+ /// The key data.
+ ///
+ public void Save(string alias, byte[] data)
+ {
+ this.ValidateAlias(alias);
+ this.ValidateData(data);
+
+ if (this.Exists(alias))
+ {
+ throw new DuplicateKeySecureStorageException(alias);
+ }
+ var record = NewSecRecord(alias, data);
+ var result = SecKeyChain.Add(record);
+ if (result != SecStatusCode.Success)
+ {
+ throw new SecureStorageException($"The key under alias '{alias}' can't be saved.");
+ };
+ }
+
+ ///
+ /// Checks if the key data exists in this storage by given alias.
+ ///
+ /// The alias.
+ /// true if the key data exists, false otherwise
+ public bool Exists(string alias)
+ {
+ this.ValidateAlias(alias);
+
+ return (this.FindRecord(alias).Item1 == SecStatusCode.Success);
+ }
+
+ ///
+ /// Loads the key data associated with the given alias.
+ ///
+ /// The alias.
+ ///
+ /// The requested data, or exception if the given key does not exist.
+ ///
+ ///
+ public byte[] Load(string alias)
+ {
+ this.ValidateAlias(alias);
+
+ var foundSecRecordWithStatus = this.FindRecord(alias);
+ if (foundSecRecordWithStatus.Item1 == SecStatusCode.Success)
+ {
+ return foundSecRecordWithStatus.Item2.ValueData.ToArray();
+ }
+
+ throw new KeyNotFoundSecureStorageException(alias);
+ }
+
+ ///
+ /// Delete key data by the alias in this storage.
+ ///
+ /// The alias.
+ ///
+ public void Delete(string alias)
+ {
+ this.ValidateAlias(alias);
+
+ var foundSecRecordWithStatus = this.FindRecord(alias);
+ if (foundSecRecordWithStatus.Item1 != SecStatusCode.Success)
+ {
+ throw new KeyNotFoundSecureStorageException(alias);
+ }
+ var secRecord = NewSecRecord(alias, null);
+ SecKeyChain.Remove(secRecord);
+ }
+
+ ///
+ /// Returns the list of aliases
+ ///
+ public string[] Aliases()
+ {
+ // all labels at the Virgil storage
+ var secRecord = new SecRecord(SecKind.GenericPassword) { Service = StorageIdentity };
+ var foundSecRecords = SecKeyChain.QueryAsRecord(secRecord, 100, out var secStatusCode);
+ var aliases = new string[foundSecRecords.Length];
+
+ for (var i = 0; i < foundSecRecords.Length; i++)
+ {
+ aliases[i] = foundSecRecords[i].Label;
+ }
+ return aliases;
+ }
+
+ private Tuple FindRecord(string alias)
+ {
+ var secRecord = NewSecRecord(alias, null);
+ var found = SecKeyChain.QueryAsRecord(secRecord, out var secStatusCode);
+ return new Tuple(secStatusCode, found);
+ }
+
+ private SecRecord NewSecRecord(string alias, byte[] data)
+ {
+ var secRecord = new SecRecord(SecKind.GenericPassword)
+ {
+ Account = alias,
+ Service = StorageIdentity,
+ Label = alias
+ };
+ if (data != null && data.Length > 0)
+ {
+ secRecord.ValueData = NSData.FromArray(data);
+ }
+ return secRecord;
+ }
+
+ private void ValidateAlias(string alias)
+ {
+ if (string.IsNullOrWhiteSpace(alias))
+ {
+ throw new ArgumentException($"{nameof(alias)} can't be empty.");
+ }
+ }
+
+ private void ValidateData(byte[] data)
+ {
+ if (data == null || data.Length == 0)
+ {
+ throw new ArgumentException($"{nameof(data)} can't be empty.");
+ }
+ }
+ }
+}
diff --git a/SDK/Source/Virgil.SDK.Mac/Virgil.SDK.Mac.csproj b/SDK/Source/Virgil.SDK.Mac/Virgil.SDK.Mac.csproj
new file mode 100644
index 00000000..5c037699
--- /dev/null
+++ b/SDK/Source/Virgil.SDK.Mac/Virgil.SDK.Mac.csproj
@@ -0,0 +1,75 @@
+
+
+
+ Debug
+ AnyCPU
+ {D4FDF98B-0EF0-47E3-ABCF-675CECC0C22D}
+ {A3F8F2AB-B479-4A4A-A458-A89E7DC349F1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Library
+ Virgil.SDK.Mac
+ Virgil.SDK.Mac
+ Resources
+ v2.0
+ Xamarin.Mac
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ false
+ false
+ false
+ false
+ false
+ HttpClientHandler
+ None
+
+
+
+ true
+ bin\Release
+
+ prompt
+ 4
+ false
+ false
+ false
+ false
+ false
+ HttpClientHandler
+ None
+
+
+
+
+
+
+
+
+
+
+ ..\packages\Virgil.Crypto.2.2.5\lib\xamarinmac\Virgil.Crypto.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SDK/Source/Virgil.SDK.Mac/packages.config b/SDK/Source/Virgil.SDK.Mac/packages.config
new file mode 100644
index 00000000..415d80d0
--- /dev/null
+++ b/SDK/Source/Virgil.SDK.Mac/packages.config
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/SDK/Source/Virgil.SDK.Shared/Client/CardInfoModel.cs b/SDK/Source/Virgil.SDK.NetFx/Exceptions/DuplicateKeyException.cs
similarity index 81%
rename from SDK/Source/Virgil.SDK.Shared/Client/CardInfoModel.cs
rename to SDK/Source/Virgil.SDK.NetFx/Exceptions/DuplicateKeyException.cs
index c39cb482..638dec24 100644
--- a/SDK/Source/Virgil.SDK.Shared/Client/CardInfoModel.cs
+++ b/SDK/Source/Virgil.SDK.NetFx/Exceptions/DuplicateKeyException.cs
@@ -1,5 +1,5 @@
#region Copyright (C) Virgil Security Inc.
-// Copyright (C) 2015-2016 Virgil Security Inc.
+// Copyright (C) 2015-2018 Virgil Security Inc.
//
// Lead Maintainer: Virgil Security Inc.
//
@@ -33,20 +33,16 @@
// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#endregion
-
-namespace Virgil.SDK.Client
+namespace Virgil.SDK.Exceptions
{
- using Newtonsoft.Json;
-
///
- /// Represents a transfered object that provide information about device.
+ /// The exception that is thrown when an key already exists.
///
- public class CardInfoModel
+ public class DuplicateKeyException : SecureStorageException
{
- [JsonProperty("device")]
- public string Device { get; set; }
-
- [JsonProperty("device_name")]
- public string DeviceName { get; set; }
+ public DuplicateKeyException(string key)
+ : base($"Specified key '{key}' is already exists in the secure storage.")
+ {
+ }
}
-}
\ No newline at end of file
+}
diff --git a/SDK/Source/Virgil.SDK.Shared/Client/TransferObjects/SignableRequestMetaModel.cs b/SDK/Source/Virgil.SDK.NetFx/Exceptions/KeyNotFoundException.cs
similarity index 80%
rename from SDK/Source/Virgil.SDK.Shared/Client/TransferObjects/SignableRequestMetaModel.cs
rename to SDK/Source/Virgil.SDK.NetFx/Exceptions/KeyNotFoundException.cs
index 6b84fc56..55c57298 100644
--- a/SDK/Source/Virgil.SDK.Shared/Client/TransferObjects/SignableRequestMetaModel.cs
+++ b/SDK/Source/Virgil.SDK.NetFx/Exceptions/KeyNotFoundException.cs
@@ -1,5 +1,5 @@
#region Copyright (C) Virgil Security Inc.
-// Copyright (C) 2015-2017 Virgil Security Inc.
+// Copyright (C) 2015-2018 Virgil Security Inc.
//
// Lead Maintainer: Virgil Security Inc.
//
@@ -33,18 +33,16 @@
// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#endregion
-
-namespace Virgil.SDK.Client
+namespace Virgil.SDK.Exceptions
{
- using System.Collections.Generic;
- using Newtonsoft.Json;
-
- internal class SignableRequestMetaModel
+ ///
+ /// The exception that is thrown when the key doesn't exist.
+ ///
+ public class KeyNotFoundException : SecureStorageException
{
- [JsonProperty("signs")]
- public Dictionary Signatures { get; set; }
-
- [JsonProperty("validation")]
- public SignableRequestValidationModel Validation { get; set; }
+ public KeyNotFoundException(string key)
+ : base($"Specified key '{key}' doesn't exist in the secure storage.")
+ {
+ }
}
-}
\ No newline at end of file
+}
diff --git a/SDK/Source/Virgil.SDK.Shared/IdentityType.cs b/SDK/Source/Virgil.SDK.NetFx/Exceptions/SecureStorageException.cs
similarity index 84%
rename from SDK/Source/Virgil.SDK.Shared/IdentityType.cs
rename to SDK/Source/Virgil.SDK.NetFx/Exceptions/SecureStorageException.cs
index 98975060..89aaed24 100644
--- a/SDK/Source/Virgil.SDK.Shared/IdentityType.cs
+++ b/SDK/Source/Virgil.SDK.NetFx/Exceptions/SecureStorageException.cs
@@ -1,5 +1,5 @@
-#region Copyright (C) Virgil Security Inc.
-// Copyright (C) 2015-2017 Virgil Security Inc.
+#region Copyright (C) Virgil Security Inc.
+// Copyright (C) 2015-2018 Virgil Security Inc.
//
// Lead Maintainer: Virgil Security Inc.
//
@@ -33,17 +33,14 @@
// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#endregion
+using System;
-namespace Virgil.SDK
+namespace Virgil.SDK.Exceptions
{
- using System.Runtime.Serialization;
-
- public enum IdentityType
+ public class SecureStorageException : Exception
{
- [EnumMember(Value = "application")]
- Application,
-
- [EnumMember(Value = "email")]
- Email
+ public SecureStorageException(string message) : base(message)
+ {
+ }
}
-}
\ No newline at end of file
+}
diff --git a/SDK/Source/Virgil.SDK.NetFx/KeyStorageReaderV4.cs b/SDK/Source/Virgil.SDK.NetFx/KeyStorageReaderV4.cs
new file mode 100644
index 00000000..c25597fc
--- /dev/null
+++ b/SDK/Source/Virgil.SDK.NetFx/KeyStorageReaderV4.cs
@@ -0,0 +1,154 @@
+#region Copyright (C) Virgil Security Inc.
+// Copyright (C) 2015-2018 Virgil Security Inc.
+//
+// Lead Maintainer: Virgil Security Inc.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// (1) Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// (2) Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+//
+// (3) Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+#endregion
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+using System.Security.Cryptography;
+using Newtonsoft.Json;
+
+namespace Virgil.SDK
+{
+ public class KeyStorageReaderV4
+ {
+ ///
+ /// The provides an opportunity to load keys
+ /// which were saved in previous storage version from SDK v4
+ ///
+
+ private readonly string keysPath;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public KeyStorageReaderV4(string keysFolderPath, bool isAbsolutePath = true)
+ {
+ if (isAbsolutePath)
+ {
+ this.keysPath = keysFolderPath;
+ }
+ else
+ {
+ var appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
+ this.keysPath = Path.Combine(appData, "VirgilSecurity", keysFolderPath);
+ }
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public KeyStorageReaderV4()
+ {
+ var appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
+ this.keysPath = Path.Combine(appData, "VirgilSecurity", "Keys");
+ }
+
+
+ ///
+ /// Loads the key associated with the given alias from SDK v4 storage.
+ ///
+ /// The alias name.
+ ///
+ ///
+ /// The requested key, or null if the given alias does not exist or does
+ /// not identify a key-related entry.
+ ///
+ public Tuple> Load(string keyName)
+ {
+
+ if (!this.Exists(keyName))
+ {
+ throw new KeyNotFoundException();
+ }
+
+ var keyEntryType = new
+ {
+ value = new byte[] { },
+ meta_data = new Dictionary()
+ };
+
+ var encryptedData = File.ReadAllBytes(this.GetKeyPairPath(keyName));
+ var data = ProtectedData.Unprotect(encryptedData, null, DataProtectionScope.CurrentUser);
+ var keyEntryJson = Encoding.UTF8.GetString(data);
+
+ var keyEntryObject = JsonConvert.DeserializeAnonymousType(keyEntryJson, keyEntryType);
+
+ return new Tuple>(keyEntryObject.value, keyEntryObject.meta_data);
+
+ }
+
+ ///
+ /// Checks if the key associated with the given alias exists in this SDK v4 keystore.
+ ///
+ /// The alias name.
+ public bool Exists(string keyName)
+ {
+ return File.Exists(this.GetKeyPairPath(keyName));
+ }
+
+ public string[] Names()
+ {
+ if (Directory.Exists(this.keysPath))
+ {
+ return Directory.GetFiles(this.keysPath).Select(f => Path.GetFileName(f)).ToArray();
+ }
+ else
+ {
+ return new string[] { };
+ }
+ }
+
+ ///
+ /// Delete the key associated with the given alias from this SDK v4 keystore.
+ ///
+ /// The alias name.
+ ///
+ public void Delete(string keyName)
+ {
+ if (!this.Exists(keyName))
+ throw new KeyNotFoundException();
+
+ File.Delete(this.GetKeyPairPath(keyName));
+ }
+
+ private string GetKeyPairPath(string alias)
+ {
+ return Path.Combine(this.keysPath, alias.ToLower());
+ }
+
+ }
+}
diff --git a/SDK/Source/Virgil.SDK.NetFx/Properties/AssemblyInfo.cs b/SDK/Source/Virgil.SDK.NetFx/Properties/AssemblyInfo.cs
index 13273ce5..795646eb 100644
--- a/SDK/Source/Virgil.SDK.NetFx/Properties/AssemblyInfo.cs
+++ b/SDK/Source/Virgil.SDK.NetFx/Properties/AssemblyInfo.cs
@@ -2,37 +2,38 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-// General Information about an assembly is controlled through the following
+// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
-[assembly: AssemblyTitle("Virgil.SDK")]
-[assembly: AssemblyDescription("Virgil SDK enable simplified software development through the use of an intuitive and straightforward Virgil Services. \nhttps://virgilsecurity.com/docs/sdk/net/index\nSupported Platforms:\n- Xamarin(MonoMac, MonoTouch, MonoAndroid, Xamarin.Mac, Xamarin iOS Universal)\n- Portable Libraries(.NET Framework 4+, Silverlight 5.0, Windows 8+)")]
+[assembly: AssemblyTitle("Virgil.SDK.NetFx")]
+[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("Virgil Security, Inc")]
-[assembly: AssemblyProduct("Virgil.SDK")]
-[assembly: AssemblyCopyright("© 2016 Virgil Security, Inc.")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Virgil.SDK.NetFx")]
+[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
+[assembly: InternalsVisibleTo("Virgil.SDK.Tests")]
+[assembly: InternalsVisibleTo("Virgil.SDK.Tests.Shared")]
+
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
-[assembly: InternalsVisibleTo("Virgil.SDK.Tests")]
-[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("e597b732-df22-4899-b27b-4c47aac4ee3f")]
+[assembly: Guid("724be592-c519-4490-9057-f62f3b2fee2c")]
// Version information for an assembly consists of the following four values:
//
// Major Version
-// Minor Version
+// Minor Version
// Build Number
// Revision
//
-// You can specify all the values or you can default the Build and Revision Numbers
+// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("4.3.1.0")]
-[assembly: AssemblyFileVersion("4.3.1.0")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/SDK/Source/Virgil.SDK.NetFx/SecureStorage.cs b/SDK/Source/Virgil.SDK.NetFx/SecureStorage.cs
new file mode 100644
index 00000000..b84cd2b0
--- /dev/null
+++ b/SDK/Source/Virgil.SDK.NetFx/SecureStorage.cs
@@ -0,0 +1,182 @@
+using System;
+using System.IO;
+using System.IO.IsolatedStorage;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using Virgil.SDK.Exceptions;
+
+namespace Virgil.SDK
+{
+
+ public class SecureStorage
+ {
+ ///
+ /// Storage identity
+ ///
+ public static string StorageIdentity = "Virgil.SecureStorage";
+
+ ///
+ /// User-scoped isolated storage
+ ///
+ private readonly IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForAssembly();
+
+ ///
+ /// Password for storage
+ ///
+ private byte[] password;
+ ///
+ /// Constructor
+ ///
+ /// Password for storage
+ public SecureStorage(string password)
+ {
+
+ if (string.IsNullOrWhiteSpace(StorageIdentity))
+ {
+ throw new SecureStorageException("StorageIdentity can't be empty");
+ }
+ if (string.IsNullOrWhiteSpace(password))
+ {
+ throw new SecureStorageException("Password can't be empty");
+ }
+ this.password = Encoding.UTF8.GetBytes(password);
+ }
+
+ ///
+ /// Stores the key data to the given alias.
+ ///
+ /// The alias.
+ /// The key data.
+ ///
+ public void Save(string alias, byte[] data)
+ {
+ this.ValidateAlias(alias);
+
+ this.ValidateData(data);
+
+ if (this.Exists(alias))
+ {
+ throw new DuplicateKeyException(alias);
+ }
+ var encryptedData = ProtectedData.Protect(data, this.password, DataProtectionScope.CurrentUser);
+
+ if (!this.appStorage.DirectoryExists(StorageIdentity))
+ {
+ this.appStorage.CreateDirectory(StorageIdentity);
+ }
+
+ try
+ {
+ // save encrypted bytes to file
+ using (var stream = this.appStorage.CreateFile(this.FilePath(alias)))
+ {
+ stream.Write(encryptedData, 0, encryptedData.Length);
+ stream.Close();
+ }
+ }
+ catch (Exception)
+ {
+ throw new SecureStorageException($"The key under alias '{alias}' can't be saved.");
+ }
+ }
+
+ ///
+ /// Checks if the key data exists in this storage by given alias.
+ ///
+ /// The alias.
+ /// true if the key data exists, false otherwise
+ public bool Exists(string alias)
+ {
+ this.ValidateAlias(alias);
+
+ return this.appStorage.FileExists(this.FilePath(alias));
+ }
+
+ ///
+ /// Loads the key data associated with the given alias.
+ ///
+ /// The alias.
+ ///
+ /// The requested data, or exception if the given key does not exist.
+ ///
+ ///
+ public byte[] Load(string alias)
+ {
+ this.ValidateAlias(alias);
+
+ if (this.Exists(alias))
+ {
+ using (var stream = this.appStorage.OpenFile(this.FilePath(alias),
+ FileMode.Open,
+ FileAccess.ReadWrite))
+ {
+ // allocate and read the protected data
+ var protectedData = new byte[stream.Length];
+ stream.Read(protectedData, 0, (int)stream.Length);
+
+ try
+ {
+ // obtain clear data by decrypting
+ return ProtectedData.Unprotect(protectedData, this.password,
+ DataProtectionScope.CurrentUser);
+ }
+ catch (CryptographicException)
+ {
+ throw new SecureStorageException("Wrong password.");
+ }
+ }
+ }
+ throw new KeyNotFoundException(alias);
+ }
+
+ ///
+ /// Delete key data by the alias in this storage.
+ ///
+ /// The alias.
+ ///
+ public void Delete(string alias)
+ {
+ this.ValidateAlias(alias);
+
+ if (!this.Exists(alias))
+ {
+ throw new KeyNotFoundException(alias);
+ }
+ this.appStorage.DeleteFile(this.FilePath(alias));
+ }
+
+ ///
+ /// Returns the list of aliases that are kept in the storage.
+ ///
+ public string[] Aliases()
+ {
+ //all filenames at the root of app storage
+ var fileNames = this.appStorage.GetFileNames($"{StorageIdentity}\\*");
+ //all keys
+ return fileNames.Select(x => Encoding.UTF8.GetString(Convert.FromBase64String(x))).ToArray();
+ }
+
+ private string FilePath(string key)
+ {
+ var keyBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(key));
+ return $"{StorageIdentity}\\{keyBase64}";
+ }
+
+ private void ValidateAlias(string alias)
+ {
+ if (string.IsNullOrWhiteSpace(alias))
+ {
+ throw new ArgumentException($"{nameof(alias)} can't be empty.");
+ }
+ }
+
+ private void ValidateData(byte[] data)
+ {
+ if (data == null || data.Length == 0)
+ {
+ throw new ArgumentException($"{nameof(data)} can't be empty.");
+ }
+ }
+ }
+}
diff --git a/SDK/Source/Virgil.SDK.NetFx/Virgil.SDK.NetFx.csproj b/SDK/Source/Virgil.SDK.NetFx/Virgil.SDK.NetFx.csproj
index df9e6681..e94af352 100644
--- a/SDK/Source/Virgil.SDK.NetFx/Virgil.SDK.NetFx.csproj
+++ b/SDK/Source/Virgil.SDK.NetFx/Virgil.SDK.NetFx.csproj
@@ -1,10 +1,10 @@

-
+
Debug
AnyCPU
- {E597B732-DF22-4899-B27B-4C47AAC4EE3F}
+ {724BE592-C519-4490-9057-F62F3B2FEE2C}
Library
Properties
Virgil.SDK
@@ -13,6 +13,7 @@
512
+
true
@@ -24,7 +25,8 @@
4
- pdbonly
+
+
true
bin\Release\
TRACE
@@ -32,12 +34,12 @@
4
-
- ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll
- True
+
+ ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
+
@@ -46,40 +48,20 @@
-
- ..\packages\Virgil.Crypto.2.1.2\lib\portable-net4+sl4+wp7+win8+wpa81\Virgil.Crypto.dll
- True
-
-
- ..\packages\Virgil.SDK.Contracts.1.1.2.0\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+xamarinios10+MonoTouch10\Virgil.SDK.Contracts.dll
- True
+
+ ..\packages\Virgil.CryptoAPI.1.0.0\lib\portable-net45+win+wpa81+MonoTouch10+xamarinmac20\Virgil.CryptoApi.dll
-
+
+
+
+
+
-
-
-
-
-
-
-
-
- This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
-
-
\ No newline at end of file
diff --git a/SDK/Source/Virgil.SDK.NetFx/Virgil.SDK.NetFx.nuspec b/SDK/Source/Virgil.SDK.NetFx/Virgil.SDK.NetFx.nuspec
deleted file mode 100644
index 8436d338..00000000
--- a/SDK/Source/Virgil.SDK.NetFx/Virgil.SDK.NetFx.nuspec
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
- Virgil.SDK
- $version$
- Virgil.SDK
- Virgil Security, Inc
- Virgil Security, Inc
- With Virgil Security every developer can build cryptographic features including end-to-end encryption, passwordless authentication, and cryptographic verification of data, devices, and identities into their products, with no cryptographic training. Virgil SDK simplifies their work with Virgil Security services(keys management and identities validation) and Crypto Library(modern algorithms with crypto agility).
-
-
-
-With Virgil Security every developer can build cryptographic features including end-to-end encryption, passwordless authentication, and cryptographic verification of data, devices, and identities into their products, with no cryptographic training. Virgil SDK simplifies their work with Virgil Security services(keys management and identities validation) and Crypto Library(modern algorithms with crypto agility).
-
-Docs - https://virgilsecurity.com/docs/sdk/net/v4.0(latest)/dot-net-csharp-sdk
-Source - https://github.com/VirgilSecurity/virgil-sdk-net
-
-Supported Platforms:
- - .NET Framework 4.5+
- - Windows 8+
-
- en-US
- https://virgilsecurity.com/
- https://avatars0.githubusercontent.com/u/9740508
- false
- http://opensource.org/licenses/Apache-2.0
- © 2016 Virgil Security, Inc.
-
-
-
- PKI, Cryptography, Crossplatform
-
-
\ No newline at end of file
diff --git a/SDK/Source/Virgil.SDK.NetFx/VirgilApiContext.cs b/SDK/Source/Virgil.SDK.NetFx/VirgilApiContext.cs
deleted file mode 100644
index ddcc9c42..00000000
--- a/SDK/Source/Virgil.SDK.NetFx/VirgilApiContext.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-#region Copyright (C) Virgil Security Inc.
-// Copyright (C) 2015-2016 Virgil Security Inc.
-//
-// Lead Maintainer: Virgil Security Inc.
-//
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// (1) Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// (2) Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in
-// the documentation and/or other materials provided with the
-// distribution.
-//
-// (3) Neither the name of the copyright holder nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR
-// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
-// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-#endregion
-
-namespace Virgil.SDK
-{
- using Virgil.SDK.Device;
- using Virgil.SDK.Storage;
-
- ///
- /// The class manages the dependencies during run time.
- /// It also contains a list of preperties that uses to configurate the high-level components.
- ///
- public partial class VirgilApiContext
- {
- private IKeyStorage GetDefaultKeyStorage()
- {
- return new DefaultKeyStorage();
- }
-
- private IDeviceManager GetDefaultDeviceManager()
- {
- return new DeviceManager();
- }
- }
-}
\ No newline at end of file
diff --git a/SDK/Source/Virgil.SDK.NetFx/VirgilBuffer.cs b/SDK/Source/Virgil.SDK.NetFx/VirgilBuffer.cs
deleted file mode 100644
index 5e3ccd53..00000000
--- a/SDK/Source/Virgil.SDK.NetFx/VirgilBuffer.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-#region Copyright (C) Virgil Security Inc.
-// Copyright (C) 2015-2016 Virgil Security Inc.
-//
-// Lead Maintainer: Virgil Security Inc.
-//
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// (1) Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// (2) Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in
-// the documentation and/or other materials provided with the
-// distribution.
-//
-// (3) Neither the name of the copyright holder nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR
-// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
-// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-#endregion
-
-namespace Virgil.SDK
-{
- using System.IO;
-
- ///
- /// The class provides a list of methods that
- /// simplify the work with an array of bytes.
- ///
- public partial class VirgilBuffer
- {
- ///
- /// Initializes a new buffer from specified file, reads the contents of the
- /// file into .
- ///
- /// A new instance of class.
- public static VirgilBuffer FromFile(string filePath)
- {
- var fileBytes = File.ReadAllBytes(filePath);
- return new VirgilBuffer(fileBytes);
- }
- }
-}
\ No newline at end of file
diff --git a/SDK/Source/Virgil.SDK.NetFx/packages.config b/SDK/Source/Virgil.SDK.NetFx/packages.config
index 522b4a97..3d0bea68 100644
--- a/SDK/Source/Virgil.SDK.NetFx/packages.config
+++ b/SDK/Source/Virgil.SDK.NetFx/packages.config
@@ -1,6 +1,5 @@

-
-
-
+
+
\ No newline at end of file
diff --git a/SDK/Source/Virgil.SDK.Shared/AppCredentials.cs b/SDK/Source/Virgil.SDK.Shared/AppCredentials.cs
deleted file mode 100644
index 2fde6732..00000000
--- a/SDK/Source/Virgil.SDK.Shared/AppCredentials.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-#region Copyright (C) Virgil Security Inc.
-// Copyright (C) 2015-2016 Virgil Security Inc.
-//
-// Lead Maintainer: Virgil Security Inc.
-//
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions
-// are met:
-//
-// (1) Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// (2) Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in
-// the documentation and/or other materials provided with the
-// distribution.
-//
-// (3) Neither the name of the copyright holder nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR
-// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-// DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
-// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-// POSSIBILITY OF SUCH DAMAGE.
-#endregion
-
-namespace Virgil.SDK
-{
- using Virgil.SDK.Cryptography;
-
- ///
- /// Provides credentials for application authentication using AppID and AppKey
- /// retrieved from development deshboard.
- ///
- public class AppCredentials : Credentials
- {
- ///
- /// Gets or sets the application ID that uniquely identifies your application in our services,
- /// and it is also used to identify the Virgil Card/Public key generated in a pair with .
- ///
- public string AppId { get; set; }
-
- ///
- /// Gets or sets the application key that is representing a Private key that is used to perform
- /// creation and revocation of Virgil Cards (Public key) in Virgil services. Also the can
- /// be used for cryptographic operations to take part in application logic.
- ///
- public VirgilBuffer AppKey { get; set; }
-
- ///
- /// Gets or sets the application key password that is used to protect the .
- ///
- public string AppKeyPassword { get; set; }
-
- ///
- /// Gets the application used to authenticate Publish/Revoke Card requests.
- ///
- public override IPrivateKey GetAppKey(ICrypto crypto)
- {
- var authorityPrivateKey = crypto.ImportPrivateKey(this.AppKey.GetBytes(), this.AppKeyPassword);
- return authorityPrivateKey;
- }
-
- ///
- /// Gets the application identifier.
- ///
- public override string GetAppId()
- {
- return this.AppId;
- }
- }
-}
\ No newline at end of file
diff --git a/SDK/Source/Virgil.SDK.Shared/Card.cs b/SDK/Source/Virgil.SDK.Shared/Card.cs
new file mode 100644
index 00000000..e6ffd0db
--- /dev/null
+++ b/SDK/Source/Virgil.SDK.Shared/Card.cs
@@ -0,0 +1,133 @@
+#region Copyright (C) Virgil Security Inc.
+// Copyright (C) 2015-2018 Virgil Security Inc.
+//
+// Lead Maintainer: Virgil Security Inc.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// (1) Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// (2) Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+//
+// (3) Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+namespace Virgil.SDK
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+
+ using Virgil.CryptoAPI;
+
+ using Virgil.SDK.Common;
+ using Virgil.SDK.Web;
+
+ ///
+ /// The class is the main entity of Virgil Services. Every user/device is
+ /// represented with a Virgil Card which contains a public key and information about identity.
+ ///
+ public class Card
+ {
+ private List signatures;
+
+ private Card()
+ {
+ }
+
+ internal Card(
+ string cardId,
+ string identity,
+ IPublicKey publicKey,
+ string version,
+ DateTime createdAt,
+ List signautes,
+ string previousCardId,
+ byte[] contentSnapshot,
+ bool isOutDated = false
+ )
+ {
+ this.Id = cardId;
+ this.Identity = identity;
+ this.PublicKey = publicKey;
+ this.Version = version;
+ this.CreatedAt = createdAt;
+ this.signatures = signautes;
+ this.PreviousCardId = previousCardId;
+ this.ContentSnapshot = contentSnapshot;
+ this.IsOutdated = isOutDated;
+ }
+
+ ///
+ /// Gets the Card ID that uniquely identifies the Card in Virgil Services.
+ ///
+ public string Id { get; private set; }
+
+ ///
+ /// Gets the identity value that can be anything which identifies the user in your application.
+ ///
+ public string Identity { get; private set; }
+
+ ///
+ /// Gets the public key.
+ ///
+ public IPublicKey PublicKey { get; private set; }
+
+ ///
+ /// Gets the version of the card.
+ ///
+ public string Version { get; private set; }
+
+ ///
+ /// Gets the date and time fo card creation in UTC.
+ ///
+ public DateTime CreatedAt { get; private set; }
+
+ ///
+ /// Get previous Card ID that current card is used to override to.
+ ///
+ public string PreviousCardId { get; private set; }
+
+ ///
+ /// Get previous Card that current card is used to override to.
+ ///
+ public Card PreviousCard { get; internal set; }
+
+ ///
+ /// Get the snapshot of .
+ ///
+ public byte[] ContentSnapshot { get; private set; }
+
+ ///
+ /// Whether the card is overridden by another card.
+ ///
+ public bool IsOutdated { get; internal set; }
+
+ ///
+ /// Gets a list of signatures.
+ ///
+ public IReadOnlyList Signatures => this.signatures;
+ }
+}
diff --git a/SDK/Source/Virgil.SDK.Shared/CardManager.cs b/SDK/Source/Virgil.SDK.Shared/CardManager.cs
new file mode 100644
index 00000000..bce15168
--- /dev/null
+++ b/SDK/Source/Virgil.SDK.Shared/CardManager.cs
@@ -0,0 +1,412 @@
+#region Copyright (C) Virgil Security Inc.
+// Copyright (C) 2015-2018 Virgil Security Inc.
+//
+// Lead Maintainer: Virgil Security Inc.
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// (1) Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// (2) Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in
+// the documentation and/or other materials provided with the
+// distribution.
+//
+// (3) Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Virgil.SDK.Signer;
+using Virgil.SDK.Web.Authorization;
+
+namespace Virgil.SDK
+{
+ using System.Threading.Tasks;
+ using Virgil.CryptoAPI;
+ using Virgil.SDK.Common;
+ using Verification;
+ using Virgil.SDK.Web;
+
+ ///
+ /// The provides operations with Virgil Cards.
+ ///
+ public class CardManager
+ {
+ ///
+ /// an instance of which provides cryptographic operations.
+ ///
+ public readonly ICardCrypto CardCrypto;
+
+
+ public readonly ModelSigner ModelSigner;
+
+ public ICardClient Client { get; internal set; }
+
+ ///
+ /// an instance of which provides card verification.
+ ///
+ public readonly ICardVerifier CardVerifier;
+
+ ///
+ /// CallBack which performs additional signatures for card before publishing.
+ ///
+ public readonly Func> SignCallBack;
+
+ ///
+ /// an instance of which provides token delivery.
+ ///
+ public readonly IAccessTokenProvider AccessTokenProvider;
+
+ ///
+ /// If true repeats once a request to the after
+ /// getting .
+ ///
+ public readonly bool RetryOnUnauthorized;
+
+ ///
+ /// Initializes a new instance of the class by
+ /// a specified set of parameters.
+ ///
+ /// the instance of .
+ public CardManager(CardManagerParams @params)
+ {
+ ValidateCardManagerParams(@params);
+ this.CardCrypto = @params.CardCrypto;
+ this.AccessTokenProvider = @params.AccessTokenProvider;
+ this.Client = string.IsNullOrWhiteSpace(@params.ApiUrl)
+ ? new CardClient()
+ : new CardClient(@params.ApiUrl);
+
+ this.CardVerifier = @params.Verifier;
+ this.ModelSigner = new ModelSigner(CardCrypto);
+ this.SignCallBack = @params.SignCallBack;
+ this.RetryOnUnauthorized = @params.RetryOnUnauthorized;
+ }
+
+
+ private static void ValidateCardManagerParams(CardManagerParams @params)
+ {
+ if (@params.CardCrypto == null)
+ {
+ throw new ArgumentException($"{nameof(@params.CardCrypto)} property is mandatory");
+ }
+
+ if (@params.AccessTokenProvider == null)
+ {
+ throw new ArgumentException($"{nameof(@params.AccessTokenProvider)} property is mandatory");
+ }
+ }
+
+ ///
+ /// Gets the card by specified ID.
+ ///
+ /// The card ID to be found.
+ /// The instance of found .
+ public async Task GetCardAsync(string cardId)
+ {
+ if (String.IsNullOrWhiteSpace(cardId))
+ {
+ throw new ArgumentException(nameof(cardId));
+ }
+ var tokenContext = new TokenContext(null, "get");
+ var accessToken = await AccessTokenProvider.GetTokenAsync(tokenContext);
+
+ var cardWithStatus = (Tuple)await TryExecute(
+ async (IAccessToken token) =>
+ {
+ return await this.Client.GetCardAsync(cardId,
+ token.ToString());
+ }, tokenContext, accessToken);
+ var card = CardUtils.Parse(this.CardCrypto, (RawSignedModel)cardWithStatus.Item1, cardWithStatus.Item2);
+
+ if (card.Id != cardId)
+ {
+ throw new CardVerificationException("Invalid card");
+ }
+ this.ValidateCards(new Card[] { card });
+
+ return card;
+ }
+
+ ///
+ /// Searches for cards by specified identity.
+ ///
+ /// The identity to be found.
+ /// The list of found .
+ public async Task> SearchCardsAsync(string identity)
+ {
+ if (String.IsNullOrWhiteSpace(identity))
+ {
+ throw new ArgumentException(nameof(identity));
+ }
+ var tokenContext = new TokenContext(null, "search");
+ var accessToken = await AccessTokenProvider.GetTokenAsync(tokenContext);
+ var rawCards = await TryExecute(
+ async (IAccessToken token) =>
+ {
+ return await Client.SearchCardsAsync(identity,
+ token.ToString()
+ );
+ }, tokenContext, accessToken);
+
+ var cards = CardUtils.Parse(this.CardCrypto, (IEnumerable)rawCards).ToArray();
+ if (cards.Any(x => x.Identity != identity))
+ {
+ throw new CardVerificationException("Invalid cards");
+ }
+ this.ValidateCards(cards);
+ return CardUtils.LinkedCardLists(cards);
+ }
+
+ ///
+ /// Publish a new Card using specified .
+ ///
+ /// The instance of class.
+ /// It should has mandatory parameters: public key, private key
+ /// The instance of newly published class.
+ public async Task PublishCardAsync(CardParams cardParams)
+ {
+ ValidateCardParams(cardParams);
+
+ var tokenContext = new TokenContext(cardParams.Identity, "publish");
+
+ var token = await this.AccessTokenProvider.GetTokenAsync(tokenContext);
+ var rawSignedModel = GenerateRawCard(new CardParams()
+ {
+ Identity = token.Identity(),
+ PrivateKey = cardParams.PrivateKey,
+ PublicKey = cardParams.PublicKey,
+ PreviousCardId = cardParams.PreviousCardId,
+ ExtraFields = cardParams.ExtraFields
+ });
+
+ return await PublishRawSignedModel(rawSignedModel, tokenContext, token);
+ }
+
+ private async Task PublishRawSignedModel(RawSignedModel rawSignedModel,
+ TokenContext context,
+ IAccessToken accessToken)
+ {
+ if (this.SignCallBack != null)
+ {
+ rawSignedModel = await this.SignCallBack.Invoke(rawSignedModel);
+ }
+
+ var publishedModel = await TryExecute(
+ async (IAccessToken token) =>
+ {
+ var rawCard = await Client.PublishCardAsync(
+ rawSignedModel,
+ token.ToString()
+ );
+ return rawCard;
+ }, context, accessToken);
+
+ if (!rawSignedModel.ContentSnapshot.SequenceEqual(((RawSignedModel)publishedModel).ContentSnapshot))
+ {
+ throw new CardVerificationException("Publishing returns invalid card");
+ }
+ var card = CardUtils.Parse(this.CardCrypto, (RawSignedModel)publishedModel);
+ this.ValidateCards(new[] { card });
+
+ return card;
+ }
+
+ private async Task