private object[] GetData() { GXAsn1ObjectIdentifier alg; if (PublicKey.Scheme == Ecdsa.Enums.Ecc.P256) { alg = new GXAsn1ObjectIdentifier("1.2.840.10045.3.1.7"); } else { alg = new GXAsn1ObjectIdentifier("1.3.132.0.34"); } object subjectPKInfo = new GXAsn1BitString(PublicKey.RawValue, 0); object[] tmp = new object[] { new GXAsn1ObjectIdentifier("1.2.840.10045.2.1"), alg }; GXAsn1Context attributes = new GXAsn1Context(); foreach (KeyValuePair <PkcsObjectIdentifier, object[]> it in Attributes) { GXAsn1Sequence s = new GXAsn1Sequence(); s.Add(new GXAsn1ObjectIdentifier(PkcsObjectIdentifierConverter.GetString(it.Key))); //Convert object array to list. List <object> values = new List <object>(); foreach (object v in it.Value) { values.Add(v); } s.Add(new KeyValuePair <object, object>(values, null)); attributes.Add(s); } return(new object[] { (sbyte)Version, GXAsn1Converter.EncodeSubject(Subject), new object[] { tmp, subjectPKInfo }, attributes }); }
private static void GetValue(GXByteBuffer bb, IList <object> objects, GXAsn1Settings s) { int len; short type; IList <object> tmp; byte[] tmp2; type = bb.GetUInt8(); len = GXCommon.GetObjectCount(bb); if (len > bb.Available) { throw new OutOfMemoryException("GXAsn1Converter.GetValue"); } int connectPos = 0; if (s != null) { connectPos = s.XmlLength; } int start = bb.Position; string tagString = null; if (s != null) { s.AppendSpaces(); if (type == (byte)BerType.Integer) { if (len == 1 || len == 2 || len == 4 || len == 8) { tagString = s.GetTag((short)-len); } else { tagString = s.GetTag((byte)BerType.Integer); } } else { tagString = s.GetTag(type); } s.Append("<" + tagString + ">"); } switch (type) { case (byte)(BerType.Constructed | BerType.Context): case ((byte)(BerType.Constructed | BerType.Context) | 1): case ((byte)(BerType.Constructed | BerType.Context) | 2): case ((byte)(BerType.Constructed | BerType.Context) | 3): case ((byte)(BerType.Constructed | BerType.Context) | 4): if (s != null) { s.Increase(); } tmp = new GXAsn1Context() { Index = type & 0xF }; objects.Add(tmp); while (bb.Position < start + len) { GetValue(bb, tmp, s); } if (s != null) { s.Decrease(); } break; case (byte)(BerType.Constructed | BerType.Sequence): if (s != null) { s.Increase(); } tmp = new GXAsn1Sequence(); objects.Add(tmp); int cnt = 0; while (bb.Position < start + len) { ++cnt; GetValue(bb, tmp, s); } if (s != null) { // Append comment. s.AppendComment(connectPos, Convert.ToString(cnt) + " elements."); s.Decrease(); } break; case (byte)(BerType.Constructed | BerType.Set): if (s != null) { s.Increase(); } tmp = new List <object>(); GetValue(bb, tmp, s); if (tmp[0] is GXAsn1Sequence) { tmp = (GXAsn1Sequence)tmp[0]; objects.Add(new KeyValuePair <object, object>(tmp[0], tmp[1])); } else { KeyValuePair <object, object> e = new KeyValuePair <object, object>(tmp, null); objects.Add(e); } if (s != null) { s.Decrease(); } break; case (byte)BerType.ObjectIdentifier: GXAsn1ObjectIdentifier oi = new GXAsn1ObjectIdentifier(bb, len); objects.Add(oi); if (s != null) { string str = oi.Description; if (str != null) { s.AppendComment(connectPos, str); } s.Append(oi.ToString()); } break; case (byte)BerType.PrintableString: objects.Add(bb.GetString(len)); if (s != null) { s.Append(Convert.ToString(objects[objects.Count - 1])); } break; case (byte)BerType.Utf8StringTag: objects.Add(new GXAsn1Utf8String(bb.GetString(bb.Position, len))); bb.Position = bb.Position + len; if (s != null) { s.Append(Convert.ToString(objects[objects.Count - 1])); } break; case (byte)BerType.Ia5String: objects.Add(new GXAsn1Ia5String(bb.GetString(len))); if (s != null) { s.Append(Convert.ToString(objects[objects.Count - 1])); } break; case (byte)BerType.Integer: if (len == 1) { objects.Add(bb.GetInt8()); } else if (len == 2) { objects.Add(bb.GetInt16()); } else if (len == 4) { objects.Add(bb.GetInt32()); } else { tmp2 = new byte[len]; bb.Get(tmp2); objects.Add(new GXAsn1Integer(tmp2)); } if (s != null) { s.Append(Convert.ToString(objects[objects.Count - 1])); } break; case (byte)BerType.Null: objects.Add(null); break; case (byte)BerType.BitString: GXAsn1BitString tmp3 = new GXAsn1BitString(bb.SubArray(bb.Position, len)); objects.Add(tmp3); bb.Position = bb.Position + len; if (s != null) { // Append comment. s.AppendComment(connectPos, Convert.ToString(tmp3.Length) + " bit."); s.Append(tmp3.asString()); } break; case (byte)BerType.UtcTime: tmp2 = new byte[len]; bb.Get(tmp2); objects.Add(GetUtcTime(ASCIIEncoding.ASCII.GetString(tmp2))); if (s != null) { s.Append(((DateTimeOffset)objects[objects.Count - 1]).UtcDateTime.ToString("yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture)); } break; case (byte)BerType.GeneralizedTime: tmp2 = new byte[len]; bb.Get(tmp2); objects.Add(GXCommon.GetGeneralizedTime(ASCIIEncoding.ASCII.GetString(tmp2))); if (s != null) { s.Append(Convert.ToString(objects[objects.Count - 1])); } break; case (byte)BerType.Context: case (byte)BerType.Context | 1: case (byte)BerType.Context | 2: case (byte)BerType.Context | 3: tmp = new GXAsn1Context() { Constructed = false, Index = type & 0xF }; tmp2 = new byte[len]; bb.Get(tmp2); tmp.Add(tmp2); objects.Add(tmp); if (s != null) { s.Append(GXCommon.ToHex(tmp2, false)); } break; case (byte)BerType.OctetString: int t = bb.GetUInt8(bb.Position); switch (t) { case (byte)(BerType.Constructed | BerType.Sequence): case (byte)BerType.BitString: if (s != null) { s.Increase(); } GetValue(bb, objects, s); if (s != null) { s.Decrease(); } break; default: tmp2 = new byte[len]; bb.Get(tmp2); objects.Add(tmp2); if (s != null) { s.Append(GXCommon.ToHex(tmp2, false)); } break; } break; case (byte)BerType.Boolean: bool b = bb.GetUInt8() != 0; objects.Add(b); if (s != null) { s.Append(Convert.ToString(b)); } break; default: throw new System.ArgumentException("Invalid type: " + type); } if (s != null) { s.Append("</" + tagString + ">\r\n"); } }
private object[] GetDataList() { if (string.IsNullOrEmpty(Issuer)) { throw new ArgumentNullException("Issuer is empty."); } if (string.IsNullOrEmpty(Subject)) { throw new ArgumentNullException("Subject is empty."); } GXAsn1ObjectIdentifier a = new GXAsn1ObjectIdentifier(HashAlgorithmConverter.GetString(SignatureAlgorithm)); GXAsn1Sequence seq; GXAsn1Context p = new GXAsn1Context(); p.Add((sbyte)Version); GXAsn1Sequence s = new GXAsn1Sequence(); GXAsn1Sequence s1; if (SubjectKeyIdentifier != null) { s1 = new GXAsn1Sequence(); s1.Add(new GXAsn1ObjectIdentifier(X509CertificateTypeConverter.GetString(Enums.X509CertificateType.SubjectKeyIdentifier))); GXByteBuffer bb = new GXByteBuffer(); bb.SetUInt8(BerType.OctetString); GXCommon.SetObjectCount(SubjectKeyIdentifier.Length, bb); bb.Set(SubjectKeyIdentifier); s1.Add(bb.Array()); s.Add(s1); } if (AuthorityKeyIdentifier != null || AuthorityCertIssuer != null || AuthorityCertificationSerialNumber != null) { s1 = new GXAsn1Sequence(); s1.Add(new GXAsn1ObjectIdentifier(X509CertificateTypeConverter.GetString(Enums.X509CertificateType.AuthorityKeyIdentifier))); s.Add(s1); GXAsn1Context s2 = new GXAsn1Context() { Index = 3 }; GXAsn1Sequence c1 = new GXAsn1Sequence(); if (AuthorityKeyIdentifier != null) { GXAsn1Context c4 = new GXAsn1Context() { Constructed = false, Index = 0 }; c4.Add(AuthorityKeyIdentifier); c1.Add(c4); s1.Add(GXAsn1Converter.ToByteArray(c1)); } if (AuthorityCertIssuer != null) { GXAsn1Context c2 = new GXAsn1Context(); c2.Index = 1; c1.Add(c2); GXAsn1Context c3 = new GXAsn1Context() { Index = 4 }; c2.Add(c3); c3.Add(GXAsn1Converter.EncodeSubject(AuthorityCertIssuer)); s2.Add(c1); } if (AuthorityCertificationSerialNumber != null) { GXAsn1Context c4 = new GXAsn1Context() { Constructed = false, Index = 2 }; c4.Add(AuthorityCertificationSerialNumber); c1.Add(c4); s1.Add(GXAsn1Converter.ToByteArray(c1)); } } // BasicConstraints s1 = new GXAsn1Sequence(); s1.Add(new GXAsn1ObjectIdentifier(X509CertificateTypeConverter.GetString(Enums.X509CertificateType.BasicConstraints))); seq = new GXAsn1Sequence(); if (BasicConstraints) { //BasicConstraints is critical if it exists. s1.Add(BasicConstraints); } else if (KeyUsage == KeyUsage.None) { throw new Exception("Key usage not present."); } s1.Add(GXAsn1Converter.ToByteArray(seq)); s.Add(s1); s1 = new GXAsn1Sequence(); s1.Add(new GXAsn1ObjectIdentifier(X509CertificateTypeConverter.GetString(Enums.X509CertificateType.KeyUsage))); byte value = 0; int min = 255; byte keyUsage = GXCommon.SwapBits((byte)KeyUsage); foreach (KeyUsage it in Enum.GetValues(typeof(KeyUsage))) { if ((((byte)it) & keyUsage) != 0) { byte val = (byte)it; value |= val; if (val < min) { min = val; } } } int ignore = 0; while ((min >>= 1) != 0) { ++ignore; } byte[] tmp = GXAsn1Converter.ToByteArray(new GXAsn1BitString(new byte[] { (byte)(ignore % 8), value })); s1.Add(tmp); s.Add(s1); GXAsn1Sequence valid = new GXAsn1Sequence(); valid.Add(ValidFrom); valid.Add(ValidTo); GXAsn1ObjectIdentifier alg; if (PublicKey.Scheme == Ecdsa.Enums.Ecc.P256) { alg = new GXAsn1ObjectIdentifier("1.2.840.10045.3.1.7"); } else { alg = new GXAsn1ObjectIdentifier("1.3.132.0.34"); } object[] list; object[] tmp3 = new object[] { new GXAsn1ObjectIdentifier("1.2.840.10045.2.1"), alg }; GXAsn1Context tmp4 = new GXAsn1Context(); tmp4.Index = 3; tmp4.Add(s); object[] tmp2 = new object[] { tmp3, new GXAsn1BitString(PublicKey.RawValue, 0) }; object[] p2; if (SignatureParameters == null) { p2 = new object[] { a }; } else { p2 = new object[] { a, SignatureParameters }; } list = new object[] { p, new GXAsn1Integer(SerialNumber.ToByteArray()), p2, GXAsn1Converter.EncodeSubject(Issuer), valid, GXAsn1Converter.EncodeSubject(Subject), tmp2, tmp4 }; return(list); }
// https://tools.ietf.org/html/rfc5280#section-4.1 private void Init(byte[] data) { rawData = data; GXAsn1Sequence seq = (GXAsn1Sequence)GXAsn1Converter.FromByteArray(data); if (seq.Count != 3) { throw new GXDLMSCertificateException("Invalid Certificate Version. Wrong number of elements in sequence."); } if (!(seq[0] is GXAsn1Sequence)) { PkcsType type = GXAsn1Converter.GetCertificateType(data, seq); switch (type) { case PkcsType.Pkcs8: throw new GXDLMSCertificateException("Invalid Certificate. This is PKCS 8 private key, not x509 certificate."); case PkcsType.Pkcs10: throw new GXDLMSCertificateException("Invalid Certificate. This is PKCS 10 certification requests, not x509 certificate."); } throw new GXDLMSCertificateException("Invalid Certificate Version."); } GXAsn1Sequence reqInfo = (GXAsn1Sequence)seq[0]; if ((reqInfo[0] is GXAsn1Integer)) { throw new GXDLMSCertificateException("Invalid Certificate. DLMS certificate version number must be 3."); } Version = (CertificateVersion)((GXAsn1Context)reqInfo[0])[0]; if (reqInfo[1] is sbyte) { SerialNumber = Convert.ToUInt64(reqInfo[1]); } else { SerialNumber = new BigInteger(((GXAsn1Integer)reqInfo[1]).Value); } string tmp = ((GXAsn1Sequence)reqInfo[2])[0].ToString(); // Signature Algorithm SignatureAlgorithm = HashAlgorithmConverter.FromString(tmp); if (SignatureAlgorithm != HashAlgorithm.Sha256WithEcdsa) { throw new Exception("DLMS certificate must be signed with ecdsa-with-SHA256."); } // Optional. if (((GXAsn1Sequence)reqInfo[2]).Count > 1) { SignatureParameters = ((GXAsn1Sequence)reqInfo[2])[1]; } // Issuer Issuer = GXAsn1Converter.GetSubject((GXAsn1Sequence)reqInfo[3]); bool basicConstraintsExists = false; // Validity ValidFrom = (DateTime)((GXAsn1Sequence)reqInfo[4])[0]; ValidTo = (DateTime)((GXAsn1Sequence)reqInfo[4])[1]; Subject = GXAsn1Converter.GetSubject((GXAsn1Sequence)reqInfo[5]); string CN = X509NameConverter.GetString(X509Name.CN); // Subject public key Info GXAsn1Sequence subjectPKInfo = (GXAsn1Sequence)reqInfo[6]; PublicKey = GXPublicKey.FromRawBytes(((GXAsn1BitString)subjectPKInfo[1]).Value); GXEcdsa.Validate(PublicKey); // Get Standard Extensions. if (reqInfo.Count > 7) { foreach (GXAsn1Sequence s in (GXAsn1Sequence)((GXAsn1Context)reqInfo[7])[0]) { GXAsn1ObjectIdentifier id = (GXAsn1ObjectIdentifier)s[0]; object value = s[1]; X509CertificateType t = X509CertificateTypeConverter.FromString(id.ToString()); switch (t) { case X509CertificateType.SubjectKeyIdentifier: SubjectKeyIdentifier = (byte[])value; break; case X509CertificateType.AuthorityKeyIdentifier: foreach (GXAsn1Context it in (GXAsn1Sequence)value) { switch (it.Index) { case 0: //Authority Key Identifier. AuthorityKeyIdentifier = (byte[])it[0]; break; case 1: { StringBuilder sb = new StringBuilder(); //authorityCertIssuer foreach (KeyValuePair <object, object> it2 in ((GXAsn1Sequence)((GXAsn1Context)it[0])[0])) { if (sb.Length != 0) { sb.Append(", "); } sb.Append(X509NameConverter.FromString(Convert.ToString(it2.Key))); sb.Append("="); sb.Append(Convert.ToString(it2.Value)); } AuthorityCertIssuer = sb.ToString(); } break; case 2: //Authority cert serial number . AuthorityCertificationSerialNumber = (byte[])it[0]; break; default: throw new ArgumentOutOfRangeException("Invalid context." + it.Index); } } break; case X509CertificateType.KeyUsage: if (value is GXAsn1BitString) { // critical is optional. BOOLEAN DEFAULT FALSE, KeyUsage = (KeyUsage)((GXAsn1BitString)value).ToInteger(); } else if (value is bool?) { value = s[2]; KeyUsage = (KeyUsage)((GXAsn1BitString)value).ToInteger(); } else { throw new ArgumentException("Invalid key usage."); } break; case X509CertificateType.BasicConstraints: basicConstraintsExists = true; if (value is GXAsn1Sequence) { if (((GXAsn1Sequence)value).Count != 0) { BasicConstraints = (bool)((GXAsn1Sequence)value)[0]; } } else if (value is bool?) { BasicConstraints = (bool)value; } else { throw new ArgumentException("Invalid key usage."); } break; default: System.Diagnostics.Debug.WriteLine("Unknown extensions: " + t.ToString()); break; } } } if (!basicConstraintsExists) { // Verify that subject Common Name includes system title. bool commonNameFound = false; foreach (KeyValuePair <object, object> it in (GXAsn1Sequence)reqInfo[5]) { if (CN == it.Key.ToString()) { if (Convert.ToString(it.Value).Length != 16) { throw new GXDLMSCertificateException("System title is not included in Common Name."); } commonNameFound = true; break; } } if (!commonNameFound) { throw new GXDLMSCertificateException("Common name doesn't exist."); } } if (KeyUsage == KeyUsage.None) { throw new Exception("Key usage not present. It's mandotory."); } if ((KeyUsage & (KeyUsage.KeyCertSign | KeyUsage.CrlSign)) != 0 && !basicConstraintsExists) { throw new Exception("Basic Constraints value not present. It's mandotory."); } PublicKeyAlgorithm = HashAlgorithmConverter.FromString(((GXAsn1Sequence)seq[1])[0].ToString()); if (PublicKeyAlgorithm != HashAlgorithm.Sha256WithEcdsa) { throw new Exception("DLMS certificate must be signed with ecdsa-with-SHA256."); } // Optional. if (((GXAsn1Sequence)seq[1]).Count > 1) { PublicKeyParameters = ((GXAsn1Sequence)seq[1])[1]; } ///////////////////////////// //Get signature. Signature = ((GXAsn1BitString)seq[2]).Value; }
private object[] GetData() { GXAsn1ObjectIdentifier a = new GXAsn1ObjectIdentifier(HashAlgorithmConverter.GetString(SignatureAlgorithm)); GXAsn1Context p = new GXAsn1Context(); p.Add((sbyte)Version); object subjectPKInfo = GXAsn1Converter.FromByteArray(PublicKey.RawValue); GXAsn1Sequence s = new GXAsn1Sequence(); GXAsn1Sequence s1; if (SubjectKeyIdentifier != null) { s1 = new GXAsn1Sequence(); s1.Add(new GXAsn1ObjectIdentifier(X509CertificateTypeConverter.GetString(Enums.X509CertificateType.SubjectKeyIdentifier))); GXByteBuffer bb = new GXByteBuffer(); bb.SetUInt8(BerType.OctetString); GXCommon.SetObjectCount(SubjectKeyIdentifier.Length, bb); bb.Set(SubjectKeyIdentifier); s1.Add(bb.Array()); s.Add(s1); } if (AuthorityKeyIdentifier != null) { s1 = new GXAsn1Sequence(); s1.Add(new GXAsn1ObjectIdentifier(X509CertificateTypeConverter.GetString(Enums.X509CertificateType.AuthorityKeyIdentifier))); GXAsn1Sequence seq = new GXAsn1Sequence(); seq.Add(AuthorityKeyIdentifier); s1.Add(GXAsn1Converter.ToByteArray(seq)); s.Add(s1); } if (BasicConstraints) { s1 = new GXAsn1Sequence(); s1.Add(new GXAsn1ObjectIdentifier(X509CertificateTypeConverter.GetString(Enums.X509CertificateType.BasicConstraints))); GXAsn1Sequence seq = new GXAsn1Sequence(); seq.Add(BasicConstraints); s1.Add(GXAsn1Converter.ToByteArray(seq)); s.Add(s1); } if (KeyUsage == KeyUsage.None) { throw new Exception("Key usage not present."); } s1 = new GXAsn1Sequence(); s1.Add(new GXAsn1ObjectIdentifier(X509CertificateTypeConverter.GetString(Enums.X509CertificateType.KeyUsage))); byte value = 0; int min = 255; foreach (KeyUsage it in Enum.GetValues(typeof(KeyUsage))) { if ((it & KeyUsage) != 0) { byte val = (byte)it; value |= val; if (val < min) { min = val; } } } int offset = 7; while ((min >>= 2) != 0) { ++offset; } byte[] tmp = GXAsn1Converter.ToByteArray(new GXAsn1BitString(new byte[] { 0, value })); s1.Add(tmp); s.Add(s1); GXAsn1Sequence valid = new GXAsn1Sequence(); valid.Add(ValidFrom); valid.Add(ValidTo); object[] list; if (s.Count == 0) { list = new object[] { p, SerialNumber, new object[] { a, SignatureParameters }, GXAsn1Converter.EncodeSubject(Issuer), valid, GXAsn1Converter.EncodeSubject(Subject), subjectPKInfo }; } else { GXAsn1Context tmp2 = new GXAsn1Context(); tmp2.Index = 3; tmp2.Add(s); list = new object[] { p, SerialNumber, new object[] { a, SignatureParameters }, GXAsn1Converter.EncodeSubject(Issuer), valid, GXAsn1Converter.EncodeSubject(Subject), subjectPKInfo, tmp2 }; } return(list); }
// https://tools.ietf.org/html/rfc5280#section-4.1 private void Init(byte[] data) { GXAsn1Sequence seq = (GXAsn1Sequence)GXAsn1Converter.FromByteArray(data); if (seq.Count != 3) { throw new ArgumentException("Wrong number of elements in sequence."); } GXAsn1Sequence reqInfo = (GXAsn1Sequence)seq[0]; Version = (CertificateVersion)((GXAsn1Context)reqInfo[0])[0]; if (reqInfo[1] is sbyte) { SerialNumber = new GXAsn1Integer(Convert.ToUInt64(reqInfo[1])); } else { SerialNumber = (GXAsn1Integer)reqInfo[1]; } string tmp = ((GXAsn1Sequence)reqInfo[2])[0].ToString(); // Signature Algorithm SignatureAlgorithm = HashAlgorithmConverter.FromString(tmp); if (SignatureAlgorithm != HashAlgorithm.Sha256withecdsa) { throw new Exception("DLMS certificate must be signed with ecdsa-with-SHA256."); } // Optional. if (((GXAsn1Sequence)reqInfo[2]).Count > 1) { SignatureParameters = ((GXAsn1Sequence)reqInfo[2])[1]; } // Issuer Issuer = GXAsn1Converter.GetSubject((GXAsn1Sequence)reqInfo[3]); // Validity ValidFrom = (DateTime)((GXAsn1Sequence)reqInfo[4])[0]; ValidTo = (DateTime)((GXAsn1Sequence)reqInfo[4])[1]; Subject = GXAsn1Converter.GetSubject((GXAsn1Sequence)reqInfo[5]); // Subject public key Info GXAsn1Sequence subjectPKInfo = (GXAsn1Sequence)reqInfo[6]; PublicKey = GXPublicKey.FromRawBytes(((GXAsn1BitString)subjectPKInfo[1]).Value); // Get Standard Extensions. if (reqInfo.Count > 7) { foreach (GXAsn1Sequence s in (GXAsn1Sequence)((GXAsn1Context)reqInfo[7])[0]) { GXAsn1ObjectIdentifier id = (GXAsn1ObjectIdentifier)s[0]; object value = s[1]; Enums.X509CertificateType t = Enums.X509CertificateTypeConverter.FromString(id.ToString()); switch (t) { case Enums.X509CertificateType.SubjectKeyIdentifier: SubjectKeyIdentifier = (byte[])value; break; case Enums.X509CertificateType.AuthorityKeyIdentifier: AuthorityKeyIdentifier = (byte[])((GXAsn1Sequence)value)[0]; break; case Enums.X509CertificateType.KeyUsage: if (value is GXAsn1BitString) { // critical is optional. BOOLEAN DEFAULT FALSE, KeyUsage = (KeyUsage)((GXAsn1BitString)value).Value[0]; } else if (value is bool?) { value = s[2]; KeyUsage = (KeyUsage)((GXAsn1BitString)value).Value[0]; } else { throw new ArgumentException("Invalid key usage."); } break; default: System.Diagnostics.Debug.WriteLine("Unknown extensions: " + t.ToString()); break; } } } if (KeyUsage == KeyUsage.None) { throw new Exception("Key usage not present."); } PublicKeySignature = HashAlgorithmConverter.FromString(((GXAsn1Sequence)seq[1])[0].ToString()); // Optional. if (((GXAsn1Sequence)seq[1]).Count > 1) { SignatureParameters = ((GXAsn1Sequence)seq[1])[1]; } // signature Signature = ((GXAsn1BitString)seq[2]).Value; }