diff options
-rw-r--r-- | crypto-test/crypto-test.csproj | 199 | ||||
-rw-r--r-- | crypto/crypto.csproj | 2 | ||||
-rw-r--r-- | crypto/src/asn1/x509/X509ExtensionsGenerator.cs | 195 | ||||
-rw-r--r-- | crypto/src/pkcs/Pkcs10CertificationRequest.cs | 583 | ||||
-rw-r--r-- | crypto/test/src/asn1/test/X509ExtensionsTest.cs | 322 | ||||
-rw-r--r-- | crypto/test/src/test/PKCS10CertRequestTest.cs | 222 | ||||
-rw-r--r-- | csharp.sln | 39 |
7 files changed, 938 insertions, 624 deletions
diff --git a/crypto-test/crypto-test.csproj b/crypto-test/crypto-test.csproj index 9bb4cdbb9..50c293aff 100644 --- a/crypto-test/crypto-test.csproj +++ b/crypto-test/crypto-test.csproj @@ -1,104 +1,95 @@ -<VisualStudioProject> - <CSHARP - ProjectType = "Local" - ProductVersion = "7.10.3077" - SchemaVersion = "2.0" - ProjectGuid = "{C857AD68-8F1B-4C7A-A76B-3DC03CBE4FB0}" - > - <Build> - <Settings - ApplicationIcon = "App.ico" - AssemblyKeyContainerName = "" - AssemblyName = "crypto-test" - AssemblyOriginatorKeyFile = "" - DefaultClientScript = "JScript" - DefaultHTMLPageLayout = "Grid" - DefaultTargetSchema = "IE50" - DelaySign = "false" - OutputType = "Exe" - PreBuildEvent = "" - PostBuildEvent = "" - RootNamespace = "crypto_test" - RunPostBuildEvent = "OnBuildSuccess" - StartupObject = "" - > - <Config - Name = "Debug" - AllowUnsafeBlocks = "false" - BaseAddress = "285212672" - CheckForOverflowUnderflow = "false" - ConfigurationOverrideFile = "" - DefineConstants = "DEBUG;TRACE" - DocumentationFile = "" - DebugSymbols = "true" - FileAlignment = "4096" - IncrementalBuild = "false" - NoStdLib = "false" - NoWarn = "" - Optimize = "false" - OutputPath = "bin\Debug\" - RegisterForComInterop = "false" - RemoveIntegerChecks = "false" - TreatWarningsAsErrors = "false" - WarningLevel = "4" - /> - <Config - Name = "Release" - AllowUnsafeBlocks = "false" - BaseAddress = "285212672" - CheckForOverflowUnderflow = "false" - ConfigurationOverrideFile = "" - DefineConstants = "TRACE" - DocumentationFile = "" - DebugSymbols = "false" - FileAlignment = "4096" - IncrementalBuild = "false" - NoStdLib = "false" - NoWarn = "" - Optimize = "true" - OutputPath = "bin\Release\" - RegisterForComInterop = "false" - RemoveIntegerChecks = "false" - TreatWarningsAsErrors = "false" - WarningLevel = "4" - /> - </Settings> - <References> - <Reference - Name = "System" - AssemblyName = "System" - HintPath = "..\..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.dll" - /> - <Reference - Name = "System.Data" - AssemblyName = "System.Data" - HintPath = "..\..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Data.dll" - /> - <Reference - Name = "System.XML" - AssemblyName = "System.Xml" - HintPath = "..\..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll" - /> - <Reference - Name = "crypto" - Project = "{38872A5F-E87E-4FAD-B109-8EB7B2E6A4A0}" - Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}" - /> - </References> - </Build> - <Files> - <Include> - <File - RelPath = "App.ico" - BuildAction = "Content" - /> - <File - RelPath = "CryptoTest.cs" - SubType = "Code" - BuildAction = "Compile" - /> - </Include> - </Files> - </CSHARP> -</VisualStudioProject> - +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build"> + <PropertyGroup> + <ProjectType>Local</ProjectType> + <ProductVersion>7.10.3077</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{C857AD68-8F1B-4C7A-A76B-3DC03CBE4FB0}</ProjectGuid> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ApplicationIcon>App.ico</ApplicationIcon> + <AssemblyKeyContainerName /> + <AssemblyName>crypto-test</AssemblyName> + <AssemblyOriginatorKeyFile /> + <DefaultClientScript>JScript</DefaultClientScript> + <DefaultHTMLPageLayout>Grid</DefaultHTMLPageLayout> + <DefaultTargetSchema>IE50</DefaultTargetSchema> + <DelaySign>false</DelaySign> + <OutputType>Exe</OutputType> + <RootNamespace>crypto_test</RootNamespace> + <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent> + <StartupObject /> + <FileUpgradeFlags> + </FileUpgradeFlags> + <UpgradeBackupLocation> + </UpgradeBackupLocation> + <OldToolsVersion>0.0</OldToolsVersion> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <OutputPath>bin\Debug\</OutputPath> + <AllowUnsafeBlocks>false</AllowUnsafeBlocks> + <BaseAddress>285212672</BaseAddress> + <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow> + <ConfigurationOverrideFile /> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <DocumentationFile /> + <DebugSymbols>true</DebugSymbols> + <FileAlignment>4096</FileAlignment> + <NoStdLib>false</NoStdLib> + <NoWarn /> + <Optimize>false</Optimize> + <RegisterForComInterop>false</RegisterForComInterop> + <RemoveIntegerChecks>false</RemoveIntegerChecks> + <TreatWarningsAsErrors>false</TreatWarningsAsErrors> + <WarningLevel>4</WarningLevel> + <DebugType>full</DebugType> + <ErrorReport>prompt</ErrorReport> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <OutputPath>bin\Release\</OutputPath> + <AllowUnsafeBlocks>false</AllowUnsafeBlocks> + <BaseAddress>285212672</BaseAddress> + <CheckForOverflowUnderflow>false</CheckForOverflowUnderflow> + <ConfigurationOverrideFile /> + <DefineConstants>TRACE</DefineConstants> + <DocumentationFile /> + <DebugSymbols>false</DebugSymbols> + <FileAlignment>4096</FileAlignment> + <NoStdLib>false</NoStdLib> + <NoWarn /> + <Optimize>true</Optimize> + <RegisterForComInterop>false</RegisterForComInterop> + <RemoveIntegerChecks>false</RemoveIntegerChecks> + <TreatWarningsAsErrors>false</TreatWarningsAsErrors> + <WarningLevel>4</WarningLevel> + <DebugType>none</DebugType> + <ErrorReport>prompt</ErrorReport> + </PropertyGroup> + <ItemGroup> + <ProjectReference Include="..\crypto\crypto.csproj"> + <Name>crypto</Name> + <Project>{38872A5F-E87E-4FAD-B109-8EB7B2E6A4A0}</Project> + <Package>{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</Package> + </ProjectReference> + <Reference Include="System"> + <Name>System</Name> + </Reference> + <Reference Include="System.Data"> + <Name>System.Data</Name> + </Reference> + <Reference Include="System.Xml"> + <Name>System.XML</Name> + </Reference> + </ItemGroup> + <ItemGroup> + <Compile Include="CryptoTest.cs"> + <SubType>Code</SubType> + </Compile> + <Content Include="App.ico" /> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <PropertyGroup> + <PreBuildEvent /> + <PostBuildEvent /> + </PropertyGroup> +</Project> \ No newline at end of file diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj index 442fda26d..a54c454ce 100644 --- a/crypto/crypto.csproj +++ b/crypto/crypto.csproj @@ -1,4 +1,4 @@ -<VisualStudioProject> +<VisualStudioProject> <CSHARP ProjectType = "Local" ProductVersion = "7.10.3077" diff --git a/crypto/src/asn1/x509/X509ExtensionsGenerator.cs b/crypto/src/asn1/x509/X509ExtensionsGenerator.cs index 58620ea5e..3b952fffa 100644 --- a/crypto/src/asn1/x509/X509ExtensionsGenerator.cs +++ b/crypto/src/asn1/x509/X509ExtensionsGenerator.cs @@ -5,88 +5,133 @@ using Org.BouncyCastle.Utilities; namespace Org.BouncyCastle.Asn1.X509 { - /// <remarks>Generator for X.509 extensions</remarks> - public class X509ExtensionsGenerator - { - private IDictionary extensions = Platform.CreateHashtable(); + /// <remarks>Generator for X.509 extensions</remarks> + public class X509ExtensionsGenerator + { + private IDictionary extensions = Platform.CreateHashtable(); private IList extOrdering = Platform.CreateArrayList(); - /// <summary>Reset the generator</summary> - public void Reset() - { + private static readonly IDictionary dupsAllowed = Platform.CreateHashtable(); + + static X509ExtensionsGenerator() + { + dupsAllowed.Add(X509Extensions.SubjectAlternativeName, true); + dupsAllowed.Add(X509Extensions.IssuerAlternativeName, true); + dupsAllowed.Add(X509Extensions.SubjectDirectoryAttributes, true); + dupsAllowed.Add(X509Extensions.CertificateIssuer, true); + + } + + + + /// <summary>Reset the generator</summary> + public void Reset() + { extensions = Platform.CreateHashtable(); extOrdering = Platform.CreateArrayList(); - } - - /// <summary> - /// Add an extension with the given oid and the passed in value to be included - /// in the OCTET STRING associated with the extension. - /// </summary> - /// <param name="oid">OID for the extension.</param> - /// <param name="critical">True if critical, false otherwise.</param> - /// <param name="extValue">The ASN.1 object to be included in the extension.</param> - public void AddExtension( - DerObjectIdentifier oid, - bool critical, - Asn1Encodable extValue) - { - byte[] encoded; - try - { - encoded = extValue.GetDerEncoded(); - } - catch (Exception e) - { - throw new ArgumentException("error encoding value: " + e); - } - - this.AddExtension(oid, critical, encoded); - } - - /// <summary> - /// Add an extension with the given oid and the passed in byte array to be wrapped - /// in the OCTET STRING associated with the extension. - /// </summary> - /// <param name="oid">OID for the extension.</param> - /// <param name="critical">True if critical, false otherwise.</param> - /// <param name="extValue">The byte array to be wrapped.</param> - public void AddExtension( - DerObjectIdentifier oid, - bool critical, - byte[] extValue) - { - if (extensions.Contains(oid)) - { - throw new ArgumentException("extension " + oid + " already added"); - } - - extOrdering.Add(oid); - extensions.Add(oid, new X509Extension(critical, new DerOctetString(extValue))); - } - - /// <summary>Return true if there are no extension present in this generator.</summary> - /// <returns>True if empty, false otherwise</returns> - public bool IsEmpty - { - get { return extOrdering.Count < 1; } - } - - /// <summary>Generate an X509Extensions object based on the current state of the generator.</summary> - /// <returns>An <c>X509Extensions</c> object</returns> - public X509Extensions Generate() - { - return new X509Extensions(extOrdering, extensions); - } - - internal void AddExtension(DerObjectIdentifier oid, X509Extension x509Extension) + } + + /// <summary> + /// Add an extension with the given oid and the passed in value to be included + /// in the OCTET STRING associated with the extension. + /// </summary> + /// <param name="oid">OID for the extension.</param> + /// <param name="critical">True if critical, false otherwise.</param> + /// <param name="extValue">The ASN.1 object to be included in the extension.</param> + public void AddExtension( + DerObjectIdentifier oid, + bool critical, + Asn1Encodable extValue) + { + byte[] encoded; + try + { + encoded = extValue.GetDerEncoded(); + } + catch (Exception e) + { + throw new ArgumentException("error encoding value: " + e); + } + + this.AddExtension(oid, critical, encoded); + } + + /// <summary> + /// Add an extension with the given oid and the passed in byte array to be wrapped + /// in the OCTET STRING associated with the extension. + /// </summary> + /// <param name="oid">OID for the extension.</param> + /// <param name="critical">True if critical, false otherwise.</param> + /// <param name="extValue">The byte array to be wrapped.</param> + public void AddExtension( + DerObjectIdentifier oid, + bool critical, + byte[] extValue) + { + if (extensions.Contains(oid)) + { + if (dupsAllowed.Contains(oid)) + { + X509Extension existingExtension = (X509Extension)extensions[oid]; + + Asn1Sequence seq1 = Asn1Sequence.GetInstance(DerOctetString.GetInstance(existingExtension.Value).GetOctets()); + Asn1EncodableVector items = Asn1EncodableVector.FromEnumerable(seq1); + Asn1Sequence seq2 = Asn1Sequence.GetInstance(extValue); + + foreach (Asn1Encodable enc in seq2) + { + items.Add(enc); + } + + extensions[oid] = new X509Extension(existingExtension.IsCritical, new DerOctetString(new DerSequence(items).GetEncoded())); + + } + else + { + throw new ArgumentException("extension " + oid + " already added"); + } + } + else + { + extOrdering.Add(oid); + extensions.Add(oid, new X509Extension(critical, new DerOctetString(extValue))); + } + } + + public void AddExtensions(X509Extensions extensions) + { + foreach (DerObjectIdentifier ident in extensions.ExtensionOids) + { + X509Extension ext = extensions.GetExtension(ident); + AddExtension(ident, ext.critical, ext.Value.GetOctets()); + } + } + + + + /// <summary>Return true if there are no extension present in this generator.</summary> + /// <returns>True if empty, false otherwise</returns> + public bool IsEmpty + { + get { return extOrdering.Count < 1; } + } + + /// <summary>Generate an X509Extensions object based on the current state of the generator.</summary> + /// <returns>An <c>X509Extensions</c> object</returns> + public X509Extensions Generate() + { + return new X509Extensions(extOrdering, extensions); + } + + internal void AddExtension(DerObjectIdentifier oid, X509Extension x509Extension) { if (extensions.Contains(oid)) - { - throw new ArgumentException ("extension " + oid + " already added"); - } + { + throw new ArgumentException("extension " + oid + " already added"); + } - extOrdering.Add(oid); - extensions.Add(oid, x509Extension); + extOrdering.Add(oid); + extensions.Add(oid, x509Extension); } } } diff --git a/crypto/src/pkcs/Pkcs10CertificationRequest.cs b/crypto/src/pkcs/Pkcs10CertificationRequest.cs index f422e0332..28b6ddb5b 100644 --- a/crypto/src/pkcs/Pkcs10CertificationRequest.cs +++ b/crypto/src/pkcs/Pkcs10CertificationRequest.cs @@ -16,50 +16,51 @@ using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.Collections; using Org.BouncyCastle.X509; using Org.BouncyCastle.Crypto.Operators; +using Org.BouncyCastle.Asn1.Utilities; namespace Org.BouncyCastle.Pkcs { - /// <remarks> - /// A class for verifying and creating Pkcs10 Certification requests. - /// </remarks> - /// <code> - /// CertificationRequest ::= Sequence { - /// certificationRequestInfo CertificationRequestInfo, - /// signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }}, - /// signature BIT STRING - /// } - /// - /// CertificationRequestInfo ::= Sequence { - /// version Integer { v1(0) } (v1,...), - /// subject Name, - /// subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }}, - /// attributes [0] Attributes{{ CRIAttributes }} - /// } - /// - /// Attributes { ATTRIBUTE:IOSet } ::= Set OF Attr{{ IOSet }} - /// - /// Attr { ATTRIBUTE:IOSet } ::= Sequence { - /// type ATTRIBUTE.&id({IOSet}), - /// values Set SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type}) - /// } - /// </code> - /// see <a href="http://www.rsasecurity.com/rsalabs/node.asp?id=2132"/> - public class Pkcs10CertificationRequest - : CertificationRequest - { - protected static readonly IDictionary algorithms = Platform.CreateHashtable(); + /// <remarks> + /// A class for verifying and creating Pkcs10 Certification requests. + /// </remarks> + /// <code> + /// CertificationRequest ::= Sequence { + /// certificationRequestInfo CertificationRequestInfo, + /// signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }}, + /// signature BIT STRING + /// } + /// + /// CertificationRequestInfo ::= Sequence { + /// version Integer { v1(0) } (v1,...), + /// subject Name, + /// subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }}, + /// attributes [0] Attributes{{ CRIAttributes }} + /// } + /// + /// Attributes { ATTRIBUTE:IOSet } ::= Set OF Attr{{ IOSet }} + /// + /// Attr { ATTRIBUTE:IOSet } ::= Sequence { + /// type ATTRIBUTE.&id({IOSet}), + /// values Set SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type}) + /// } + /// </code> + /// see <a href="http://www.rsasecurity.com/rsalabs/node.asp?id=2132"/> + public class Pkcs10CertificationRequest + : CertificationRequest + { + protected static readonly IDictionary algorithms = Platform.CreateHashtable(); protected static readonly IDictionary exParams = Platform.CreateHashtable(); protected static readonly IDictionary keyAlgorithms = Platform.CreateHashtable(); protected static readonly IDictionary oids = Platform.CreateHashtable(); - protected static readonly ISet noParams = new HashSet(); - - static Pkcs10CertificationRequest() - { - algorithms.Add("MD2WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD2WithRsaEncryption); - algorithms.Add("MD2WITHRSA", PkcsObjectIdentifiers.MD2WithRsaEncryption); - algorithms.Add("MD5WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD5WithRsaEncryption); - algorithms.Add("MD5WITHRSA", PkcsObjectIdentifiers.MD5WithRsaEncryption); - algorithms.Add("RSAWITHMD5", PkcsObjectIdentifiers.MD5WithRsaEncryption); + protected static readonly ISet noParams = new HashSet(); + + static Pkcs10CertificationRequest() + { + algorithms.Add("MD2WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD2WithRsaEncryption); + algorithms.Add("MD2WITHRSA", PkcsObjectIdentifiers.MD2WithRsaEncryption); + algorithms.Add("MD5WITHRSAENCRYPTION", PkcsObjectIdentifiers.MD5WithRsaEncryption); + algorithms.Add("MD5WITHRSA", PkcsObjectIdentifiers.MD5WithRsaEncryption); + algorithms.Add("RSAWITHMD5", PkcsObjectIdentifiers.MD5WithRsaEncryption); algorithms.Add("SHA1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption); algorithms.Add("SHA-1WITHRSAENCRYPTION", PkcsObjectIdentifiers.Sha1WithRsaEncryption); algorithms.Add("SHA1WITHRSA", PkcsObjectIdentifiers.Sha1WithRsaEncryption); @@ -89,38 +90,38 @@ namespace Org.BouncyCastle.Pkcs algorithms.Add("SHA512(256)WITHRSA", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption); algorithms.Add("SHA-512(256)WITHRSA", PkcsObjectIdentifiers.Sha512_256WithRSAEncryption); algorithms.Add("SHA1WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); - algorithms.Add("SHA224WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); - algorithms.Add("SHA256WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); - algorithms.Add("SHA384WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); - algorithms.Add("SHA512WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); - algorithms.Add("RSAWITHSHA1", PkcsObjectIdentifiers.Sha1WithRsaEncryption); - algorithms.Add("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128); - algorithms.Add("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128); - algorithms.Add("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160); - algorithms.Add("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160); - algorithms.Add("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256); - algorithms.Add("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256); - algorithms.Add("SHA1WITHDSA", X9ObjectIdentifiers.IdDsaWithSha1); - algorithms.Add("DSAWITHSHA1", X9ObjectIdentifiers.IdDsaWithSha1); - algorithms.Add("SHA224WITHDSA", NistObjectIdentifiers.DsaWithSha224); - algorithms.Add("SHA256WITHDSA", NistObjectIdentifiers.DsaWithSha256); - algorithms.Add("SHA384WITHDSA", NistObjectIdentifiers.DsaWithSha384); - algorithms.Add("SHA512WITHDSA", NistObjectIdentifiers.DsaWithSha512); - algorithms.Add("SHA1WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha1); - algorithms.Add("SHA224WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha224); - algorithms.Add("SHA256WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha256); - algorithms.Add("SHA384WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha384); - algorithms.Add("SHA512WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha512); - algorithms.Add("ECDSAWITHSHA1", X9ObjectIdentifiers.ECDsaWithSha1); - algorithms.Add("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); - algorithms.Add("GOST3410WITHGOST3411", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); - algorithms.Add("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); - algorithms.Add("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); - algorithms.Add("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); - - // - // reverse mappings - // + algorithms.Add("SHA224WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA256WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA384WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("SHA512WITHRSAANDMGF1", PkcsObjectIdentifiers.IdRsassaPss); + algorithms.Add("RSAWITHSHA1", PkcsObjectIdentifiers.Sha1WithRsaEncryption); + algorithms.Add("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128); + algorithms.Add("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD128); + algorithms.Add("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160); + algorithms.Add("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD160); + algorithms.Add("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256); + algorithms.Add("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.RsaSignatureWithRipeMD256); + algorithms.Add("SHA1WITHDSA", X9ObjectIdentifiers.IdDsaWithSha1); + algorithms.Add("DSAWITHSHA1", X9ObjectIdentifiers.IdDsaWithSha1); + algorithms.Add("SHA224WITHDSA", NistObjectIdentifiers.DsaWithSha224); + algorithms.Add("SHA256WITHDSA", NistObjectIdentifiers.DsaWithSha256); + algorithms.Add("SHA384WITHDSA", NistObjectIdentifiers.DsaWithSha384); + algorithms.Add("SHA512WITHDSA", NistObjectIdentifiers.DsaWithSha512); + algorithms.Add("SHA1WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha1); + algorithms.Add("SHA224WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha224); + algorithms.Add("SHA256WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha256); + algorithms.Add("SHA384WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha384); + algorithms.Add("SHA512WITHECDSA", X9ObjectIdentifiers.ECDsaWithSha512); + algorithms.Add("ECDSAWITHSHA1", X9ObjectIdentifiers.ECDsaWithSha1); + algorithms.Add("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + algorithms.Add("GOST3410WITHGOST3411", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + algorithms.Add("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + algorithms.Add("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + algorithms.Add("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + + // + // reverse mappings + // oids.Add(PkcsObjectIdentifiers.Sha1WithRsaEncryption, "SHA1WITHRSA"); oids.Add(PkcsObjectIdentifiers.Sha224WithRsaEncryption, "SHA224WITHRSA"); oids.Add(PkcsObjectIdentifiers.Sha256WithRsaEncryption, "SHA256WITHRSA"); @@ -145,82 +146,82 @@ namespace Org.BouncyCastle.Pkcs oids.Add(NistObjectIdentifiers.DsaWithSha224, "SHA224WITHDSA"); oids.Add(NistObjectIdentifiers.DsaWithSha256, "SHA256WITHDSA"); - // - // key types - // - keyAlgorithms.Add(PkcsObjectIdentifiers.RsaEncryption, "RSA"); - keyAlgorithms.Add(X9ObjectIdentifiers.IdDsa, "DSA"); - - // - // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. - // The parameters field SHALL be NULL for RSA based signature algorithms. - // - noParams.Add(X9ObjectIdentifiers.ECDsaWithSha1); - noParams.Add(X9ObjectIdentifiers.ECDsaWithSha224); - noParams.Add(X9ObjectIdentifiers.ECDsaWithSha256); - noParams.Add(X9ObjectIdentifiers.ECDsaWithSha384); - noParams.Add(X9ObjectIdentifiers.ECDsaWithSha512); - noParams.Add(X9ObjectIdentifiers.IdDsaWithSha1); + // + // key types + // + keyAlgorithms.Add(PkcsObjectIdentifiers.RsaEncryption, "RSA"); + keyAlgorithms.Add(X9ObjectIdentifiers.IdDsa, "DSA"); + + // + // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. + // The parameters field SHALL be NULL for RSA based signature algorithms. + // + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha1); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha224); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha256); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha384); + noParams.Add(X9ObjectIdentifiers.ECDsaWithSha512); + noParams.Add(X9ObjectIdentifiers.IdDsaWithSha1); noParams.Add(OiwObjectIdentifiers.DsaWithSha1); noParams.Add(NistObjectIdentifiers.DsaWithSha224); - noParams.Add(NistObjectIdentifiers.DsaWithSha256); - - // - // RFC 4491 - // - noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); - noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); - - // - // explicit params - // - AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance); - exParams.Add("SHA1WITHRSAANDMGF1", CreatePssParams(sha1AlgId, 20)); - - AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha224, DerNull.Instance); - exParams.Add("SHA224WITHRSAANDMGF1", CreatePssParams(sha224AlgId, 28)); - - AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance); - exParams.Add("SHA256WITHRSAANDMGF1", CreatePssParams(sha256AlgId, 32)); - - AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384, DerNull.Instance); - exParams.Add("SHA384WITHRSAANDMGF1", CreatePssParams(sha384AlgId, 48)); - - AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512, DerNull.Instance); - exParams.Add("SHA512WITHRSAANDMGF1", CreatePssParams(sha512AlgId, 64)); - } - - private static RsassaPssParameters CreatePssParams( - AlgorithmIdentifier hashAlgId, - int saltSize) - { - return new RsassaPssParameters( - hashAlgId, - new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, hashAlgId), - new DerInteger(saltSize), - new DerInteger(1)); - } - - protected Pkcs10CertificationRequest() - { - } - - public Pkcs10CertificationRequest( - byte[] encoded) - : base((Asn1Sequence) Asn1Object.FromByteArray(encoded)) - { - } - - public Pkcs10CertificationRequest( - Asn1Sequence seq) - : base(seq) - { - } - - public Pkcs10CertificationRequest( - Stream input) - : base((Asn1Sequence) Asn1Object.FromStream(input)) - { + noParams.Add(NistObjectIdentifiers.DsaWithSha256); + + // + // RFC 4491 + // + noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94); + noParams.Add(CryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001); + + // + // explicit params + // + AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OiwObjectIdentifiers.IdSha1, DerNull.Instance); + exParams.Add("SHA1WITHRSAANDMGF1", CreatePssParams(sha1AlgId, 20)); + + AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha224, DerNull.Instance); + exParams.Add("SHA224WITHRSAANDMGF1", CreatePssParams(sha224AlgId, 28)); + + AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha256, DerNull.Instance); + exParams.Add("SHA256WITHRSAANDMGF1", CreatePssParams(sha256AlgId, 32)); + + AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha384, DerNull.Instance); + exParams.Add("SHA384WITHRSAANDMGF1", CreatePssParams(sha384AlgId, 48)); + + AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NistObjectIdentifiers.IdSha512, DerNull.Instance); + exParams.Add("SHA512WITHRSAANDMGF1", CreatePssParams(sha512AlgId, 64)); + } + + private static RsassaPssParameters CreatePssParams( + AlgorithmIdentifier hashAlgId, + int saltSize) + { + return new RsassaPssParameters( + hashAlgId, + new AlgorithmIdentifier(PkcsObjectIdentifiers.IdMgf1, hashAlgId), + new DerInteger(saltSize), + new DerInteger(1)); + } + + protected Pkcs10CertificationRequest() + { + } + + public Pkcs10CertificationRequest( + byte[] encoded) + : base((Asn1Sequence)Asn1Object.FromByteArray(encoded)) + { + } + + public Pkcs10CertificationRequest( + Asn1Sequence seq) + : base(seq) + { + } + + public Pkcs10CertificationRequest( + Stream input) + : base((Asn1Sequence)Asn1Object.FromStream(input)) + { } /// <summary> @@ -232,14 +233,14 @@ namespace Org.BouncyCastle.Pkcs /// <param name="attributes">ASN1Set of Attributes.</param> /// <param name="signingKey">Matching Private key for nominated (above) public key to be used to sign the request.</param> public Pkcs10CertificationRequest( - string signatureAlgorithm, - X509Name subject, - AsymmetricKeyParameter publicKey, - Asn1Set attributes, - AsymmetricKeyParameter signingKey) + string signatureAlgorithm, + X509Name subject, + AsymmetricKeyParameter publicKey, + Asn1Set attributes, + AsymmetricKeyParameter signingKey) : this(new Asn1SignatureFactory(signatureAlgorithm, signingKey), subject, publicKey, attributes) - { - } + { + } /// <summary> /// Instantiate a Pkcs10CertificationRequest object with the necessary credentials. @@ -286,7 +287,7 @@ namespace Org.BouncyCastle.Pkcs } private void Init( - ISignatureFactory signatureFactory, + ISignatureFactory signatureFactory, X509Name subject, AsymmetricKeyParameter publicKey, Asn1Set attributes) @@ -330,24 +331,24 @@ namespace Org.BouncyCastle.Pkcs /// </summary> /// <returns>The public key.</returns> public AsymmetricKeyParameter GetPublicKey() - { - return PublicKeyFactory.CreateKey(reqInfo.SubjectPublicKeyInfo); - } - - /// <summary> - /// Verify Pkcs10 Cert Request is valid. - /// </summary> - /// <returns>true = valid.</returns> - public bool Verify() - { - return Verify(this.GetPublicKey()); - } - - public bool Verify( - AsymmetricKeyParameter publicKey) - { + { + return PublicKeyFactory.CreateKey(reqInfo.SubjectPublicKeyInfo); + } + + /// <summary> + /// Verify Pkcs10 Cert Request is valid. + /// </summary> + /// <returns>true = valid.</returns> + public bool Verify() + { + return Verify(this.GetPublicKey()); + } + + public bool Verify( + AsymmetricKeyParameter publicKey) + { return Verify(new Asn1VerifierFactoryProvider(publicKey)); - } + } public bool Verify( IVerifierFactoryProvider verifierProvider) @@ -387,82 +388,82 @@ namespace Org.BouncyCastle.Pkcs // TODO Figure out how to set parameters on an ISigner private void SetSignatureParameters( - ISigner signature, - Asn1Encodable asn1Params) - { - if (asn1Params != null && !(asn1Params is Asn1Null)) - { -// AlgorithmParameters sigParams = AlgorithmParameters.GetInstance(signature.getAlgorithm()); -// -// try -// { -// sigParams.init(asn1Params.ToAsn1Object().GetDerEncoded()); -// } -// catch (IOException e) -// { -// throw new SignatureException("IOException decoding parameters: " + e.Message); -// } - - if (Platform.EndsWith(signature.AlgorithmName, "MGF1")) - { - throw Platform.CreateNotImplementedException("signature algorithm with MGF1"); - -// try -// { -// signature.setParameter(sigParams.getParameterSpec(PSSParameterSpec.class)); -// } -// catch (GeneralSecurityException e) -// { -// throw new SignatureException("Exception extracting parameters: " + e.getMessage()); -// } - } - } - } - - internal static string GetSignatureName( - AlgorithmIdentifier sigAlgId) - { - Asn1Encodable asn1Params = sigAlgId.Parameters; - - if (asn1Params != null && !(asn1Params is Asn1Null)) - { + ISigner signature, + Asn1Encodable asn1Params) + { + if (asn1Params != null && !(asn1Params is Asn1Null)) + { + // AlgorithmParameters sigParams = AlgorithmParameters.GetInstance(signature.getAlgorithm()); + // + // try + // { + // sigParams.init(asn1Params.ToAsn1Object().GetDerEncoded()); + // } + // catch (IOException e) + // { + // throw new SignatureException("IOException decoding parameters: " + e.Message); + // } + + if (Platform.EndsWith(signature.AlgorithmName, "MGF1")) + { + throw Platform.CreateNotImplementedException("signature algorithm with MGF1"); + + // try + // { + // signature.setParameter(sigParams.getParameterSpec(PSSParameterSpec.class)); + // } + // catch (GeneralSecurityException e) + // { + // throw new SignatureException("Exception extracting parameters: " + e.getMessage()); + // } + } + } + } + + internal static string GetSignatureName( + AlgorithmIdentifier sigAlgId) + { + Asn1Encodable asn1Params = sigAlgId.Parameters; + + if (asn1Params != null && !(asn1Params is Asn1Null)) + { if (sigAlgId.Algorithm.Equals(PkcsObjectIdentifiers.IdRsassaPss)) - { - RsassaPssParameters rsaParams = RsassaPssParameters.GetInstance(asn1Params); + { + RsassaPssParameters rsaParams = RsassaPssParameters.GetInstance(asn1Params); return GetDigestAlgName(rsaParams.HashAlgorithm.Algorithm) + "withRSAandMGF1"; - } - } + } + } return sigAlgId.Algorithm.Id; - } - - private static string GetDigestAlgName( - DerObjectIdentifier digestAlgOID) - { - if (PkcsObjectIdentifiers.MD5.Equals(digestAlgOID)) - { - return "MD5"; - } - else if (OiwObjectIdentifiers.IdSha1.Equals(digestAlgOID)) - { - return "SHA1"; - } - else if (NistObjectIdentifiers.IdSha224.Equals(digestAlgOID)) - { - return "SHA224"; - } - else if (NistObjectIdentifiers.IdSha256.Equals(digestAlgOID)) - { - return "SHA256"; - } - else if (NistObjectIdentifiers.IdSha384.Equals(digestAlgOID)) - { - return "SHA384"; - } - else if (NistObjectIdentifiers.IdSha512.Equals(digestAlgOID)) - { - return "SHA512"; - } + } + + private static string GetDigestAlgName( + DerObjectIdentifier digestAlgOID) + { + if (PkcsObjectIdentifiers.MD5.Equals(digestAlgOID)) + { + return "MD5"; + } + else if (OiwObjectIdentifiers.IdSha1.Equals(digestAlgOID)) + { + return "SHA1"; + } + else if (NistObjectIdentifiers.IdSha224.Equals(digestAlgOID)) + { + return "SHA224"; + } + else if (NistObjectIdentifiers.IdSha256.Equals(digestAlgOID)) + { + return "SHA256"; + } + else if (NistObjectIdentifiers.IdSha384.Equals(digestAlgOID)) + { + return "SHA384"; + } + else if (NistObjectIdentifiers.IdSha512.Equals(digestAlgOID)) + { + return "SHA512"; + } else if (NistObjectIdentifiers.IdSha512_224.Equals(digestAlgOID)) { return "SHA512(224)"; @@ -472,25 +473,83 @@ namespace Org.BouncyCastle.Pkcs return "SHA512(256)"; } else if (TeleTrusTObjectIdentifiers.RipeMD128.Equals(digestAlgOID)) - { - return "RIPEMD128"; - } - else if (TeleTrusTObjectIdentifiers.RipeMD160.Equals(digestAlgOID)) - { - return "RIPEMD160"; - } - else if (TeleTrusTObjectIdentifiers.RipeMD256.Equals(digestAlgOID)) - { - return "RIPEMD256"; - } - else if (CryptoProObjectIdentifiers.GostR3411.Equals(digestAlgOID)) - { - return "GOST3411"; - } - else - { - return digestAlgOID.Id; - } - } - } + { + return "RIPEMD128"; + } + else if (TeleTrusTObjectIdentifiers.RipeMD160.Equals(digestAlgOID)) + { + return "RIPEMD160"; + } + else if (TeleTrusTObjectIdentifiers.RipeMD256.Equals(digestAlgOID)) + { + return "RIPEMD256"; + } + else if (CryptoProObjectIdentifiers.GostR3411.Equals(digestAlgOID)) + { + return "GOST3411"; + } + else + { + return digestAlgOID.Id; + } + } + + /// <summary> + /// Returns X509Extensions if the attribute can be found and returns the extensions block. + /// </summary> + /// <returns>X509Extensions block or null if one cannot be found.</returns> + public X509Extensions GetX509Extensions() + { + if (reqInfo.Attributes != null) + { + foreach (Asn1Encodable item in reqInfo.Attributes) + { + AttributePkcs attributePkcs; + try + { + attributePkcs = AttributePkcs.GetInstance(item); + + } + catch (ArgumentException ex) + { + throw new ArgumentException("encountered non PKCS attribute in extensions block", ex); + } + + if (attributePkcs.AttrType.Equals(PkcsObjectIdentifiers.Pkcs9AtExtensionRequest)) + { + X509ExtensionsGenerator generator = new X509ExtensionsGenerator(); + + Asn1Sequence extensionSequence = Asn1Sequence.GetInstance(attributePkcs.AttrValues[0]); + + + foreach (Asn1Encodable seqItem in extensionSequence) + { + + Asn1Sequence itemSeq = Asn1Sequence.GetInstance(seqItem); + bool critical = itemSeq.Count == 3 && DerBoolean.GetInstance(itemSeq[1]).IsTrue; + + if (itemSeq.Count == 2) + { + generator.AddExtension(DerObjectIdentifier.GetInstance(itemSeq[0]), false, Asn1OctetString.GetInstance(itemSeq[1]).GetOctets()); + } + else if (itemSeq.Count == 3) + { + generator.AddExtension(DerObjectIdentifier.GetInstance(itemSeq[0]), DerBoolean.GetInstance(itemSeq[1]).IsTrue, Asn1OctetString.GetInstance(itemSeq[2]).GetOctets()); + } + else + { + throw new ArgumentException("incorrect sequence size of X509Extension got " + itemSeq.Count + " expected 2 or 3"); + } + } + + return generator.Generate(); + } + + } + } + + return null; + } + + } } diff --git a/crypto/test/src/asn1/test/X509ExtensionsTest.cs b/crypto/test/src/asn1/test/X509ExtensionsTest.cs index f1efd3a9b..71bb5ef67 100644 --- a/crypto/test/src/asn1/test/X509ExtensionsTest.cs +++ b/crypto/test/src/asn1/test/X509ExtensionsTest.cs @@ -7,111 +7,219 @@ using Org.BouncyCastle.Utilities.Test; namespace Org.BouncyCastle.Asn1.Tests { - [TestFixture] - public class X509ExtensionsTest - : SimpleTest - { - private static readonly DerObjectIdentifier Oid1 = new DerObjectIdentifier("1.2.1"); - private static readonly DerObjectIdentifier Oid2 = new DerObjectIdentifier("1.2.2"); - private static readonly DerObjectIdentifier Oid3 = new DerObjectIdentifier("1.2.3"); - - public override string Name - { - get { return "X509Extensions"; } - } - - public override void PerformTest() - { - X509ExtensionsGenerator gen = new X509ExtensionsGenerator(); - - gen.AddExtension(Oid1, true, new byte[20]); - gen.AddExtension(Oid2, true, new byte[20]); - - X509Extensions ext1 = gen.Generate(); - X509Extensions ext2 = gen.Generate(); - - if (!ext1.Equals(ext2)) - { - Fail("Equals test failed"); - } - - gen.Reset(); - - gen.AddExtension(Oid2, true, new byte[20]); - gen.AddExtension(Oid1, true, new byte[20]); - - ext2 = gen.Generate(); - - if (ext1.Equals(ext2)) - { - Fail("inequality test failed"); - } - - if (!ext1.Equivalent(ext2)) - { - Fail("equivalence true failed"); - } - - gen.Reset(); - - gen.AddExtension(Oid1, true, new byte[22]); - gen.AddExtension(Oid2, true, new byte[20]); - - ext2 = gen.Generate(); - - if (ext1.Equals(ext2)) - { - Fail("inequality 1 failed"); - } - - if (ext1.Equivalent(ext2)) - { - Fail("non-equivalence 1 failed"); - } - - gen.Reset(); - - gen.AddExtension(Oid3, true, new byte[20]); - gen.AddExtension(Oid2, true, new byte[20]); - - ext2 = gen.Generate(); - - if (ext1.Equals(ext2)) - { - Fail("inequality 2 failed"); - } - - if (ext1.Equivalent(ext2)) - { - Fail("non-equivalence 2 failed"); - } - - try - { - gen.AddExtension(Oid2, true, new byte[20]); - Fail("repeated oid"); - } - catch (ArgumentException e) - { - if (!e.Message.Equals("extension 1.2.2 already added")) - { - Fail("wrong exception on repeated oid: " + e.Message); - } - } - } - - public static void Main( - string[] args) - { - RunTest(new X509ExtensionsTest()); - } - - [Test] - public void TestFunction() - { - string resultText = Perform().ToString(); - - Assert.AreEqual(Name + ": Okay", resultText); - } - } + [TestFixture] + public class X509ExtensionsTest + : SimpleTest + { + private static readonly DerObjectIdentifier Oid1 = new DerObjectIdentifier("1.2.1"); + private static readonly DerObjectIdentifier Oid2 = new DerObjectIdentifier("1.2.2"); + private static readonly DerObjectIdentifier Oid3 = new DerObjectIdentifier("1.2.3"); + + public override string Name + { + get { return "X509Extensions"; } + } + + + [Test] + public void TestDuplicateExtensions() + { + + // Testing for handling of duplicates + + GeneralName name1 = new GeneralName(GeneralName.DnsName, "bc1.local"); + GeneralName name2 = new GeneralName(GeneralName.DnsName, "bc2.local"); + + + X509ExtensionsGenerator extensionsGenerator = new X509ExtensionsGenerator(); + extensionsGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name1 }))); + extensionsGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name2 }))); + + // + // Generate and deserialise. + // + X509Extensions ext = X509Extensions.GetInstance(Asn1Sequence.GetInstance(extensionsGenerator.Generate().GetEncoded())); + X509Extension returnedExtension = ext.GetExtension(X509Extensions.SubjectAlternativeName); + Asn1Sequence seq = Asn1Sequence.GetInstance(returnedExtension.GetParsedValue()); + + + // + // Check expected order and value. + // + if (!GeneralName.GetInstance(seq[0]).Equals(name1)) + { + Fail("expected name 1"); + } + + if (!GeneralName.GetInstance(seq[1]).Equals(name2)) + { + Fail("expected name 2"); + } + + + // + // Test we can load dup extensions into a new generator + // + + X509ExtensionsGenerator genX = new X509ExtensionsGenerator(); + genX.AddExtensions(ext); + + ext = X509Extensions.GetInstance(Asn1Sequence.GetInstance(genX.Generate().GetEncoded())); + returnedExtension = ext.GetExtension(X509Extensions.SubjectAlternativeName); + seq = Asn1Sequence.GetInstance(returnedExtension.GetParsedValue()); + + + + // + // Check expected order and value. + // + if (!GeneralName.GetInstance(seq[0]).Equals(name1)) + { + Fail("expected name 1"); + } + + if (!GeneralName.GetInstance(seq[1]).Equals(name2)) + { + Fail("expected name 2"); + } + + + + + } + + + [Test] + public void TestAllowedDuplicateExtensions() + { + + // Testing for handling of duplicates + + GeneralName name1 = new GeneralName(GeneralName.DnsName, "bc1.local"); + GeneralName name2 = new GeneralName(GeneralName.DnsName, "bc2.local"); + + + X509ExtensionsGenerator extensionsGenerator = new X509ExtensionsGenerator(); + extensionsGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name1 }))); + extensionsGenerator.AddExtension(X509Extensions.SubjectAlternativeName, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name2 }))); + + extensionsGenerator.AddExtension(X509Extensions.IssuerAlternativeName, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name1 }))); + extensionsGenerator.AddExtension(X509Extensions.IssuerAlternativeName, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name2 }))); + + + extensionsGenerator.AddExtension(X509Extensions.SubjectDirectoryAttributes, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name1 }))); + extensionsGenerator.AddExtension(X509Extensions.SubjectDirectoryAttributes, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name2 }))); + + extensionsGenerator.AddExtension(X509Extensions.CertificateIssuer, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name1 }))); + extensionsGenerator.AddExtension(X509Extensions.CertificateIssuer, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name2 }))); + + + extensionsGenerator.AddExtension(X509Extensions.AuditIdentity, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name1 }))); + try + { + extensionsGenerator.AddExtension(X509Extensions.AuditIdentity, false, new DerSequence(new Asn1EncodableVector(new Asn1Encodable[] { name2 }))); + Fail("Expected exception, not a white listed duplicate."); + } + catch (Exception ex) + { + // ok + } + + } + + + public override void PerformTest() + { + X509ExtensionsGenerator gen = new X509ExtensionsGenerator(); + + gen.AddExtension(Oid1, true, new byte[20]); + gen.AddExtension(Oid2, true, new byte[20]); + + X509Extensions ext1 = gen.Generate(); + X509Extensions ext2 = gen.Generate(); + + if (!ext1.Equals(ext2)) + { + Fail("Equals test failed"); + } + + gen.Reset(); + + gen.AddExtension(Oid2, true, new byte[20]); + gen.AddExtension(Oid1, true, new byte[20]); + + ext2 = gen.Generate(); + + if (ext1.Equals(ext2)) + { + Fail("inequality test failed"); + } + + if (!ext1.Equivalent(ext2)) + { + Fail("equivalence true failed"); + } + + gen.Reset(); + + gen.AddExtension(Oid1, true, new byte[22]); + gen.AddExtension(Oid2, true, new byte[20]); + + ext2 = gen.Generate(); + + if (ext1.Equals(ext2)) + { + Fail("inequality 1 failed"); + } + + if (ext1.Equivalent(ext2)) + { + Fail("non-equivalence 1 failed"); + } + + gen.Reset(); + + gen.AddExtension(Oid3, true, new byte[20]); + gen.AddExtension(Oid2, true, new byte[20]); + + ext2 = gen.Generate(); + + if (ext1.Equals(ext2)) + { + Fail("inequality 2 failed"); + } + + if (ext1.Equivalent(ext2)) + { + Fail("non-equivalence 2 failed"); + } + + try + { + gen.AddExtension(Oid2, true, new byte[20]); + Fail("repeated oid"); + } + catch (ArgumentException e) + { + if (!e.Message.Equals("extension 1.2.2 already added")) + { + Fail("wrong exception on repeated oid: " + e.Message); + } + } + } + + public static void Main( + string[] args) + { + RunTest(new X509ExtensionsTest()); + } + + [Test] + public void TestFunction() + { + string resultText = Perform().ToString(); + + Assert.AreEqual(Name + ": Okay", resultText); + } + } } diff --git a/crypto/test/src/test/PKCS10CertRequestTest.cs b/crypto/test/src/test/PKCS10CertRequestTest.cs index ea27d5111..26a8ab20c 100644 --- a/crypto/test/src/test/PKCS10CertRequestTest.cs +++ b/crypto/test/src/test/PKCS10CertRequestTest.cs @@ -1,11 +1,12 @@ using System; using System.Collections; - +using System.IO; using NUnit.Framework; using Org.BouncyCastle.Asn1; using Org.BouncyCastle.Asn1.CryptoPro; using Org.BouncyCastle.Asn1.Pkcs; +using Org.BouncyCastle.Asn1.Utilities; using Org.BouncyCastle.Asn1.X509; using Org.BouncyCastle.Asn1.X9; using Org.BouncyCastle.Crypto; @@ -15,7 +16,9 @@ using Org.BouncyCastle.Math.EC; using Org.BouncyCastle.Pkcs; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities.Encoders; +using Org.BouncyCastle.Utilities.IO.Pem; using Org.BouncyCastle.Utilities.Test; +using Org.BouncyCastle.X509; using Org.BouncyCastle.X509.Extension; namespace Org.BouncyCastle.Tests @@ -26,27 +29,27 @@ namespace Org.BouncyCastle.Tests { private static readonly byte[] gost3410EC_A = Base64.Decode( "MIIBOzCB6wIBADB/MQ0wCwYDVQQDEwR0ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBMdGQxHjAcBgNV" - +"BAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYDVQQGEwJydTEZ" - +"MBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMCAh4B" - +"A0MABEBYx0P2D7YuuZo5HgdIAUKAXcLBDZ+4LYFgbKjrfStVfH59lc40BQ2FZ7M703hLpXK8GiBQ" - +"GEYpKaAuQZnMIpByoAAwCAYGKoUDAgIDA0EAgXMcTrhdOY2Er2tHOSAgnMezqrYxocZTWhxmW5Rl" - +"JY6lbXH5rndCn4swFzXU+YhgAsJv1wQBaoZEWRl5WV4/nA=="); + + "BAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYDVQQGEwJydTEZ" + + "MBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMBBgcqhQMCAh4B" + + "A0MABEBYx0P2D7YuuZo5HgdIAUKAXcLBDZ+4LYFgbKjrfStVfH59lc40BQ2FZ7M703hLpXK8GiBQ" + + "GEYpKaAuQZnMIpByoAAwCAYGKoUDAgIDA0EAgXMcTrhdOY2Er2tHOSAgnMezqrYxocZTWhxmW5Rl" + + "JY6lbXH5rndCn4swFzXU+YhgAsJv1wQBaoZEWRl5WV4/nA=="); private static readonly byte[] gost3410EC_B = Base64.Decode( "MIIBPTCB7QIBADCBgDENMAsGA1UEAxMEdGVzdDEWMBQGA1UEChMNRGVtb3MgQ28gTHRkLjEeMBwG" - +"A1UECxMVQ3J5cHRvZ3JhcGh5IGRpdmlzaW9uMQ8wDQYDVQQHEwZNb3Njb3cxCzAJBgNVBAYTAnJ1" - +"MRkwFwYJKoZIhvcNAQkBFgpzZGJAZG9sLnJ1MGMwHAYGKoUDAgITMBIGByqFAwICIwIGByqFAwIC" - +"HgEDQwAEQI5SLoWT7dZVilbV9j5B/fyIDuDs6x4pjqNC2TtFYbpRHrk/Wc5g/mcHvD80tsm5o1C7" - +"7cizNzkvAVUM4VT4Dz6gADAIBgYqhQMCAgMDQQAoT5TwJ8o+bSrxckymyo3diwG7ZbSytX4sRiKy" - +"wXPWRS9LlBvPO2NqwpS2HUnxSU8rzfL9fJcybATf7Yt1OEVq"); + + "A1UECxMVQ3J5cHRvZ3JhcGh5IGRpdmlzaW9uMQ8wDQYDVQQHEwZNb3Njb3cxCzAJBgNVBAYTAnJ1" + + "MRkwFwYJKoZIhvcNAQkBFgpzZGJAZG9sLnJ1MGMwHAYGKoUDAgITMBIGByqFAwICIwIGByqFAwIC" + + "HgEDQwAEQI5SLoWT7dZVilbV9j5B/fyIDuDs6x4pjqNC2TtFYbpRHrk/Wc5g/mcHvD80tsm5o1C7" + + "7cizNzkvAVUM4VT4Dz6gADAIBgYqhQMCAgMDQQAoT5TwJ8o+bSrxckymyo3diwG7ZbSytX4sRiKy" + + "wXPWRS9LlBvPO2NqwpS2HUnxSU8rzfL9fJcybATf7Yt1OEVq"); private static readonly byte[] gost3410EC_C = Base64.Decode( "MIIBRDCB9AIBADCBhzEVMBMGA1UEAxMMdGVzdCByZXF1ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBM" - +"dGQxHjAcBgNVBAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYD" - +"VQQGEwJydTEZMBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMD" - +"BgcqhQMCAh4BA0MABEBcmGh7OmR4iqqj+ycYo1S1fS7r5PhisSQU2Ezuz8wmmmR2zeTZkdMYCOBa" - +"UTMNms0msW3wuYDho7nTDNscHTB5oAAwCAYGKoUDAgIDA0EAVoOMbfyo1Un4Ss7WQrUjHJoiaYW8" - +"Ime5LeGGU2iW3ieAv6es/FdMrwTKkqn5dhd3aL/itFg5oQbhyfXw5yw/QQ=="); + + "dGQxHjAcBgNVBAsTFUNyeXB0b2dyYXBoeSBkaXZpc2lvbjEPMA0GA1UEBxMGTW9zY293MQswCQYD" + + "VQQGEwJydTEZMBcGCSqGSIb3DQEJARYKc2RiQGRvbC5ydTBjMBwGBiqFAwICEzASBgcqhQMCAiMD" + + "BgcqhQMCAh4BA0MABEBcmGh7OmR4iqqj+ycYo1S1fS7r5PhisSQU2Ezuz8wmmmR2zeTZkdMYCOBa" + + "UTMNms0msW3wuYDho7nTDNscHTB5oAAwCAYGKoUDAgIDA0EAVoOMbfyo1Un4Ss7WQrUjHJoiaYW8" + + "Ime5LeGGU2iW3ieAv6es/FdMrwTKkqn5dhd3aL/itFg5oQbhyfXw5yw/QQ=="); private static readonly byte[] gost3410EC_ExA = Base64.Decode( "MIIBOzCB6wIBADB/MQ0wCwYDVQQDEwR0ZXN0MRUwEwYDVQQKEwxEZW1vcyBDbyBMdGQxHjAcBgNV" @@ -70,13 +73,13 @@ namespace Org.BouncyCastle.Tests } private void generationTest( - int keySize, - string keyName, - string sigName) + int keySize, + string keyName, + string sigName) { IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator(keyName); -// kpg.initialize(keySize); + // kpg.initialize(keySize); kpg.Init(new KeyGenerationParameters(new SecureRandom(), keySize)); AsymmetricCipherKeyPair kp = kpg.GenerateKeyPair(); @@ -123,8 +126,8 @@ namespace Org.BouncyCastle.Tests * we generate a self signed certificate for the sake of testing - SHA224withECDSA */ private void createECRequest( - string algorithm, - DerObjectIdentifier algOid) + string algorithm, + DerObjectIdentifier algOid) { X9ECParameters x9 = ECNamedCurveTable.GetByName("secp521r1"); ECCurve curve = x9.Curve; @@ -135,20 +138,20 @@ namespace Org.BouncyCastle.Tests spec); ECPublicKeyParameters pubKey = new ECPublicKeyParameters( -// curve.DecodePoint(Hex.Decode("026BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q + // curve.DecodePoint(Hex.Decode("026BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q curve.DecodePoint(Hex.Decode("02006BFDD2C9278B63C92D6624F151C9D7A822CC75BD983B17D25D74C26740380022D3D8FAF304781E416175EADF4ED6E2B47142D2454A7AC7801DD803CF44A4D1F0AC")), // Q spec); -// // -// // set up the keys -// // -// AsymmetricKeyParameter privKey; -// AsymmetricKeyParameter pubKey; -// -// KeyFactory fact = KeyFactory.getInstance("ECDSA"); -// -// privKey = fact.generatePrivate(privKeySpec); -// pubKey = fact.generatePublic(pubKeySpec); + // // + // // set up the keys + // // + // AsymmetricKeyParameter privKey; + // AsymmetricKeyParameter pubKey; + // + // KeyFactory fact = KeyFactory.getInstance("ECDSA"); + // + // privKey = fact.generatePrivate(privKeySpec); + // pubKey = fact.generatePublic(pubKeySpec); Pkcs10CertificationRequest req = new Pkcs10CertificationRequest( algorithm, new X509Name("CN=XXX"), pubKey, null, privKey); @@ -166,7 +169,7 @@ namespace Org.BouncyCastle.Tests // // try with point compression turned off // -// ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); + // ((ECPointEncoder)pubKey).setPointFormat("UNCOMPRESSED"); ECPoint q = pubKey.Q.Normalize(); pubKey = new ECPublicKeyParameters( pubKey.AlgorithmName, @@ -266,26 +269,26 @@ namespace Org.BouncyCastle.Tests private void createPssTest( string algorithm) { -// RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( + // RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( RsaKeyParameters pubKey = new RsaKeyParameters(false, - new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), - new BigInteger("010001",16)); + new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137", 16), + new BigInteger("010001", 16)); -// RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( + // RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters( - new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137",16), - new BigInteger("010001",16), - new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325",16), - new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443",16), - new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd",16), - new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979",16), - new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729",16), - new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d",16)); - -// KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); -// -// PrivateKey privKey = fact.generatePrivate(privKeySpec); -// PublicKey pubKey = fact.generatePublic(pubKeySpec); + new BigInteger("a56e4a0e701017589a5187dc7ea841d156f2ec0e36ad52a44dfeb1e61f7ad991d8c51056ffedb162b4c0f283a12a88a394dff526ab7291cbb307ceabfce0b1dfd5cd9508096d5b2b8b6df5d671ef6377c0921cb23c270a70e2598e6ff89d19f105acc2d3f0cb35f29280e1386b6f64c4ef22e1e1f20d0ce8cffb2249bd9a2137", 16), + new BigInteger("010001", 16), + new BigInteger("33a5042a90b27d4f5451ca9bbbd0b44771a101af884340aef9885f2a4bbe92e894a724ac3c568c8f97853ad07c0266c8c6a3ca0929f1e8f11231884429fc4d9ae55fee896a10ce707c3ed7e734e44727a39574501a532683109c2abacaba283c31b4bd2f53c3ee37e352cee34f9e503bd80c0622ad79c6dcee883547c6a3b325", 16), + new BigInteger("e7e8942720a877517273a356053ea2a1bc0c94aa72d55c6e86296b2dfc967948c0a72cbccca7eacb35706e09a1df55a1535bd9b3cc34160b3b6dcd3eda8e6443", 16), + new BigInteger("b69dca1cf7d4d7ec81e75b90fcca874abcde123fd2700180aa90479b6e48de8d67ed24f9f19d85ba275874f542cd20dc723e6963364a1f9425452b269a6799fd", 16), + new BigInteger("28fa13938655be1f8a159cbaca5a72ea190c30089e19cd274a556f36c4f6e19f554b34c077790427bbdd8dd3ede2448328f385d81b30e8e43b2fffa027861979", 16), + new BigInteger("1a8b38f398fa712049898d7fb79ee0a77668791299cdfa09efc0e507acb21ed74301ef5bfd48be455eaeb6e1678255827580a8e4e8e14151d1510a82a3f2e729", 16), + new BigInteger("27156aba4126d24a81f3a528cbfb27f56886f840a9f6e86e17a44b94fe9319584b8e22fdde1e5a2e3bd8aa5ba8d8584194eb2190acf832b847f13a3d24a79f4d", 16)); + + // KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); + // + // PrivateKey privKey = fact.generatePrivate(privKeySpec); + // PublicKey pubKey = fact.generatePublic(pubKeySpec); Pkcs10CertificationRequest req = new Pkcs10CertificationRequest( algorithm, new X509Name("CN=XXX"), pubKey, null, privKey); @@ -360,6 +363,8 @@ namespace Org.BouncyCastle.Tests public override void PerformTest() { + + generationTest(512, "RSA", "SHA1withRSA"); generationTest(512, "GOST3410", "GOST3411withGOST3410"); @@ -410,7 +415,7 @@ namespace Org.BouncyCastle.Tests ECCurve curve = x9.Curve; ECDomainParameters ecSpec = new ECDomainParameters(curve, x9.G, x9.N, x9.H); -// g.initialize(ecSpec, new SecureRandom()); + // g.initialize(ecSpec, new SecureRandom()); g.Init(new ECKeyGenerationParameters(ecSpec, new SecureRandom())); AsymmetricCipherKeyPair kp = g.GenerateKeyPair(); @@ -432,14 +437,119 @@ namespace Org.BouncyCastle.Tests createECGostRequest(); // TODO The setting of parameters for MGF algorithms is not implemented -// createPssTest("SHA1withRSAandMGF1"); -// createPssTest("SHA224withRSAandMGF1"); -// createPssTest("SHA256withRSAandMGF1"); -// createPssTest("SHA384withRSAandMGF1"); + // createPssTest("SHA1withRSAandMGF1"); + // createPssTest("SHA224withRSAandMGF1"); + // createPssTest("SHA256withRSAandMGF1"); + // createPssTest("SHA384withRSAandMGF1"); nullPointerTest(); } + + + [Test] + public void BrokenRequestWithDuplicateExtension() + { + + String keyName = "RSA"; + int keySize = 2048; + + String sigName = "SHA256withRSA"; + + IAsymmetricCipherKeyPairGenerator kpg = GeneratorUtilities.GetKeyPairGenerator(keyName); + + // kpg.initialize(keySize); + kpg.Init(new KeyGenerationParameters(new SecureRandom(), keySize)); + + AsymmetricCipherKeyPair kp = kpg.GenerateKeyPair(); + + IDictionary attrs = new Hashtable(); + attrs.Add(X509Name.C, "AU"); + attrs.Add(X509Name.O, "The Legion of the Bouncy Castle"); + attrs.Add(X509Name.L, "Melbourne"); + attrs.Add(X509Name.ST, "Victoria"); + attrs.Add(X509Name.EmailAddress, "feedback-crypto@bouncycastle.org"); + + IList order = new ArrayList(); + order.Add(X509Name.C); + order.Add(X509Name.O); + order.Add(X509Name.L); + order.Add(X509Name.ST); + order.Add(X509Name.EmailAddress); + + X509Name subject = new X509Name(order, attrs); + + // + // This is simulate the creation of a certification request with duplicate extensions. + // + + GeneralName name1 = new GeneralName(GeneralName.DnsName, "bc1.local"); + GeneralName name2 = new GeneralName(GeneralName.DnsName, "bc2.local"); + + Asn1EncodableVector v = new Asn1EncodableVector(); + Asn1EncodableVector e1 = new Asn1EncodableVector(); + e1.Add(X509Extensions.SubjectAlternativeName); + e1.Add(new DerOctetString(new GeneralNames(name1).GetEncoded())); + + Asn1EncodableVector e2 = new Asn1EncodableVector(); + e2.Add(X509Extensions.SubjectAlternativeName); + e2.Add(new DerOctetString(new GeneralNames(name2).GetEncoded())); + + v.Add(new DerSequence(e1)); + v.Add(new DerSequence(e2)); + + AttributePkcs attribute = new AttributePkcs(PkcsObjectIdentifiers.Pkcs9AtExtensionRequest, new DerSet(new DerSequence(v))); + + Pkcs10CertificationRequest req1 = new Pkcs10CertificationRequest( + sigName, + subject, + kp.Public, + new DerSet(attribute), + kp.Private); + + + // Round trip serialisation + byte[] bytes = req1.GetEncoded(); + Pkcs10CertificationRequest req2 = new Pkcs10CertificationRequest(bytes); + + + // + // Check verification after round tripping serialisation. + // + + if (!req2.Verify()) + { + Fail(sigName + ": Failed Verify check."); + } + + if (!req2.GetPublicKey().Equals(req1.GetPublicKey())) + { + Fail(keyName + ": Failed public key check."); + } + + // + // Disassemble the attributes with the duplicate extensions. + // + + var extensions = req2.GetX509Extensions(); + + X509Extension returnedExtension = extensions.GetExtension(X509Extensions.SubjectAlternativeName); + Asn1Sequence seq = Asn1Sequence.GetInstance(returnedExtension.GetParsedValue()); + + // + // Check expected order and value. + // + if (!GeneralName.GetInstance(seq[0]).Equals(name1)) + { + Fail("expected name 1"); + } + + if (!GeneralName.GetInstance(seq[1]).Equals(name2)) + { + Fail("expected name 2"); + } + } + public static void Main( string[] args) { diff --git a/csharp.sln b/csharp.sln index ce64a084a..3b0413e9e 100644 --- a/csharp.sln +++ b/csharp.sln @@ -1,29 +1,30 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31624.102 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "crypto", "crypto\crypto.csproj", "{38872A5F-E87E-4FAD-B109-8EB7B2E6A4A0}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "crypto-test", "crypto-test\crypto-test.csproj", "{C857AD68-8F1B-4C7A-A76B-3DC03CBE4FB0}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection EndProject Global - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - Release = Release + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {38872A5F-E87E-4FAD-B109-8EB7B2E6A4A0}.Debug.ActiveCfg = Debug|.NET - {38872A5F-E87E-4FAD-B109-8EB7B2E6A4A0}.Debug.Build.0 = Debug|.NET - {38872A5F-E87E-4FAD-B109-8EB7B2E6A4A0}.Release.ActiveCfg = Release|.NET - {38872A5F-E87E-4FAD-B109-8EB7B2E6A4A0}.Release.Build.0 = Release|.NET - {C857AD68-8F1B-4C7A-A76B-3DC03CBE4FB0}.Debug.ActiveCfg = Debug|.NET - {C857AD68-8F1B-4C7A-A76B-3DC03CBE4FB0}.Debug.Build.0 = Debug|.NET - {C857AD68-8F1B-4C7A-A76B-3DC03CBE4FB0}.Release.ActiveCfg = Release|.NET - {C857AD68-8F1B-4C7A-A76B-3DC03CBE4FB0}.Release.Build.0 = Release|.NET + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {38872A5F-E87E-4FAD-B109-8EB7B2E6A4A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {38872A5F-E87E-4FAD-B109-8EB7B2E6A4A0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {38872A5F-E87E-4FAD-B109-8EB7B2E6A4A0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {38872A5F-E87E-4FAD-B109-8EB7B2E6A4A0}.Release|Any CPU.Build.0 = Release|Any CPU + {C857AD68-8F1B-4C7A-A76B-3DC03CBE4FB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C857AD68-8F1B-4C7A-A76B-3DC03CBE4FB0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C857AD68-8F1B-4C7A-A76B-3DC03CBE4FB0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C857AD68-8F1B-4C7A-A76B-3DC03CBE4FB0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {93DA6E72-9E82-46AE-A4EC-24E6B9389191} EndGlobalSection EndGlobal |