/// <summary> /// Encodes public key to a ASN.1 compatible format that includes key algorithm, key algorithm parameters /// and encoded key value. /// </summary> /// <param name="publicKey"></param> /// <returns>ASN.1 encoded byte array.</returns> public static Byte[] Encode(this PublicKey publicKey) { var rawData = new List <Byte>(); rawData.AddRange(new Asn1ObjectIdentifier(publicKey.Oid.Value).RawData); rawData.AddRange(publicKey.EncodedParameters.RawData); rawData.InsertRange(0, Asn1Utils.GetLengthBytes(rawData.Count)); rawData.Insert(0, 48); rawData.AddRange(new Asn1BitString(publicKey.EncodedKeyValue.RawData, false).RawData); return(Asn1Utils.Encode(rawData.ToArray(), 48)); }
// updates binary source (header). // If header length (in bytes) is changed, all child nodes receives new offset // Verified: true void notifyLengthChanged(Int32 difference) { T me = (T)this; Int32 oldHeaderLength = me.HeaderLength; Byte[] newLenBytes = Asn1Utils.GetLengthBytes(me.PayloadLength + difference); me.PayloadLength += difference; // 1 means tag byte. Source.RawData.RemoveRangeSilent(me.Offset + 1, oldHeaderLength - 1); Source.RawData.InsertRangeSilent(me.Offset + 1, newLenBytes); Int32 lenDiff = newLenBytes.Length - (oldHeaderLength - 1); // if (lenDiff != 0 && Parent != null) { Parent.updateOffsetByCaller(me, lenDiff); Parent.notifyLengthChanged(lenDiff); } }
void writeTagHeader(Asn1TreeNode node, String leftPadString) { Asn1Lite value = node.Value; line.Clear(); _headList.Clear(); _headList.Add(value.Tag); _headList.AddRange(Asn1Utils.GetLengthBytes(value.PayloadLength)); // write tag address line.AppendFormat("{0:x4}: ", value.Offset); // pad from line.Append(leftPadString); line.Append(AsnFormatter.BinaryToString(_headList.ToArray(), EncodingType.Hex, EncodingFormat.NOCRLF)); if (line.Length < 48) { Int32 padLeft = 48 - line.Length; line.Append(new String(' ', padLeft)); } line.AppendFormat("; {0} ({1:x} Bytes)", value.TagName, value.PayloadLength); line.Append(nl); _sb.Append(line); }
void notifySizeChanged(Asn1TreeNode source, Int32 difference) { Asn1TreeNode t = this; do { if (t.Children.Count > 0) { // update offset of every node below modified (source) node Int32 callerIndex = t.Children.IndexOf(source); if (callerIndex < 0) { return; } for (Int32 index = callerIndex + 1; index < t.Children.Count; index++) { t.Children[index].updateOffset(difference); } } Byte[] newLenBytes = Asn1Utils.GetLengthBytes(t.Value.PayloadLength + difference); App.Container.Resolve <IDataSource>().RawData.RemoveRange(t.Value.Offset + 1, t.Value.HeaderLength - 1); App.Container.Resolve <IDataSource>().RawData.InsertRange(t.Value.Offset + 1, newLenBytes); // check if extra length byte is added. If so, add this byte to difference variable Int32 diff = newLenBytes.Length - (t.Value.HeaderLength - 1); if (diff != 0) { // shift payload start offset to extra length bytes t.Value.PayloadStartOffset += diff; t.updateOffset(diff); t.Value.Offset -= diff; // TODO this: updateOffset method updates current node as well which is not neccessary } source = t; t = t.Parent; source.Value.PayloadLength += difference; difference += diff; } while (t != null); }