Showing preview only (201K chars total). Download the full file or copy to clipboard to get everything.
Repository: dnauck/Portable.Licensing
Branch: develop
Commit: 6ec8ce3b20d0
Files: 71
Total size: 182.3 KB
Directory structure:
gitextract_zc1asx_w/
├── .gitignore
├── .paket/
│ └── paket.targets
├── .travis.yml
├── Icons/
│ └── Portable.Licensing.icns
├── LICENSE.md
├── Portable.Licensing.nuspec
├── README.md
├── Samples/
│ ├── Android.Sample/
│ │ ├── Android.Sample/
│ │ │ ├── Android.Sample.csproj
│ │ │ ├── Assets/
│ │ │ │ └── AboutAssets.txt
│ │ │ ├── MainActivity.cs
│ │ │ ├── Properties/
│ │ │ │ └── AssemblyInfo.cs
│ │ │ └── Resources/
│ │ │ ├── AboutResources.txt
│ │ │ ├── Layout/
│ │ │ │ └── Main.axml
│ │ │ ├── Resource.Designer.cs
│ │ │ └── Values/
│ │ │ └── Strings.xml
│ │ ├── Android.Sample.sln
│ │ └── Android.Sample.sln.DotSettings
│ └── iOS.Sample/
│ ├── iOS.Sample/
│ │ ├── AppDelegate.cs
│ │ ├── Info.plist
│ │ ├── Main.cs
│ │ ├── MyViewController.cs
│ │ ├── Properties/
│ │ │ └── AssemblyInfo.cs
│ │ └── iOS.Sample.csproj
│ ├── iOS.Sample.sln
│ └── iOS.Sample.sln.DotSettings
├── Tools/
│ └── xpkg/
│ └── xpkg
├── Xamarin/
│ ├── Details.md
│ └── GettingStarted.md
├── appveyor.yml
├── build-runTests.bat
├── build.bat
├── build.fsx
├── build.sh
├── lib/
│ └── License.txt
├── paket.dependencies
└── src/
├── CommonAssemblyInfo.cs
├── Portable.Licensing/
│ ├── AssemblyBuildDateAttribute.cs
│ ├── Customer.cs
│ ├── IFluentInterface.cs
│ ├── ILicenseBuilder.cs
│ ├── License.cs
│ ├── LicenseAttributes.cs
│ ├── LicenseBuilder.cs
│ ├── LicenseType.cs
│ ├── Portable.Licensing.csproj
│ ├── Properties/
│ │ └── AssemblyInfo.cs
│ ├── Security/
│ │ └── Cryptography/
│ │ ├── KeyFactory.cs
│ │ ├── KeyGenerator.cs
│ │ └── KeyPair.cs
│ └── Validation/
│ ├── GeneralValidationFailure.cs
│ ├── IAddAdditionalValidationChain.cs
│ ├── IAssertValidation.cs
│ ├── ICompleteValidationChain.cs
│ ├── ILicenseValidator.cs
│ ├── IStartValidationChain.cs
│ ├── IValidationChain.cs
│ ├── IValidationChainCondition.cs
│ ├── IValidationFailure.cs
│ ├── InvalidSignatureValidationFailure.cs
│ ├── LicenseExpiredValidationFailure.cs
│ ├── LicenseValidationExtensions.cs
│ ├── LicenseValidator.cs
│ └── ValidationChainBuilder.cs
├── Portable.Licensing.Tests/
│ ├── KeyGeneratorTests.cs
│ ├── LicenseSignatureTests.cs
│ ├── LicenseValidationTests.cs
│ ├── Portable.Licensing.Tests.csproj
│ ├── Properties/
│ │ └── AssemblyInfo.cs
│ └── paket.references
├── Portable.Licensing.sln
└── Portable.Licensing.sln.DotSettings
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
/Build
/Publish
/Distribution
/nant-*.log*
packages/
BuildMetrics/
#ignore thumbnails created by windows
Thumbs.db
#Ignore files build by Visual Studio
*.obj
*.exe
*.pdb
*.user
*.aps
*.pch
*.vspscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.cache
*.ilk
*.log
[Bb]in
[Dd]ebug*/
*.lib
*.sbr
obj/
[Rr]elease*/
_ReSharper*/
[Tt]est[Rr]esult*
*.userprefs
================================================
FILE: .paket/paket.targets
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<!-- Enable the restore command to run before builds -->
<RestorePackages Condition=" '$(RestorePackages)' == '' ">true</RestorePackages>
<!-- Download Paket.exe if it does not already exist -->
<DownloadPaket Condition=" '$(DownloadPaket)' == '' ">true</DownloadPaket>
<PaketToolsPath>$(MSBuildThisFileDirectory)</PaketToolsPath>
<PaketRootPath>$(MSBuildThisFileDirectory)..\</PaketRootPath>
</PropertyGroup>
<PropertyGroup>
<!-- Paket command -->
<PaketExePath Condition=" '$(PaketExePath)' == '' ">$(PaketToolsPath)paket.exe</PaketExePath>
<PaketBootStrapperExePath Condition=" '$(PaketBootStrapperExePath)' == '' ">$(PaketToolsPath)paket.bootstrapper.exe</PaketBootStrapperExePath>
<PaketCommand Condition=" '$(OS)' == 'Windows_NT'">"$(PaketExePath)"</PaketCommand>
<PaketCommand Condition=" '$(OS)' != 'Windows_NT' ">mono --runtime=v4.0.30319 $(PaketExePath)</PaketCommand>
<PaketBootStrapperCommand Condition=" '$(OS)' == 'Windows_NT'">"$(PaketBootStrapperExePath)"</PaketBootStrapperCommand>
<PaketBootStrapperCommand Condition=" '$(OS)' != 'Windows_NT' ">mono --runtime=v4.0.30319 $(PaketBootStrapperExePath)</PaketBootStrapperCommand>
<!-- Commands -->
<PaketReferences Condition="!Exists('$(MSBuildProjectFullPath).paket.references')">$(MSBuildProjectDirectory)\paket.references</PaketReferences>
<PaketReferences Condition="Exists('$(MSBuildProjectFullPath).paket.references')">$(MSBuildProjectFullPath).paket.references</PaketReferences>
<RestoreCommand>$(PaketCommand) restore --references-files $(PaketReferences)</RestoreCommand>
<DownloadPaketCommand>$(PaketBootStrapperCommand)</DownloadPaketCommand>
<!-- We need to ensure packages are restored prior to assembly resolve -->
<BuildDependsOn Condition="$(RestorePackages) == 'true'">RestorePackages; $(BuildDependsOn);</BuildDependsOn>
</PropertyGroup>
<Target Name="CheckPrerequisites">
<!-- Raise an error if we're unable to locate paket.exe -->
<Error Condition="'$(DownloadPaket)' != 'true' AND !Exists('$(PaketExePath)')" Text="Unable to locate '$(PaketExePath)'" />
<MsBuild Targets="DownloadPaket" Projects="$(MSBuildThisFileFullPath)" Properties="Configuration=NOT_IMPORTANT;DownloadPaket=$(DownloadPaket)" />
</Target>
<Target Name="DownloadPaket">
<Exec Command="$(DownloadPaketCommand)" Condition=" '$(DownloadPaket)' == 'true' AND !Exists('$(PaketExePath)')" />
</Target>
<Target Name="RestorePackages" DependsOnTargets="CheckPrerequisites">
<Exec Command="$(RestoreCommand)" WorkingDirectory="$(PaketRootPath)" Condition="Exists('$(PaketReferences)')" />
</Target>
</Project>
================================================
FILE: .travis.yml
================================================
language: objective-c
env:
matrix:
- MONO_VERSION="3.10.0"
before_install:
- wget "http://download.mono-project.com/archive/${MONO_VERSION}/macos-10-x86/MonoFramework-MDK-${MONO_VERSION}.macos10.xamarin.x86.pkg"
- sudo installer -pkg "MonoFramework-MDK-${MONO_VERSION}.macos10.xamarin.x86.pkg" -target /
- mozroots --import --sync --quiet
script:
- ./build.sh PackageNuGetDistribution
================================================
FILE: LICENSE.md
================================================
The MIT License
Copyright (c) 2012 - 2014 Nauck IT KG http://www.nauck-it.de
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: Portable.Licensing.nuspec
================================================
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>Portable.Licensing</id>
<version>$version$</version>
<authors>Nauck IT KG</authors>
<owners>Daniel Nauck</owners>
<licenseUrl>http://opensource.org/licenses/MIT</licenseUrl>
<projectUrl>http://dev.nauck-it.de/projects/portable-licensing</projectUrl>
<iconUrl>http://www.nauck-it.de/fileadmin/Portable.Licensing/Portable.Licensing.ico</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>
Portable.Licensing is a cross platform software licensing framework which allows you to
implement licensing into your application or library. It provides you all tools to create
and validate licenses for your software.
Portable.Licensing is using the latest military strength, state-of-the-art cryptographic algorithm
to ensure that your software and thus your intellectual property is protected.
It is targeting the Portable Class Library and thus runs on nearly every .NET/Mono profile
including Silverlight, Windows Phone, Windows Store App, Xamarin.iOS, Xamarin.Android, Xamarin.Mac
and XBox 360. Use it for your Desktop- (WinForms, WPF, etc.), Console-, Service-,
Web- (ASP.NET, MVC, etc.), Mobile (Xamarin.iOS, Xamarin.Android) or even LightSwitch applications.
FEATURES
- runs on .NET >= 4.0.3, Silverlight 5, Windows Phone >= 8, Windows Store Apps, Mono, Xamarin.iOS, Xamarin.Android, Xamarin.Mac, XBox 360
- easy creation and validation of your licenses
- trial, standard and subscription licenses
- cryptographic signed licenses, no alteration possible
- allows you to enable/disable program modules or product features
- limit various parameters for your software, e.g. max transactions, etc.
- add additional key/value pair attributes to your licenses
- easily extend the fluent validation API with extension methods
</description>
<copyright>Copyright 2012-2014 Nauck IT KG</copyright>
<tags>Portable.Licensing PCL Portable Licensing License Key KeyGenerator Protection Signing Nauck</tags>
<!--<dependencies>
<dependency id="BouncyCastle" version="1.7" />
</dependencies>-->
</metadata>
<files>
<file src="Distribution/lib/portable-net403+sl5+netcore45+wp8+MonoAndroid1+MonoTouch1/Portable.Licensing.dll" target="lib/portable-net403+sl5+netcore45+wp8+MonoAndroid1+MonoTouch1/Portable.Licensing.dll" />
<file src="Distribution/lib/portable-net403+sl5+netcore45+wp8+MonoAndroid1+MonoTouch1/Portable.Licensing.XML" target="lib/portable-net403+sl5+netcore45+wp8+MonoAndroid1+MonoTouch1/Portable.Licensing.XML" />
<file src="Distribution/Documentation/LICENSE.md" target="LICENSE.md" />
<file src="Distribution/README.txt" target="README.txt" />
</files>
</package>
================================================
FILE: README.md
================================================
# Documentation #
----------
## About Portable.Licensing ##
Portable.Licensing is a cross platform software licensing framework which allows you to implement licensing into your application or library. It provides you all tools to create and validate licenses for your software.
Portable.Licensing is using the latest military strength, state-of-the-art cryptographic algorithm to ensure that your software and thus your intellectual property is protected.
It is targeting the *Portable Class Library* and thus runs on nearly every .NET/Mono profile including Silverlight, Windows Phone, Windows Store App, Xamarin.iOS, Xamarin.Android, Xamarin.Mac and XBox 360. Use it for your Desktop- (WinForms, WPF, etc.), Console-, Service-, Web- (ASP.NET, MVC, etc.), Mobile (Xamarin.iOS, Xamarin.Android) or even LightSwitch applications.
## Features ##
- runs on .NET >= 4.0.3, Silverlight 5, Windows Phone >= 8, Windows Store Apps, Mono, Xamarin.iOS, Xamarin.Android, Xamarin.Mac, XBox 360
- easy creation and validation of your licenses
- trial, standard and subscription licenses
- cryptographic signed licenses, no alteration possible
- allows you to enable/disable program modules or product features
- limit various parameters for your software, e.g. max transactions, etc.
- add additional key/value pair attributes to your licenses
- easily extend the fluent validation API with extension methods
## Build status
| Platform | Status of last build |
| :------ | :------: | :------: |
| **Mono** | [](https://travis-ci.org/dnauck/Portable.Licensing) |
| **Windows** | [](https://ci.appveyor.com/project/dnauck/portable-licensing) |
----------
## Getting started ##
### License.Manager light ###
A reference implementation of a management application for products, customers and licenses is available here: [https://github.com/dnauck/License.Manager-Light](https://github.com/dnauck/License.Manager-Light)
### License.Manager ###
License.Manager is a web-based management solution for Portable.Licensing developed using AngularJS and ServiceStack.
It enables you to manage customers, products and licenses and provides a
REST service backend for integration with payment providers and 3rd party tools.
License.Manager is available here: [https://github.com/dnauck/License.Manager](https://github.com/dnauck/License.Manager)
### Download ###
[Portable.Licensing](https://nuget.org/packages/Portable.Licensing) is distributed with the popular NuGet Packaging Manager. This will make it easier for developers to get the Portable.Licensing distribution into their project.
Go to the NuGet website for more details: [http://nuget.org/](http://nuget.org/)
NuGet provides several ways to get Portable.Licensing into your Project. The easiest way is to right click your project references in Visual Studio and choose the menu item "Manage NuGet Packages".
Search in the "Online" tab for "Portable.Licensing" and click "Install" on your selected packages.
It is also possible to install the Portable.Licensing packages via the "NuGet Package Manager Console".
Type the following to install the Portable.Licensing library:
PM> Install-Package Portable.Licensing
Or use the following command to get a specific version:
PM> Install-Package Portable.Licensing -Version 1.0.0
### Create a private and public key for your product ###
Portable.Licensing uses the Elliptic Curve Digital Signature Algorithmus (ECDSA) to ensure the license cannot be altered after creation.
First you need to create a new public/private key pair for your product:
var keyGenerator = Portable.Licensing.Security.Cryptography.KeyGenerator.Create();
var keyPair = keyGenerator.GenerateKeyPair();
var privateKey = keyPair.ToEncryptedPrivateKeyString(passPhrase);
var publicKey = keyPair.ToPublicKeyString();
Store the private key securely and distribute the public key with your product.
Normally you create one key pair for each product, otherwise it is possible to use a license with all products using the same key pair.
If you want your customer to buy a new license on each major release you can create a key pair for each release and product.
### Create the license generator ###
Now we need something to generate licenses. This could be easily done with the *LicenseFactory*:
var license = License.New()
.WithUniqueIdentifier(Guid.NewGuid())
.As(LicenseType.Trial)
.ExpiresAt(DateTime.Now.AddDays(30))
.WithMaximumUtilization(5)
.WithProductFeatures(new Dictionary<string, string>
{
{"Sales Module", "yes"},
{"Purchase Module", "yes"},
{"Maximum Transactions", "10000"}
})
.LicensedTo("John Doe", "john.doe@yourmail.here")
.CreateAndSignWithPrivateKey(privateKey, passPhrase);
Now you can take the license and save it to a file:
File.WriteAllText("License.lic", license.ToString(), Encoding.UTF8);
or
license.Save(xmlWriter);
### Validate the license in your application ###
The easiest way to assert the license is in the entry point of your application.
First load the license from a file or resource:
var license = License.Load(...);
Then you can assert the license:
using Portable.Licensing.Validation;
var validationFailures = license.Validate()
.ExpirationDate()
.When(lic => lic.Type == LicenseType.Trial)
.And()
.Signature(publicKey)
.AssertValidLicense();
Portable.Licesing will not throw any Exception and just return an enumeration of validation failures.
Now you can iterate over possible validation failures:
foreach (var failure in validationFailures)
Console.WriteLine(failure.GetType().Name + ": " + failure.Message + " - " + failure.HowToResolve);
Or simply check if there is any failure:
if (validationFailures.Any())
// ...
Make sure to call `validationFailures.ToList()` or `validationFailures.ToArray()` before using the result multiple times.
----------
## License ##
Portable.Licensing is distributed using the MIT/X11 License.
## Further Information ##
The latest release and documentation can be found on the Portable.Licensing project website:
[http://dev.nauck-it.de/projects/portable-licensing](http://dev.nauck-it.de/projects/portable-licensing)
================================================
FILE: Samples/Android.Sample/Android.Sample/Android.Sample.csproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{C1669549-42DA-49E5-B88B-A6D0AD0A545F}</ProjectGuid>
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Android.Sample</RootNamespace>
<AssemblyName>Android.Sample</AssemblyName>
<FileAlignment>512</FileAlignment>
<AndroidApplication>true</AndroidApplication>
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AndroidUseSharedRuntime>True</AndroidUseSharedRuntime>
<AndroidLinkMode>None</AndroidLinkMode>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AndroidUseSharedRuntime>False</AndroidUseSharedRuntime>
<AndroidLinkMode>SdkOnly</AndroidLinkMode>
</PropertyGroup>
<ItemGroup>
<Reference Include="Mono.Android" />
<Reference Include="mscorlib" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Xml" />
<Reference Include="Portable.Licensing">
<HintPath>..\Components\Portable.Licensing-1.0.0.0\lib\mobile\Portable.Licensing.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="MainActivity.cs" />
<Compile Include="Resources\Resource.Designer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\AboutResources.txt" />
<None Include="Assets\AboutAssets.txt" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\Layout\Main.axml" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\Values\Strings.xml" />
</ItemGroup>
<ItemGroup>
<AndroidResource Include="Resources\Drawable\Icon.png" />
</ItemGroup>
<ItemGroup>
<XamarinComponent Include="Portable.Licensing">
<Visible>False</Visible>
<Version>1.0.0.0</Version>
</XamarinComponent>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<ItemGroup>
<XamarinComponentReference Include="Portable.Licensing">
<InstallationInProgress>True</InstallationInProgress>
<Version>1.0.0.0</Version>
<Visible>False</Visible>
</XamarinComponentReference>
</ItemGroup>
<Import Project="..\..\..\.paket\paket.targets" />
</Project>
================================================
FILE: Samples/Android.Sample/Android.Sample/Assets/AboutAssets.txt
================================================
Any raw assets you want to be deployed with your application can be placed in
this directory (and child directories) and given a Build Action of "AndroidAsset".
These files will be deployed with you package and will be accessible using Android's
AssetManager, like this:
public class ReadAsset : Activity
{
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
InputStream input = Assets.Open ("my_asset.txt");
}
}
Additionally, some Android functions will automatically load asset files:
Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf");
================================================
FILE: Samples/Android.Sample/Android.Sample/MainActivity.cs
================================================
using System;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Portable.Licensing;
using Portable.Licensing.Validation;
namespace Android.Sample
{
[Activity(Label = "Android.Sample", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
int count = 1;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
var licenseContent = @"<License>
<Id>77d4c193-6088-4c64-9663-ed7398ae8c1a</Id>
<Type>Trial</Type>
<Expiration>Thu, 31 Dec 2009 23:00:00 GMT</Expiration>
<Quantity>1</Quantity>
<Customer>
<Name>John Doe</Name>
<Email>john@doe.tld</Email>
</Customer>
<LicenseAttributes />
<ProductFeatures />
<Signature>MEUCIQDdDpq/Ddt4hZJlird/BcR6FVKLdWF/DENnd6r/0LuB3gIgVm7RSQx5mcjC32JjCoHNdoL8C+etXOtWKiYGLCT4q6w=</Signature>
</License>";
var license = License.Load(licenseContent);
var validationFailures =
license.Validate()
.ExpirationDate()
.When(lic => lic.Type == LicenseType.Trial)
.And()
.Signature(Resources.GetString(Resource.String.LicensePublicKey))
.AssertValidLicense().ToList();
if (validationFailures.Any())
{
var dialogBuilder = new AlertDialog.Builder(this);
dialogBuilder.SetTitle("License validation failure!");
dialogBuilder.SetIcon(Android.Resource.Drawable.IcDialogAlert);
var messageBuilder = new StringBuilder();
foreach (var validationFailure in validationFailures)
{
messageBuilder.AppendLine("Failure:");
messageBuilder.AppendLine(validationFailure.Message);
messageBuilder.AppendLine(" ");
messageBuilder.AppendLine("Resolve issue by:");
messageBuilder.AppendLine(validationFailure.HowToResolve);
messageBuilder.AppendLine(" ");
messageBuilder.AppendLine(" ");
}
dialogBuilder.SetMessage(messageBuilder.ToString());
dialogBuilder.SetNeutralButton("Cancel", (sender, args) => { /* close app */ });
dialogBuilder.Show();
}
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
// Get our button from the layout resource,
// and attach an event to it
Button button = FindViewById<Button>(Resource.Id.MyButton);
button.Click += delegate { button.Text = string.Format("{0} clicks!", count++); };
}
}
}
================================================
FILE: Samples/Android.Sample/Android.Sample/Properties/AssemblyInfo.cs
================================================
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Android.App;
// 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("Android.Sample")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Android.Sample")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: ComVisible(false)]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// 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("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
// Add some common permissions, these can be removed if not needed
[assembly: UsesPermission(Android.Manifest.Permission.Internet)]
[assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]
================================================
FILE: Samples/Android.Sample/Android.Sample/Resources/AboutResources.txt
================================================
Images, layout descriptions, binary blobs and string dictionaries can be included
in your application as resource files. Various Android APIs are designed to
operate on the resource IDs instead of dealing with images, strings or binary blobs
directly.
For example, a sample Android app that contains a user interface layout (main.xml),
an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
would keep its resources in the "Resources" directory of the application:
Resources/
drawable-hdpi/
icon.png
drawable-ldpi/
icon.png
drawable-mdpi/
icon.png
layout/
main.xml
values/
strings.xml
In order to get the build system to recognize Android resources, set the build action to
"AndroidResource". The native Android APIs do not operate directly with filenames, but
instead operate on resource IDs. When you compile an Android application that uses resources,
the build system will package the resources for distribution and generate a class called
"Resource" that contains the tokens for each one of the resources included. For example,
for the above Resources layout, this is what the Resource class would expose:
public class Resource {
public class drawable {
public const int icon = 0x123;
}
public class layout {
public const int main = 0x456;
}
public class strings {
public const int first_string = 0xabc;
public const int second_string = 0xbcd;
}
}
You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main
to reference the layout/main.xml file, or Resource.strings.first_string to reference the first
string in the dictionary file values/strings.xml.
================================================
FILE: Samples/Android.Sample/Android.Sample/Resources/Layout/Main.axml
================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:id="@+id/MyButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/Hello"
/>
</LinearLayout>
================================================
FILE: Samples/Android.Sample/Android.Sample/Resources/Resource.Designer.cs
================================================
#pragma warning disable 1591
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.18033
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
[assembly: Android.Runtime.ResourceDesignerAttribute("Android.Sample.Resource", IsApplication=true)]
namespace Android.Sample
{
[System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")]
public partial class Resource
{
Resource()
{
global::Android.Runtime.ResourceIdManager.UpdateIdValues ();
}
public static void UpdateIdValues()
{
}
public partial class Attribute
{
private Attribute()
{
}
}
public partial class Drawable
{
// aapt resource value: 0x7f020000
public const int Icon = 2130837504;
private Drawable()
{
}
}
public partial class Id
{
// aapt resource value: 0x7f050000
public const int MyButton = 2131034112;
private Id()
{
}
}
public partial class Layout
{
// aapt resource value: 0x7f030000
public const int Main = 2130903040;
private Layout()
{
}
}
public partial class String
{
// aapt resource value: 0x7f040002
public const int ApplicationName = 2130968578;
// aapt resource value: 0x7f040001
public const int Hello = 2130968577;
// aapt resource value: 0x7f040000
public const int LicensePublicKey = 2130968576;
private String()
{
}
}
}
}
#pragma warning restore 1591
================================================
FILE: Samples/Android.Sample/Android.Sample/Resources/Values/Strings.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="LicensePublicKey">MIIBKjCB4wYHKoZIzj0CATCB1wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEIQNrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClgIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABNVLQ1xKY80BFMgGXec++Vw7n8vvNrq32PaHuBiYMm0PEj2JoB7qSSWhfgcjxNVJsxqJ6gDQVWgl0r7LH4dr0KU=</string>
<string name="Hello">Hello World, Click Me!</string>
<string name="ApplicationName">Android.Sample</string>
</resources>
================================================
FILE: Samples/Android.Sample/Android.Sample.sln
================================================
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{706292EF-A192-48CF-9DB7-9FDC32CB0F0A}"
ProjectSection(SolutionItems) = preProject
..\..\..\Portable.Licensing\paket.dependencies = ..\..\..\Portable.Licensing\paket.dependencies
..\..\..\Portable.Licensing\paket.lock = ..\..\..\Portable.Licensing\paket.lock
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Android.Sample", "Android.Sample\Android.Sample.csproj", "{C1669549-42DA-49E5-B88B-A6D0AD0A545F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C1669549-42DA-49E5-B88B-A6D0AD0A545F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C1669549-42DA-49E5-B88B-A6D0AD0A545F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C1669549-42DA-49E5-B88B-A6D0AD0A545F}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{C1669549-42DA-49E5-B88B-A6D0AD0A545F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C1669549-42DA-49E5-B88B-A6D0AD0A545F}.Release|Any CPU.Build.0 = Release|Any CPU
{C1669549-42DA-49E5-B88B-A6D0AD0A545F}.Release|Any CPU.Deploy.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
================================================
FILE: Samples/Android.Sample/Android.Sample.sln.DotSettings
================================================
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue"><data><IncludeFilters /><ExcludeFilters /></data></s:String>
<s:String x:Key="/Default/FilterSettingsManager/AttributeFilterXml/@EntryValue"><data /></s:String></wpf:ResourceDictionary>
================================================
FILE: Samples/iOS.Sample/iOS.Sample/AppDelegate.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using Portable.Licensing;
using Portable.Licensing.Validation;
namespace iOS.Sample
{
[Register("AppDelegate")]
public partial class AppDelegate : UIApplicationDelegate
{
const string licensePublicKey = @"MIIBKjCB4wYHKoZIzj0CATCB1wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEIQNrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClgIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABNVLQ1xKY80BFMgGXec++Vw7n8vvNrq32PaHuBiYMm0PEj2JoB7qSSWhfgcjxNVJsxqJ6gDQVWgl0r7LH4dr0KU=";
UIWindow window;
MyViewController viewController;
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
var licenseContent = @"<License>
<Id>77d4c193-6088-4c64-9663-ed7398ae8c1a</Id>
<Type>Trial</Type>
<Expiration>Thu, 31 Dec 2009 23:00:00 GMT</Expiration>
<Quantity>1</Quantity>
<Customer>
<Name>John Doe</Name>
<Email>john@doe.tld</Email>
</Customer>
<LicenseAttributes />
<ProductFeatures />
<Signature>MEUCIQDdDpq/Ddt4hZJlird/BcR6FVKLdWF/DENnd6r/0LuB3gIgVm7RSQx5mcjC32JjCoHNdoL8C+etXOtWKiYGLCT4q6w=</Signature>
</License>";
var license = License.Load(licenseContent);
var validationFailures =
license.Validate()
.ExpirationDate()
.When(lic => lic.Type == LicenseType.Trial)
.And()
.Signature(licensePublicKey)
.AssertValidLicense().ToList();
if (validationFailures.Any())
{
var messageBuilder = new StringBuilder();
foreach (var validationFailure in validationFailures)
{
messageBuilder.AppendLine("Failure:");
messageBuilder.AppendLine(validationFailure.Message);
messageBuilder.AppendLine(" ");
messageBuilder.AppendLine("Resolve issue by:");
messageBuilder.AppendLine(validationFailure.HowToResolve);
messageBuilder.AppendLine(" ");
messageBuilder.AppendLine(" ");
}
new UIAlertView ("License validation failure!", messageBuilder.ToString(), null, "Cancel").Show();
}
window = new UIWindow(UIScreen.MainScreen.Bounds);
viewController = new MyViewController();
window.RootViewController = viewController;
window.MakeKeyAndVisible();
return true;
}
}
}
================================================
FILE: Samples/iOS.Sample/iOS.Sample/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
<integer>2</integer>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>MinimumOSVersion</key>
<string>3.2</string>
<key>CFBundleDisplayName</key>
<string>Licensing Sample</string>
</dict>
</plist>
================================================
FILE: Samples/iOS.Sample/iOS.Sample/Main.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace iOS.Sample
{
public class Application
{
// This is the main entry point of the application.
static void Main(string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, "AppDelegate");
}
}
}
================================================
FILE: Samples/iOS.Sample/iOS.Sample/MyViewController.cs
================================================
using System;
using MonoTouch.UIKit;
using System.Drawing;
namespace iOS.Sample
{
public class MyViewController : UIViewController
{
UIButton button;
int numClicks = 0;
float buttonWidth = 200;
float buttonHeight = 50;
public MyViewController()
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
View.Frame = UIScreen.MainScreen.Bounds;
View.BackgroundColor = UIColor.White;
View.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight;
button = UIButton.FromType(UIButtonType.RoundedRect);
button.Frame = new RectangleF(
View.Frame.Width / 2 - buttonWidth / 2,
View.Frame.Height / 2 - buttonHeight / 2,
buttonWidth,
buttonHeight);
button.SetTitle("Click me", UIControlState.Normal);
button.TouchUpInside += (object sender, EventArgs e) =>
{
button.SetTitle(String.Format("clicked {0} times", numClicks++), UIControlState.Normal);
};
button.AutoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleTopMargin |
UIViewAutoresizing.FlexibleBottomMargin;
View.AddSubview(button);
}
}
}
================================================
FILE: Samples/iOS.Sample/iOS.Sample/Properties/AssemblyInfo.cs
================================================
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 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("iOS.Sample")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("iOS.Sample")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 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)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("20e317da-48a5-44bf-aade-5da1046bf568")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// 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("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
================================================
FILE: Samples/iOS.Sample/iOS.Sample/iOS.Sample.csproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{2C8B478A-A9A6-4C6B-81C5-EE2923B7ECCA}</ProjectGuid>
<ProjectTypeGuids>{6BC8ED88-2882-458C-8E55-DFD12B67127B};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Exe</OutputType>
<RootNamespace>iOS.Sample</RootNamespace>
<IPhoneResourcePrefix>Resources</IPhoneResourcePrefix>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
<DebugSymbols>True</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>False</Optimize>
<OutputPath>bin\iPhoneSimulator\Debug</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>False</ConsolePause>
<MtouchLink>None</MtouchLink>
<MtouchDebug>True</MtouchDebug>
<AssemblyName>PortableLicensingiOSSample</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\iPhoneSimulator\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>False</ConsolePause>
<MtouchLink>None</MtouchLink>
<AssemblyName>PortableLicensingiOSSample</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
<DebugSymbols>True</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>False</Optimize>
<OutputPath>bin\iPhone\Debug</OutputPath>
<DefineConstants>DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>False</ConsolePause>
<MtouchDebug>True</MtouchDebug>
<CodesignKey>iPhone Developer</CodesignKey>
<AssemblyName>iOS.Sample</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\iPhone\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>False</ConsolePause>
<CodesignKey>iPhone Developer</CodesignKey>
<AssemblyName>iOS.Sample</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Ad-Hoc|iPhone' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\iPhone\Ad-Hoc</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>False</ConsolePause>
<CodesignKey>iPhone Distribution</CodesignKey>
<BuildIpa>True</BuildIpa>
<AssemblyName>iOS.Sample</AssemblyName>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'AppStore|iPhone' ">
<DebugType>none</DebugType>
<Optimize>True</Optimize>
<OutputPath>bin\iPhone\AppStore</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>False</ConsolePause>
<CodesignKey>iPhone Distribution</CodesignKey>
<AssemblyName>iOS.Sample</AssemblyName>
</PropertyGroup>
<ItemGroup>
<Compile Include="Main.cs" />
<Compile Include="AppDelegate.cs" />
<None Include="Info.plist" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="MyViewController.cs" />
<BundleResource Include="Resources\Default.png" />
<BundleResource Include="Resources\Default%402x.png" />
<BundleResource Include="Resources\Default-568h%402x.png" />
</ItemGroup>
<ItemGroup>
<XamarinComponent Include="Portable.Licensing">
<Visible>False</Visible>
<Version>1.0.0.0</Version>
</XamarinComponent>
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
<Reference Include="monotouch" />
<Reference Include="Portable.Licensing">
<HintPath>..\Components\Portable.Licensing-1.0.0.0\lib\mobile\Portable.Licensing.dll</HintPath>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.MonoTouch.CSharp.targets" />
<ItemGroup>
<XamarinComponentReference Include="Portable.Licensing">
<InstallationInProgress>True</InstallationInProgress>
<Version>1.0.0.0</Version>
<Visible>False</Visible>
</XamarinComponentReference>
</ItemGroup>
<Import Project="..\..\..\.paket\paket.targets" />
</Project>
================================================
FILE: Samples/iOS.Sample/iOS.Sample.sln
================================================
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{1E85F3C2-210B-43F2-9135-CC771B654196}"
ProjectSection(SolutionItems) = preProject
..\..\..\Portable.Licensing\paket.dependencies = ..\..\..\Portable.Licensing\paket.dependencies
..\..\..\Portable.Licensing\paket.lock = ..\..\..\Portable.Licensing\paket.lock
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "iOS.Sample", "iOS.Sample\iOS.Sample.csproj", "{2C8B478A-A9A6-4C6B-81C5-EE2923B7ECCA}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Ad-Hoc|iPhone = Ad-Hoc|iPhone
Ad-Hoc|iPhoneSimulator = Ad-Hoc|iPhoneSimulator
AppStore|iPhone = AppStore|iPhone
AppStore|iPhoneSimulator = AppStore|iPhoneSimulator
Debug|iPhone = Debug|iPhone
Debug|iPhoneSimulator = Debug|iPhoneSimulator
Release|iPhone = Release|iPhone
Release|iPhoneSimulator = Release|iPhoneSimulator
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2C8B478A-A9A6-4C6B-81C5-EE2923B7ECCA}.Ad-Hoc|iPhone.ActiveCfg = Ad-Hoc|iPhone
{2C8B478A-A9A6-4C6B-81C5-EE2923B7ECCA}.Ad-Hoc|iPhone.Build.0 = Ad-Hoc|iPhone
{2C8B478A-A9A6-4C6B-81C5-EE2923B7ECCA}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Ad-Hoc|iPhoneSimulator
{2C8B478A-A9A6-4C6B-81C5-EE2923B7ECCA}.Ad-Hoc|iPhoneSimulator.Build.0 = Ad-Hoc|iPhoneSimulator
{2C8B478A-A9A6-4C6B-81C5-EE2923B7ECCA}.AppStore|iPhone.ActiveCfg = AppStore|iPhone
{2C8B478A-A9A6-4C6B-81C5-EE2923B7ECCA}.AppStore|iPhone.Build.0 = AppStore|iPhone
{2C8B478A-A9A6-4C6B-81C5-EE2923B7ECCA}.AppStore|iPhoneSimulator.ActiveCfg = AppStore|iPhoneSimulator
{2C8B478A-A9A6-4C6B-81C5-EE2923B7ECCA}.AppStore|iPhoneSimulator.Build.0 = AppStore|iPhoneSimulator
{2C8B478A-A9A6-4C6B-81C5-EE2923B7ECCA}.Debug|iPhone.ActiveCfg = Debug|iPhone
{2C8B478A-A9A6-4C6B-81C5-EE2923B7ECCA}.Debug|iPhone.Build.0 = Debug|iPhone
{2C8B478A-A9A6-4C6B-81C5-EE2923B7ECCA}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
{2C8B478A-A9A6-4C6B-81C5-EE2923B7ECCA}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
{2C8B478A-A9A6-4C6B-81C5-EE2923B7ECCA}.Release|iPhone.ActiveCfg = Release|iPhone
{2C8B478A-A9A6-4C6B-81C5-EE2923B7ECCA}.Release|iPhone.Build.0 = Release|iPhone
{2C8B478A-A9A6-4C6B-81C5-EE2923B7ECCA}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
{2C8B478A-A9A6-4C6B-81C5-EE2923B7ECCA}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
================================================
FILE: Samples/iOS.Sample/iOS.Sample.sln.DotSettings
================================================
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue"><data><IncludeFilters /><ExcludeFilters /></data></s:String>
<s:String x:Key="/Default/FilterSettingsManager/AttributeFilterXml/@EntryValue"><data /></s:String></wpf:ResourceDictionary>
================================================
FILE: Tools/xpkg/xpkg
================================================
#!/bin/bash
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
mono $DIR/xpkg.exe "$@"
================================================
FILE: Xamarin/Details.md
================================================
Portable.Licensing is a cross platform software licensing framework which allows you to implement licensing into your application or library. It provides you all tools to create and validate licenses for your software.
Portable.Licensing is using the latest military strength, state-of-the-art cryptographic algorithm to ensure that your software and thus your intellectual property is protected.
It is targeting the *Portable Class Library* and thus runs on nearly every .NET/Mono profile including Silverlight, Windows Phone, Windows Store App, Xamarin.iOS, Xamarin.Android, Xamarin.Mac and XBox 360. Use it for your Desktop- (WinForms, WPF, etc.), Console-, Service-, Web- (ASP.NET, MVC, etc.), Mobile (Xamarin.iOS, Xamarin.Android) or even LightSwitch applications.
## Features ##
- runs on .NET >= 4.0.3, Silverlight 5, Windows Phone >= 8, Windows Store Apps, Mono, Xamarin.iOS, Xamarin.Android, Xamarin.Mac, XBox 360
- easy creation and validation of your licenses
- trial, standard and subscription licenses
- cryptographic signed licenses, no alteration possible
- allows you to enable/disable program modules or product features
- limit various parameters for your software, e.g. max transactions, etc.
- add additional key/value pair attributes to your licenses
- easily extend the fluent validation API with extension methods
----------
### License.Manager light ###
A reference implementation of a management application for products, customers and licenses is available here: [https://github.com/dnauck/License.Manager-Light](https://github.com/dnauck/License.Manager-Light)
### License.Manager ###
License.Manager is a web-based management solution for Portable.Licensing developed using AngularJS and ServiceStack.
It enables you to manage customers, products and licenses and provides a
REST service backend for integration with payment providers and 3rd party tools.
License.Manager is available here: [https://github.com/dnauck/License.Manager](https://github.com/dnauck/License.Manager)
### Validate the license in your application ###
The easiest way to assert the license is in the entry point of your application.
First load the license from a file or resource:
var license = License.Load(...);
Then you can assert the license:
var validationFailures = license.Validate()
.ExpirationDate()
.When(lic => lic.Type == LicenseType.Trial)
.And()
.Signature(publicKey)
.AssertValidLicense();
----------
## License ##
Portable.Licensing is distributed using the MIT/X11 License.
## Further Information ##
The latest release and documentation can be found on the Portable.Licensing project website:
[http://dev.nauck-it.de/projects/portable-licensing](http://dev.nauck-it.de/projects/portable-licensing)
================================================
FILE: Xamarin/GettingStarted.md
================================================
## Getting started ##
### License.Manager light ###
A reference implementation of a management application for products, customers and licenses is available here: [https://github.com/dnauck/License.Manager-Light](https://github.com/dnauck/License.Manager-Light)
### Create a private and public key for your product ###
Portable.Licensing uses the Elliptic Curve Digital Signature Algorithmus (ECDSA) to ensure the license cannot be altered after creation.
First you need to create a new public/private key pair for your product:
var keyGenerator = Portable.Licensing.Security.Cryptography.KeyGenerator.Create();
var keyPair = keyGenerator.GenerateKeyPair();
var privateKey = keyPair.ToEncryptedPrivateKeyString(passPhrase);
var publicKey = keyPair.ToPublicKeyString();
Store the private key securely and distribute the public key with your product.
Normally you create one key pair for each product, otherwise it is possible to use a license with all products using the same key pair.
If you want your customer to buy a new license on each major release you can create a key pair for each release and product.
### Create the license generator ###
Now we need something to generate licenses. This could be easily done with the *LicenseFactory*:
var license = License.New()
.WithUniqueIdentifier(Guid.NewGuid())
.As(LicenseType.Trial)
.ExpiresAt(DateTime.Now.AddDays(30))
.WithMaximumUtilization(5)
.WithProductFeatures(new Dictionary<string, string>
{
{"Sales Module", "yes"},
{"Purchase Module", "yes"},
{"Maximum Transactions", "10000"}
})
.LicensedTo("John Doe", "john.doe@yourmail.here")
.CreateAndSignWithPrivateKey(privateKey, passPhrase);
Now you can take the license and save it to a file:
File.WriteAllText("License.lic", license.ToString(), Encoding.UTF8);
or
license.Save(xmlWriter);
### Validate the license in your application ###
The easiest way to assert the license is in the entry point of your application.
First load the license from a file or resource:
var license = License.Load(...);
Then you can assert the license:
using Portable.Licensing.Validation;
var validationFailures = license.Validate()
.ExpirationDate()
.When(lic => lic.Type == LicenseType.Trial)
.And()
.Signature(publicKey)
.AssertValidLicense();
Portable.Licesing will not throw any Exception and just return an enumeration of validation failures.
Now you can iterate over possible validation failures:
foreach (var failure in validationFailures)
Console.WriteLine(failure.GetType().Name + ": " + failure.Message + " - " + failure.HowToResolve);
Or simply check if there is any failure:
if (validationResults.Any())
// ...
Make sure to call `validationFailures.ToList()` or `validationFailures.ToArray()` before using the result multiple times.
================================================
FILE: appveyor.yml
================================================
init:
- git config --global core.autocrlf input
build_script:
- cmd: build.bat PackageNuGetDistribution
test: off
artifacts:
- path: bin
name: bin
================================================
FILE: build-runTests.bat
================================================
@echo off
cls
.paket\paket.bootstrapper.exe prerelease
if errorlevel 1 (
exit /b %errorlevel%
)
.paket\paket.exe restore -v
if errorlevel 1 (
exit /b %errorlevel%
)
packages\FAKE\tools\FAKE.exe build.fsx target=Test %*
================================================
FILE: build.bat
================================================
@echo off
cls
.paket\paket.bootstrapper.exe prerelease
if errorlevel 1 (
exit /b %errorlevel%
)
.paket\paket.exe restore -v
if errorlevel 1 (
exit /b %errorlevel%
)
packages\FAKE\tools\FAKE.exe build.fsx %*
================================================
FILE: build.fsx
================================================
// include Fake lib
#I @"packages/FAKE/tools"
#r @"FakeLib.dll"
open Fake
open Fake.AssemblyInfoFile
open System
// build properties
let frameworkProfile = @"portable-net403+sl5+netcore45+wp8+MonoAndroid1+MonoTouch1" // profile 147
let buildTarget = getBuildParamOrDefault "buildTarget" "Build"
let buildConfiguration = getBuildParamOrDefault "buildConfiguration" "Release"
// common path properties
let sourceDir = currentDirectory @@ "src"
let buildDir = currentDirectory @@ "Build"
let buildMergedDir = buildDir @@ "merged"
let buildMetricsDir = currentDirectory @@ "BuildMetrics"
let distributionDir = currentDirectory @@ "Distribution"
let publishDir = currentDirectory @@ "Publish"
let solutionFile = sourceDir @@ "Portable.Licensing.sln"
// tools path properties
let toolsDir = currentDirectory @@ "Tools"
let nugetExecutable = "packages" @@ "NuGet.CommandLine" @@ "tools" @@ "NuGet.exe"
let mergerExecutable = toolsDir @@ "ILRepack" @@ "ILRepack.exe"
let xpkgExecutable = toolsDir @@ "xpkg" @@ "xpkg.exe"
// common assembly info properties
let assemblyVersion = getBuildParamOrDefault "assemblyVersion" "1.0.0.0"
let assemblyFileVersion = getBuildParamOrDefault "assemblyFileVersion" "1.1.0.0"
let assemblyInformationalVersion = getBuildParamOrDefault "assemblyInformationalVersion" "1.1.0"
// Targets
Target "All" DoNothing
Target "Clean" (fun _ ->
CleanDirs [
buildDir
buildMetricsDir
distributionDir
publishDir ]
)
Target "CreateAssemblyInfo" (fun _ ->
CreateCSharpAssemblyInfo (sourceDir @@ "CommonAssemblyInfo.cs")
[
Attribute.Company "Nauck IT KG"
Attribute.Product "Portable.Licensing"
Attribute.Copyright (sprintf "Copyright 2012 - %A Nauck IT KG" DateTime.Now.Year)
Attribute.Version assemblyVersion
Attribute.FileVersion assemblyFileVersion
Attribute.InformationalVersion assemblyInformationalVersion
]
)
Target "Build" (fun _ ->
build (fun msbuild ->
{msbuild with
Targets = [buildTarget]
Properties = ["Configuration", buildConfiguration]
}
) solutionFile
)
Target "Test" (fun _ ->
!! (buildDir @@ "*Tests.dll")
|> NUnit (fun p ->
{p with
//DisableShadowCopy = true;
OutputFile = buildMetricsDir @@ "nunit-result.xml" })
)
Target "MergeAssemblies" (fun _ ->
CreateDir buildMergedDir
let result =
ExecProcess (fun info ->
info.FileName <- mergerExecutable
info.WorkingDirectory <- buildDir
info.Arguments <- sprintf "-target:library -internalize -verbose -lib:%s /out:%s %s %s" buildDir (buildMergedDir @@ "Portable.Licensing.dll") "Portable.Licensing.dll" "BouncyCastle.Crypto.dll"
) (TimeSpan.FromMinutes 5.)
if result <> 0 then failwithf "Error during ILRepack execution."
let filesToDelete =
!+ (buildDir @@ "Portable.Licensing.*")
++ (buildDir @@ "BouncyCastle.Crypto.*")
-- (buildDir @@ "Portable.Licensing.XML") |> Scan
DeleteFiles filesToDelete
let filesToCopy =
!+ (buildMergedDir @@ "Portable.Licensing.*") |> Scan
Copy buildDir filesToCopy
)
Target "PreparePackaging" (fun _ ->
// create the directory structure for the deployment zip and NuGet package
// and copy in the files to deploy
let docsDir = distributionDir @@ "Documentation"
CreateDir docsDir
CopyFile docsDir "Readme.md"
CopyFile docsDir "LICENSE.md"
let libsDir = distributionDir @@ "lib" @@ frameworkProfile
CreateDir libsDir
let librariesToDeploy =
!+ (buildDir @@ "Portable.Licensing.dll")
++ (buildDir @@ "Portable.Licensing.XML")
-- (buildDir @@ "Portable.Licensing.pdb") |> Scan
Copy libsDir librariesToDeploy
)
Target "PackgaeZipDistribution" (fun _ ->
Zip distributionDir (publishDir @@ String.Format(@"Portable.Licensing-{0}.zip", assemblyInformationalVersion)) !! (distributionDir @@ "**")
)
Target "PackageNuGetDistribution" (fun _ ->
// rename Readme.md to Readme.txt in the NuGet package, so that the file
// could be shown automaticly by VS during package installation
CopyFile distributionDir "Readme.md"
Rename (distributionDir @@ "Readme.txt") (distributionDir @@ "Readme.md")
let result =
ExecProcess (fun info ->
info.FileName <- nugetExecutable
info.WorkingDirectory <- "./"
info.Arguments <- sprintf "pack Portable.Licensing.nuspec -Version %s -OutputDirectory %s" assemblyInformationalVersion publishDir
) (TimeSpan.FromMinutes 5.)
if result <> 0 then failwithf "Error during NuGet creation."
// delete the renamed file
DeleteFile (distributionDir @@ "Readme.txt")
)
Target "PackageXamarinDistribution" (fun _ ->
xpkgPack (fun p ->
{p with
ToolPath = xpkgExecutable;
Package = "Portable.Licensing";
Version = assemblyFileVersion;
OutputPath = publishDir
Project = "Portable.Licensing"
Summary = "Portable.Licensing is a cross platform software licensing framework which allows you to implement licensing into your application or library"
Publisher = "Nauck IT KG"
Website = "http://dev.nauck-it.de/projects/portable-licensing"
Details = "./Xamarin/Details.md"
License = "License.md"
GettingStarted = "./Xamarin/GettingStarted.md"
Icons = ["./Xamarin/Portable.Licensing_512x512.png"; "./Xamarin/Portable.Licensing_128x128.png"]
Libraries = ["mobile", "./Distribution/lib/" @@ frameworkProfile @@ "/Portable.Licensing.dll"]
Samples = ["Android Sample. A simple sample that validates a trial license.", "./Samples/Android.Sample/Android.Sample.sln";
"iOS Sample. A simple sample that validates a trial license.", "./Samples/iOS.Sample/iOS.Sample.sln"]
}
)
xpkgValidate (fun p ->
{p with
ToolPath = xpkgExecutable;
Package = "Portable.Licensing";
Version = assemblyFileVersion;
OutputPath = publishDir
Project = "Portable.Licensing"
}
)
)
// Dependencies
"Clean"
==> "CreateAssemblyInfo"
==> "Build"
==> "Test"
==> "MergeAssemblies"
==> "PreparePackaging"
==> "PackgaeZipDistribution"
==> "PackageNuGetDistribution"
==> "PackageXamarinDistribution"
==> "All"
// start build
Run <| getBuildParamOrDefault "target" "All"
================================================
FILE: build.sh
================================================
#!/bin/bash
if test "$OS" = "Windows_NT"
then
# use .Net
.paket/paket.bootstrapper.exe prerelease
exit_code=$?
if [ $exit_code -ne 0 ]; then
exit $exit_code
fi
.paket/paket.exe restore -v
exit_code=$?
if [ $exit_code -ne 0 ]; then
exit $exit_code
fi
packages/FAKE/tools/FAKE.exe $@ --fsiargs -d:MONO build.fsx
else
# use mono
mono .paket/paket.bootstrapper.exe prerelease
exit_code=$?
if [ $exit_code -ne 0 ]; then
exit $exit_code
fi
mono .paket/paket.exe restore -v
exit_code=$?
if [ $exit_code -ne 0 ]; then
exit $exit_code
fi
mono packages/FAKE/tools/FAKE.exe $@ --fsiargs -d:MONO build.fsx
fi
================================================
FILE: lib/License.txt
================================================
Please note: our license is an adaptation of the MIT X11 License and should be read as such.
LICENSE
Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: paket.dependencies
================================================
source https://nuget.org/api/v2
nuget FAKE
nuget NUnit
nuget NUnit.Runners
nuget NuGet.CommandLine
================================================
FILE: src/CommonAssemblyInfo.cs
================================================
// <auto-generated/>
using System.Reflection;
[assembly: AssemblyCompanyAttribute("Nauck IT KG")]
[assembly: AssemblyProductAttribute("Portable.Licensing")]
[assembly: AssemblyCopyrightAttribute("Copyright � 2012 - 2014 Nauck IT KG")]
[assembly: AssemblyVersionAttribute("1.0.0.0")]
[assembly: AssemblyFileVersionAttribute("1.1.0.0")]
[assembly: AssemblyInformationalVersionAttribute("1.1.0")]
namespace System {
internal static class AssemblyVersionInformation {
internal const string Version = "1.0.0.0";
}
}
================================================
FILE: src/Portable.Licensing/AssemblyBuildDateAttribute.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
using System.Globalization;
namespace Portable.Licensing
{
/// <summary>
/// Defines assembly build date information for an assembly manifest.
/// </summary>
[AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
public sealed class AssemblyBuildDateAttribute : Attribute
{
private readonly DateTime buildDate;
/// <summary>
/// Initializes a new instance of the <see cref="AssemblyBuildDateAttribute"/> class
/// with the specified build date.
/// </summary>
/// <param name="buildDate">The build date of the assembly.</param>
public AssemblyBuildDateAttribute(DateTime buildDate)
{
this.buildDate = buildDate;
}
/// <summary>
/// Initializes a new instance of the <see cref="AssemblyBuildDateAttribute"/> class
/// with the specified build date string.
/// </summary>
/// <param name="buildDateString">The build date of the assembly.</param>
public AssemblyBuildDateAttribute(string buildDateString)
{
buildDate = DateTime.Parse(buildDateString, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
}
/// <summary>
/// Gets the assembly build date.
/// </summary>
public DateTime BuildDate
{
get { return buildDate; }
}
}
}
================================================
FILE: src/Portable.Licensing/Customer.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System.Xml.Linq;
namespace Portable.Licensing
{
/// <summary>
/// The customer of a <see cref="License"/>.
/// </summary>
public class Customer : LicenseAttributes
{
internal Customer(XElement xmlData)
: base(xmlData, "CustomerData")
{
}
/// <summary>
/// Gets or sets the Name of this <see cref="Customer"/>.
/// </summary>
public string Name
{
get { return GetTag("Name"); }
set { SetTag("Name", value); }
}
/// <summary>
/// Gets or sets the Company of this <see cref="Customer"/>.
/// </summary>
public string Company
{
get { return GetTag("Company"); }
set { SetTag("Company", value); }
}
/// <summary>
/// Gets or sets the Email of this <see cref="Customer"/>.
/// </summary>
public string Email
{
get { return GetTag("Email"); }
set { SetTag("Email", value); }
}
}
}
================================================
FILE: src/Portable.Licensing/IFluentInterface.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
using System.ComponentModel;
namespace Portable.Licensing
{
/// <summary>
/// Interface that is used to build fluent interfaces and hides methods declared by <see cref="object"/> from IntelliSense.
/// </summary>
/// <remarks>
/// Code that consumes implementations of this interface should expect one of two things:
/// <list type = "number">
/// <item>When referencing the interface from within the same solution (project reference), you will still see the methods this interface is meant to hide.</item>
/// <item>When referencing the interface through the compiled output assembly (external reference), the standard Object methods will be hidden as intended.</item>
/// </list>
/// See http://bit.ly/ifluentinterface for more information.
/// </remarks>
[EditorBrowsable(EditorBrowsableState.Never)]
public interface IFluentInterface
{
/// <summary>
/// Redeclaration that hides the <see cref="object.GetType()"/> method from IntelliSense.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
Type GetType();
/// <summary>
/// Redeclaration that hides the <see cref="object.GetHashCode()"/> method from IntelliSense.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
int GetHashCode();
/// <summary>
/// Redeclaration that hides the <see cref="object.ToString()"/> method from IntelliSense.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
string ToString();
/// <summary>
/// Redeclaration that hides the <see cref="object.Equals(object)"/> method from IntelliSense.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
bool Equals(object obj);
}
}
================================================
FILE: src/Portable.Licensing/ILicenseBuilder.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
namespace Portable.Licensing
{
/// <summary>
/// Fluent api to create and sign a new <see cref="License"/>.
/// </summary>
public interface ILicenseBuilder : IFluentInterface
{
/// <summary>
/// Sets the unique identifier of the <see cref="License"/>.
/// </summary>
/// <param name="id">The unique identifier of the <see cref="License"/>.</param>
/// <returns>The <see cref="ILicenseBuilder"/>.</returns>
ILicenseBuilder WithUniqueIdentifier(Guid id);
/// <summary>
/// Sets the <see cref="LicenseType"/> of the <see cref="License"/>.
/// </summary>
/// <param name="type">The <see cref="LicenseType"/> of the <see cref="License"/>.</param>
/// <returns>The <see cref="ILicenseBuilder"/>.</returns>
ILicenseBuilder As(LicenseType type);
/// <summary>
/// Sets the expiration date of the <see cref="License"/>.
/// </summary>
/// <param name="date">The expiration date of the <see cref="License"/>.</param>
/// <returns>The <see cref="ILicenseBuilder"/>.</returns>
ILicenseBuilder ExpiresAt(DateTime date);
/// <summary>
/// Sets the maximum utilization of the <see cref="License"/>.
/// This can be the quantity of developers for a "per-developer-license".
/// </summary>
/// <param name="utilization">The maximum utilization of the <see cref="License"/>.</param>
/// <returns>The <see cref="ILicenseBuilder"/>.</returns>
ILicenseBuilder WithMaximumUtilization(int utilization);
/// <summary>
/// Sets the <see cref="Customer">license holder</see> of the <see cref="License"/>.
/// </summary>
/// <param name="name">The name of the license holder.</param>
/// <param name="email">The email of the license holder.</param>
/// <returns>The <see cref="ILicenseBuilder"/>.</returns>
ILicenseBuilder LicensedTo(string name, string email);
/// <summary>
/// Sets the <see cref="Customer">license holder</see> of the <see cref="License"/>.
/// </summary>
/// <param name="name">The name of the license holder.</param>
/// <param name="email">The email of the license holder.</param>
/// <param name="configureCustomer">A delegate to configure the license holder.</param>
/// <returns>The <see cref="ILicenseBuilder"/>.</returns>
ILicenseBuilder LicensedTo(string name, string email, Action<Customer> configureCustomer);
/// <summary>
/// Sets the <see cref="Customer">license holder</see> of the <see cref="License"/>.
/// </summary>
/// <param name="configureCustomer">A delegate to configure the license holder.</param>
/// <returns>The <see cref="ILicenseBuilder"/>.</returns>
ILicenseBuilder LicensedTo(Action<Customer> configureCustomer);
/// <summary>
/// Sets the licensed product features of the <see cref="License"/>.
/// </summary>
/// <param name="productFeatures">The licensed product features of the <see cref="License"/>.</param>
/// <returns>The <see cref="ILicenseBuilder"/>.</returns>
ILicenseBuilder WithProductFeatures(IDictionary<string, string> productFeatures);
/// <summary>
/// Sets the licensed product features of the <see cref="License"/>.
/// </summary>
/// <param name="configureProductFeatures">A delegate to configure the product features.</param>
/// <returns>The <see cref="ILicenseBuilder"/>.</returns>
ILicenseBuilder WithProductFeatures(Action<LicenseAttributes> configureProductFeatures);
/// <summary>
/// Sets the licensed additional attributes of the <see cref="License"/>.
/// </summary>
/// <param name="additionalAttributes">The additional attributes of the <see cref="License"/>.</param>
/// <returns>The <see cref="ILicenseBuilder"/>.</returns>
ILicenseBuilder WithAdditionalAttributes(IDictionary<string, string> additionalAttributes);
/// <summary>
/// Sets the licensed additional attributes of the <see cref="License"/>.
/// </summary>
/// <param name="configureAdditionalAttributes">A delegate to configure the additional attributes.</param>
/// <returns>The <see cref="ILicenseBuilder"/>.</returns>
ILicenseBuilder WithAdditionalAttributes(Action<LicenseAttributes> configureAdditionalAttributes);
/// <summary>
/// Create and sign a new <see cref="License"/> with the specified
/// private encryption key.
/// </summary>
/// <param name="privateKey">The private encryption key for the signature.</param>
/// <param name="passPhrase">The pass phrase to decrypt the private key.</param>
/// <returns>The signed <see cref="License"/>.</returns>
License CreateAndSignWithPrivateKey(string privateKey, string passPhrase);
}
}
================================================
FILE: src/Portable.Licensing/License.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
using System.Globalization;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Security;
using Portable.Licensing.Security.Cryptography;
namespace Portable.Licensing
{
/// <summary>
/// A software license
/// </summary>
public class License
{
private readonly XElement xmlData;
private readonly string signatureAlgorithm = X9ObjectIdentifiers.ECDsaWithSha512.Id;
/// <summary>
/// Initializes a new instance of the <see cref="License"/> class.
/// </summary>
internal License()
{
xmlData = new XElement("License");
}
/// <summary>
/// Initializes a new instance of the <see cref="License"/> class
/// with the specified content.
/// </summary>
/// <remarks>This constructor is only used for loading from XML.</remarks>
/// <param name="xmlData">The initial content of this <see cref="License"/>.</param>
internal License(XElement xmlData)
{
this.xmlData = xmlData;
}
/// <summary>
/// Gets or sets the unique identifier of this <see cref="License"/>.
/// </summary>
public Guid Id
{
get { return new Guid(GetTag("Id") ?? Guid.Empty.ToString()); }
set { if (!IsSigned) SetTag("Id", value.ToString()); }
}
/// <summary>
/// Gets or set the <see cref="LicenseType"/> or this <see cref="License"/>.
/// </summary>
public LicenseType Type
{
get
{
return
(LicenseType)
Enum.Parse(typeof (LicenseType), GetTag("Type") ?? LicenseType.Trial.ToString(), false);
}
set { if (!IsSigned) SetTag("Type", value.ToString()); }
}
/// <summary>
/// Get or sets the quantity of this license.
/// E.g. the count of per-developer-licenses.
/// </summary>
public int Quantity
{
get { return int.Parse(GetTag("Quantity") ?? "0"); }
set { if (!IsSigned) SetTag("Quantity", value.ToString()); }
}
/// <summary>
/// Gets or sets the product features of this <see cref="License"/>.
/// </summary>
public LicenseAttributes ProductFeatures
{
get
{
var xmlElement = xmlData.Element("ProductFeatures");
if (!IsSigned && xmlElement == null)
{
xmlData.Add(new XElement("ProductFeatures"));
xmlElement = xmlData.Element("ProductFeatures");
}
else if (IsSigned && xmlElement == null)
{
return null;
}
return new LicenseAttributes(xmlElement, "Feature");
}
}
/// <summary>
/// Gets or sets the <see cref="Customer"/> of this <see cref="License"/>.
/// </summary>
public Customer Customer
{
get
{
var xmlElement = xmlData.Element("Customer");
if (!IsSigned && xmlElement == null)
{
xmlData.Add(new XElement("Customer"));
xmlElement = xmlData.Element("Customer");
}
else if (IsSigned && xmlElement == null)
{
return null;
}
return new Customer(xmlElement);
}
}
/// <summary>
/// Gets or sets the additional attributes of this <see cref="License"/>.
/// </summary>
public LicenseAttributes AdditionalAttributes
{
get
{
var xmlElement = xmlData.Element("LicenseAttributes");
if (!IsSigned && xmlElement == null)
{
xmlData.Add(new XElement("LicenseAttributes"));
xmlElement = xmlData.Element("LicenseAttributes");
}
else if (IsSigned && xmlElement == null)
{
return null;
}
return new LicenseAttributes(xmlElement, "Attribute");
}
}
/// <summary>
/// Gets or sets the expiration date of this <see cref="License"/>.
/// Use this property to set the expiration date for a trial license
/// or the expiration of support & subscription updates for a standard license.
/// </summary>
public DateTime Expiration
{
get
{
return
DateTime.ParseExact(
GetTag("Expiration") ??
DateTime.MaxValue.ToUniversalTime().ToString("r", CultureInfo.InvariantCulture)
, "r", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
}
set { if (!IsSigned) SetTag("Expiration", value.ToUniversalTime().ToString("r", CultureInfo.InvariantCulture)); }
}
/// <summary>
/// Gets the digital signature of this license.
/// </summary>
/// <remarks>Use the <see cref="License.Sign"/> method to compute a signature.</remarks>
public string Signature
{
get { return GetTag("Signature"); }
}
/// <summary>
/// Compute a signature and sign this <see cref="License"/> with the provided key.
/// </summary>
/// <param name="privateKey">The private key in xml string format to compute the signature.</param>
/// <param name="passPhrase">The pass phrase to decrypt the private key.</param>
public void Sign(string privateKey, string passPhrase)
{
var signTag = xmlData.Element("Signature") ?? new XElement("Signature");
try
{
if (signTag.Parent != null)
signTag.Remove();
var privKey = KeyFactory.FromEncryptedPrivateKeyString(privateKey, passPhrase);
var documentToSign = Encoding.UTF8.GetBytes(xmlData.ToString(SaveOptions.DisableFormatting));
var signer = SignerUtilities.GetSigner(signatureAlgorithm);
signer.Init(true, privKey);
signer.BlockUpdate(documentToSign, 0, documentToSign.Length);
var signature = signer.GenerateSignature();
signTag.Value = Convert.ToBase64String(signature);
}
finally
{
xmlData.Add(signTag);
}
}
/// <summary>
/// Determines whether the <see cref="License.Signature"/> property verifies for the specified key.
/// </summary>
/// <param name="publicKey">The public key in xml string format to verify the <see cref="License.Signature"/>.</param>
/// <returns>true if the <see cref="License.Signature"/> verifies; otherwise false.</returns>
public bool VerifySignature(string publicKey)
{
var signTag = xmlData.Element("Signature");
if (signTag == null)
return false;
try
{
signTag.Remove();
var pubKey = KeyFactory.FromPublicKeyString(publicKey);
var documentToSign = Encoding.UTF8.GetBytes(xmlData.ToString(SaveOptions.DisableFormatting));
var signer = SignerUtilities.GetSigner(signatureAlgorithm);
signer.Init(false, pubKey);
signer.BlockUpdate(documentToSign, 0, documentToSign.Length);
return signer.VerifySignature(Convert.FromBase64String(signTag.Value));
}
finally
{
xmlData.Add(signTag);
}
}
/// <summary>
/// Create a new <see cref="License"/> using the <see cref="ILicenseBuilder"/>
/// fluent api.
/// </summary>
/// <returns>An instance of the <see cref="ILicenseBuilder"/> class.</returns>
public static ILicenseBuilder New()
{
return new LicenseBuilder();
}
/// <summary>
/// Loads a <see cref="License"/> from a string that contains XML.
/// </summary>
/// <param name="xmlString">A <see cref="string"/> that contains XML.</param>
/// <returns>A <see cref="License"/> populated from the <see cref="string"/> that contains XML.</returns>
public static License Load(string xmlString)
{
return new License(XElement.Parse(xmlString, LoadOptions.None));
}
/// <summary>
/// Loads a <see cref="License"/> by using the specified <see cref="Stream"/>
/// that contains the XML.
/// </summary>
/// <param name="stream">A <see cref="Stream"/> that contains the XML.</param>
/// <returns>A <see cref="License"/> populated from the <see cref="Stream"/> that contains XML.</returns>
public static License Load(Stream stream)
{
return new License(XElement.Load(stream, LoadOptions.None));
}
/// <summary>
/// Loads a <see cref="License"/> by using the specified <see cref="TextReader"/>
/// that contains the XML.
/// </summary>
/// <param name="reader">A <see cref="TextReader"/> that contains the XML.</param>
/// <returns>A <see cref="License"/> populated from the <see cref="TextReader"/> that contains XML.</returns>
public static License Load(TextReader reader)
{
return new License(XElement.Load(reader, LoadOptions.None));
}
/// <summary>
/// Loads a <see cref="License"/> by using the specified <see cref="XmlReader"/>
/// that contains the XML.
/// </summary>
/// <param name="reader">A <see cref="XmlReader"/> that contains the XML.</param>
/// <returns>A <see cref="License"/> populated from the <see cref="TextReader"/> that contains XML.</returns>
public static License Load(XmlReader reader)
{
return new License(XElement.Load(reader, LoadOptions.None));
}
/// <summary>
/// Serialize this <see cref="License"/> to a <see cref="Stream"/>.
/// </summary>
/// <param name="stream">A <see cref="Stream"/> that the
/// <see cref="License"/> will be written to.</param>
public void Save(Stream stream)
{
xmlData.Save(stream);
}
/// <summary>
/// Serialize this <see cref="License"/> to a <see cref="TextWriter"/>.
/// </summary>
/// <param name="textWriter">A <see cref="TextWriter"/> that the
/// <see cref="License"/> will be written to.</param>
public void Save(TextWriter textWriter)
{
xmlData.Save(textWriter);
}
/// <summary>
/// Serialize this <see cref="License"/> to a <see cref="XmlWriter"/>.
/// </summary>
/// <param name="xmlWriter">A <see cref="XmlWriter"/> that the
/// <see cref="License"/> will be written to.</param>
public void Save(XmlWriter xmlWriter)
{
xmlData.Save(xmlWriter);
}
/// <summary>
/// Returns the indented XML for this <see cref="License"/>.
/// </summary>
/// <returns>A string containing the indented XML.</returns>
public override string ToString()
{
return xmlData.ToString();
}
/// <summary>
/// Gets a value indicating whether this <see cref="License"/> is already signed.
/// </summary>
private bool IsSigned
{
get { return (!string.IsNullOrEmpty(Signature)); }
}
private void SetTag(string name, string value)
{
var element = xmlData.Element(name);
if (element == null)
{
element = new XElement(name);
xmlData.Add(element);
}
if (value != null)
element.Value = value;
}
private string GetTag(string name)
{
var element = xmlData.Element(name);
return element != null ? element.Value : null;
}
}
}
================================================
FILE: src/Portable.Licensing/LicenseAttributes.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Portable.Licensing
{
/// <summary>
/// Represents a dictionary of license attributes.
/// </summary>
public class LicenseAttributes
{
protected readonly XElement xmlData;
protected readonly XName childName;
/// <summary>
/// Initializes a new instance of the <see cref="LicenseAttributes"/> class.
/// </summary>
internal LicenseAttributes(XElement xmlData, XName childName)
{
this.xmlData = xmlData ?? new XElement("null");
this.childName = childName;
}
/// <summary>
/// Adds a new element with the specified key and value
/// to the collection.
/// </summary>
/// <param name="key">The key of the element.</param>
/// <param name="value">The value of the element.</param>
public virtual void Add(string key, string value)
{
SetChildTag(key, value);
}
/// <summary>
/// Adds all new element into the collection.
/// </summary>
/// <param name="features">The dictionary of elements.</param>
public virtual void AddAll(IDictionary<string, string> features)
{
foreach (var feature in features)
Add(feature.Key, feature.Value);
}
/// <summary>
/// Removes a element with the specified key
/// from the collection.
/// </summary>
/// <param name="key">The key of the element.</param>
public virtual void Remove(string key)
{
var element =
xmlData.Elements(childName)
.FirstOrDefault(e => e.Attribute("name") != null && e.Attribute("name").Value == key);
if (element != null)
element.Remove();
}
/// <summary>
/// Removes all elements from the collection.
/// </summary>
public virtual void RemoveAll()
{
xmlData.RemoveAll();
}
/// <summary>
/// Gets the value of a element with the
/// specified key.
/// </summary>
/// <param name="key">The key of the element.</param>
/// <returns>The value of the element if available; otherwise null.</returns>
public virtual string Get(string key)
{
return GetChildTag(key);
}
/// <summary>
/// Gets all elements.
/// </summary>
/// <returns>A dictionary of all elements in this collection.</returns>
public virtual IDictionary<string, string> GetAll()
{
return xmlData.Elements(childName).ToDictionary(e => e.Attribute("name").Value, e => e.Value);
}
/// <summary>
/// Determines whether the specified element is in
/// this collection.
/// </summary>
/// <param name="key">The key of the element.</param>
/// <returns>true if the collection contains this element; otherwise false.</returns>
public virtual bool Contains(string key)
{
return xmlData.Elements(childName).Any(e => e.Attribute("name") != null && e.Attribute("name").Value == key);
}
/// <summary>
/// Determines whether all specified elements are in
/// this collection.
/// </summary>
/// <param name="keys">The list of keys of the elements.</param>
/// <returns>true if the collection contains all specified elements; otherwise false.</returns>
public virtual bool ContainsAll(string[] keys)
{
return xmlData.Elements(childName).All(e => e.Attribute("name") != null && keys.Contains(e.Attribute("name").Value));
}
protected virtual void SetTag(string name, string value)
{
var element = xmlData.Element(name);
if (element == null)
{
element = new XElement(name);
xmlData.Add(element);
}
if (value != null)
element.Value = value;
}
protected virtual void SetChildTag(string name, string value)
{
var element =
xmlData.Elements(childName)
.FirstOrDefault(e => e.Attribute("name") != null && e.Attribute("name").Value == name);
if (element == null)
{
element = new XElement(childName);
element.Add(new XAttribute("name", name));
xmlData.Add(element);
}
if (value != null)
element.Value = value;
}
protected virtual string GetTag(string name)
{
var element = xmlData.Element(name);
return element != null ? element.Value : null;
}
protected virtual string GetChildTag(string name)
{
var element =
xmlData.Elements(childName)
.FirstOrDefault(e => e.Attribute("name") != null && e.Attribute("name").Value == name);
return element != null ? element.Value : null;
}
}
}
================================================
FILE: src/Portable.Licensing/LicenseBuilder.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
namespace Portable.Licensing
{
/// <summary>
/// Implementation of the <see cref="ILicenseBuilder"/>, a fluent api
/// to create new licenses.
/// </summary>
internal class LicenseBuilder : ILicenseBuilder
{
private readonly License license;
/// <summary>
/// Initializes a new instance of the <see cref="LicenseBuilder"/> class.
/// </summary>
public LicenseBuilder()
{
license = new License();
}
/// <summary>
/// Sets the unique identifier of the <see cref="License"/>.
/// </summary>
/// <param name="id">The unique identifier of the <see cref="License"/>.</param>
/// <returns>The <see cref="ILicenseBuilder"/>.</returns>
public ILicenseBuilder WithUniqueIdentifier(Guid id)
{
license.Id = id;
return this;
}
/// <summary>
/// Sets the <see cref="LicenseType"/> of the <see cref="License"/>.
/// </summary>
/// <param name="type">The <see cref="LicenseType"/> of the <see cref="License"/>.</param>
/// <returns>The <see cref="ILicenseBuilder"/>.</returns>
public ILicenseBuilder As(LicenseType type)
{
license.Type = type;
return this;
}
/// <summary>
/// Sets the expiration date of the <see cref="License"/>.
/// </summary>
/// <param name="date">The expiration date of the <see cref="License"/>.</param>
/// <returns>The <see cref="ILicenseBuilder"/>.</returns>
public ILicenseBuilder ExpiresAt(DateTime date)
{
license.Expiration = date.ToUniversalTime();
return this;
}
/// <summary>
/// Sets the maximum utilization of the <see cref="License"/>.
/// This can be the quantity of developers for a "per-developer-license".
/// </summary>
/// <param name="utilization">The maximum utilization of the <see cref="License"/>.</param>
/// <returns>The <see cref="ILicenseBuilder"/>.</returns>
public ILicenseBuilder WithMaximumUtilization(int utilization)
{
license.Quantity = utilization;
return this;
}
/// <summary>
/// Sets the <see cref="Customer">license holder</see> of the <see cref="License"/>.
/// </summary>
/// <param name="name">The name of the license holder.</param>
/// <param name="email">The email of the license holder.</param>
/// <returns>The <see cref="ILicenseBuilder"/>.</returns>
public ILicenseBuilder LicensedTo(string name, string email)
{
license.Customer.Name = name;
license.Customer.Email = email;
return this;
}
/// <summary>
/// Sets the <see cref="Customer">license holder</see> of the <see cref="License"/>.
/// </summary>
/// <param name="name">The name of the license holder.</param>
/// <param name="email">The email of the license holder.</param>
/// <param name="configureCustomer">A delegate to configure the license holder.</param>
/// <returns>The <see cref="ILicenseBuilder"/>.</returns>
public ILicenseBuilder LicensedTo(string name, string email, Action<Customer> configureCustomer)
{
license.Customer.Name = name;
license.Customer.Email = email;
configureCustomer(license.Customer);
return this;
}
/// <summary>
/// Sets the <see cref="Customer">license holder</see> of the <see cref="License"/>.
/// </summary>
/// <param name="configureCustomer">A delegate to configure the license holder.</param>
/// <returns>The <see cref="ILicenseBuilder"/>.</returns>
public ILicenseBuilder LicensedTo(Action<Customer> configureCustomer)
{
configureCustomer(license.Customer);
return this;
}
/// <summary>
/// Sets the licensed product features of the <see cref="License"/>.
/// </summary>
/// <param name="productFeatures">The licensed product features of the <see cref="License"/>.</param>
/// <returns>The <see cref="ILicenseBuilder"/>.</returns>
public ILicenseBuilder WithProductFeatures(IDictionary<string, string> productFeatures)
{
license.ProductFeatures.AddAll(productFeatures);
return this;
}
/// <summary>
/// Sets the licensed product features of the <see cref="License"/>.
/// </summary>
/// <param name="configureProductFeatures">A delegate to configure the product features.</param>
/// <returns>The <see cref="ILicenseBuilder"/>.</returns>
public ILicenseBuilder WithProductFeatures(Action<LicenseAttributes> configureProductFeatures)
{
configureProductFeatures(license.ProductFeatures);
return this;
}
/// <summary>
/// Sets the licensed additional attributes of the <see cref="License"/>.
/// </summary>
/// <param name="additionalAttributes">The additional attributes of the <see cref="License"/>.</param>
/// <returns>The <see cref="ILicenseBuilder"/>.</returns>
public ILicenseBuilder WithAdditionalAttributes(IDictionary<string, string> additionalAttributes)
{
license.AdditionalAttributes.AddAll(additionalAttributes);
return this;
}
/// <summary>
/// Sets the licensed additional attributes of the <see cref="License"/>.
/// </summary>
/// <param name="configureAdditionalAttributes">A delegate to configure the additional attributes.</param>
/// <returns>The <see cref="ILicenseBuilder"/>.</returns>
public ILicenseBuilder WithAdditionalAttributes(Action<LicenseAttributes> configureAdditionalAttributes)
{
configureAdditionalAttributes(license.AdditionalAttributes);
return this;
}
/// <summary>
/// Create and sign a new <see cref="License"/> with the specified
/// private encryption key.
/// </summary>
/// <param name="privateKey">The private encryption key for the signature.</param>
/// <param name="passPhrase">The pass phrase to decrypt the private key.</param>
/// <returns>The signed <see cref="License"/>.</returns>
public License CreateAndSignWithPrivateKey(string privateKey, string passPhrase)
{
license.Sign(privateKey, passPhrase);
return license;
}
}
}
================================================
FILE: src/Portable.Licensing/LicenseType.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
namespace Portable.Licensing
{
/// <summary>
/// Defines the type of a <see cref="License"/>
/// </summary>
public enum LicenseType
{
/// <summary>
/// For trial or demo use
/// </summary>
Trial = 1,
/// <summary>
/// Standard license
/// </summary>
Standard = 2
}
}
================================================
FILE: src/Portable.Licensing/Portable.Licensing.csproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<MinimumVisualStudioVersion>10.0</MinimumVisualStudioVersion>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{6D2B800C-C252-4A33-BA05-904AE5B79417}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Portable.Licensing</RootNamespace>
<AssemblyName>Portable.Licensing</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>Profile147</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\Build\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>..\..\Build\Portable.Licensing.XML</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\Build\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>..\..\Build\Portable.Licensing.XML</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<!-- A reference to the entire .NET Framework is automatically included -->
</ItemGroup>
<ItemGroup>
<Compile Include="..\CommonAssemblyInfo.cs">
<Link>Properties\CommonAssemblyInfo.cs</Link>
</Compile>
<Compile Include="AssemblyBuildDateAttribute.cs" />
<Compile Include="Customer.cs" />
<Compile Include="IFluentInterface.cs" />
<Compile Include="ILicenseBuilder.cs" />
<Compile Include="License.cs" />
<Compile Include="LicenseAttributes.cs" />
<Compile Include="LicenseBuilder.cs" />
<Compile Include="LicenseType.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Security\Cryptography\KeyFactory.cs" />
<Compile Include="Security\Cryptography\KeyGenerator.cs" />
<Compile Include="Security\Cryptography\KeyPair.cs" />
<Compile Include="Validation\GeneralValidationFailure.cs" />
<Compile Include="Validation\IAddAdditionalValidationChain.cs" />
<Compile Include="Validation\IAssertValidation.cs" />
<Compile Include="Validation\ICompleteValidationChain.cs" />
<Compile Include="Validation\ILicenseValidator.cs" />
<Compile Include="Validation\InvalidSignatureValidationFailure.cs" />
<Compile Include="Validation\IStartValidationChain.cs" />
<Compile Include="Validation\IValidationChain.cs" />
<Compile Include="Validation\IValidationChainCondition.cs" />
<Compile Include="Validation\IValidationFailure.cs" />
<Compile Include="Validation\LicenseExpiredValidationFailure.cs" />
<Compile Include="Validation\LicenseValidationExtensions.cs" />
<Compile Include="Validation\LicenseValidator.cs" />
<Compile Include="Validation\ValidationChainBuilder.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="BouncyCastle.Crypto">
<HintPath>..\..\lib\BouncyCastle.Crypto.dll</HintPath>
</Reference>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<Import Project="..\..\.paket\paket.targets" />
</Project>
================================================
FILE: src/Portable.Licensing/Properties/AssemblyInfo.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
using System.Resources;
using System.Reflection;
// 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("Portable.Licensing")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]
[assembly: CLSCompliant(true)]
================================================
FILE: src/Portable.Licensing/Security/Cryptography/KeyFactory.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
namespace Portable.Licensing.Security.Cryptography
{
internal static class KeyFactory
{
private static readonly string keyEncryptionAlgorithm = PkcsObjectIdentifiers.PbeWithShaAnd3KeyTripleDesCbc.Id;
/// <summary>
/// Encrypts and encodes the private key.
/// </summary>
/// <param name="key">The private key.</param>
/// <param name="passPhrase">The pass phrase to encrypt the private key.</param>
/// <returns>The encrypted private key.</returns>
public static string ToEncryptedPrivateKeyString(AsymmetricKeyParameter key, string passPhrase)
{
var salt = new byte[16];
var secureRandom = SecureRandom.GetInstance("SHA256PRNG");
secureRandom.SetSeed(SecureRandom.GetSeed(16)); //See Bug #135
secureRandom.NextBytes(salt);
return
Convert.ToBase64String(PrivateKeyFactory.EncryptKey(keyEncryptionAlgorithm, passPhrase.ToCharArray(),
salt, 10, key));
}
/// <summary>
/// Decrypts the provided private key.
/// </summary>
/// <param name="privateKey">The encrypted private key.</param>
/// <param name="passPhrase">The pass phrase to decrypt the private key.</param>
/// <returns>The private key.</returns>
public static AsymmetricKeyParameter FromEncryptedPrivateKeyString(string privateKey, string passPhrase)
{
return PrivateKeyFactory.DecryptKey(passPhrase.ToCharArray(), Convert.FromBase64String(privateKey));
}
/// <summary>
/// Encodes the public key into DER encoding.
/// </summary>
/// <param name="key">The public key.</param>
/// <returns>The encoded public key.</returns>
public static string ToPublicKeyString(AsymmetricKeyParameter key)
{
return
Convert.ToBase64String(
SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(key)
.ToAsn1Object()
.GetDerEncoded());
}
/// <summary>
/// Decoded the public key from DER encoding.
/// </summary>
/// <param name="publicKey">The encoded public key.</param>
/// <returns>The public key.</returns>
public static AsymmetricKeyParameter FromPublicKeyString(string publicKey)
{
return PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
}
}
}
================================================
FILE: src/Portable.Licensing/Security/Cryptography/KeyGenerator.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Security;
namespace Portable.Licensing.Security.Cryptography
{
/// <summary>
/// Represents a generator for signature keys of <see cref="License"/>.
/// </summary>
public class KeyGenerator
{
private readonly IAsymmetricCipherKeyPairGenerator keyGenerator;
/// <summary>
/// Initializes a new instance of the <see cref="KeyGenerator"/> class
/// with a key size of 256 bits.
/// </summary>
public KeyGenerator()
: this(256)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="KeyGenerator"/> class
/// with the specified key size.
/// </summary>
/// <remarks>Following key sizes are supported:
/// - 192
/// - 224
/// - 239
/// - 256 (default)
/// - 384
/// - 521</remarks>
/// <param name="keySize">The key size.</param>
public KeyGenerator(int keySize)
: this(keySize, SecureRandom.GetSeed(32))
{
}
/// <summary>
/// Initializes a new instance of the <see cref="KeyGenerator"/> class
/// with the specified key size and seed.
/// </summary>
/// <remarks>Following key sizes are supported:
/// - 192
/// - 224
/// - 239
/// - 256 (default)
/// - 384
/// - 521</remarks>
/// <param name="keySize">The key size.</param>
/// <param name="seed">The seed.</param>
public KeyGenerator(int keySize, byte[] seed)
{
var secureRandom = SecureRandom.GetInstance("SHA256PRNG");
secureRandom.SetSeed(seed);
var keyParams = new KeyGenerationParameters(secureRandom, keySize);
keyGenerator = new ECKeyPairGenerator();
keyGenerator.Init(keyParams);
}
/// <summary>
/// Creates a new instance of the <see cref="KeyGenerator"/> class.
/// </summary>
public static KeyGenerator Create()
{
return new KeyGenerator();
}
/// <summary>
/// Generates a private/public key pair for license signing.
/// </summary>
/// <returns>An <see cref="KeyPair"/> containing the keys.</returns>
public KeyPair GenerateKeyPair()
{
return new KeyPair(keyGenerator.GenerateKeyPair());
}
}
}
================================================
FILE: src/Portable.Licensing/Security/Cryptography/KeyPair.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using Org.BouncyCastle.Crypto;
namespace Portable.Licensing.Security.Cryptography
{
/// <summary>
/// Represents a private/public encryption key pair.
/// </summary>
public class KeyPair
{
private readonly AsymmetricCipherKeyPair keyPair;
/// <summary>
/// Initializes a new instance of the <see cref="KeyPair"/> class
/// with the provided asymmetric key pair.
/// </summary>
/// <param name="keyPair"></param>
internal KeyPair(AsymmetricCipherKeyPair keyPair)
{
this.keyPair = keyPair;
}
/// <summary>
/// Gets the encrypted and DER encoded private key.
/// </summary>
/// <param name="passPhrase">The pass phrase to encrypt the private key.</param>
/// <returns>The encrypted private key.</returns>
public string ToEncryptedPrivateKeyString(string passPhrase)
{
return KeyFactory.ToEncryptedPrivateKeyString(keyPair.Private, passPhrase);
}
/// <summary>
/// Gets the DER encoded public key.
/// </summary>
/// <returns>The public key.</returns>
public string ToPublicKeyString()
{
return KeyFactory.ToPublicKeyString(keyPair.Public);
}
}
}
================================================
FILE: src/Portable.Licensing/Validation/GeneralValidationFailure.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
namespace Portable.Licensing.Validation
{
/// <summary>
/// Represents a general validation failure.
/// </summary>
public class GeneralValidationFailure : IValidationFailure
{
/// <summary>
/// Gets or sets a message that describes the validation failure.
/// </summary>
public string Message { get; set; }
/// <summary>
/// Gets or sets a message that describes how to recover from the validation failure.
/// </summary>
public string HowToResolve { get; set; }
}
}
================================================
FILE: src/Portable.Licensing/Validation/IAddAdditionalValidationChain.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
namespace Portable.Licensing.Validation
{
/// <summary>
/// Interface for the fluent validation syntax.
/// </summary>
public interface IAddAdditionalValidationChain : IFluentInterface
{
/// <summary>
/// Adds an additional validation chain.
/// </summary>
/// <returns>An instance of <see cref="IStartValidationChain"/>.</returns>
IStartValidationChain And();
}
}
================================================
FILE: src/Portable.Licensing/Validation/IAssertValidation.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System.Collections.Generic;
namespace Portable.Licensing.Validation
{
/// <summary>
/// Interface for the fluent validation syntax.
/// </summary>
public interface IAssertValidation : IFluentInterface
{
/// <summary>
/// Invokes the license assertion.
/// </summary>
/// <returns>An array is <see cref="IValidationFailure"/> when the validation fails.</returns>
IEnumerable<IValidationFailure> AssertValidLicense();
}
}
================================================
FILE: src/Portable.Licensing/Validation/ICompleteValidationChain.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
namespace Portable.Licensing.Validation
{
/// <summary>
/// Interface for the fluent validation syntax.
/// This interface is used to complete a validation chain.
/// </summary>
public interface ICompleteValidationChain : IAddAdditionalValidationChain, IAssertValidation
{
}
}
================================================
FILE: src/Portable.Licensing/Validation/ILicenseValidator.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
namespace Portable.Licensing.Validation
{
/// <summary>
/// Represents a <see cref="License"/> validator.
/// </summary>
public interface ILicenseValidator
{
/// <summary>
/// Gets or sets the predicate to determine if the <see cref="License"/>
/// is valid.
/// </summary>
Predicate<License> Validate { get; set; }
/// <summary>
/// Gets or sets the predicate to determine if the <see cref="ILicenseValidator"/>
/// should be executed.
/// </summary>
Predicate<License> ValidateWhen { get; set; }
/// <summary>
/// Gets or sets the <see cref="IValidationFailure"/> result. The <see cref="IValidationFailure"/>
/// will be returned to the application when the <see cref="ILicenseValidator"/> fails.
/// </summary>
IValidationFailure FailureResult { get; set; }
}
}
================================================
FILE: src/Portable.Licensing/Validation/IStartValidationChain.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
namespace Portable.Licensing.Validation
{
/// <summary>
/// Interface for the fluent validation syntax.
/// Validators should use this interface to start a new validation chain.
/// </summary>
public interface IStartValidationChain : IFluentInterface
{
}
}
================================================
FILE: src/Portable.Licensing/Validation/IValidationChain.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
namespace Portable.Licensing.Validation
{
/// <summary>
/// Interface for the fluent validation syntax.
/// This interface is used to add a condition or to complete a validation chain.
/// </summary>
public interface IValidationChain : IValidationChainCondition, ICompleteValidationChain
{
}
}
================================================
FILE: src/Portable.Licensing/Validation/IValidationChainCondition.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
namespace Portable.Licensing.Validation
{
/// <summary>
/// Interface for the fluent validation syntax.
/// </summary>
public interface IValidationChainCondition : IFluentInterface
{
/// <summary>
/// Adds a when predicate to the current validator.
/// </summary>
/// <param name="predicate">The predicate that defines the conditions.</param>
/// <returns>An instance of <see cref="ICompleteValidationChain"/>.</returns>
ICompleteValidationChain When(Predicate<License> predicate);
}
}
================================================
FILE: src/Portable.Licensing/Validation/IValidationFailure.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
namespace Portable.Licensing.Validation
{
/// <summary>
/// Represents a failure of a <see cref="ILicenseValidator"/>.
/// </summary>
public interface IValidationFailure
{
/// <summary>
/// Gets or sets a message that describes the validation failure.
/// </summary>
string Message { get; set; }
/// <summary>
/// Gets or sets a message that describes how to recover from the validation failure.
/// </summary>
string HowToResolve { get; set; }
}
}
================================================
FILE: src/Portable.Licensing/Validation/InvalidSignatureValidationFailure.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
namespace Portable.Licensing.Validation
{
/// <summary>
/// Represents a failure when the <see cref="License.Signature"/> is invalid.
/// </summary>
public class InvalidSignatureValidationFailure : IValidationFailure
{
/// <summary>
/// Gets or sets a message that describes the validation failure.
/// </summary>
public string Message { get; set; }
/// <summary>
/// Gets or sets a message that describes how to recover from the validation failure.
/// </summary>
public string HowToResolve { get; set; }
}
}
================================================
FILE: src/Portable.Licensing/Validation/LicenseExpiredValidationFailure.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
namespace Portable.Licensing.Validation
{
/// <summary>
/// Represents a <see cref="License"/> expired failure of a <see cref="ILicenseValidator"/>.
/// </summary>
public class LicenseExpiredValidationFailure : IValidationFailure
{
/// <summary>
/// Gets or sets a message that describes the validation failure.
/// </summary>
public string Message { get; set; }
/// <summary>
/// Gets or sets a message that describes how to recover from the validation failure.
/// </summary>
public string HowToResolve { get; set; }
}
}
================================================
FILE: src/Portable.Licensing/Validation/LicenseValidationExtensions.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using System.Reflection;
namespace Portable.Licensing.Validation
{
/// <summary>
/// Extension methods for <see cref="License"/> validation.
/// </summary>
public static class LicenseValidationExtensions
{
/// <summary>
/// Starts the validation chain of the <see cref="License"/>.
/// </summary>
/// <param name="license">The <see cref="License"/> to validate.</param>
/// <returns>An instance of <see cref="IStartValidationChain"/>.</returns>
public static IStartValidationChain Validate(this License license)
{
return new ValidationChainBuilder(license);
}
/// <summary>
/// Validates if the license has been expired.
/// </summary>
/// <param name="validationChain">The current <see cref="IStartValidationChain"/>.</param>
/// <returns>An instance of <see cref="IStartValidationChain"/>.</returns>
public static IValidationChain ExpirationDate(this IStartValidationChain validationChain)
{
var validationChainBuilder = (validationChain as ValidationChainBuilder);
var validator = validationChainBuilder.StartValidatorChain();
validator.Validate = license => license.Expiration > DateTime.Now;
validator.FailureResult = new LicenseExpiredValidationFailure()
{
Message = "Licensing for this product has expired!",
HowToResolve = @"Your license is expired. Please contact your distributor/vendor to renew the license."
};
return validationChainBuilder;
}
/// <summary>
/// Check whether the product build date of the provided assemblies
/// exceeded the <see cref="License.Expiration"/> date.
/// </summary>
/// <param name="validationChain">The current <see cref="IStartValidationChain"/>.</param>
/// <param name="assemblies">The list of assemblies to check.</param>
/// <returns>An instance of <see cref="IStartValidationChain"/>.</returns>
public static IValidationChain ProductBuildDate(this IStartValidationChain validationChain, Assembly[] assemblies)
{
var validationChainBuilder = (validationChain as ValidationChainBuilder);
var validator = validationChainBuilder.StartValidatorChain();
validator.Validate = license => assemblies.All(
asm =>
asm.GetCustomAttributes(typeof (AssemblyBuildDateAttribute), false)
.Cast<AssemblyBuildDateAttribute>()
.All(a => a.BuildDate < license.Expiration));
validator.FailureResult = new LicenseExpiredValidationFailure()
{
Message = "Licensing for this product has expired!",
HowToResolve = @"Your license is expired. Please contact your distributor/vendor to renew the license."
};
return validationChainBuilder;
}
/// <summary>
/// Allows you to specify a custom assertion that validates the <see cref="License"/>.
/// </summary>
/// <param name="validationChain">The current <see cref="IStartValidationChain"/>.</param>
/// <param name="predicate">The predicate to determine of the <see cref="License"/> is valid.</param>
/// <param name="failure">The <see cref="IValidationFailure"/> will be returned to the application when the <see cref="ILicenseValidator"/> fails.</param>
/// <returns>An instance of <see cref="IStartValidationChain"/>.</returns>
public static IValidationChain AssertThat(this IStartValidationChain validationChain, Predicate<License> predicate, IValidationFailure failure)
{
var validationChainBuilder = (validationChain as ValidationChainBuilder);
var validator = validationChainBuilder.StartValidatorChain();
validator.Validate = predicate;
validator.FailureResult = failure;
return validationChainBuilder;
}
/// <summary>
/// Validates the <see cref="License.Signature"/>.
/// </summary>
/// <param name="validationChain">The current <see cref="IStartValidationChain"/>.</param>
/// <param name="publicKey">The public product key to validate the signature..</param>
/// <returns>An instance of <see cref="IStartValidationChain"/>.</returns>
public static IValidationChain Signature(this IStartValidationChain validationChain, string publicKey)
{
var validationChainBuilder = (validationChain as ValidationChainBuilder);
var validator = validationChainBuilder.StartValidatorChain();
validator.Validate = license => license.VerifySignature(publicKey);
validator.FailureResult = new InvalidSignatureValidationFailure()
{
Message = "License signature validation error!",
HowToResolve = @"The license signature and data does not match. This usually happens when a license file is corrupted or has been altered."
};
return validationChainBuilder;
}
}
}
================================================
FILE: src/Portable.Licensing/Validation/LicenseValidator.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
namespace Portable.Licensing.Validation
{
/// <summary>
/// Represents a <see cref="License"/> validator.
/// </summary>
internal class LicenseValidator : ILicenseValidator
{
/// <summary>
/// Gets or sets the predicate to determine if the <see cref="License"/>
/// is valid.
/// </summary>
public Predicate<License> Validate { get; set; }
/// <summary>
/// Gets or sets the predicate to determine if the <see cref="ILicenseValidator"/>
/// should be executed.
/// </summary>
public Predicate<License> ValidateWhen { get; set; }
/// <summary>
/// Gets or sets the <see cref="IValidationFailure"/> result. The <see cref="IValidationFailure"/>
/// will be returned to the application when the <see cref="ILicenseValidator"/> fails.
/// </summary>
public IValidationFailure FailureResult { get; set; }
}
}
================================================
FILE: src/Portable.Licensing/Validation/ValidationChainBuilder.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
namespace Portable.Licensing.Validation
{
internal class ValidationChainBuilder : IStartValidationChain, IValidationChain
{
private readonly Queue<ILicenseValidator> validators;
private ILicenseValidator currentValidatorChain;
private readonly License license;
public ValidationChainBuilder(License license)
{
this.license = license;
validators = new Queue<ILicenseValidator>();
}
public ILicenseValidator StartValidatorChain()
{
return currentValidatorChain = new LicenseValidator();
}
public void CompleteValidatorChain()
{
if (currentValidatorChain == null)
return;
validators.Enqueue(currentValidatorChain);
currentValidatorChain = null;
}
public ICompleteValidationChain When(Predicate<License> predicate)
{
currentValidatorChain.ValidateWhen = predicate;
return this;
}
public IStartValidationChain And()
{
CompleteValidatorChain();
return this;
}
public IEnumerable<IValidationFailure> AssertValidLicense()
{
CompleteValidatorChain();
while (validators.Count > 0)
{
var validator = validators.Dequeue();
if (validator.ValidateWhen != null && !validator.ValidateWhen(license))
continue;
if (!validator.Validate(license))
yield return validator.FailureResult
?? new GeneralValidationFailure
{
Message = "License validation failed!"
};
}
}
}
}
================================================
FILE: src/Portable.Licensing.Tests/KeyGeneratorTests.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System.Collections.Generic;
using NUnit.Framework;
using Portable.Licensing.Security.Cryptography;
namespace Portable.Licensing.Tests
{
[TestFixture]
public class KeyGeneratorTests
{
[Test] // See Bug #135
public void Ensure_To_Not_Generate_Identical_Keys()
{
var passPhrase = "test";
var privKeySet = new HashSet<string>();
var pubKeySet = new HashSet<string>();
// add well known key
privKeySet.Add(
"MIICITAjBgoqhkiG9w0BDAEDMBUEEF5Fx1gxrWd+0G10a7+UbxQCAQoEggH4SUUim2C3kcHApCKVgIeXpKlZQHcaRgfWt0rVEWr8zRnzO9xT5itU2Sw7j0N3oh6cPer/QGNCmAgnRyiDatruJznDPOmMzK5Yskj6mlCaY6JEjcol+E4SBZJDgvIejy8HVCy+DOIR42JXs9oxgeq8eqB+0RZwvDMBG2hrUjnZ4/hPKRPJY134cqTH68jLv6SXglIPcrL9OxOwdzJBaq0ngSBfqhBWbLRIy/Th2btl9Q/0b+sZxG6r2b80wOxIewlr6EUqXtMaA8Bo5dgVZt1itWYafIAbLWzjZavwdO+EkUMCjZhsfvbXSCmcLRmitdJ6beG7jg7R6m6Q92DpU3qZhEio9akX3MQmOTO63Er4T2t6HHYnTzPaZPjdn8D+8lcTUntp/0vD8SvC3+Cb7tZOHSVGMUDdj7WIW+Bl/5bhdmnChE83HSxR4OsBjLATuZOpYtOefWbXyT8qsUn1IouaCjH+BYejBIPrmFVVl0WZADtbyE0LAOyHCD2quAjCpIwXXONG/gXm+XVGst5clbcuxaG4TxKWA8ifIXaio3aJgLfI+D0Izt2GscKRg6oGTlbC3YFIJg+PAH3A4qufoRSPmtREz0oR1X1ZsS6m/IKezf8vl3S+fSpmR/mUuc6uBx9qI9yJIEW/In90r5vO9fKGusEElP6svlub");
pubKeySet.Add(
"MIIBKjCB4wYHKoZIzj0CATCB1wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEIQNrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClgIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABNVLQ1xKY80BFMgGXec++Vw7n8vvNrq32PaHuBiYMm0PEj2JoB7qSSWhfgcjxNVJsxqJ6gDQVWgl0r7LH4dr0KU=");
for (int i = 0; i < 100; i++)
{
var keyGenerator = new KeyGenerator(256); //default key size
var pair = keyGenerator.GenerateKeyPair();
var privateKey = pair.ToEncryptedPrivateKeyString(passPhrase);
var publicKey = pair.ToPublicKeyString();
Assert.That(privKeySet.Add(privateKey), Is.True);
Assert.That(pubKeySet.Add(publicKey), Is.True);
}
privKeySet.Clear();
pubKeySet.Clear();
}
}
}
================================================
FILE: src/Portable.Licensing.Tests/LicenseSignatureTests.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Xml.Linq;
using NUnit.Framework;
namespace Portable.Licensing.Tests
{
[TestFixture]
public class LicenseSignatureTests
{
private string passPhrase;
private string privateKey;
private string publicKey;
[SetUp]
public void Init()
{
passPhrase = Guid.NewGuid().ToString();
var keyGenerator = Security.Cryptography.KeyGenerator.Create();
var keyPair = keyGenerator.GenerateKeyPair();
privateKey = keyPair.ToEncryptedPrivateKeyString(passPhrase);
publicKey = keyPair.ToPublicKeyString();
}
private static DateTime ConvertToRfc1123(DateTime dateTime)
{
return DateTime.ParseExact(
dateTime.ToUniversalTime().ToString("r", CultureInfo.InvariantCulture)
, "r", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
}
[Test]
public void Can_Generate_And_Validate_Signature_With_Empty_License()
{
var license = License.New()
.CreateAndSignWithPrivateKey(privateKey, passPhrase);
Assert.That(license, Is.Not.Null);
Assert.That(license.Signature, Is.Not.Null);
// validate xml
var xmlElement = XElement.Parse(license.ToString(), LoadOptions.None);
Assert.That(xmlElement.HasElements, Is.True);
// validate default values when not set
Assert.That(license.Id, Is.EqualTo(Guid.Empty));
Assert.That(license.Type, Is.EqualTo(LicenseType.Trial));
Assert.That(license.Quantity, Is.EqualTo(0));
Assert.That(license.ProductFeatures, Is.Null);
Assert.That(license.Customer, Is.Null);
Assert.That(license.Expiration, Is.EqualTo(ConvertToRfc1123(DateTime.MaxValue)));
// verify signature
Assert.That(license.VerifySignature(publicKey), Is.True);
}
[Test]
public void Can_Generate_And_Validate_Signature_With_Standard_License()
{
var licenseId = Guid.NewGuid();
var customerName = "Max Mustermann";
var customerEmail = "max@mustermann.tld";
var expirationDate = DateTime.Now.AddYears(1);
var productFeatures = new Dictionary<string, string>
{
{"Sales Module", "yes"},
{"Purchase Module", "yes"},
{"Maximum Transactions", "10000"}
};
var license = License.New()
.WithUniqueIdentifier(licenseId)
.As(LicenseType.Standard)
.WithMaximumUtilization(10)
.WithProductFeatures(productFeatures)
.LicensedTo(customerName, customerEmail)
.ExpiresAt(expirationDate)
.CreateAndSignWithPrivateKey(privateKey, passPhrase);
Assert.That(license, Is.Not.Null);
Assert.That(license.Signature, Is.Not.Null);
// validate xml
var xmlElement = XElement.Parse(license.ToString(), LoadOptions.None);
Assert.That(xmlElement.HasElements, Is.True);
// validate default values when not set
Assert.That(license.Id, Is.EqualTo(licenseId));
Assert.That(license.Type, Is.EqualTo(LicenseType.Standard));
Assert.That(license.Quantity, Is.EqualTo(10));
Assert.That(license.ProductFeatures, Is.Not.Null);
Assert.That(license.ProductFeatures.GetAll(), Is.EquivalentTo(productFeatures));
Assert.That(license.Customer, Is.Not.Null);
Assert.That(license.Customer.Name, Is.EqualTo(customerName));
Assert.That(license.Customer.Email, Is.EqualTo(customerEmail));
Assert.That(license.Expiration, Is.EqualTo(ConvertToRfc1123(expirationDate)));
// verify signature
Assert.That(license.VerifySignature(publicKey), Is.True);
}
[Test]
public void Can_Detect_Hacked_License()
{
var licenseId = Guid.NewGuid();
var customerName = "Max Mustermann";
var customerEmail = "max@mustermann.tld";
var expirationDate = DateTime.Now.AddYears(1);
var productFeatures = new Dictionary<string, string>
{
{"Sales Module", "yes"},
{"Purchase Module", "yes"},
{"Maximum Transactions", "10000"}
};
var license = License.New()
.WithUniqueIdentifier(licenseId)
.As(LicenseType.Standard)
.WithMaximumUtilization(10)
.WithProductFeatures(productFeatures)
.LicensedTo(customerName, customerEmail)
.ExpiresAt(expirationDate)
.CreateAndSignWithPrivateKey(privateKey, passPhrase);
Assert.That(license, Is.Not.Null);
Assert.That(license.Signature, Is.Not.Null);
// verify signature
Assert.That(license.VerifySignature(publicKey), Is.True);
// validate xml
var xmlElement = XElement.Parse(license.ToString(), LoadOptions.None);
Assert.That(xmlElement.HasElements, Is.True);
// manipulate xml
Assert.That(xmlElement.Element("Quantity"), Is.Not.Null);
xmlElement.Element("Quantity").Value = "11"; // now we want to have 11 licenses
// load license from manipulated xml
var hackedLicense = License.Load(xmlElement.ToString());
// validate default values when not set
Assert.That(hackedLicense.Id, Is.EqualTo(licenseId));
Assert.That(hackedLicense.Type, Is.EqualTo(LicenseType.Standard));
Assert.That(hackedLicense.Quantity, Is.EqualTo(11)); // now with 10+1 licenses
Assert.That(hackedLicense.ProductFeatures, Is.Not.Null);
Assert.That(hackedLicense.ProductFeatures.GetAll(), Is.EquivalentTo(productFeatures));
Assert.That(hackedLicense.Customer, Is.Not.Null);
Assert.That(hackedLicense.Customer.Name, Is.EqualTo(customerName));
Assert.That(hackedLicense.Customer.Email, Is.EqualTo(customerEmail));
Assert.That(hackedLicense.Expiration, Is.EqualTo(ConvertToRfc1123(expirationDate)));
// verify signature
Assert.That(hackedLicense.VerifySignature(publicKey), Is.False);
}
}
}
================================================
FILE: src/Portable.Licensing.Tests/LicenseValidationTests.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using Portable.Licensing.Validation;
namespace Portable.Licensing.Tests
{
[TestFixture]
public class LicenseValidationTests
{
[Test]
public void Can_Validate_Valid_Signature()
{
var publicKey =
@"MIIBKjCB4wYHKoZIzj0CATCB1wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEIQNrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClgIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABNVLQ1xKY80BFMgGXec++Vw7n8vvNrq32PaHuBiYMm0PEj2JoB7qSSWhfgcjxNVJsxqJ6gDQVWgl0r7LH4dr0KU=";
var licenseData = @"<License>
<Id>77d4c193-6088-4c64-9663-ed7398ae8c1a</Id>
<Type>Trial</Type>
<Expiration>Sun, 31 Dec 1899 23:00:00 GMT</Expiration>
<Quantity>1</Quantity>
<Customer>
<Name>John Doe</Name>
<Email>john@doe.tld</Email>
</Customer>
<LicenseAttributes />
<ProductFeatures />
<Signature>MEUCIQCCEDAldOZHHIKvYZRDdzUP4V51y23d6deeK5jIFy27GQIgDz2CndjBh4Vb8tiC3FGQ6fn3GKt8d/P5+luJH0cWv+I=</Signature>
</License>";
var license = License.Load(licenseData);
var validationResults = license
.Validate()
.Signature(publicKey)
.AssertValidLicense();
Assert.That(validationResults, Is.Not.Null);
Assert.That(validationResults.Count(), Is.EqualTo(0));
}
[Test]
public void Can_Validate_Invalid_Signature()
{
var publicKey =
@"MIIBKjCB4wYHKoZIzj0CATCB1wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEIQNrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClgIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABNVLQ1xKY80BFMgGXec++Vw7n8vvNrq32PaHuBiYMm0PEj2JoB7qSSWhfgcjxNVJsxqJ6gDQVWgl0r7LH4dr0KU=";
var licenseData = @"<License>
<Id>77d4c193-6088-4c64-9663-ed7398ae8c1a</Id>
<Type>Trial</Type>
<Expiration>Sun, 31 Dec 1899 23:00:00 GMT</Expiration>
<Quantity>999</Quantity>
<Customer>
<Name>John Doe</Name>
<Email>john@doe.tld</Email>
</Customer>
<LicenseAttributes />
<ProductFeatures />
<Signature>MEUCIQCCEDAldOZHHIKvYZRDdzUP4V51y23d6deeK5jIFy27GQIgDz2CndjBh4Vb8tiC3FGQ6fn3GKt8d/P5+luJH0cWv+I=</Signature>
</License>";
var license = License.Load(licenseData);
var validationResults = license
.Validate()
.Signature(publicKey)
.AssertValidLicense().ToList();
Assert.That(validationResults, Is.Not.Null);
Assert.That(validationResults.Count(), Is.EqualTo(1));
Assert.That(validationResults.FirstOrDefault(), Is.TypeOf<InvalidSignatureValidationFailure>());
}
[Test]
public void Can_Validate_Expired_ExpirationDate()
{
var publicKey = "";
var licenseData = @"<License>
<Id>77d4c193-6088-4c64-9663-ed7398ae8c1a</Id>
<Type>Trial</Type>
<Expiration>Sun, 31 Dec 1899 23:00:00 GMT</Expiration>
<Quantity>1</Quantity>
<Customer>
<Name>John Doe</Name>
<Email>john@doe.tld</Email>
</Customer>
<LicenseAttributes />
<ProductFeatures />
<Signature>MEUCIQCCEDAldOZHHIKvYZRDdzUP4V51y23d6deeK5jIFy27GQIgDz2CndjBh4Vb8tiC3FGQ6fn3GKt8d/P5+luJH0cWv+I=</Signature>
</License>";
var license = License.Load(licenseData);
var validationResults = license
.Validate()
.ExpirationDate()
.AssertValidLicense().ToList();
Assert.That(validationResults, Is.Not.Null);
Assert.That(validationResults.Count(), Is.EqualTo(1));
Assert.That(validationResults.FirstOrDefault(), Is.TypeOf<LicenseExpiredValidationFailure>());
}
[Test]
public void Can_Validate_CustomAssertion()
{
var publicKey = @"MIIBKjCB4wYHKoZIzj0CATCB1wIBATAsBgcqhkjOPQEBAiEA/////wAAAAEAAAAAAAAAAAAAAAD///////////////8wWwQg/////wAAAAEAAAAAAAAAAAAAAAD///////////////wEIFrGNdiqOpPns+u9VXaYhrxlHQawzFOw9jvOPD4n0mBLAxUAxJ02CIbnBJNqZnjhE50mt4GffpAEIQNrF9Hy4SxCR/i85uVjpEDydwN9gS3rM6D0oTlF2JjClgIhAP////8AAAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBA0IABNVLQ1xKY80BFMgGXec++Vw7n8vvNrq32PaHuBiYMm0PEj2JoB7qSSWhfgcjxNVJsxqJ6gDQVWgl0r7LH4dr0KU=";
var licenseData = @"<License>
<Id>77d4c193-6088-4c64-9663-ed7398ae8c1a</Id>
<Type>Trial</Type>
<Expiration>Thu, 31 Dec 2009 23:00:00 GMT</Expiration>
<Quantity>1</Quantity>
<Customer>
<Name>John Doe</Name>
<Email>john@doe.tld</Email>
</Customer>
<LicenseAttributes>
<Attribute name=""Assembly Signature"">123456789</Attribute>
</LicenseAttributes>
<ProductFeatures>
<Feature name=""Sales Module"">yes</Feature>
<Feature name=""Workflow Module"">yes</Feature>
<Feature name=""Maximum Transactions"">10000</Feature>
</ProductFeatures>
<Signature>MEUCIQCa6A7Cts5ex4rGHAPxiXpy+2ocZzTDSP7SsddopKUx5QIgHnqv0DjoOpc+K9wALqajxxvmLCRJAywCX5vDAjmWqr8=</Signature>
</License>";
var license = License.Load(licenseData);
var validationResults = license
.Validate()
.AssertThat(lic => lic.ProductFeatures.Contains("Sales Module"),
new GeneralValidationFailure {Message = "Sales Module not licensed!"})
.And()
.AssertThat(lic => lic.AdditionalAttributes.Get("Assembly Signature") == "123456789",
new GeneralValidationFailure {Message = "Assembly Signature does not match!"})
.And()
.Signature(publicKey)
.AssertValidLicense().ToList();
Assert.That(validationResults, Is.Not.Null);
Assert.That(validationResults.Count(), Is.EqualTo(0));
}
[Test]
public void Do_Not_Crash_On_Invalid_Data()
{
var publicKey = "1234";
var licenseData =
@"<license expiration='2013-06-30T00:00:00.0000000' type='Trial'><name>John Doe</name></license>";
var license = License.Load(licenseData);
var validationResults = license
.Validate()
.ExpirationDate()
.And()
.Signature(publicKey)
.AssertValidLicense().ToList();
Assert.That(validationResults, Is.Not.Null);
Assert.That(validationResults.Count(), Is.EqualTo(1));
Assert.That(validationResults.FirstOrDefault(), Is.TypeOf<InvalidSignatureValidationFailure>());
}
}
}
================================================
FILE: src/Portable.Licensing.Tests/Portable.Licensing.Tests.csproj
================================================
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{16CEEFD4-62BF-4539-9A08-0D05EC695572}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Portable.Licensing.Tests</RootNamespace>
<AssemblyName>Portable.Licensing.Tests</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\Build\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\Build\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\CommonAssemblyInfo.cs">
<Link>Properties\CommonAssemblyInfo.cs</Link>
</Compile>
<Compile Include="KeyGeneratorTests.cs" />
<Compile Include="LicenseSignatureTests.cs" />
<Compile Include="LicenseValidationTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Portable.Licensing\Portable.Licensing.csproj">
<Project>{6d2b800c-c252-4a33-ba05-904ae5b79417}</Project>
<Name>Portable.Licensing</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="paket.references" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<Import Project="..\..\.paket\paket.targets" />
<ItemGroup>
<Reference Include="nunit.framework">
<HintPath>..\..\packages\NUnit\lib\nunit.framework.dll</HintPath>
<Private>True</Private>
<Paket>True</Paket>
</Reference>
</ItemGroup>
</Project>
================================================
FILE: src/Portable.Licensing.Tests/Properties/AssemblyInfo.cs
================================================
//
// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de
//
// Author:
// Daniel Nauck <d.nauck(at)nauck-it.de>
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System.Reflection;
using System.Runtime.InteropServices;
// 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("Portable.Licensing.Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCulture("")]
// 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)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("ecb19417-e47a-43ec-b573-063931631cd3")]
================================================
FILE: src/Portable.Licensing.Tests/paket.references
================================================
NUnit
================================================
FILE: src/Portable.Licensing.sln
================================================
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.30723.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{476022A4-7C0A-4FC7-830E-ED32D3F82B13}"
ProjectSection(SolutionItems) = preProject
..\paket.dependencies = ..\paket.dependencies
..\paket.lock = ..\paket.lock
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Common", "Common", "{449E5271-6EE5-49BA-AB0E-370978ACD89C}"
ProjectSection(SolutionItems) = preProject
..\build.fsx = ..\build.fsx
..\LICENSE.md = ..\LICENSE.md
..\Portable.Licensing.nuspec = ..\Portable.Licensing.nuspec
..\README.md = ..\README.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Xamarin", "Xamarin", "{BB17039C-1F40-476D-8F75-DA11576E4168}"
ProjectSection(SolutionItems) = preProject
..\Xamarin\Details.md = ..\Xamarin\Details.md
..\Xamarin\GettingStarted.md = ..\Xamarin\GettingStarted.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Portable.Licensing", "Portable.Licensing\Portable.Licensing.csproj", "{6D2B800C-C252-4A33-BA05-904AE5B79417}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Portable.Licensing.Tests", "Portable.Licensing.Tests\Portable.Licensing.Tests.csproj", "{16CEEFD4-62BF-4539-9A08-0D05EC695572}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Ad-Hoc|Any CPU = Ad-Hoc|Any CPU
Ad-Hoc|iPhone = Ad-Hoc|iPhone
Ad-Hoc|iPhoneSimulator = Ad-Hoc|iPhoneSimulator
Ad-Hoc|Mixed Platforms = Ad-Hoc|Mixed Platforms
AppStore|Any CPU = AppStore|Any CPU
AppStore|iPhone = AppStore|iPhone
AppStore|iPhoneSimulator = AppStore|iPhoneSimulator
AppStore|Mixed Platforms = AppStore|Mixed Platforms
Debug|Any CPU = Debug|Any CPU
Debug|iPhone = Debug|iPhone
Debug|iPhoneSimulator = Debug|iPhoneSimulator
Debug|Mixed Platforms = Debug|Mixed Platforms
Release|Any CPU = Release|Any CPU
Release|iPhone = Release|iPhone
Release|iPhoneSimulator = Release|iPhoneSimulator
Release|Mixed Platforms = Release|Mixed Platforms
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6D2B800C-C252-4A33-BA05-904AE5B79417}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.Ad-Hoc|Mixed Platforms.ActiveCfg = Debug|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.Ad-Hoc|Mixed Platforms.Build.0 = Debug|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.AppStore|Mixed Platforms.ActiveCfg = Debug|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.AppStore|Mixed Platforms.Build.0 = Debug|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.Debug|Any CPU.ActiveCfg = Release|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.Debug|Any CPU.Build.0 = Release|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.Release|Any CPU.Build.0 = Release|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.Release|iPhone.ActiveCfg = Release|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{6D2B800C-C252-4A33-BA05-904AE5B79417}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.Ad-Hoc|Mixed Platforms.ActiveCfg = Debug|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.Ad-Hoc|Mixed Platforms.Build.0 = Debug|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.AppStore|Mixed Platforms.ActiveCfg = Debug|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.AppStore|Mixed Platforms.Build.0 = Debug|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.Debug|Any CPU.ActiveCfg = Release|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.Debug|Any CPU.Build.0 = Release|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.Release|Any CPU.ActiveCfg = Release|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.Release|Any CPU.Build.0 = Release|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.Release|iPhone.ActiveCfg = Release|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{16CEEFD4-62BF-4539-9A08-0D05EC695572}.Release|Mixed Platforms.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{BB17039C-1F40-476D-8F75-DA11576E4168} = {449E5271-6EE5-49BA-AB0E-370978ACD89C}
EndGlobalSection
EndGlobal
================================================
FILE: src/Portable.Licensing.sln.DotSettings
================================================
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue"><data><IncludeFilters /><ExcludeFilters /></data></s:String>
<s:String x:Key="/Default/FilterSettingsManager/AttributeFilterXml/@EntryValue"><data /></s:String></wpf:ResourceDictionary>
gitextract_zc1asx_w/
├── .gitignore
├── .paket/
│ └── paket.targets
├── .travis.yml
├── Icons/
│ └── Portable.Licensing.icns
├── LICENSE.md
├── Portable.Licensing.nuspec
├── README.md
├── Samples/
│ ├── Android.Sample/
│ │ ├── Android.Sample/
│ │ │ ├── Android.Sample.csproj
│ │ │ ├── Assets/
│ │ │ │ └── AboutAssets.txt
│ │ │ ├── MainActivity.cs
│ │ │ ├── Properties/
│ │ │ │ └── AssemblyInfo.cs
│ │ │ └── Resources/
│ │ │ ├── AboutResources.txt
│ │ │ ├── Layout/
│ │ │ │ └── Main.axml
│ │ │ ├── Resource.Designer.cs
│ │ │ └── Values/
│ │ │ └── Strings.xml
│ │ ├── Android.Sample.sln
│ │ └── Android.Sample.sln.DotSettings
│ └── iOS.Sample/
│ ├── iOS.Sample/
│ │ ├── AppDelegate.cs
│ │ ├── Info.plist
│ │ ├── Main.cs
│ │ ├── MyViewController.cs
│ │ ├── Properties/
│ │ │ └── AssemblyInfo.cs
│ │ └── iOS.Sample.csproj
│ ├── iOS.Sample.sln
│ └── iOS.Sample.sln.DotSettings
├── Tools/
│ └── xpkg/
│ └── xpkg
├── Xamarin/
│ ├── Details.md
│ └── GettingStarted.md
├── appveyor.yml
├── build-runTests.bat
├── build.bat
├── build.fsx
├── build.sh
├── lib/
│ └── License.txt
├── paket.dependencies
└── src/
├── CommonAssemblyInfo.cs
├── Portable.Licensing/
│ ├── AssemblyBuildDateAttribute.cs
│ ├── Customer.cs
│ ├── IFluentInterface.cs
│ ├── ILicenseBuilder.cs
│ ├── License.cs
│ ├── LicenseAttributes.cs
│ ├── LicenseBuilder.cs
│ ├── LicenseType.cs
│ ├── Portable.Licensing.csproj
│ ├── Properties/
│ │ └── AssemblyInfo.cs
│ ├── Security/
│ │ └── Cryptography/
│ │ ├── KeyFactory.cs
│ │ ├── KeyGenerator.cs
│ │ └── KeyPair.cs
│ └── Validation/
│ ├── GeneralValidationFailure.cs
│ ├── IAddAdditionalValidationChain.cs
│ ├── IAssertValidation.cs
│ ├── ICompleteValidationChain.cs
│ ├── ILicenseValidator.cs
│ ├── IStartValidationChain.cs
│ ├── IValidationChain.cs
│ ├── IValidationChainCondition.cs
│ ├── IValidationFailure.cs
│ ├── InvalidSignatureValidationFailure.cs
│ ├── LicenseExpiredValidationFailure.cs
│ ├── LicenseValidationExtensions.cs
│ ├── LicenseValidator.cs
│ └── ValidationChainBuilder.cs
├── Portable.Licensing.Tests/
│ ├── KeyGeneratorTests.cs
│ ├── LicenseSignatureTests.cs
│ ├── LicenseValidationTests.cs
│ ├── Portable.Licensing.Tests.csproj
│ ├── Properties/
│ │ └── AssemblyInfo.cs
│ └── paket.references
├── Portable.Licensing.sln
└── Portable.Licensing.sln.DotSettings
SYMBOL INDEX (148 symbols across 34 files)
FILE: Samples/Android.Sample/Android.Sample/MainActivity.cs
class MainActivity (line 15) | [Activity(Label = "Android.Sample", MainLauncher = true, Icon = "@drawab...
method OnCreate (line 20) | protected override void OnCreate(Bundle bundle)
FILE: Samples/Android.Sample/Android.Sample/Resources/Resource.Designer.cs
class Resource (line 18) | [System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.T...
method Resource (line 22) | Resource()
method UpdateIdValues (line 27) | public static void UpdateIdValues()
class Attribute (line 31) | public partial class Attribute
method Attribute (line 34) | private Attribute()
class Drawable (line 39) | public partial class Drawable
method Drawable (line 45) | private Drawable()
class Id (line 50) | public partial class Id
method Id (line 56) | private Id()
class Layout (line 61) | public partial class Layout
method Layout (line 67) | private Layout()
class String (line 72) | public partial class String
method String (line 84) | private String()
FILE: Samples/iOS.Sample/iOS.Sample/AppDelegate.cs
class AppDelegate (line 14) | [Register("AppDelegate")]
method FinishedLaunching (line 21) | public override bool FinishedLaunching(UIApplication app, NSDictionary...
FILE: Samples/iOS.Sample/iOS.Sample/Main.cs
class Application (line 10) | public class Application
method Main (line 13) | static void Main(string[] args)
FILE: Samples/iOS.Sample/iOS.Sample/MyViewController.cs
class MyViewController (line 7) | public class MyViewController : UIViewController
method MyViewController (line 14) | public MyViewController()
method ViewDidLoad (line 18) | public override void ViewDidLoad()
FILE: src/CommonAssemblyInfo.cs
class AssemblyVersionInformation (line 11) | internal static class AssemblyVersionInformation {
FILE: src/Portable.Licensing.Tests/KeyGeneratorTests.cs
class KeyGeneratorTests (line 32) | [TestFixture]
method Ensure_To_Not_Generate_Identical_Keys (line 35) | [Test] // See Bug #135
FILE: src/Portable.Licensing.Tests/LicenseSignatureTests.cs
class LicenseSignatureTests (line 34) | [TestFixture]
method Init (line 41) | [SetUp]
method ConvertToRfc1123 (line 51) | private static DateTime ConvertToRfc1123(DateTime dateTime)
method Can_Generate_And_Validate_Signature_With_Empty_License (line 58) | [Test]
method Can_Generate_And_Validate_Signature_With_Standard_License (line 83) | [Test]
method Can_Detect_Hacked_License (line 128) | [Test]
FILE: src/Portable.Licensing.Tests/LicenseValidationTests.cs
class LicenseValidationTests (line 36) | [TestFixture]
method Can_Validate_Valid_Signature (line 39) | [Test]
method Can_Validate_Invalid_Signature (line 69) | [Test]
method Can_Validate_Expired_ExpirationDate (line 100) | [Test]
method Can_Validate_CustomAssertion (line 131) | [Test]
method Do_Not_Crash_On_Invalid_Data (line 172) | [Test]
FILE: src/Portable.Licensing/AssemblyBuildDateAttribute.cs
class AssemblyBuildDateAttribute (line 34) | [AttributeUsage(AttributeTargets.Assembly, Inherited = false)]
method AssemblyBuildDateAttribute (line 44) | public AssemblyBuildDateAttribute(DateTime buildDate)
method AssemblyBuildDateAttribute (line 54) | public AssemblyBuildDateAttribute(string buildDateString)
FILE: src/Portable.Licensing/Customer.cs
class Customer (line 33) | public class Customer : LicenseAttributes
method Customer (line 35) | internal Customer(XElement xmlData)
FILE: src/Portable.Licensing/IFluentInterface.cs
type IFluentInterface (line 42) | [EditorBrowsable(EditorBrowsableState.Never)]
method GetType (line 48) | [EditorBrowsable(EditorBrowsableState.Never)]
method GetHashCode (line 54) | [EditorBrowsable(EditorBrowsableState.Never)]
method ToString (line 60) | [EditorBrowsable(EditorBrowsableState.Never)]
method Equals (line 66) | [EditorBrowsable(EditorBrowsableState.Never)]
FILE: src/Portable.Licensing/ILicenseBuilder.cs
type ILicenseBuilder (line 34) | public interface ILicenseBuilder : IFluentInterface
method WithUniqueIdentifier (line 41) | ILicenseBuilder WithUniqueIdentifier(Guid id);
method As (line 48) | ILicenseBuilder As(LicenseType type);
method ExpiresAt (line 55) | ILicenseBuilder ExpiresAt(DateTime date);
method WithMaximumUtilization (line 63) | ILicenseBuilder WithMaximumUtilization(int utilization);
method LicensedTo (line 71) | ILicenseBuilder LicensedTo(string name, string email);
method LicensedTo (line 80) | ILicenseBuilder LicensedTo(string name, string email, Action<Customer>...
method LicensedTo (line 87) | ILicenseBuilder LicensedTo(Action<Customer> configureCustomer);
method WithProductFeatures (line 94) | ILicenseBuilder WithProductFeatures(IDictionary<string, string> produc...
method WithProductFeatures (line 101) | ILicenseBuilder WithProductFeatures(Action<LicenseAttributes> configur...
method WithAdditionalAttributes (line 108) | ILicenseBuilder WithAdditionalAttributes(IDictionary<string, string> a...
method WithAdditionalAttributes (line 115) | ILicenseBuilder WithAdditionalAttributes(Action<LicenseAttributes> con...
method CreateAndSignWithPrivateKey (line 124) | License CreateAndSignWithPrivateKey(string privateKey, string passPhra...
FILE: src/Portable.Licensing/License.cs
class License (line 41) | public class License
method License (line 49) | internal License()
method License (line 60) | internal License(XElement xmlData)
method Sign (line 199) | public void Sign(string privateKey, string passPhrase)
method VerifySignature (line 228) | public bool VerifySignature(string publicKey)
method New (line 259) | public static ILicenseBuilder New()
method Load (line 269) | public static License Load(string xmlString)
method Load (line 280) | public static License Load(Stream stream)
method Load (line 291) | public static License Load(TextReader reader)
method Load (line 302) | public static License Load(XmlReader reader)
method Save (line 312) | public void Save(Stream stream)
method Save (line 322) | public void Save(TextWriter textWriter)
method Save (line 332) | public void Save(XmlWriter xmlWriter)
method ToString (line 341) | public override string ToString()
method SetTag (line 354) | private void SetTag(string name, string value)
method GetTag (line 368) | private string GetTag(string name)
FILE: src/Portable.Licensing/LicenseAttributes.cs
class LicenseAttributes (line 35) | public class LicenseAttributes
method LicenseAttributes (line 43) | internal LicenseAttributes(XElement xmlData, XName childName)
method Add (line 55) | public virtual void Add(string key, string value)
method AddAll (line 64) | public virtual void AddAll(IDictionary<string, string> features)
method Remove (line 75) | public virtual void Remove(string key)
method RemoveAll (line 88) | public virtual void RemoveAll()
method Get (line 99) | public virtual string Get(string key)
method GetAll (line 108) | public virtual IDictionary<string, string> GetAll()
method Contains (line 119) | public virtual bool Contains(string key)
method ContainsAll (line 130) | public virtual bool ContainsAll(string[] keys)
method SetTag (line 135) | protected virtual void SetTag(string name, string value)
method SetChildTag (line 149) | protected virtual void SetChildTag(string name, string value)
method GetTag (line 166) | protected virtual string GetTag(string name)
method GetChildTag (line 172) | protected virtual string GetChildTag(string name)
FILE: src/Portable.Licensing/LicenseBuilder.cs
class LicenseBuilder (line 35) | internal class LicenseBuilder : ILicenseBuilder
method LicenseBuilder (line 42) | public LicenseBuilder()
method WithUniqueIdentifier (line 52) | public ILicenseBuilder WithUniqueIdentifier(Guid id)
method As (line 63) | public ILicenseBuilder As(LicenseType type)
method ExpiresAt (line 74) | public ILicenseBuilder ExpiresAt(DateTime date)
method WithMaximumUtilization (line 86) | public ILicenseBuilder WithMaximumUtilization(int utilization)
method LicensedTo (line 98) | public ILicenseBuilder LicensedTo(string name, string email)
method LicensedTo (line 112) | public ILicenseBuilder LicensedTo(string name, string email, Action<Cu...
method LicensedTo (line 125) | public ILicenseBuilder LicensedTo(Action<Customer> configureCustomer)
method WithProductFeatures (line 136) | public ILicenseBuilder WithProductFeatures(IDictionary<string, string>...
method WithProductFeatures (line 147) | public ILicenseBuilder WithProductFeatures(Action<LicenseAttributes> c...
method WithAdditionalAttributes (line 158) | public ILicenseBuilder WithAdditionalAttributes(IDictionary<string, st...
method WithAdditionalAttributes (line 169) | public ILicenseBuilder WithAdditionalAttributes(Action<LicenseAttribut...
method CreateAndSignWithPrivateKey (line 182) | public License CreateAndSignWithPrivateKey(string privateKey, string p...
FILE: src/Portable.Licensing/LicenseType.cs
type LicenseType (line 31) | public enum LicenseType
FILE: src/Portable.Licensing/Security/Cryptography/KeyFactory.cs
class KeyFactory (line 34) | internal static class KeyFactory
method ToEncryptedPrivateKeyString (line 44) | public static string ToEncryptedPrivateKeyString(AsymmetricKeyParamete...
method FromEncryptedPrivateKeyString (line 62) | public static AsymmetricKeyParameter FromEncryptedPrivateKeyString(str...
method ToPublicKeyString (line 72) | public static string ToPublicKeyString(AsymmetricKeyParameter key)
method FromPublicKeyString (line 86) | public static AsymmetricKeyParameter FromPublicKeyString(string public...
FILE: src/Portable.Licensing/Security/Cryptography/KeyGenerator.cs
class KeyGenerator (line 35) | public class KeyGenerator
method KeyGenerator (line 43) | public KeyGenerator()
method KeyGenerator (line 60) | public KeyGenerator(int keySize)
method KeyGenerator (line 78) | public KeyGenerator(int keySize, byte[] seed)
method Create (line 91) | public static KeyGenerator Create()
method GenerateKeyPair (line 100) | public KeyPair GenerateKeyPair()
FILE: src/Portable.Licensing/Security/Cryptography/KeyPair.cs
class KeyPair (line 33) | public class KeyPair
method KeyPair (line 42) | internal KeyPair(AsymmetricCipherKeyPair keyPair)
method ToEncryptedPrivateKeyString (line 53) | public string ToEncryptedPrivateKeyString(string passPhrase)
method ToPublicKeyString (line 62) | public string ToPublicKeyString()
FILE: src/Portable.Licensing/Validation/GeneralValidationFailure.cs
class GeneralValidationFailure (line 31) | public class GeneralValidationFailure : IValidationFailure
FILE: src/Portable.Licensing/Validation/IAddAdditionalValidationChain.cs
type IAddAdditionalValidationChain (line 31) | public interface IAddAdditionalValidationChain : IFluentInterface
method And (line 37) | IStartValidationChain And();
FILE: src/Portable.Licensing/Validation/IAssertValidation.cs
type IAssertValidation (line 33) | public interface IAssertValidation : IFluentInterface
method AssertValidLicense (line 39) | IEnumerable<IValidationFailure> AssertValidLicense();
FILE: src/Portable.Licensing/Validation/ICompleteValidationChain.cs
type ICompleteValidationChain (line 32) | public interface ICompleteValidationChain : IAddAdditionalValidationChai...
FILE: src/Portable.Licensing/Validation/ILicenseValidator.cs
type ILicenseValidator (line 33) | public interface ILicenseValidator
FILE: src/Portable.Licensing/Validation/IStartValidationChain.cs
type IStartValidationChain (line 32) | public interface IStartValidationChain : IFluentInterface
FILE: src/Portable.Licensing/Validation/IValidationChain.cs
type IValidationChain (line 32) | public interface IValidationChain : IValidationChainCondition, IComplete...
FILE: src/Portable.Licensing/Validation/IValidationChainCondition.cs
type IValidationChainCondition (line 33) | public interface IValidationChainCondition : IFluentInterface
method When (line 40) | ICompleteValidationChain When(Predicate<License> predicate);
FILE: src/Portable.Licensing/Validation/IValidationFailure.cs
type IValidationFailure (line 31) | public interface IValidationFailure
FILE: src/Portable.Licensing/Validation/InvalidSignatureValidationFailure.cs
class InvalidSignatureValidationFailure (line 31) | public class InvalidSignatureValidationFailure : IValidationFailure
FILE: src/Portable.Licensing/Validation/LicenseExpiredValidationFailure.cs
class LicenseExpiredValidationFailure (line 31) | public class LicenseExpiredValidationFailure : IValidationFailure
FILE: src/Portable.Licensing/Validation/LicenseValidationExtensions.cs
class LicenseValidationExtensions (line 35) | public static class LicenseValidationExtensions
method Validate (line 42) | public static IStartValidationChain Validate(this License license)
method ExpirationDate (line 52) | public static IValidationChain ExpirationDate(this IStartValidationCha...
method ProductBuildDate (line 74) | public static IValidationChain ProductBuildDate(this IStartValidationC...
method AssertThat (line 100) | public static IValidationChain AssertThat(this IStartValidationChain v...
method Signature (line 117) | public static IValidationChain Signature(this IStartValidationChain va...
FILE: src/Portable.Licensing/Validation/LicenseValidator.cs
class LicenseValidator (line 33) | internal class LicenseValidator : ILicenseValidator
FILE: src/Portable.Licensing/Validation/ValidationChainBuilder.cs
class ValidationChainBuilder (line 31) | internal class ValidationChainBuilder : IStartValidationChain, IValidati...
method ValidationChainBuilder (line 37) | public ValidationChainBuilder(License license)
method StartValidatorChain (line 43) | public ILicenseValidator StartValidatorChain()
method CompleteValidatorChain (line 48) | public void CompleteValidatorChain()
method When (line 57) | public ICompleteValidationChain When(Predicate<License> predicate)
method And (line 63) | public IStartValidationChain And()
method AssertValidLicense (line 69) | public IEnumerable<IValidationFailure> AssertValidLicense()
Condensed preview — 71 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (199K chars).
[
{
"path": ".gitignore",
"chars": 352,
"preview": "/Build\n/Publish\n/Distribution\n/nant-*.log*\npackages/\nBuildMetrics/\n\n#ignore thumbnails created by windows\nThumbs.db\n#Ign"
},
{
"path": ".paket/paket.targets",
"chars": 2820,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild"
},
{
"path": ".travis.yml",
"chars": 403,
"preview": "language: objective-c\n\nenv:\n matrix:\n - MONO_VERSION=\"3.10.0\"\n\nbefore_install:\n - wget \"http://download.mono-projec"
},
{
"path": "LICENSE.md",
"chars": 1103,
"preview": "The MIT License\n\nCopyright (c) 2012 - 2014 Nauck IT KG\t\thttp://www.nauck-it.de\n\nPermission is hereby granted, free of ch"
},
{
"path": "Portable.Licensing.nuspec",
"chars": 2919,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<package xmlns=\"http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd\">\n <me"
},
{
"path": "README.md",
"chars": 6839,
"preview": "# Documentation #\n\n----------\n\n## About Portable.Licensing ##\n\nPortable.Licensing is a cross platform software licensing"
},
{
"path": "Samples/Android.Sample/Android.Sample/Android.Sample.csproj",
"chars": 3789,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microso"
},
{
"path": "Samples/Android.Sample/Android.Sample/Assets/AboutAssets.txt",
"chars": 602,
"preview": "Any raw assets you want to be deployed with your application can be placed in\nthis directory (and child directories) and"
},
{
"path": "Samples/Android.Sample/Android.Sample/MainActivity.cs",
"chars": 3303,
"preview": "using System;\nusing System.Linq;\nusing System.Text;\nusing Android.App;\nusing Android.Content;\nusing Android.Runtime;\nus"
},
{
"path": "Samples/Android.Sample/Android.Sample/Properties/AssemblyInfo.cs",
"chars": 1275,
"preview": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\nusing Android.App"
},
{
"path": "Samples/Android.Sample/Android.Sample/Resources/AboutResources.txt",
"chars": 1771,
"preview": "Images, layout descriptions, binary blobs and string dictionaries can be included \nin your application as resource files"
},
{
"path": "Samples/Android.Sample/Android.Sample/Resources/Layout/Main.axml",
"chars": 411,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n andr"
},
{
"path": "Samples/Android.Sample/Android.Sample/Resources/Resource.Designer.cs",
"chars": 1747,
"preview": "#pragma warning disable 1591\n//------------------------------------------------------------------------------\n// <auto-g"
},
{
"path": "Samples/Android.Sample/Android.Sample/Resources/Values/Strings.xml",
"chars": 630,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <string name=\"LicensePublicKey\">MIIBKjCB4wYHKoZIzj0CATCB1wIBATAsB"
},
{
"path": "Samples/Android.Sample/Android.Sample.sln",
"chars": 1440,
"preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{2150E333-8FDC-42A3-9474-1A39"
},
{
"path": "Samples/Android.Sample/Android.Sample.sln.DotSettings",
"chars": 575,
"preview": "<wpf:ResourceDictionary xml:space=\"preserve\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:s=\"clr-namesp"
},
{
"path": "Samples/iOS.Sample/iOS.Sample/AppDelegate.cs",
"chars": 2907,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nusing MonoTouch.Foundation;\nusing"
},
{
"path": "Samples/iOS.Sample/iOS.Sample/Info.plist",
"chars": 913,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Samples/iOS.Sample/iOS.Sample/Main.cs",
"chars": 497,
"preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nusing MonoTouch.Foundation;\nusing MonoTouch.UIKit;\n"
},
{
"path": "Samples/iOS.Sample/iOS.Sample/MyViewController.cs",
"chars": 1392,
"preview": "using System;\nusing MonoTouch.UIKit;\nusing System.Drawing;\n\nnamespace iOS.Sample\n{\n public class MyViewController : U"
},
{
"path": "Samples/iOS.Sample/iOS.Sample/Properties/AssemblyInfo.cs",
"chars": 1393,
"preview": "using System.Reflection;\nusing System.Runtime.CompilerServices;\nusing System.Runtime.InteropServices;\n\n// General Infor"
},
{
"path": "Samples/iOS.Sample/iOS.Sample/iOS.Sample.csproj",
"chars": 4924,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microso"
},
{
"path": "Samples/iOS.Sample/iOS.Sample.sln",
"chars": 2644,
"preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{2150E333-8FDC-42A3-9474-1A39"
},
{
"path": "Samples/iOS.Sample/iOS.Sample.sln.DotSettings",
"chars": 575,
"preview": "<wpf:ResourceDictionary xml:space=\"preserve\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:s=\"clr-namesp"
},
{
"path": "Tools/xpkg/xpkg",
"chars": 92,
"preview": "#!/bin/bash\nDIR=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" && pwd )\"\nmono $DIR/xpkg.exe \"$@\"\n"
},
{
"path": "Xamarin/Details.md",
"chars": 2944,
"preview": "Portable.Licensing is a cross platform software licensing framework which allows you to implement licensing into your ap"
},
{
"path": "Xamarin/GettingStarted.md",
"chars": 3307,
"preview": "## Getting started ##\n\n### License.Manager light ###\n\nA reference implementation of a management application for product"
},
{
"path": "appveyor.yml",
"chars": 157,
"preview": "init:\n - git config --global core.autocrlf input\nbuild_script:\n - cmd: build.bat PackageNuGetDistribution\ntest: off\nar"
},
{
"path": "build-runTests.bat",
"chars": 226,
"preview": "@echo off\ncls\n\n.paket\\paket.bootstrapper.exe prerelease\nif errorlevel 1 (\n exit /b %errorlevel%\n)\n\n.paket\\paket.exe res"
},
{
"path": "build.bat",
"chars": 214,
"preview": "@echo off\ncls\n\n.paket\\paket.bootstrapper.exe prerelease\nif errorlevel 1 (\n exit /b %errorlevel%\n)\n\n.paket\\paket.exe res"
},
{
"path": "build.fsx",
"chars": 6576,
"preview": "// include Fake lib\n#I @\"packages/FAKE/tools\"\n#r @\"FakeLib.dll\"\n\nopen Fake\nopen Fake.AssemblyInfoFile\nopen System\n\n// bu"
},
{
"path": "build.sh",
"chars": 655,
"preview": "#!/bin/bash\nif test \"$OS\" = \"Windows_NT\"\nthen\n # use .Net\n\n .paket/paket.bootstrapper.exe prerelease\n exit_code=$?\n "
},
{
"path": "lib/License.txt",
"chars": 1213,
"preview": "Please note: our license is an adaptation of the MIT X11 License and should be read as such.\n\nLICENSE\nCopyright (c) 2000"
},
{
"path": "paket.dependencies",
"chars": 118,
"preview": "source https://nuget.org/api/v2\n\nnuget FAKE\nnuget NUnit \nnuget NUnit.Runners\nnuget NuGet.CommandLine"
},
{
"path": "src/CommonAssemblyInfo.cs",
"chars": 529,
"preview": "// <auto-generated/>\nusing System.Reflection;\n\n[assembly: AssemblyCompanyAttribute(\"Nauck IT KG\")]\n[assembly: AssemblyP"
},
{
"path": "src/Portable.Licensing/AssemblyBuildDateAttribute.cs",
"chars": 2624,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/Customer.cs",
"chars": 2282,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/IFluentInterface.cs",
"chars": 3049,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/ILicenseBuilder.cs",
"chars": 6290,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/License.cs",
"chars": 13734,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/LicenseAttributes.cs",
"chars": 6432,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/LicenseBuilder.cs",
"chars": 7950,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/LicenseType.cs",
"chars": 1570,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/Portable.Licensing.csproj",
"chars": 4333,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microso"
},
{
"path": "src/Portable.Licensing/Properties/AssemblyInfo.cs",
"chars": 1695,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/Security/Cryptography/KeyFactory.cs",
"chars": 3972,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/Security/Cryptography/KeyGenerator.cs",
"chars": 3732,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/Security/Cryptography/KeyPair.cs",
"chars": 2514,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/Validation/GeneralValidationFailure.cs",
"chars": 1771,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/Validation/IAddAdditionalValidationChain.cs",
"chars": 1643,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/Validation/IAssertValidation.cs",
"chars": 1705,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/Validation/ICompleteValidationChain.cs",
"chars": 1519,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/Validation/ILicenseValidator.cs",
"chars": 2140,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/Validation/IStartValidationChain.cs",
"chars": 1499,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/Validation/IValidationChain.cs",
"chars": 1536,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/Validation/IValidationChainCondition.cs",
"chars": 1787,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/Validation/IValidationFailure.cs",
"chars": 1752,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/Validation/InvalidSignatureValidationFailure.cs",
"chars": 1813,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/Validation/LicenseExpiredValidationFailure.cs",
"chars": 1826,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/Validation/LicenseValidationExtensions.cs",
"chars": 6836,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/Validation/LicenseValidator.cs",
"chars": 2178,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing/Validation/ValidationChainBuilder.cs",
"chars": 3129,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing.Tests/KeyGeneratorTests.cs",
"chars": 3483,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing.Tests/LicenseSignatureTests.cs",
"chars": 8315,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing.Tests/LicenseValidationTests.cs",
"chars": 9754,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing.Tests/Portable.Licensing.Tests.csproj",
"chars": 3288,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" DefaultTargets=\"Build\" xmlns=\"http://schemas.microso"
},
{
"path": "src/Portable.Licensing.Tests/Properties/AssemblyInfo.cs",
"chars": 2011,
"preview": "//\n// Copyright © 2012 - 2013 Nauck IT KG http://www.nauck-it.de\n//\n// Author:\n// Daniel Nauck <d.nauck(at"
},
{
"path": "src/Portable.Licensing.Tests/paket.references",
"chars": 5,
"preview": "NUnit"
},
{
"path": "src/Portable.Licensing.sln",
"chars": 6669,
"preview": "Microsoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2013\nVisualStudioVersion = 12.0.30723.0\nMini"
},
{
"path": "src/Portable.Licensing.sln.DotSettings",
"chars": 575,
"preview": "<wpf:ResourceDictionary xml:space=\"preserve\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\" xmlns:s=\"clr-namesp"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the dnauck/Portable.Licensing GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 71 files (182.3 KB), approximately 46.1k tokens, and a symbol index with 148 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.