From 12ba3375f2d8a485577dffa3c18c6661cc32469b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BD=AD=E4=BC=9F?= Date: Sun, 17 Apr 2022 21:19:32 +0800 Subject: [PATCH] Add support ArraySegment. https://docs.microsoft.com/en-us/dotnet/api/system.arraysegment-1#remarks --- crypto/src/asn1/Asn1Null.cs | 11 ++++ crypto/src/asn1/Asn1Object.cs | 38 ++++++++---- crypto/src/asn1/Asn1ObjectDescriptor.cs | 11 ++++ crypto/src/asn1/Asn1OctetString.cs | 11 ++++ crypto/src/asn1/Asn1RelativeOid.cs | 11 ++++ crypto/src/asn1/Asn1Sequence.cs | 11 ++++ crypto/src/asn1/Asn1Set.cs | 11 ++++ crypto/src/asn1/Asn1TaggedObject.cs | 11 ++++ crypto/src/asn1/Asn1UniversalType.cs | 6 ++ crypto/src/asn1/DERExternal.cs | 11 ++++ crypto/src/asn1/DerApplicationSpecific.cs | 11 ++++ crypto/src/asn1/DerBMPString.cs | 11 ++++ crypto/src/asn1/DerBitString.cs | 11 ++++ crypto/src/asn1/DerBoolean.cs | 11 ++++ crypto/src/asn1/DerEnumerated.cs | 11 ++++ crypto/src/asn1/DerGeneralString.cs | 11 ++++ crypto/src/asn1/DerGeneralizedTime.cs | 11 ++++ crypto/src/asn1/DerGraphicString.cs | 11 ++++ crypto/src/asn1/DerIA5String.cs | 11 ++++ crypto/src/asn1/DerInteger.cs | 11 ++++ crypto/src/asn1/DerNumericString.cs | 11 ++++ crypto/src/asn1/DerObjectIdentifier.cs | 11 ++++ crypto/src/asn1/DerPrintableString.cs | 11 ++++ crypto/src/asn1/DerT61String.cs | 11 ++++ crypto/src/asn1/DerUTCTime.cs | 11 ++++ crypto/src/asn1/DerUTF8String.cs | 11 ++++ crypto/src/asn1/DerUniversalString.cs | 11 ++++ crypto/src/asn1/DerVideotexString.cs | 11 ++++ crypto/src/asn1/DerVisibleString.cs | 11 ++++ crypto/src/asn1/x509/GeneralName.cs | 12 ++++ crypto/src/asn1/x9/X962Parameters.cs | 12 ++++ crypto/src/pkcs/Pkcs10CertificationRequest.cs | 6 ++ crypto/src/security/PrivateKeyFactory.cs | 15 +++++ crypto/src/security/PublicKeyFactory.cs | 8 +++ .../x509/store/X509AttrCertStoreSelector.cs | 4 ++ crypto/test/src/asn1/test/BitStringTest.cs | 61 +++++++++++++++++++ 36 files changed, 446 insertions(+), 13 deletions(-) diff --git a/crypto/src/asn1/Asn1Null.cs b/crypto/src/asn1/Asn1Null.cs index 9ea9b43752..f405a948c4 100644 --- a/crypto/src/asn1/Asn1Null.cs +++ b/crypto/src/asn1/Asn1Null.cs @@ -46,6 +46,17 @@ public static Asn1Null GetInstance(object obj) throw new ArgumentException("failed to construct NULL from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (Asn1Null)Meta.Instance.FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct NULL from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); } diff --git a/crypto/src/asn1/Asn1Object.cs b/crypto/src/asn1/Asn1Object.cs index 0cf89052b2..a0c613f961 100644 --- a/crypto/src/asn1/Asn1Object.cs +++ b/crypto/src/asn1/Asn1Object.cs @@ -34,21 +34,33 @@ public bool Equals(Asn1Object other) public static Asn1Object FromByteArray( byte[] data) { - try - { - MemoryStream input = new MemoryStream(data, false); - Asn1InputStream asn1 = new Asn1InputStream(input, data.Length); - Asn1Object result = asn1.ReadObject(); - if (input.Position != input.Length) - throw new IOException("extra data found after object"); - return result; - } - catch (InvalidCastException) - { - throw new IOException("cannot recognise object in byte array"); - } + return FromByteArray(new ArraySegment(data, 0, data.Length)); } + /// Create a base ASN.1 object from a byte array segment. + /// The byte array segment to parse. + /// The base ASN.1 object represented by the byte array. + /// + /// If there is a problem parsing the data, or parsing an object did not exhaust the available data. + /// + public static Asn1Object FromByteArray( + ArraySegment data) + { + try + { + MemoryStream input = new MemoryStream(data.Array ?? new byte[0], data.Offset, data.Count, false); + Asn1InputStream asn1 = new Asn1InputStream(input, data.Count); + Asn1Object result = asn1.ReadObject(); + if (input.Position != input.Length) + throw new IOException("extra data found after object"); + return result; + } + catch (InvalidCastException) + { + throw new IOException("cannot recognise object in byte array"); + } + } + /// Read a base ASN.1 object from a stream. /// The stream to parse. /// The base ASN.1 object represented by the byte array. diff --git a/crypto/src/asn1/Asn1ObjectDescriptor.cs b/crypto/src/asn1/Asn1ObjectDescriptor.cs index 9c99f441ee..fa2d64a789 100644 --- a/crypto/src/asn1/Asn1ObjectDescriptor.cs +++ b/crypto/src/asn1/Asn1ObjectDescriptor.cs @@ -57,6 +57,17 @@ public static Asn1ObjectDescriptor GetInstance(object obj) throw new ArgumentException("failed to construct object descriptor from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (Asn1ObjectDescriptor)Meta.Instance.FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct object descriptor from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } diff --git a/crypto/src/asn1/Asn1OctetString.cs b/crypto/src/asn1/Asn1OctetString.cs index d34686134d..8bee5a010f 100644 --- a/crypto/src/asn1/Asn1OctetString.cs +++ b/crypto/src/asn1/Asn1OctetString.cs @@ -58,6 +58,17 @@ public static Asn1OctetString GetInstance(object obj) throw new ArgumentException("failed to construct OCTET STRING from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (Asn1OctetString)Meta.Instance.FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct OCTET STRING from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } diff --git a/crypto/src/asn1/Asn1RelativeOid.cs b/crypto/src/asn1/Asn1RelativeOid.cs index 9c4f917f2e..1895df0478 100644 --- a/crypto/src/asn1/Asn1RelativeOid.cs +++ b/crypto/src/asn1/Asn1RelativeOid.cs @@ -50,6 +50,17 @@ public static Asn1RelativeOid GetInstance(object obj) throw new ArgumentException("failed to construct relative OID from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (Asn1RelativeOid)FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct relative OID from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } diff --git a/crypto/src/asn1/Asn1Sequence.cs b/crypto/src/asn1/Asn1Sequence.cs index d7f84d3e41..6e5d84c192 100644 --- a/crypto/src/asn1/Asn1Sequence.cs +++ b/crypto/src/asn1/Asn1Sequence.cs @@ -52,6 +52,17 @@ public static Asn1Sequence GetInstance(object obj) throw new ArgumentException("failed to construct sequence from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (Asn1Sequence)Meta.Instance.FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct sequence from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } diff --git a/crypto/src/asn1/Asn1Set.cs b/crypto/src/asn1/Asn1Set.cs index f3b94121ba..187631b386 100644 --- a/crypto/src/asn1/Asn1Set.cs +++ b/crypto/src/asn1/Asn1Set.cs @@ -58,6 +58,17 @@ public static Asn1Set GetInstance(object obj) throw new ArgumentException("failed to construct set from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (Asn1Set)Meta.Instance.FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct set from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } diff --git a/crypto/src/asn1/Asn1TaggedObject.cs b/crypto/src/asn1/Asn1TaggedObject.cs index ce5e9e3f21..e246601cdf 100644 --- a/crypto/src/asn1/Asn1TaggedObject.cs +++ b/crypto/src/asn1/Asn1TaggedObject.cs @@ -43,6 +43,17 @@ public static Asn1TaggedObject GetInstance(object obj) throw new ArgumentException("failed to construct tagged object from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return CheckedCast(FromByteArray((ArraySegment)obj)); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct tagged object from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } diff --git a/crypto/src/asn1/Asn1UniversalType.cs b/crypto/src/asn1/Asn1UniversalType.cs index 46cacb4362..c45116a1cc 100644 --- a/crypto/src/asn1/Asn1UniversalType.cs +++ b/crypto/src/asn1/Asn1UniversalType.cs @@ -40,6 +40,12 @@ internal Asn1Object FromByteArray(byte[] bytes) return CheckedCast(Asn1Object.FromByteArray(bytes)); } + /// + internal Asn1Object FromByteArray(ArraySegment bytes) + { + return CheckedCast(Asn1Object.FromByteArray(bytes)); + } + internal Asn1Object GetContextInstance(Asn1TaggedObject taggedObject, bool declaredExplicit) { if (Asn1Tags.ContextSpecific != taggedObject.TagClass) diff --git a/crypto/src/asn1/DERExternal.cs b/crypto/src/asn1/DERExternal.cs index b8987d53e7..42c9595d89 100644 --- a/crypto/src/asn1/DERExternal.cs +++ b/crypto/src/asn1/DERExternal.cs @@ -46,6 +46,17 @@ public static DerExternal GetInstance(object obj) throw new ArgumentException("failed to construct external from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (DerExternal)Meta.Instance.FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct external from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } diff --git a/crypto/src/asn1/DerApplicationSpecific.cs b/crypto/src/asn1/DerApplicationSpecific.cs index d474034ed3..eacacca648 100644 --- a/crypto/src/asn1/DerApplicationSpecific.cs +++ b/crypto/src/asn1/DerApplicationSpecific.cs @@ -28,6 +28,17 @@ public static DerApplicationSpecific GetInstance(object obj) throw new ArgumentException("failed to construct application-specific from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return GetInstance(FromByteArray((ArraySegment)obj)); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct application-specific from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } diff --git a/crypto/src/asn1/DerBMPString.cs b/crypto/src/asn1/DerBMPString.cs index a289eed1b8..8991313a20 100644 --- a/crypto/src/asn1/DerBMPString.cs +++ b/crypto/src/asn1/DerBMPString.cs @@ -52,6 +52,17 @@ public static DerBmpString GetInstance(object obj) throw new ArgumentException("failed to construct BMP string from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (DerBmpString)Meta.Instance.FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct BMP string from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); } diff --git a/crypto/src/asn1/DerBitString.cs b/crypto/src/asn1/DerBitString.cs index 2b1ff3354a..0e725c5ae9 100644 --- a/crypto/src/asn1/DerBitString.cs +++ b/crypto/src/asn1/DerBitString.cs @@ -60,6 +60,17 @@ public static DerBitString GetInstance(object obj) throw new ArgumentException("failed to construct BIT STRING from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return GetInstance(FromByteArray((ArraySegment)obj)); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct BIT STRING from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); } diff --git a/crypto/src/asn1/DerBoolean.cs b/crypto/src/asn1/DerBoolean.cs index ad578ae80a..7086fe56e5 100644 --- a/crypto/src/asn1/DerBoolean.cs +++ b/crypto/src/asn1/DerBoolean.cs @@ -51,6 +51,17 @@ public static DerBoolean GetInstance(object obj) throw new ArgumentException("failed to construct boolean from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (DerBoolean)Meta.Instance.FromByteArray((byte[])obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct boolean from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); } diff --git a/crypto/src/asn1/DerEnumerated.cs b/crypto/src/asn1/DerEnumerated.cs index 920b3dc8ed..6745a34d88 100644 --- a/crypto/src/asn1/DerEnumerated.cs +++ b/crypto/src/asn1/DerEnumerated.cs @@ -49,6 +49,17 @@ public static DerEnumerated GetInstance(object obj) throw new ArgumentException("failed to construct enumerated from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (DerEnumerated)Meta.Instance.FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct enumerated from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); } diff --git a/crypto/src/asn1/DerGeneralString.cs b/crypto/src/asn1/DerGeneralString.cs index e6637732ad..4d4597a1a4 100644 --- a/crypto/src/asn1/DerGeneralString.cs +++ b/crypto/src/asn1/DerGeneralString.cs @@ -43,6 +43,17 @@ public static DerGeneralString GetInstance(object obj) throw new ArgumentException("failed to construct general string from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (DerGeneralString)Meta.Instance.FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct general string from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); } diff --git a/crypto/src/asn1/DerGeneralizedTime.cs b/crypto/src/asn1/DerGeneralizedTime.cs index ed2cb5e62f..9902b895ed 100644 --- a/crypto/src/asn1/DerGeneralizedTime.cs +++ b/crypto/src/asn1/DerGeneralizedTime.cs @@ -53,6 +53,17 @@ public static DerGeneralizedTime GetInstance(object obj) throw new ArgumentException("failed to construct generalized time from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (DerGeneralizedTime)Meta.Instance.FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct generalized time from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } diff --git a/crypto/src/asn1/DerGraphicString.cs b/crypto/src/asn1/DerGraphicString.cs index cb32d14eb8..30358d2fd7 100644 --- a/crypto/src/asn1/DerGraphicString.cs +++ b/crypto/src/asn1/DerGraphicString.cs @@ -50,6 +50,17 @@ public static DerGraphicString GetInstance(object obj) throw new ArgumentException("failed to construct graphic string from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (DerGraphicString)Meta.Instance.FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct graphic string from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } diff --git a/crypto/src/asn1/DerIA5String.cs b/crypto/src/asn1/DerIA5String.cs index a568798310..0f8a7314dd 100644 --- a/crypto/src/asn1/DerIA5String.cs +++ b/crypto/src/asn1/DerIA5String.cs @@ -51,6 +51,17 @@ public static DerIA5String GetInstance(object obj) throw new ArgumentException("failed to construct IA5 string from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (DerIA5String)Meta.Instance.FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct IA5 string from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); } diff --git a/crypto/src/asn1/DerInteger.cs b/crypto/src/asn1/DerInteger.cs index c8d4e47dfa..58c25db15a 100644 --- a/crypto/src/asn1/DerInteger.cs +++ b/crypto/src/asn1/DerInteger.cs @@ -63,6 +63,17 @@ public static DerInteger GetInstance(object obj) throw new ArgumentException("failed to construct integer from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (DerInteger)Meta.Instance.FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct integer from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); } diff --git a/crypto/src/asn1/DerNumericString.cs b/crypto/src/asn1/DerNumericString.cs index 693ff7d6e4..2ca1a7c857 100644 --- a/crypto/src/asn1/DerNumericString.cs +++ b/crypto/src/asn1/DerNumericString.cs @@ -51,6 +51,17 @@ public static DerNumericString GetInstance(object obj) throw new ArgumentException("failed to construct numeric string from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (DerNumericString)Meta.Instance.FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct numeric string from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); } diff --git a/crypto/src/asn1/DerObjectIdentifier.cs b/crypto/src/asn1/DerObjectIdentifier.cs index 8b77f966c5..a9daeaa081 100644 --- a/crypto/src/asn1/DerObjectIdentifier.cs +++ b/crypto/src/asn1/DerObjectIdentifier.cs @@ -55,6 +55,17 @@ public static DerObjectIdentifier GetInstance(object obj) throw new ArgumentException("failed to construct object identifier from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (DerObjectIdentifier)Meta.Instance.FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct object identifier from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } diff --git a/crypto/src/asn1/DerPrintableString.cs b/crypto/src/asn1/DerPrintableString.cs index 3c44a2d529..11a964232e 100644 --- a/crypto/src/asn1/DerPrintableString.cs +++ b/crypto/src/asn1/DerPrintableString.cs @@ -51,6 +51,17 @@ public static DerPrintableString GetInstance(object obj) throw new ArgumentException("failed to construct printable string from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (DerPrintableString)Meta.Instance.FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct printable string from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); } diff --git a/crypto/src/asn1/DerT61String.cs b/crypto/src/asn1/DerT61String.cs index a0e4f1d22d..7da0ccbea6 100644 --- a/crypto/src/asn1/DerT61String.cs +++ b/crypto/src/asn1/DerT61String.cs @@ -51,6 +51,17 @@ public static DerT61String GetInstance(object obj) throw new ArgumentException("failed to construct T61 string from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (DerT61String)Meta.Instance.FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct T61 string from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); } diff --git a/crypto/src/asn1/DerUTCTime.cs b/crypto/src/asn1/DerUTCTime.cs index cb3f133530..ddf3da07e7 100644 --- a/crypto/src/asn1/DerUTCTime.cs +++ b/crypto/src/asn1/DerUTCTime.cs @@ -52,6 +52,17 @@ public static DerUtcTime GetInstance(object obj) throw new ArgumentException("failed to construct UTC time from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (DerUtcTime)Meta.Instance.FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct UTC time from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); } diff --git a/crypto/src/asn1/DerUTF8String.cs b/crypto/src/asn1/DerUTF8String.cs index d15a19d39d..97f90021dc 100644 --- a/crypto/src/asn1/DerUTF8String.cs +++ b/crypto/src/asn1/DerUTF8String.cs @@ -51,6 +51,17 @@ public static DerUtf8String GetInstance(object obj) throw new ArgumentException("failed to construct UTF8 string from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (DerUtf8String)Meta.Instance.FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct UTF8 string from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); } diff --git a/crypto/src/asn1/DerUniversalString.cs b/crypto/src/asn1/DerUniversalString.cs index e4e93bd7df..35ba4aad1a 100644 --- a/crypto/src/asn1/DerUniversalString.cs +++ b/crypto/src/asn1/DerUniversalString.cs @@ -56,6 +56,17 @@ public static DerUniversalString GetInstance( throw new ArgumentException("failed to construct universal string from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (DerUniversalString)Meta.Instance.FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct universal string from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); } diff --git a/crypto/src/asn1/DerVideotexString.cs b/crypto/src/asn1/DerVideotexString.cs index a5fbe06027..4607ce83af 100644 --- a/crypto/src/asn1/DerVideotexString.cs +++ b/crypto/src/asn1/DerVideotexString.cs @@ -50,6 +50,17 @@ public static DerVideotexString GetInstance(object obj) throw new ArgumentException("failed to construct videotex string from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (DerVideotexString)Meta.Instance.FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct videotex string from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } diff --git a/crypto/src/asn1/DerVisibleString.cs b/crypto/src/asn1/DerVisibleString.cs index 3593700403..5d6c297cbb 100644 --- a/crypto/src/asn1/DerVisibleString.cs +++ b/crypto/src/asn1/DerVisibleString.cs @@ -52,6 +52,17 @@ public static DerVisibleString GetInstance( throw new ArgumentException("failed to construct visible string from byte[]: " + e.Message); } } + else if (obj is ArraySegment) + { + try + { + return (DerVisibleString)Meta.Instance.FromByteArray((ArraySegment)obj); + } + catch (IOException e) + { + throw new ArgumentException("failed to construct visible string from ArraySegment: " + e.Message); + } + } throw new ArgumentException("illegal object in GetInstance: " + Platform.GetTypeName(obj)); } diff --git a/crypto/src/asn1/x509/GeneralName.cs b/crypto/src/asn1/x509/GeneralName.cs index fe00323ee4..77e50bf2d0 100644 --- a/crypto/src/asn1/x509/GeneralName.cs +++ b/crypto/src/asn1/x509/GeneralName.cs @@ -204,6 +204,18 @@ public static GeneralName GetInstance( } } + if (obj is ArraySegment) + { + try + { + return GetInstance(Asn1Object.FromByteArray((ArraySegment)obj)); + } + catch (IOException) + { + throw new ArgumentException("unable to parse encoded general name"); + } + } + throw new ArgumentException("unknown object in GetInstance: " + Platform.GetTypeName(obj), "obj"); } diff --git a/crypto/src/asn1/x9/X962Parameters.cs b/crypto/src/asn1/x9/X962Parameters.cs index 5bdabc6475..c31ee61bd5 100644 --- a/crypto/src/asn1/x9/X962Parameters.cs +++ b/crypto/src/asn1/x9/X962Parameters.cs @@ -34,6 +34,18 @@ public static X962Parameters GetInstance( } } + if (obj is ArraySegment) + { + try + { + return new X962Parameters(Asn1Object.FromByteArray((ArraySegment)obj)); + } + catch (Exception e) + { + throw new ArgumentException("unable to parse encoded data: " + e.Message, e); + } + } + throw new ArgumentException("unknown object in getInstance()"); } diff --git a/crypto/src/pkcs/Pkcs10CertificationRequest.cs b/crypto/src/pkcs/Pkcs10CertificationRequest.cs index c4624bfdc3..7ea0cc8c86 100644 --- a/crypto/src/pkcs/Pkcs10CertificationRequest.cs +++ b/crypto/src/pkcs/Pkcs10CertificationRequest.cs @@ -212,6 +212,12 @@ public Pkcs10CertificationRequest( { } + public Pkcs10CertificationRequest( + ArraySegment encoded) + : base((Asn1Sequence)Asn1Object.FromByteArray(encoded)) + { + } + public Pkcs10CertificationRequest( Asn1Sequence seq) : base(seq) diff --git a/crypto/src/security/PrivateKeyFactory.cs b/crypto/src/security/PrivateKeyFactory.cs index a8c4d94d06..adecb49a97 100644 --- a/crypto/src/security/PrivateKeyFactory.cs +++ b/crypto/src/security/PrivateKeyFactory.cs @@ -35,6 +35,14 @@ public static AsymmetricKeyParameter CreateKey( Asn1Object.FromByteArray(privateKeyInfoData))); } + public static AsymmetricKeyParameter CreateKey( + ArraySegment privateKeyInfoData) + { + return CreateKey( + PrivateKeyInfo.GetInstance( + Asn1Object.FromByteArray(privateKeyInfoData))); + } + public static AsymmetricKeyParameter CreateKey( Stream inStr) { @@ -299,6 +307,13 @@ public static AsymmetricKeyParameter DecryptKey( return DecryptKey(passPhrase, Asn1Object.FromByteArray(encryptedPrivateKeyInfoData)); } + public static AsymmetricKeyParameter DecryptKey( + char[] passPhrase, + ArraySegment encryptedPrivateKeyInfoData) + { + return DecryptKey(passPhrase, Asn1Object.FromByteArray(encryptedPrivateKeyInfoData)); + } + public static AsymmetricKeyParameter DecryptKey( char[] passPhrase, Stream encryptedPrivateKeyInfoStream) diff --git a/crypto/src/security/PublicKeyFactory.cs b/crypto/src/security/PublicKeyFactory.cs index 10b2aacdc3..69ab975547 100644 --- a/crypto/src/security/PublicKeyFactory.cs +++ b/crypto/src/security/PublicKeyFactory.cs @@ -36,6 +36,14 @@ public static AsymmetricKeyParameter CreateKey( Asn1Object.FromByteArray(keyInfoData))); } + public static AsymmetricKeyParameter CreateKey( + ArraySegment keyInfoData) + { + return CreateKey( + SubjectPublicKeyInfo.GetInstance( + Asn1Object.FromByteArray(keyInfoData))); + } + public static AsymmetricKeyParameter CreateKey( Stream inStr) { diff --git a/crypto/src/x509/store/X509AttrCertStoreSelector.cs b/crypto/src/x509/store/X509AttrCertStoreSelector.cs index 24255fad25..c3e173a81e 100644 --- a/crypto/src/x509/store/X509AttrCertStoreSelector.cs +++ b/crypto/src/x509/store/X509AttrCertStoreSelector.cs @@ -362,6 +362,10 @@ private ISet ExtractGeneralNames( { result.Add(o); } + else if (o is ArraySegment) + { + result.Add(GeneralName.GetInstance(Asn1Object.FromByteArray((ArraySegment) o))); + } else { result.Add(GeneralName.GetInstance(Asn1Object.FromByteArray((byte[]) o))); diff --git a/crypto/test/src/asn1/test/BitStringTest.cs b/crypto/test/src/asn1/test/BitStringTest.cs index af893fe9ff..b1b54b3780 100644 --- a/crypto/test/src/asn1/test/BitStringTest.cs +++ b/crypto/test/src/asn1/test/BitStringTest.cs @@ -78,7 +78,37 @@ private void DoTestRandomPadBits() EncodingCheck(test, test3); EncodingCheck(test, test4); } + + private void DoTestRandomPadArraySegmentBits() + { + byte[] test = Hex.Decode("030206c0"); + + byte[] test1 = Hex.Decode("030206f0"); + byte[] test2 = Hex.Decode("030206c1"); + byte[] test3 = Hex.Decode("030206c7"); + byte[] test4 = Hex.Decode("030206d1"); + + EncodingCheck(MakeRandomArraySegment(test), MakeRandomArraySegment(test1)); + EncodingCheck(MakeRandomArraySegment(test), MakeRandomArraySegment(test2)); + EncodingCheck(MakeRandomArraySegment(test), MakeRandomArraySegment(test3)); + EncodingCheck(MakeRandomArraySegment(test), MakeRandomArraySegment(test4)); + } + + private static ArraySegment MakeRandomArraySegment(byte[] buffer) + { + var random = new Random(); + + var array = new byte[buffer.Length + random.Next(100)]; + + var offset = random.Next(array.Length - buffer.Length); + + random.NextBytes(array); + + buffer.CopyTo(array, offset); + return new ArraySegment(array, offset, buffer.Length); + } + private void EncodingCheck(byte[] derData, byte[] dlData) { if (Arrays.AreEqual(derData, Asn1Object.FromByteArray(dlData).GetEncoded())) @@ -104,6 +134,36 @@ private void EncodingCheck(byte[] derData, byte[] dlData) DerBitString der = DerBitString.GetInstance(derData); IsTrue("DER test failed", typeof(DerBitString) == der.GetType()); } + + private void EncodingCheck(ArraySegment derData, ArraySegment dlData) + { + var encodeed = Asn1Object.FromByteArray(dlData).GetEncoded(); + + if (Arrays.AreEqual(derData.Array, derData.Offset, derData.Offset + derData.Count, encodeed, 0, encodeed.Length)) + { + Fail("failed DL check"); + } + DerBitString dl = DerBitString.GetInstance(dlData); + + IsTrue("DL test failed", dl is DLBitString); + + encodeed = Asn1Object.FromByteArray(dlData).GetDerEncoded(); + if (!Arrays.AreEqual(derData.Array, derData.Offset, derData.Offset + derData.Count, encodeed, 0, encodeed.Length)) + { + Fail("failed DER check"); + } + try + { + // GetInstance should work for "an object that can be converted into [a DerBitString]". + DerBitString.GetInstance(dlData); + } + catch (ArgumentException) + { + Fail("failed DL encoding conversion"); + } + DerBitString der = DerBitString.GetInstance(derData); + IsTrue("DER test failed", typeof(DerBitString) == der.GetType()); + } public override void PerformTest() { @@ -148,6 +208,7 @@ public override void PerformTest() } DoTestRandomPadBits(); + DoTestRandomPadArraySegmentBits(); DoTestZeroLengthStrings(); }