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 }); }
/// <summary> /// Constructor for RSA Public Key (PKCS#1). This is read from PEM file. /// </summary> /// <param name="data">(PKCS#1) Public key. </param> /// public GXAsn1PublicKey(GXAsn1BitString data) { if (data == null) { throw new System.ArgumentException("key"); } GXAsn1Sequence seq = (GXAsn1Sequence)GXAsn1Converter.FromByteArray(data.Value); Init(GXAsn1Converter.ToByteArray(new object[] { seq[0], seq[1] })); }
/// <summary> /// Add ASN1 object to byte buffer. /// </summary> /// <param name="bb">Byte buffer where ANS1 object is serialized. </param> /// <param name="target">ANS1 object </param> /// <returns>Size of object. </returns> private static int GetBytes(GXByteBuffer bb, object target) { GXByteBuffer tmp; string str; int start = bb.Size; int cnt = 0; if (target is GXAsn1Context a) { tmp = new GXByteBuffer(); foreach (object it in a) { cnt += GetBytes(tmp, it); } start = bb.Size; if (a.Constructed) { bb.SetUInt8((byte)((int)BerType.Constructed | (int)BerType.Context | a.Index)); GXCommon.SetObjectCount(cnt, bb); } else { tmp.SetUInt8(0, (byte)((int)BerType.Context | a.Index)); } cnt += bb.Size - start; bb.Set(tmp); return(cnt); } else if (target is object[]) { tmp = new GXByteBuffer(); foreach (object it in (object[])target) { cnt += GetBytes(tmp, it); } start = bb.Size; bb.SetUInt8(BerType.Constructed | BerType.Sequence); GXCommon.SetObjectCount(cnt, bb); cnt += bb.Size - start; bb.Set(tmp); return(cnt); } else if (target is string) { bb.SetUInt8(BerType.PrintableString); GXCommon.SetObjectCount(((string)target).Length, bb); bb.Add(target); } else if (target is sbyte) { bb.SetUInt8((byte)BerType.Integer); GXCommon.SetObjectCount(1, bb); bb.Add(target); } else if (target is short) { bb.SetUInt8((byte)BerType.Integer); GXCommon.SetObjectCount(2, bb); bb.Add(target); } else if (target is int) { bb.SetUInt8((byte)BerType.Integer); GXCommon.SetObjectCount(4, bb); bb.Add(target); } else if (target is GXAsn1Integer) { bb.SetUInt8((byte)BerType.Integer); byte[] b = ((GXAsn1Integer)target).Value; GXCommon.SetObjectCount(b.Length, bb); bb.Add(b); } else if (target is long) { bb.SetUInt8((byte)BerType.Integer); GXCommon.SetObjectCount(8, bb); bb.Add(target); } else if (target is byte[]) { bb.SetUInt8(BerType.OctetString); GXCommon.SetObjectCount(((byte[])target).Length, bb); bb.Add(target); } else if (target == null) { bb.SetUInt8(BerType.Null); GXCommon.SetObjectCount(0, bb); } else if (target is bool) { bb.SetUInt8(BerType.Boolean); bb.SetUInt8(1); if ((bool)target) { bb.SetUInt8(255); } else { bb.SetUInt8(0); } } else if (target is GXAsn1ObjectIdentifier) { bb.SetUInt8(BerType.ObjectIdentifier); byte[] t = ((GXAsn1ObjectIdentifier)target).Encoded; GXCommon.SetObjectCount(t.Length, bb); bb.Add(t); } else if (target is KeyValuePair <object, object> ) { KeyValuePair <object, object> e = (KeyValuePair <object, object>)target; GXByteBuffer tmp2 = new GXByteBuffer(); if (e.Value != null) { tmp = new GXByteBuffer(); cnt += GetBytes(tmp2, e.Key); cnt += GetBytes(tmp2, e.Value); tmp.SetUInt8(BerType.Constructed | BerType.Sequence); GXCommon.SetObjectCount(cnt, tmp); tmp.Set(tmp2); } else { GetBytes(tmp2, (e.Key as List <object>)[0]); tmp = tmp2; } // Update len. cnt = bb.Size; bb.SetUInt8(BerType.Constructed | BerType.Set); GXCommon.SetObjectCount(tmp.Size, bb); bb.Set(tmp); return(bb.Size - cnt); } else if (target is GXAsn1Utf8String) { bb.SetUInt8(BerType.Utf8StringTag); str = target.ToString(); GXCommon.SetObjectCount(str.Length, bb); bb.Add(str); } else if (target is GXAsn1Ia5String) { bb.SetUInt8(BerType.Ia5String); str = target.ToString(); GXCommon.SetObjectCount(str.Length, bb); bb.Add(str); } else if (target is GXAsn1BitString) { GXAsn1BitString bs = (GXAsn1BitString)target; bb.SetUInt8(BerType.BitString); GXCommon.SetObjectCount(1 + bs.Value.Length, bb); bb.SetUInt8((byte)bs.PadBits); bb.Add(bs.Value); } else if (target is GXAsn1PublicKey) { GXAsn1PublicKey bs = (GXAsn1PublicKey)target; bb.SetUInt8(BerType.BitString); // Size is 64 bytes + padding and uncompressed point indicator. GXCommon.SetObjectCount(66, bb); // Add padding. bb.SetUInt8(0); // prefixed with the uncompressed point indicator 04 bb.SetUInt8(4); bb.Add(bs.Value); // Count is type + size + 64 bytes + padding + uncompressed point // indicator. return(68); } else if (target is DateTime) { // Save date time in UTC. bb.SetUInt8(BerType.UtcTime); str = DateToString((DateTime)target); bb.SetUInt8((byte)str.Length); bb.Add(str); } else if (target is GXAsn1Sequence || target is IList) { tmp = new GXByteBuffer(); foreach (object it in (IList)target) { cnt += GetBytes(tmp, it); } start = bb.Size; if (target is GXAsn1Context c) { if (c.Constructed) { bb.SetUInt8((byte)((byte)BerType.Constructed | (byte)BerType.Sequence | c.Index)); } else { bb.SetUInt8((byte)((byte)BerType.Sequence | c.Index)); } } else { bb.SetUInt8(BerType.Constructed | BerType.Sequence); } GXCommon.SetObjectCount(cnt, bb); cnt += bb.Size - start; bb.Set(tmp); return(cnt); } else { throw new ArgumentException("Invalid type: " + target.GetType().ToString()); } return(bb.Size - start); }
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"); } }