Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corefx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pkg/Microsoft.Private.PackageBaseline/packageIndex.json2
-rw-r--r--src/System.Security.Cryptography.Encoding/dir.props2
-rw-r--r--src/System.Security.Cryptography.Encoding/pkg/System.Security.Cryptography.Encoding.pkgproj2
-rw-r--r--src/System.Security.Cryptography.Encoding/ref/System.Security.Cryptography.Encoding.cs78
-rw-r--r--src/System.Security.Cryptography.Encoding/ref/System.Security.Cryptography.Encoding.csproj2
-rw-r--r--src/System.Security.Cryptography.Encoding/ref/project.json7
-rw-r--r--src/System.Security.Cryptography.Encoding/src/Resources/Strings.resx12
-rw-r--r--src/System.Security.Cryptography.Encoding/src/System.Security.Cryptography.Encoding.builds2
-rw-r--r--src/System.Security.Cryptography.Encoding/src/System.Security.Cryptography.Encoding.csproj17
-rw-r--r--src/System.Security.Cryptography.Encoding/src/System/Security/Cryptography/Base64Transforms.cs265
-rw-r--r--src/System.Security.Cryptography.Encoding/src/project.json31
-rw-r--r--src/System.Security.Cryptography.Encoding/tests/Base64TransformsTests.cs204
-rw-r--r--src/System.Security.Cryptography.Encoding/tests/Oid.cs8
-rw-r--r--src/System.Security.Cryptography.Encoding/tests/System.Security.Cryptography.Encoding.Tests.builds11
-rw-r--r--src/System.Security.Cryptography.Encoding/tests/System.Security.Cryptography.Encoding.Tests.csproj9
-rw-r--r--src/System.Security.Cryptography.Encoding/tests/project.json33
16 files changed, 616 insertions, 69 deletions
diff --git a/pkg/Microsoft.Private.PackageBaseline/packageIndex.json b/pkg/Microsoft.Private.PackageBaseline/packageIndex.json
index b2dcfc0398..c1f0bea3f6 100644
--- a/pkg/Microsoft.Private.PackageBaseline/packageIndex.json
+++ b/pkg/Microsoft.Private.PackageBaseline/packageIndex.json
@@ -1823,7 +1823,7 @@
"BaselineVersion": "4.0.0",
"AssemblyVersionInPackageVersion": {
"4.0.0.0": "4.0.0",
- "4.0.1.0": "4.3.0"
+ "4.1.0.0": "4.3.0"
}
},
"System.Security.Cryptography.OpenSsl": {
diff --git a/src/System.Security.Cryptography.Encoding/dir.props b/src/System.Security.Cryptography.Encoding/dir.props
index 38aaf93ed7..0769c12aaa 100644
--- a/src/System.Security.Cryptography.Encoding/dir.props
+++ b/src/System.Security.Cryptography.Encoding/dir.props
@@ -1,7 +1,7 @@
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\dir.props" />
<PropertyGroup>
- <AssemblyVersion>4.0.1.0</AssemblyVersion>
+ <AssemblyVersion>4.1.0.0</AssemblyVersion>
</PropertyGroup>
</Project>
diff --git a/src/System.Security.Cryptography.Encoding/pkg/System.Security.Cryptography.Encoding.pkgproj b/src/System.Security.Cryptography.Encoding/pkg/System.Security.Cryptography.Encoding.pkgproj
index b8547733f4..77d2ac2571 100644
--- a/src/System.Security.Cryptography.Encoding/pkg/System.Security.Cryptography.Encoding.pkgproj
+++ b/src/System.Security.Cryptography.Encoding/pkg/System.Security.Cryptography.Encoding.pkgproj
@@ -3,7 +3,7 @@
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<ItemGroup>
<ProjectReference Include="..\ref\System.Security.Cryptography.Encoding.csproj">
- <SupportedFramework>net46;netcore50;netcoreapp1.0;$(AllXamarinFrameworks)</SupportedFramework>
+ <SupportedFramework>net463;netcoreapp1.1;$(AllXamarinFrameworks)</SupportedFramework>
</ProjectReference>
<ProjectReference Include="..\src\System.Security.Cryptography.Encoding.builds" />
diff --git a/src/System.Security.Cryptography.Encoding/ref/System.Security.Cryptography.Encoding.cs b/src/System.Security.Cryptography.Encoding/ref/System.Security.Cryptography.Encoding.cs
index 0b3eea4d3f..71e4f64ad5 100644
--- a/src/System.Security.Cryptography.Encoding/ref/System.Security.Cryptography.Encoding.cs
+++ b/src/System.Security.Cryptography.Encoding/ref/System.Security.Cryptography.Encoding.cs
@@ -20,6 +20,49 @@ namespace System.Security.Cryptography
public virtual void CopyFrom(System.Security.Cryptography.AsnEncodedData asnEncodedData) { }
public virtual string Format(bool multiLine) { return default(string); }
}
+ public sealed partial class AsnEncodedDataCollection : System.Collections.ICollection, System.Collections.IEnumerable
+ {
+ public AsnEncodedDataCollection() { }
+ public AsnEncodedDataCollection(System.Security.Cryptography.AsnEncodedData asnEncodedData) { }
+ public int Count { get { return default(int); } }
+ public System.Security.Cryptography.AsnEncodedData this[int index] { get { return default(System.Security.Cryptography.AsnEncodedData); } }
+ bool System.Collections.ICollection.IsSynchronized { get { return default(bool); } }
+ object System.Collections.ICollection.SyncRoot { get { return default(object); } }
+ public int Add(System.Security.Cryptography.AsnEncodedData asnEncodedData) { return default(int); }
+ public void CopyTo(System.Security.Cryptography.AsnEncodedData[] array, int index) { }
+ public System.Security.Cryptography.AsnEncodedDataEnumerator GetEnumerator() { return default(System.Security.Cryptography.AsnEncodedDataEnumerator); }
+ public void Remove(System.Security.Cryptography.AsnEncodedData asnEncodedData) { }
+ void System.Collections.ICollection.CopyTo(System.Array array, int index) { }
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return default(System.Collections.IEnumerator); }
+ }
+ public sealed partial class AsnEncodedDataEnumerator : System.Collections.IEnumerator
+ {
+ internal AsnEncodedDataEnumerator() { }
+ public System.Security.Cryptography.AsnEncodedData Current { get { return default(System.Security.Cryptography.AsnEncodedData); } }
+ object System.Collections.IEnumerator.Current { get { return default(object); } }
+ public bool MoveNext() { return default(bool); }
+ public void Reset() { }
+ }
+ public partial class FromBase64Transform : System.IDisposable, System.Security.Cryptography.ICryptoTransform
+ {
+ public FromBase64Transform() { }
+ public FromBase64Transform(System.Security.Cryptography.FromBase64TransformMode whitespaces) { }
+ public virtual bool CanReuseTransform { get { return default(bool); } }
+ public bool CanTransformMultipleBlocks { get { return default(bool); } }
+ public int InputBlockSize { get { return default(int); } }
+ public int OutputBlockSize { get { return default(int); } }
+ public void Clear() { }
+ public void Dispose() { }
+ protected virtual void Dispose(bool disposing) { }
+ ~FromBase64Transform() { }
+ public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { return default(int); }
+ public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) { return default(byte[]); }
+ }
+ public enum FromBase64TransformMode
+ {
+ DoNotIgnoreWhiteSpaces = 1,
+ IgnoreWhiteSpaces = 0,
+ }
public sealed partial class Oid
{
public Oid(System.Security.Cryptography.Oid oid) { }
@@ -66,29 +109,18 @@ namespace System.Security.Cryptography
SignatureAlgorithm = 4,
Template = 9,
}
-
- public sealed class AsnEncodedDataCollection : System.Collections.ICollection, System.Collections.IEnumerable
- {
- public AsnEncodedDataCollection() { }
- public AsnEncodedDataCollection(AsnEncodedData asnEncodedData) { }
- public int Count { get { return default(int); } }
- bool System.Collections.ICollection.IsSynchronized { get { return default(bool); } }
- object System.Collections.ICollection.SyncRoot { get { return default(object); } }
- public AsnEncodedData this[int index] { get { return default(AsnEncodedData); } }
- public int Add(AsnEncodedData asnEncodedData) { return default(int); }
- public void CopyTo(AsnEncodedData[] array, int index) { }
- public AsnEncodedDataEnumerator GetEnumerator() { return default(AsnEncodedDataEnumerator); }
- public void Remove(AsnEncodedData asnEncodedData) { }
- void System.Collections.ICollection.CopyTo(Array array, int index) { }
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return default(System.Collections.IEnumerator); }
- }
-
- public sealed class AsnEncodedDataEnumerator : System.Collections.IEnumerator
+ public partial class ToBase64Transform : System.IDisposable, System.Security.Cryptography.ICryptoTransform
{
- private AsnEncodedDataEnumerator() { }
- public AsnEncodedData Current { get { return default(AsnEncodedData); } }
- object System.Collections.IEnumerator.Current { get { return default(object); } }
- public bool MoveNext() { return default(bool); }
- public void Reset() { }
+ public ToBase64Transform() { }
+ public virtual bool CanReuseTransform { get { return default(bool); } }
+ public bool CanTransformMultipleBlocks { get { return default(bool); } }
+ public int InputBlockSize { get { return default(int); } }
+ public int OutputBlockSize { get { return default(int); } }
+ public void Clear() { }
+ public void Dispose() { }
+ protected virtual void Dispose(bool disposing) { }
+ ~ToBase64Transform() { }
+ public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { return default(int); }
+ public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) { return default(byte[]); }
}
}
diff --git a/src/System.Security.Cryptography.Encoding/ref/System.Security.Cryptography.Encoding.csproj b/src/System.Security.Cryptography.Encoding/ref/System.Security.Cryptography.Encoding.csproj
index fb9b809089..81f9b4ca59 100644
--- a/src/System.Security.Cryptography.Encoding/ref/System.Security.Cryptography.Encoding.csproj
+++ b/src/System.Security.Cryptography.Encoding/ref/System.Security.Cryptography.Encoding.csproj
@@ -3,7 +3,7 @@
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<OutputType>Library</OutputType>
- <NuGetTargetMoniker>.NETStandard,Version=v1.3</NuGetTargetMoniker>
+ <NuGetTargetMoniker>.NETStandard,Version=v1.7</NuGetTargetMoniker>
</PropertyGroup>
<ItemGroup>
<Compile Include="System.Security.Cryptography.Encoding.cs" />
diff --git a/src/System.Security.Cryptography.Encoding/ref/project.json b/src/System.Security.Cryptography.Encoding/ref/project.json
index e131fe0dbc..1b1510f8fa 100644
--- a/src/System.Security.Cryptography.Encoding/ref/project.json
+++ b/src/System.Security.Cryptography.Encoding/ref/project.json
@@ -1,11 +1,12 @@
{
"dependencies": {
- "System.Runtime": "4.0.0"
+ "System.Runtime": "4.3.0-beta-24522-03",
+ "System.Security.Cryptography.Primitives": "4.3.0-beta-24522-03"
},
"frameworks": {
- "netstandard1.3": {
+ "netstandard1.7": {
"imports": [
- "dotnet5.4"
+ "dotnet5.8"
]
}
}
diff --git a/src/System.Security.Cryptography.Encoding/src/Resources/Strings.resx b/src/System.Security.Cryptography.Encoding/src/Resources/Strings.resx
index c7396653a9..c0d44d9639 100644
--- a/src/System.Security.Cryptography.Encoding/src/Resources/Strings.resx
+++ b/src/System.Security.Cryptography.Encoding/src/Resources/Strings.resx
@@ -123,13 +123,25 @@
<data name="Cryptography_Oid_InvalidName" xml:space="preserve">
<value>No OID value matches this name.</value>
</data>
+ <data name="Cryptography_SSE_InvalidDataSize" xml:space="preserve">
+ <value>NoLength of the data to encrypt is invalid.</value>
+ </data>
<data name="Arg_RankMultiDimNotSupported" xml:space="preserve">
<value>Only single dimensional arrays are supported for the requested action.</value>
</data>
<data name="ArgumentOutOfRange_Index" xml:space="preserve">
<value>Index was out of range. Must be non-negative and less than the size of the collection.</value>
</data>
+ <data name="ArgumentOutOfRange_NeedNonNegNum" xml:space="preserve">
+ <value>Non-negative number required.</value>
+ </data>
<data name="Argument_InvalidOffLen" xml:space="preserve">
<value>Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.</value>
</data>
+ <data name="Argument_InvalidValue" xml:space="preserve">
+ <value>Value was invalid.</value>
+ </data>
+ <data name="ObjectDisposed_Generic" xml:space="preserve">
+ <value>Cannot access a disposed object.</value>
+ </data>
</root> \ No newline at end of file
diff --git a/src/System.Security.Cryptography.Encoding/src/System.Security.Cryptography.Encoding.builds b/src/System.Security.Cryptography.Encoding/src/System.Security.Cryptography.Encoding.builds
index 4ff1613681..2210a34f22 100644
--- a/src/System.Security.Cryptography.Encoding/src/System.Security.Cryptography.Encoding.builds
+++ b/src/System.Security.Cryptography.Encoding/src/System.Security.Cryptography.Encoding.builds
@@ -10,7 +10,7 @@
</Project>
<Project Include="System.Security.Cryptography.Encoding.csproj">
<OSGroup>Windows_NT</OSGroup>
- <TargetGroup>net46</TargetGroup>
+ <TargetGroup>net463</TargetGroup>
</Project>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.traversal.targets))\dir.traversal.targets" />
diff --git a/src/System.Security.Cryptography.Encoding/src/System.Security.Cryptography.Encoding.csproj b/src/System.Security.Cryptography.Encoding/src/System.Security.Cryptography.Encoding.csproj
index 65bf5f93b6..cfd7b3fd06 100644
--- a/src/System.Security.Cryptography.Encoding/src/System.Security.Cryptography.Encoding.csproj
+++ b/src/System.Security.Cryptography.Encoding/src/System.Security.Cryptography.Encoding.csproj
@@ -8,29 +8,30 @@
<ProjectGuid>{AA81E343-5E54-40B0-9381-C459419BE780}</ProjectGuid>
<AssemblyName>System.Security.Cryptography.Encoding</AssemblyName>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- <IsPartialFacadeAssembly Condition="'$(TargetGroup)' == 'net46'">true</IsPartialFacadeAssembly>
- <ResourcesSourceOutputDirectory Condition="'$(TargetGroup)' == 'net46'">None</ResourcesSourceOutputDirectory>
- <NuGetTargetMoniker Condition="'$(TargetGroup)' == ''">.NETStandard,Version=v1.3</NuGetTargetMoniker>
+ <IsPartialFacadeAssembly Condition="'$(TargetGroup)' == 'net463'">true</IsPartialFacadeAssembly>
+ <ResourcesSourceOutputDirectory Condition="'$(TargetGroup)' == 'net463'">None</ResourcesSourceOutputDirectory>
+ <NuGetTargetMoniker Condition="'$(TargetGroup)' == ''">.NETStandard,Version=v1.7</NuGetTargetMoniker>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Unix_Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Unix_Release|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Windows_Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Windows_Release|AnyCPU'" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'net46_Debug|AnyCPU'" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'net46_Release|AnyCPU'" />
- <ItemGroup Condition="'$(TargetGroup)' != 'net46'">
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'net463_Debug|AnyCPU'" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'net463_Release|AnyCPU'" />
+ <ItemGroup Condition="'$(TargetGroup)' != 'net463'">
<Compile Include="Internal\Cryptography\AsnFormatter.cs" />
<Compile Include="Internal\Cryptography\Helpers.cs" />
<Compile Include="Internal\Cryptography\OidLookup.cs" />
<Compile Include="System\Security\Cryptography\AsnEncodedData.cs" />
<Compile Include="System\Security\Cryptography\AsnEncodedDataCollection.cs" />
<Compile Include="System\Security\Cryptography\AsnEncodedDataEnumerator.cs" />
+ <Compile Include="System\Security\Cryptography\Base64Transforms.cs" />
<Compile Include="System\Security\Cryptography\Oid.cs" />
<Compile Include="System\Security\Cryptography\OidCollection.cs" />
<Compile Include="System\Security\Cryptography\OidEnumerator.cs" />
<Compile Include="System\Security\Cryptography\OidGroup.cs" />
</ItemGroup>
- <ItemGroup Condition=" '$(TargetsWindows)' == 'true' And '$(TargetGroup)' != 'net46'">
+ <ItemGroup Condition=" '$(TargetsWindows)' == 'true' And '$(TargetGroup)' != 'net463'">
<Compile Include="Internal\Cryptography\AsnFormatter.Windows.cs" />
<Compile Include="Internal\Cryptography\CngAsnFormatter.cs" />
<Compile Include="Internal\Cryptography\OidLookup.Windows.cs" />
@@ -88,7 +89,7 @@
<Link>Common\Microsoft\Win32\SafeHandles\X509ExtensionSafeHandles.Unix.cs</Link>
</Compile>
</ItemGroup>
- <ItemGroup Condition="'$(TargetGroup)' == 'net46'">
+ <ItemGroup Condition="'$(TargetGroup)' == 'net463'">
<TargetingPackReference Include="mscorlib" />
<TargetingPackReference Include="System" />
</ItemGroup>
diff --git a/src/System.Security.Cryptography.Encoding/src/System/Security/Cryptography/Base64Transforms.cs b/src/System.Security.Cryptography.Encoding/src/System/Security/Cryptography/Base64Transforms.cs
new file mode 100644
index 0000000000..afd2f07a13
--- /dev/null
+++ b/src/System.Security.Cryptography.Encoding/src/System/Security/Cryptography/Base64Transforms.cs
@@ -0,0 +1,265 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// This file contains two ICryptoTransforms: ToBase64Transform and FromBase64Transform
+// they may be attached to a CryptoStream in either read or write mode
+
+using System.Text;
+
+namespace System.Security.Cryptography
+{
+ public enum FromBase64TransformMode
+ {
+ IgnoreWhiteSpaces = 0,
+ DoNotIgnoreWhiteSpaces = 1,
+ }
+
+ public class ToBase64Transform : ICryptoTransform
+ {
+ // converting to Base64 takes 3 bytes input and generates 4 bytes output
+ public int InputBlockSize => 3;
+ public int OutputBlockSize => 4;
+ public bool CanTransformMultipleBlocks => false;
+ public virtual bool CanReuseTransform => true;
+
+ public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
+ {
+ ValidateTransformBlock(inputBuffer, inputOffset, inputCount);
+
+ // For now, only convert 3 bytes to 4
+ byte[] tempBytes = ConvertToBase64(inputBuffer, inputOffset, 3);
+
+ Buffer.BlockCopy(tempBytes, 0, outputBuffer, outputOffset, tempBytes.Length);
+ return tempBytes.Length;
+ }
+
+ public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
+ {
+ ValidateTransformBlock(inputBuffer, inputOffset, inputCount);
+
+ // Convert.ToBase64CharArray already does padding, so all we have to check is that
+ // the inputCount wasn't 0
+ if (inputCount == 0)
+ {
+ return Array.Empty<byte>();
+ }
+
+ // Again, for now only a block at a time
+ return ConvertToBase64(inputBuffer, inputOffset, inputCount);
+ }
+
+ private byte[] ConvertToBase64(byte[] inputBuffer, int inputOffset, int inputCount)
+ {
+ char[] temp = new char[4];
+ Convert.ToBase64CharArray(inputBuffer, inputOffset, inputCount, temp, 0);
+ byte[] tempBytes = Encoding.ASCII.GetBytes(temp);
+ if (tempBytes.Length != 4)
+ throw new CryptographicException(SR.Cryptography_SSE_InvalidDataSize);
+
+ return tempBytes;
+ }
+
+ private static void ValidateTransformBlock(byte[] inputBuffer, int inputOffset, int inputCount)
+ {
+ if (inputBuffer == null) throw new ArgumentNullException(nameof(inputBuffer));
+ if (inputOffset < 0) throw new ArgumentOutOfRangeException(nameof(inputOffset), SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (inputCount < 0 || (inputCount > inputBuffer.Length)) throw new ArgumentException(SR.Argument_InvalidValue);
+ if ((inputBuffer.Length - inputCount) < inputOffset) throw new ArgumentException(SR.Argument_InvalidOffLen);
+ }
+
+ // Must implement IDisposable, but in this case there's nothing to do.
+
+ public void Dispose()
+ {
+ Clear();
+ }
+
+ public void Clear()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing) { }
+
+ ~ToBase64Transform()
+ {
+ // A finalizer is not necessary here, however since we shipped a finalizer that called
+ // Dispose(false) in desktop v2.0, we need to keep it in case any existing code had subclassed
+ // this transform and expects to have a base class finalizer call its dispose method.
+ Dispose(false);
+ }
+ }
+
+ public class FromBase64Transform : ICryptoTransform
+ {
+ private byte[] _inputBuffer = new byte[4];
+ private int _inputIndex;
+ private FromBase64TransformMode _whitespaces;
+
+ public FromBase64Transform() : this(FromBase64TransformMode.IgnoreWhiteSpaces) { }
+ public FromBase64Transform(FromBase64TransformMode whitespaces)
+ {
+ _whitespaces = whitespaces;
+ _inputIndex = 0;
+ }
+
+ // Converting from Base64 generates 3 bytes output from each 4 bytes input block
+ public int InputBlockSize => 1;
+ public int OutputBlockSize => 3;
+ public bool CanTransformMultipleBlocks => false;
+ public virtual bool CanReuseTransform => true;
+
+ public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
+ {
+ ValidateTransformBlock(inputBuffer, inputOffset, inputCount);
+ if (_inputBuffer == null) throw new ObjectDisposedException(null, SR.ObjectDisposed_Generic);
+
+ int effectiveCount;
+ byte[] temp = GetTempBuffer(inputBuffer, inputOffset, inputCount, out effectiveCount);
+
+ if (effectiveCount + _inputIndex < 4)
+ {
+ Buffer.BlockCopy(temp, 0, _inputBuffer, _inputIndex, effectiveCount);
+ _inputIndex += effectiveCount;
+ return 0;
+ }
+
+ byte[] result = ConvertFromBase64(temp, effectiveCount);
+
+ Buffer.BlockCopy(result, 0, outputBuffer, outputOffset, result.Length);
+
+ return result.Length;
+ }
+
+ public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
+ {
+ ValidateTransformBlock(inputBuffer, inputOffset, inputCount);
+ if (_inputBuffer == null) throw new ObjectDisposedException(null, SR.ObjectDisposed_Generic);
+
+ int effectiveCount;
+ byte[] temp = GetTempBuffer(inputBuffer, inputOffset, inputCount, out effectiveCount);
+
+ if (effectiveCount + _inputIndex < 4)
+ {
+ Reset();
+ return Array.Empty<byte>();
+ }
+
+ byte[] result = ConvertFromBase64(temp, effectiveCount);
+
+ // reinitialize the transform
+ Reset();
+
+ return result;
+ }
+
+ private byte[] GetTempBuffer(byte[] inputBuffer, int inputOffset, int inputCount, out int effectiveCount)
+ {
+ byte[] temp;
+
+ if (_whitespaces == FromBase64TransformMode.IgnoreWhiteSpaces)
+ {
+ temp = DiscardWhiteSpaces(inputBuffer, inputOffset, inputCount);
+ effectiveCount = temp.Length;
+ }
+ else
+ {
+ temp = new byte[inputCount];
+ Buffer.BlockCopy(inputBuffer, inputOffset, temp, 0, inputCount);
+ effectiveCount = inputCount;
+ }
+
+ return temp;
+ }
+
+ private byte[] ConvertFromBase64(byte[] temp, int effectiveCount)
+ {
+ // Get the number of 4 bytes blocks to transform
+ int numBlocks = (effectiveCount + _inputIndex) / 4;
+
+ byte[] transformBuffer = new byte[_inputIndex + effectiveCount];
+ Buffer.BlockCopy(_inputBuffer, 0, transformBuffer, 0, _inputIndex);
+ Buffer.BlockCopy(temp, 0, transformBuffer, _inputIndex, effectiveCount);
+
+ _inputIndex = (effectiveCount + _inputIndex) % 4;
+ Buffer.BlockCopy(temp, effectiveCount - _inputIndex, _inputBuffer, 0, _inputIndex);
+
+ char[] tempChar = Encoding.ASCII.GetChars(transformBuffer, 0, 4 * numBlocks);
+ byte[] tempBytes = Convert.FromBase64CharArray(tempChar, 0, 4 * numBlocks);
+ return tempBytes;
+ }
+
+ private byte[] DiscardWhiteSpaces(byte[] inputBuffer, int inputOffset, int inputCount)
+ {
+ int i, iCount = 0;
+ for (i = 0; i < inputCount; i++)
+ {
+ if (char.IsWhiteSpace((char)inputBuffer[inputOffset + i])) iCount++;
+ }
+
+ // If there's nothing to do, leave early
+ if (iCount == 0 && inputOffset == 0)
+ {
+ return inputBuffer;
+ }
+
+ byte[] rgbOut = new byte[inputCount - iCount];
+ iCount = 0;
+ for (i = 0; i < inputCount; i++)
+ {
+ if (!char.IsWhiteSpace((char)inputBuffer[inputOffset + i]))
+ {
+ rgbOut[iCount++] = inputBuffer[inputOffset + i];
+ }
+ }
+
+ return rgbOut;
+ }
+
+ private static void ValidateTransformBlock(byte[] inputBuffer, int inputOffset, int inputCount)
+ {
+ if (inputBuffer == null) throw new ArgumentNullException(nameof(inputBuffer));
+ if (inputOffset < 0) throw new ArgumentOutOfRangeException(nameof(inputOffset), SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (inputCount < 0 || (inputCount > inputBuffer.Length)) throw new ArgumentException(SR.Argument_InvalidValue);
+ if ((inputBuffer.Length - inputCount) < inputOffset) throw new ArgumentException(SR.Argument_InvalidOffLen);
+ }
+
+ // must implement IDisposable, which in this case means clearing the input buffer
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ // Reset the state of the transform so it can be used again
+ private void Reset()
+ {
+ _inputIndex = 0;
+ }
+
+ public void Clear()
+ {
+ Dispose();
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ // we always want to clear the input buffer
+ if (disposing)
+ {
+ if (_inputBuffer != null)
+ Array.Clear(_inputBuffer, 0, _inputBuffer.Length);
+ _inputBuffer = null;
+ _inputIndex = 0;
+ }
+ }
+
+ ~FromBase64Transform()
+ {
+ Dispose(false);
+ }
+ }
+}
diff --git a/src/System.Security.Cryptography.Encoding/src/project.json b/src/System.Security.Cryptography.Encoding/src/project.json
index 7b9d9a0b6e..eeb30e9c99 100644
--- a/src/System.Security.Cryptography.Encoding/src/project.json
+++ b/src/System.Security.Cryptography.Encoding/src/project.json
@@ -1,26 +1,27 @@
{
"frameworks": {
- "netstandard1.3": {
+ "netstandard1.7": {
"dependencies": {
- "Microsoft.NETCore.Platforms": "1.0.1",
- "System.Collections": "4.0.0",
- "System.Collections.Concurrent": "4.0.0",
- "System.Diagnostics.Contracts": "4.0.0",
- "System.Diagnostics.Debug": "4.0.10",
- "System.Linq": "4.0.0",
- "System.Resources.ResourceManager": "4.0.0",
- "System.Runtime": "4.0.20",
- "System.Runtime.InteropServices": "4.0.20",
- "System.Text.Encoding": "4.0.10",
- "System.Security.Cryptography.Primitives": "4.0.0"
+ "Microsoft.NETCore.Platforms": "1.0.2-beta-24522-03",
+ "System.Collections": "4.3.0-beta-24522-03",
+ "System.Collections.Concurrent": "4.3.0-beta-24522-03",
+ "System.Diagnostics.Contracts": "4.3.0-beta-24522-03",
+ "System.Diagnostics.Debug": "4.3.0-beta-24522-03",
+ "System.Linq": "4.3.0-beta-24522-03",
+ "System.Resources.ResourceManager": "4.3.0-beta-24522-03",
+ "System.Runtime": "4.3.0-beta-24522-03",
+ "System.Runtime.Extensions": "4.3.0-beta-24522-03",
+ "System.Runtime.InteropServices": "4.3.0-beta-24522-03",
+ "System.Text.Encoding": "4.3.0-beta-24522-03",
+ "System.Security.Cryptography.Primitives": "4.3.0-beta-24522-03"
},
"imports": [
- "dotnet5.4"
+ "dotnet5.8"
]
},
- "net46": {
+ "net463": {
"dependencies": {
- "Microsoft.TargetingPack.NETFramework.v4.6": "1.0.1"
+ "Microsoft.TargetingPack.NETFramework.v4.6.2": "1.0.1"
}
}
}
diff --git a/src/System.Security.Cryptography.Encoding/tests/Base64TransformsTests.cs b/src/System.Security.Cryptography.Encoding/tests/Base64TransformsTests.cs
new file mode 100644
index 0000000000..c7ced87de5
--- /dev/null
+++ b/src/System.Security.Cryptography.Encoding/tests/Base64TransformsTests.cs
@@ -0,0 +1,204 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Collections.Generic;
+using System.IO;
+using Test.Cryptography;
+using Xunit;
+
+namespace System.Security.Cryptography.Encoding.Tests
+{
+ public class Base64TransformsTests
+ {
+ public static IEnumerable<object[]> TestData_Ascii()
+ {
+ // Test data taken from RFC 4648 Test Vectors
+ yield return new object[] { "", "" };
+ yield return new object[] { "f", "Zg==" };
+ yield return new object[] { "fo", "Zm8=" };
+ yield return new object[] { "foo", "Zm9v" };
+ yield return new object[] { "foob", "Zm9vYg==" };
+ yield return new object[] { "fooba", "Zm9vYmE=" };
+ yield return new object[] { "foobar", "Zm9vYmFy" };
+ }
+
+ public static IEnumerable<object[]> TestData_LongBlock_Ascii()
+ {
+ yield return new object[] { "fooba", "Zm9vYmE=" };
+ yield return new object[] { "foobar", "Zm9vYmFy" };
+ }
+
+ public static IEnumerable<object[]> TestData_Ascii_NoPadding()
+ {
+ // Test data without padding
+ yield return new object[] { "Zg" };
+ yield return new object[] { "Zm9vYg" };
+ yield return new object[] { "Zm9vYmE" };
+ }
+
+ public static IEnumerable<object[]> TestData_Ascii_Whitespace()
+ {
+ yield return new object[] { "fo", "\tZ\tm8=\n" };
+ yield return new object[] { "foo", " Z m 9 v" };
+ }
+
+ [Fact]
+ public void InvalidInput_ToBase64Transform()
+ {
+ byte[] data_5bytes = Text.Encoding.ASCII.GetBytes("aaaaa");
+
+ using (var transform = new ToBase64Transform())
+ {
+ InvalidInput_Base64Transform(transform);
+
+ // These exceptions only thrown in ToBase
+ Assert.Throws<ArgumentOutOfRangeException>("offsetOut", () => transform.TransformFinalBlock(data_5bytes, 0, 5));
+ }
+ }
+
+ [Fact]
+ public void InvalidInput_FromBase64Transform()
+ {
+ byte[] data_4bytes = Text.Encoding.ASCII.GetBytes("aaaa");
+
+ ICryptoTransform transform = new FromBase64Transform();
+ InvalidInput_Base64Transform(transform);
+
+ // These exceptions only thrown in FromBase
+ transform.Dispose();
+ Assert.Throws<ObjectDisposedException>(() => transform.TransformBlock(data_4bytes, 0, 4, null, 0));
+ Assert.Throws<ObjectDisposedException>(() => transform.TransformFinalBlock(Array.Empty<byte>(), 0, 0));
+ }
+
+ private void InvalidInput_Base64Transform(ICryptoTransform transform)
+ {
+ byte[] data_4bytes = Text.Encoding.ASCII.GetBytes("aaaa");
+
+ Assert.Throws<ArgumentNullException>("inputBuffer", () => transform.TransformBlock(null, 0, 0, null, 0));
+ Assert.Throws<ArgumentOutOfRangeException>("inputOffset", () => transform.TransformBlock(Array.Empty<byte>(), -1, 0, null, 0));
+ Assert.Throws<ArgumentNullException>("dst", () => transform.TransformBlock(data_4bytes, 0, 4, null, 0));
+ Assert.Throws<ArgumentException>(null, () => transform.TransformBlock(Array.Empty<byte>(), 0, 1, null, 0));
+ Assert.Throws<ArgumentException>(null, () => transform.TransformBlock(Array.Empty<byte>(), 1, 0, null, 0));
+
+ Assert.Throws<ArgumentNullException>("inputBuffer", () => transform.TransformFinalBlock(null, 0, 0));
+ Assert.Throws<ArgumentOutOfRangeException>("inputOffset", () => transform.TransformFinalBlock(Array.Empty<byte>(), -1, 0));
+ Assert.Throws<ArgumentOutOfRangeException>("inputOffset", () => transform.TransformFinalBlock(Array.Empty<byte>(), -1, 0));
+ Assert.Throws<ArgumentException>(null, () => transform.TransformFinalBlock(Array.Empty<byte>(), 1, 0));
+ }
+
+ [Theory, MemberData(nameof(TestData_Ascii))]
+ public static void ValidateToBase64CryptoStream(string data, string encoding)
+ {
+ using (var transform = new ToBase64Transform())
+ {
+ ValidateCryptoStream(encoding, data, transform);
+ }
+ }
+
+ [Theory, MemberData(nameof(TestData_Ascii))]
+ public static void ValidateFromBase64CryptoStream(string data, string encoding)
+ {
+ using (var transform = new FromBase64Transform())
+ {
+ ValidateCryptoStream(data, encoding, transform);
+ }
+ }
+
+ private static void ValidateCryptoStream(string expected, string data, ICryptoTransform transform)
+ {
+ byte[] inputBytes = Text.Encoding.ASCII.GetBytes(data);
+ byte[] outputBytes = new byte[100];
+
+ using (var ms = new MemoryStream(inputBytes))
+ using (var cs = new CryptoStream(ms, transform, CryptoStreamMode.Read))
+ {
+ int bytesRead = cs.Read(outputBytes, 0, outputBytes.Length);
+ string outputString = Text.Encoding.ASCII.GetString(outputBytes, 0, bytesRead);
+ Assert.Equal(expected, outputString);
+ }
+ }
+
+ [Theory, MemberData(nameof(TestData_LongBlock_Ascii))]
+ public static void ValidateToBase64TransformFinalBlock(string data, string expected)
+ {
+ using (var transform = new ToBase64Transform())
+ {
+ byte[] inputBytes = Text.Encoding.ASCII.GetBytes(data);
+ Assert.True(inputBytes.Length > 4);
+
+ // Test passing blocks > 4 characters to TransformFinalBlock (not supported)
+ Assert.Throws<ArgumentOutOfRangeException>("offsetOut", () => transform.TransformFinalBlock(inputBytes, 0, inputBytes.Length));
+ }
+ }
+
+ [Theory, MemberData(nameof(TestData_LongBlock_Ascii))]
+ public static void ValidateFromBase64TransformFinalBlock(string expected, string encoding)
+ {
+ using (var transform = new FromBase64Transform())
+ {
+ byte[] inputBytes = Text.Encoding.ASCII.GetBytes(encoding);
+ Assert.True(inputBytes.Length > 4);
+
+ // Test passing blocks > 4 characters to TransformFinalBlock (supported)
+ byte[] outputBytes = transform.TransformFinalBlock(inputBytes, 0, inputBytes.Length);
+ string outputString = Text.Encoding.ASCII.GetString(outputBytes, 0, outputBytes.Length);
+ Assert.Equal(expected, outputString);
+ }
+ }
+
+ [Theory, MemberData(nameof(TestData_Ascii_NoPadding))]
+ public static void ValidateFromBase64_NoPadding(string data)
+ {
+ using (var transform = new FromBase64Transform())
+ {
+ byte[] inputBytes = Text.Encoding.ASCII.GetBytes(data);
+ byte[] outputBytes = new byte[100];
+
+ using (var ms = new MemoryStream(inputBytes))
+ using (var cs = new CryptoStream(ms, transform, CryptoStreamMode.Read))
+ {
+ int bytesRead = cs.Read(outputBytes, 0, outputBytes.Length);
+
+ // Missing padding bytes not supported (no exception, however)
+ Assert.NotEqual(inputBytes.Length, bytesRead);
+ }
+ }
+ }
+
+ [Theory, MemberData(nameof(TestData_Ascii_Whitespace))]
+ public static void ValidateWhitespace(string expected, string data)
+ {
+ byte[] inputBytes = Text.Encoding.ASCII.GetBytes(data);
+ byte[] outputBytes = new byte[100];
+
+ // Verify default of FromBase64TransformMode.IgnoreWhiteSpaces
+ using (var base64Transform = new FromBase64Transform())
+ using (var ms = new MemoryStream(inputBytes))
+ using (var cs = new CryptoStream(ms, base64Transform, CryptoStreamMode.Read))
+ {
+ int bytesRead = cs.Read(outputBytes, 0, outputBytes.Length);
+ string outputString = Text.Encoding.ASCII.GetString(outputBytes, 0, bytesRead);
+ Assert.Equal(expected, outputString);
+ }
+
+ // Verify explicit FromBase64TransformMode.IgnoreWhiteSpaces
+ using (var base64Transform = new FromBase64Transform(FromBase64TransformMode.IgnoreWhiteSpaces))
+ using (var ms = new MemoryStream(inputBytes))
+ using (var cs = new CryptoStream(ms, base64Transform, CryptoStreamMode.Read))
+ {
+ int bytesRead = cs.Read(outputBytes, 0, outputBytes.Length);
+ string outputString = Text.Encoding.ASCII.GetString(outputBytes, 0, bytesRead);
+ Assert.Equal(expected, outputString);
+ }
+
+ // Verify FromBase64TransformMode.DoNotIgnoreWhiteSpaces
+ using (var base64Transform = new FromBase64Transform(FromBase64TransformMode.DoNotIgnoreWhiteSpaces))
+ using (var ms = new MemoryStream(inputBytes))
+ using (var cs = new CryptoStream(ms, base64Transform, CryptoStreamMode.Read))
+ {
+ Assert.Throws<FormatException>(() => cs.Read(outputBytes, 0, outputBytes.Length));
+ }
+ }
+ }
+}
diff --git a/src/System.Security.Cryptography.Encoding/tests/Oid.cs b/src/System.Security.Cryptography.Encoding/tests/Oid.cs
index 0e89ea7223..bc2f000069 100644
--- a/src/System.Security.Cryptography.Encoding/tests/Oid.cs
+++ b/src/System.Security.Cryptography.Encoding/tests/Oid.cs
@@ -175,7 +175,7 @@ namespace System.Security.Cryptography.Encoding.Tests
[Theory]
[MemberData(nameof(ValidOidFriendlyNameHashAlgorithmPairs))]
- [PlatformSpecific(PlatformID.Windows)]
+ [PlatformSpecific(Xunit.PlatformID.Windows)]
public static void LookupOidByValue_Method_WrongGroup(string oidValue, string friendlyName)
{
// Oid group is implemented strictly - no fallback to OidGroup.All as with many other parts of Crypto.
@@ -231,7 +231,7 @@ namespace System.Security.Cryptography.Encoding.Tests
[Theory]
[MemberData(nameof(ValidOidFriendlyNameHashAlgorithmPairs))]
- [PlatformSpecific(PlatformID.Windows)]
+ [PlatformSpecific(Xunit.PlatformID.Windows)]
public static void LookupOidByFriendlyName_Method_WrongGroup(string oidValue, string friendlyName)
{
// Oid group is implemented strictly - no fallback to OidGroup.All as with many other parts of Crypto.
@@ -253,7 +253,7 @@ namespace System.Security.Cryptography.Encoding.Tests
}
[Fact]
- [PlatformSpecific(PlatformID.AnyUnix)]
+ [PlatformSpecific(Xunit.PlatformID.AnyUnix)]
public static void LookupOidByValue_Method_UnixOnly()
{
// This needs to be an OID not in the static lookup table. The purpose is to verify the
@@ -267,7 +267,7 @@ namespace System.Security.Cryptography.Encoding.Tests
}
[Fact]
- [PlatformSpecific(PlatformID.AnyUnix)]
+ [PlatformSpecific(Xunit.PlatformID.AnyUnix)]
public static void LookupOidByFriendlyName_Method_UnixOnly()
{
// This needs to be a name not in the static lookup table. The purpose is to verify the
diff --git a/src/System.Security.Cryptography.Encoding/tests/System.Security.Cryptography.Encoding.Tests.builds b/src/System.Security.Cryptography.Encoding/tests/System.Security.Cryptography.Encoding.Tests.builds
index 478303b742..5f029c7d7d 100644
--- a/src/System.Security.Cryptography.Encoding/tests/System.Security.Cryptography.Encoding.Tests.builds
+++ b/src/System.Security.Cryptography.Encoding/tests/System.Security.Cryptography.Encoding.Tests.builds
@@ -6,7 +6,16 @@
<OSGroup>Unix</OSGroup>
</Project>
<Project Include="System.Security.Cryptography.Encoding.Tests.csproj">
- <TestTFMs>netcore50;netcoreapp1.0;net46</TestTFMs>
+ <TargetGroup>netstandard1.7</TargetGroup>
+ <TestTFMs>netcoreapp1.1</TestTFMs>
+ <OSGroup>Unix</OSGroup>
+ </Project>
+ <Project Include="System.Security.Cryptography.Encoding.Tests.csproj">
+ <OSGroup>Windows_NT</OSGroup>
+ </Project>
+ <Project Include="System.Security.Cryptography.Encoding.Tests.csproj">
+ <TargetGroup>netstandard1.7</TargetGroup>
+ <TestTFMs>netcoreapp1.1;net463</TestTFMs>
<OSGroup>Windows_NT</OSGroup>
</Project>
</ItemGroup>
diff --git a/src/System.Security.Cryptography.Encoding/tests/System.Security.Cryptography.Encoding.Tests.csproj b/src/System.Security.Cryptography.Encoding/tests/System.Security.Cryptography.Encoding.Tests.csproj
index 76d302590c..03fe8707b9 100644
--- a/src/System.Security.Cryptography.Encoding/tests/System.Security.Cryptography.Encoding.Tests.csproj
+++ b/src/System.Security.Cryptography.Encoding/tests/System.Security.Cryptography.Encoding.Tests.csproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition="'$(Configuration)'==''">Windows_Debug</Configuration>
@@ -12,7 +12,7 @@
<AssemblyName>System.Security.Cryptography.Encoding.Tests</AssemblyName>
<RootNamespace>System.Security.Cryptography.Encoding.Tests</RootNamespace>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
- <NugetTargetMoniker>.NETStandard,Version=v1.3</NugetTargetMoniker>
+ <NugetTargetMoniker Condition="'$(NugetTargetMoniker)'==''">.NETStandard,Version=v1.3</NugetTargetMoniker>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\pkg\System.Security.Cryptography.Encoding.pkgproj">
@@ -37,8 +37,11 @@
<Link>CommonTest\System\Security\Cryptography\ByteUtils.cs</Link>
</Compile>
</ItemGroup>
+ <ItemGroup Condition="'$(TargetGroup)'=='netstandard1.7'">
+ <Compile Include="Base64TransformsTests.cs" />
+ </ItemGroup>
<ItemGroup>
<None Include="project.json" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
-</Project>
+</Project> \ No newline at end of file
diff --git a/src/System.Security.Cryptography.Encoding/tests/project.json b/src/System.Security.Cryptography.Encoding/tests/project.json
index 547abd08cc..3e4389806a 100644
--- a/src/System.Security.Cryptography.Encoding/tests/project.json
+++ b/src/System.Security.Cryptography.Encoding/tests/project.json
@@ -9,17 +9,18 @@
"System.Runtime.Numerics": "4.3.0-beta-24522-03",
"System.Security.Cryptography.Primitives": "4.3.0-beta-24522-03",
"System.Text.RegularExpressions": "4.3.0-beta-24522-03",
- "test-runtime": {
- "target": "project",
- "exclude": "compile"
- },
+ "System.Xml.XmlSerializer": "4.3.0-beta-24522-03",
"Microsoft.xunit.netcore.extensions": "1.0.0-prerelease-00807-03",
"Microsoft.DotNet.BuildTools.TestSuite": "1.0.0-prerelease-00807-03",
"Microsoft.DotNet.xunit.performance": "1.0.0-alpha-build0040",
- "System.Xml.XmlSerializer": "4.3.0-beta-24522-03"
+ "test-runtime": {
+ "target": "project",
+ "exclude": "compile"
+ }
},
"frameworks": {
- "netstandard1.3": {}
+ "netstandard1.3": {},
+ "netstandard1.7": {}
},
"supports": {
"coreFx.Test.netcore50": {},
@@ -27,6 +28,24 @@
"coreFx.Test.net46": {},
"coreFx.Test.net461": {},
"coreFx.Test.net462": {},
- "coreFx.Test.net463": {}
+ "coreFx.Test.net463": {},
+ "coreFx.Test.netcoreapp1.1-ns17": {
+ "netstandard1.7": [
+ "win7-x86",
+ "win7-x64",
+ "win10-arm64",
+ "osx.10.10-x64",
+ "centos.7-x64",
+ "debian.8-x64",
+ "rhel.7-x64",
+ "ubuntu.14.04-x64",
+ "ubuntu.16.04-x64",
+ "ubuntu.16.10-x64",
+ "fedora.23-x64",
+ "linux-x64",
+ "opensuse.13.2-x64",
+ "opensuse.42.1-x64"
+ ]
+ }
}
}