/// <summary> /// Декодируем из байтового массива в формате ASN1 /// </summary> /// <param name="baAsn1">Байтовый массив в формате ASN1</param> /// <returns>Текстовое представление пакета ASN1</returns> public string DecodeFromAsn1(byte[] baAsn1) { var memoryStream = new MemoryStream(baAsn1); using (var berReader = new BerReader(memoryStream)) { //Формируем маркант try { var node = berReader.ReadToEnd().ChildNodes[0]; string result = ""; foreach (var childNode in node.ChildNodes) { result = berReader.PrintStructure(childNode, result, 1, true); } Version = (int)node.ChildNodes[0].ReadContentAsBigInteger(); SessionKey = node.ChildNodes[1].RawValue; IV = node.ChildNodes[2].RawValue; PublicKey = node.ChildNodes[3].RawValue; return(result); } catch (Exception e) { throw new Exception("Invalid markant format", e); } } }
/// <summary> /// Load ASN.1 object in form of a stream, parse it and display its structure. /// </summary> /// <param name="asn1Content">ASN.1 object to parse.</param> public void LoadContent(Stream asn1Content) { // clear any existing nodes Nodes.Clear(); // use parser to get the structure using (var reader = new BerReader(asn1Content)) { var rootNode = new InternalNode(); try { // read whole object. This may fail if there is no valid ASN.1 object in the stream. rootNode = reader.ReadToEnd(ReadContent); } catch (Exception ex) { // something went wrong when reading file. Possibly it was not an ASN.1 object. Trace.WriteLine(String.Format("Parsing exception: {0}", ex)); var safetyNode = new Asn1TreeNode(null, "Invalid ASN.1 structure."); Nodes.Add(safetyNode); } // reader does not parse encapsulated data. Do it manually. foreach (InternalNode internalNode in rootNode.ChildNodes) { // This will enrich list of nodes with additional nodes parsed out of values of Primitive ASN.1 nodes if (EncapsulatedDataParsing) { ParseEncapsulatedData(internalNode); } // build tree from list of ASN.1 nodes var rootTreeNode = new Asn1TreeNode(internalNode); MakeTreeNode(rootTreeNode, internalNode, 1, EncapsulatedDataParsing); Nodes.Add(rootTreeNode); } } // expand tree ExpandAll(); SelectedNode = Nodes[0]; }
/// <summary> /// Method will parse value of given node for existing ASN.1 objects. /// </summary> /// <param name="innerNode">Node to parse.</param> internal static void ParseEncapsulatedData(InternalNode innerNode) { if (innerNode.NodeType != Asn1NodeType.Primitive) { return; } if (innerNode.RawValue == null) { return; // nothing to parse } // for now, only BIT STRING or OCTET STRING may contain encapsulated data if (innerNode.Identifier.Tag != Asn1Type.BitString && innerNode.Identifier.Tag != Asn1Type.OctetString) { return; } byte[] dataToParse = innerNode.RawValue; if (innerNode.Identifier.Tag == Asn1Type.BitString) { dataToParse = innerNode.ReadContentAsBitString(); } // Reader will close the stream when it is done parsing var memStream = new MemoryStream(dataToParse); using (var innerReader = new BerReader(memStream)) { try { InternalNode innerRootNode = innerReader.ReadToEnd(true); innerNode.ChildNodes.AddRange(innerRootNode.ChildNodes); } catch (Exception) { // nothing to do. Value of primitive node did not contain valid ASN.1 structure. } } }
/// <summary> /// Формирует строка со структурным представлением байтового массива в формате ASN1 /// </summary> /// <param name="baAsn1">Байтовый массив в формате ASN1</param> /// <returns>Строка с текстовым представлением байтового массива в формате ASN1</returns> public static string PrintFromAsn1(byte[] baAsn1) { var memoryStream = new MemoryStream(baAsn1); using (var berReader = new BerReader(memoryStream)) { //Формируем текстовое представление марканта try { var node = berReader.ReadToEnd().ChildNodes[0]; string result = "ASN1:"; foreach (var childNode in node.ChildNodes) { result = berReader.PrintStructure(childNode, result, 1, true); } return(result); } catch (Exception e) { throw new Exception("Invalid ASN format", e); } } }