/// <summary> /// Retrieve the node description. /// </summary> /// <param name="pureHexMode">true:Return hex string only; /// false:Convert to more readable string depending on the node tag.</param> /// <returns>string</returns> public string GetDataStr(bool pureHexMode) { const int lineLen = 32; string dataStr = ""; if (pureHexMode) { dataStr = Asn1Util.FormatString(Asn1Util.ToHexString(data), lineLen, 2); } else { switch (tag) { case Asn1Tag.BIT_STRING: dataStr = Asn1Util.FormatString(Asn1Util.ToHexString(data), lineLen, 2); break; case Asn1Tag.OBJECT_IDENTIFIER: Oid xoid = new Oid(); dataStr = xoid.Decode(new MemoryStream(data)); break; case Asn1Tag.RELATIVE_OID: RelativeOid roid = new RelativeOid(); dataStr = roid.Decode(new MemoryStream(data)); break; case Asn1Tag.PRINTABLE_STRING: case Asn1Tag.IA5_STRING: case Asn1Tag.UNIVERSAL_STRING: case Asn1Tag.VISIBLE_STRING: case Asn1Tag.NUMERIC_STRING: case Asn1Tag.UTC_TIME: case Asn1Tag.BMPSTRING: case Asn1Tag.GENERAL_STRING: case Asn1Tag.GENERALIZED_TIME: dataStr = Asn1Util.BytesToString(data); break; case Asn1Tag.UTF8_STRING: UTF8Encoding utf8 = new UTF8Encoding(); dataStr = utf8.GetString(data); break; case Asn1Tag.INTEGER: dataStr = Asn1Util.FormatString(Asn1Util.ToHexString(data), lineLen, 2); break; default: if ((tag & Asn1Tag.TAG_MASK) == 6) // Visible string for certificate { dataStr = Asn1Util.BytesToString(data); } else { dataStr = Asn1Util.FormatString(Asn1Util.ToHexString(data), lineLen, 2); } break; }; } return dataStr; }
/// <summary> /// Get node label string. /// </summary> /// <param name="mask"> /// <code> /// SHOW_OFFSET /// SHOW_DATA /// USE_HEX_OFFSET /// SHOW_TAG_NUMBER /// SHOW_PATH</code> /// </param> /// <returns>string</returns> public string GetLabel(uint mask) { string nodeStr = ""; string dataStr = ""; string offsetStr = ""; if ((mask & TagTextMask.USE_HEX_OFFSET) != 0) { if ((mask & TagTextMask.SHOW_TAG_NUMBER) != 0) offsetStr = String.Format("(0x{0:X2},0x{1:X6},0x{2:X4})", tag, dataOffset, dataLength); else offsetStr = String.Format("(0x{0:X6},0x{1:X4})", dataOffset, dataLength); } else { if ((mask & TagTextMask.SHOW_TAG_NUMBER) != 0) offsetStr = String.Format("({0},{1},{2})", tag, dataOffset, dataLength); else offsetStr = String.Format("({0},{1})", dataOffset, dataLength); } string oid, oidName; switch (tag) { case Asn1Tag.BIT_STRING: if ((mask & TagTextMask.SHOW_OFFSET) != 0) { nodeStr += offsetStr; } nodeStr += " " + TagName + " UnusedBits: " + unusedBits.ToString(); if ((mask & TagTextMask.SHOW_DATA) != 0) { dataStr = Asn1Util.ToHexString(data); nodeStr += ((dataStr.Length>0) ? " : '" + dataStr + "'" : ""); } break; case Asn1Tag.OBJECT_IDENTIFIER: Oid xoid = new Oid(); oid = xoid.Decode(data); oidName = xoid.GetOidName(oid); if ((mask & TagTextMask.SHOW_OFFSET) != 0) { nodeStr += offsetStr; } nodeStr += " " + TagName; nodeStr += " : " + oidName; if ((mask & TagTextMask.SHOW_DATA) != 0) { nodeStr += ((oid.Length>0) ? " : '" + oid + "'" : ""); } break; case Asn1Tag.RELATIVE_OID: RelativeOid roid = new RelativeOid(); oid = roid.Decode(data); oidName = ""; if ((mask & TagTextMask.SHOW_OFFSET) != 0) { nodeStr += offsetStr; } nodeStr += " " + TagName; nodeStr += " : " + oidName; if ((mask & TagTextMask.SHOW_DATA) != 0) { nodeStr += ((oid.Length>0) ? " : '" + oid + "'" : ""); } break; case Asn1Tag.PRINTABLE_STRING: case Asn1Tag.IA5_STRING: case Asn1Tag.UNIVERSAL_STRING: case Asn1Tag.VISIBLE_STRING: case Asn1Tag.NUMERIC_STRING: case Asn1Tag.UTC_TIME: case Asn1Tag.UTF8_STRING: case Asn1Tag.BMPSTRING: case Asn1Tag.GENERAL_STRING: case Asn1Tag.GENERALIZED_TIME: if ((mask & TagTextMask.SHOW_OFFSET) != 0) { nodeStr += offsetStr; } nodeStr += " " + TagName; if ((mask & TagTextMask.SHOW_DATA) != 0) { if ( tag == Asn1Tag.UTF8_STRING ) { UTF8Encoding unicode = new UTF8Encoding(); dataStr = unicode.GetString(data); } else { dataStr = Asn1Util.BytesToString(data); } nodeStr += ((dataStr.Length>0) ? " : '" + dataStr + "'" : ""); } break; case Asn1Tag.INTEGER: if ((mask & TagTextMask.SHOW_OFFSET) != 0) { nodeStr += offsetStr; } nodeStr += " " + TagName; if ((mask & TagTextMask.SHOW_DATA) != 0) { if (data != null && dataLength < 8) { dataStr = Asn1Util.BytesToLong(data).ToString(); } else { dataStr = Asn1Util.ToHexString(data); } nodeStr += ((dataStr.Length>0) ? " : '" + dataStr + "'" : ""); } break; default: if ((mask & TagTextMask.SHOW_OFFSET) != 0) { nodeStr += offsetStr; } nodeStr += " " + TagName; if ((mask & TagTextMask.SHOW_DATA) != 0) { if ((tag & Asn1Tag.TAG_MASK) == 6) // Visible string for certificate { dataStr = Asn1Util.BytesToString(data); } else { dataStr = Asn1Util.ToHexString(data); } nodeStr += ((dataStr.Length>0) ? " : '" + dataStr + "'" : ""); } break; }; if ((mask & TagTextMask.SHOW_PATH) != 0) { nodeStr = "(" + path + ") " + nodeStr; } return nodeStr; }
/// <summary> /// Get the node and all the descendents text description. /// </summary> /// <param name="startNode">starting node.</param> /// <param name="lineLen">line length.</param> /// <returns></returns> public string GetText(Asn1Node startNode, int lineLen) { string nodeStr = ""; string baseLine = ""; string dataStr = ""; const string lStr = " | | | "; string oid, oidName; switch (tag) { case Asn1Tag.BIT_STRING: baseLine = String.Format("{0,6}|{1,6}|{2,7}|{3} {4} UnusedBits:{5} : ", dataOffset, dataLength, lengthFieldBytes, GetIndentStr(startNode), TagName, unusedBits ); dataStr = Asn1Util.ToHexString(data); if (baseLine.Length + dataStr.Length < lineLen) { if (dataStr.Length<1) { nodeStr += baseLine + "\r\n"; } else { nodeStr += baseLine + "'" + dataStr + "'\r\n"; } } else { nodeStr += baseLine + FormatLineHexString( lStr, GetIndentStr(startNode).Length, lineLen, dataStr + "\r\n" ); } break; case Asn1Tag.OBJECT_IDENTIFIER: Oid xoid = new Oid(); oid = xoid.Decode(new MemoryStream(data)); oidName = xoid.GetOidName(oid); nodeStr += String.Format("{0,6}|{1,6}|{2,7}|{3} {4} : {5} [{6}]\r\n", dataOffset, dataLength, lengthFieldBytes, GetIndentStr(startNode), TagName, oidName, oid ); break; case Asn1Tag.RELATIVE_OID: RelativeOid xiod = new RelativeOid(); oid = xiod.Decode(new MemoryStream(data)); oidName = ""; nodeStr += String.Format("{0,6}|{1,6}|{2,7}|{3} {4} : {5} [{6}]\r\n", dataOffset, dataLength, lengthFieldBytes, GetIndentStr(startNode), TagName, oidName, oid ); break; case Asn1Tag.PRINTABLE_STRING: case Asn1Tag.IA5_STRING: case Asn1Tag.UNIVERSAL_STRING: case Asn1Tag.VISIBLE_STRING: case Asn1Tag.NUMERIC_STRING: case Asn1Tag.UTC_TIME: case Asn1Tag.UTF8_STRING: case Asn1Tag.BMPSTRING: case Asn1Tag.GENERAL_STRING: case Asn1Tag.GENERALIZED_TIME: baseLine = String.Format("{0,6}|{1,6}|{2,7}|{3} {4} : ", dataOffset, dataLength, lengthFieldBytes, GetIndentStr(startNode), TagName ); if ( tag == Asn1Tag.UTF8_STRING ) { UTF8Encoding unicode = new UTF8Encoding(); dataStr = unicode.GetString(data); } else { dataStr = Asn1Util.BytesToString(data); } if (baseLine.Length + dataStr.Length < lineLen) { nodeStr += baseLine + "'" + dataStr + "'\r\n"; } else { nodeStr += baseLine + FormatLineString( lStr, GetIndentStr(startNode).Length, lineLen, dataStr) + "\r\n"; } break; case Asn1Tag.INTEGER: if (data != null && dataLength < 8) { nodeStr += String.Format("{0,6}|{1,6}|{2,7}|{3} {4} : {5}\r\n", dataOffset, dataLength, lengthFieldBytes, GetIndentStr(startNode), TagName, Asn1Util.BytesToLong(data).ToString() ); } else { baseLine = String.Format("{0,6}|{1,6}|{2,7}|{3} {4} : ", dataOffset, dataLength, lengthFieldBytes, GetIndentStr(startNode), TagName ); nodeStr += GetHexPrintingStr(startNode, baseLine, lStr, lineLen); } break; default: if ((tag & Asn1Tag.TAG_MASK) == 6) // Visible string for certificate { baseLine = String.Format("{0,6}|{1,6}|{2,7}|{3} {4} : ", dataOffset, dataLength, lengthFieldBytes, GetIndentStr(startNode), TagName ); dataStr = Asn1Util.BytesToString(data); if (baseLine.Length + dataStr.Length < lineLen) { nodeStr += baseLine + "'" + dataStr + "'\r\n"; } else { nodeStr += baseLine + FormatLineString( lStr, GetIndentStr(startNode).Length, lineLen, dataStr) + "\r\n"; } } else { baseLine = String.Format("{0,6}|{1,6}|{2,7}|{3} {4} : ", dataOffset, dataLength, lengthFieldBytes, GetIndentStr(startNode), TagName ); nodeStr += GetHexPrintingStr(startNode, baseLine, lStr, lineLen); } break; }; if (childNodeList.Count >= 0) { nodeStr += GetListStr(startNode, lineLen); } return nodeStr; }
/// <summary> /// Get node by OID. /// </summary> /// <param name="oid">OID.</param> /// <param name="startNode">Starting node.</param> /// <returns>Null or Asn1Node.</returns> static public Asn1Node GetDecendantNodeByOid(string oid, Asn1Node startNode) { Asn1Node retval = null; Oid xoid = new Oid(); for (int i = 0; i<startNode.ChildNodeCount; i++) { Asn1Node childNode = startNode.GetChildNode(i); int tmpTag = childNode.tag & Asn1Tag.TAG_MASK; if (tmpTag == Asn1Tag.OBJECT_IDENTIFIER) { if (oid == xoid.Decode(childNode.Data)) { retval = childNode; break; } } retval = GetDecendantNodeByOid(oid, childNode); if (retval != null) break; } return retval; }
public static bool IsOidStr(string inStr) { bool retval = false; MemoryStream ms = new MemoryStream(); Oid xoid = new Oid(); xoid.Encode(ms, inStr); ms.Close(); retval = true; return retval; }
public static bool EditNode(IWin32Window parent, Asn1Node aNode, bool enableTagEdit, bool pureHexMode) { byte[] val; byte[] data; FormNodeContentEditor ed = new FormNodeContentEditor(); ed.aNode = aNode; MemoryStream ms = new MemoryStream(); ed.checker = FormNodeContentEditor.DataChecker.None; ed.enableTagEdit = enableTagEdit; ed.pureHexMode = pureHexMode; if ( ((aNode.Tag&Asn1Tag.TAG_MASK) == Asn1Tag.BIT_STRING) && (aNode.ChildNodeCount<1)) { ed.panelUnusedBits.Visible = true; ed.textBoxUnusedBits.Text = aNode.UnusedBits.ToString(); } else { ed.panelUnusedBits.Visible = false; } if (pureHexMode) { ed.checker = DataChecker.Hex; ed.ShowDialog(parent); if (!ed.isOK) return false; data = Asn1Util.HexStrToBytes(ed.GetValueStr()); aNode.Data = data; } else { byte[] oidVal; switch (aNode.Tag) { case Asn1Tag.OBJECT_IDENTIFIER: ed.checker = DataChecker.Oid; ed.ShowDialog(parent); if (!ed.isOK) return false; Oid xoid = new Oid(); xoid.Encode(ms, ed.GetValueStr()); ms.Position = 0; oidVal = new byte[ms.Length]; ms.Read(oidVal, 0, (int)ms.Length); ms.Close(); aNode.Data = oidVal; break; case Asn1Tag.RELATIVE_OID: ed.checker = DataChecker.Roid; ed.ShowDialog(parent); if (!ed.isOK) return false; RelativeOid roid = new RelativeOid(); roid.Encode(ms, ed.GetValueStr()); ms.Position = 0; oidVal = new byte[ms.Length]; ms.Read(oidVal, 0, (int)ms.Length); ms.Close(); aNode.Data = oidVal; break; case Asn1Tag.PRINTABLE_STRING: case Asn1Tag.IA5_STRING: case Asn1Tag.UNIVERSAL_STRING: case Asn1Tag.VISIBLE_STRING: case Asn1Tag.NUMERIC_STRING: case Asn1Tag.UTC_TIME: case Asn1Tag.GENERAL_STRING: case Asn1Tag.GENERALIZED_TIME: ed.ShowDialog(parent); if (!ed.isOK) return false; val = Asn1Util.StringToBytes(ed.GetValueStr()); aNode.Data = val; break; case Asn1Tag.UTF8_STRING: ed.ShowDialog(parent); if (!ed.isOK) return false; UTF8Encoding u8 = new UTF8Encoding(false); val = u8.GetBytes(ed.GetValueStr()); aNode.Data = val; break; case Asn1Tag.BMPSTRING: ed.ShowDialog(parent); if (!ed.isOK) return false; byte[] tmpval = Asn1Util.StringToBytes(ed.GetValueStr()); val = new byte[tmpval.Length*2]; for (int i = 0; i<tmpval.Length; i++) { val[i*2] = 0; val[i*2+1] = tmpval[i]; } aNode.Data = val; break; case Asn1Tag.INTEGER: case Asn1Tag.BIT_STRING: ed.checker = DataChecker.Hex; ed.ShowDialog(parent); if (!ed.isOK) return false; aNode.UnusedBits = (byte)(Convert.ToUInt16(ed.textBoxUnusedBits.Text)%8); data = Asn1Util.HexStrToBytes(ed.GetValueStr()); aNode.Data = data; break; default: if ((aNode.Tag & Asn1Tag.TAG_MASK) == 6) // Visible string for certificate { ed.ShowDialog(parent); if (!ed.isOK) return false; val = Asn1Util.StringToBytes(ed.GetValueStr()); aNode.Data = val; } else { ed.checker = DataChecker.Hex; ed.ShowDialog(parent); if (!ed.isOK) return false; data = Asn1Util.HexStrToBytes(ed.GetValueStr()); aNode.Data = data; } break; }; } return true; }
public DistinguishedName(Asn1Node n) { /* Name: * SET * SEQ (attr) * Object Identifier * Printable String || UTF8String */ if (n.MaskedTag == Asn1Tag.SEQUENCE) { for (int i = 0; i < n.ChildNodeCount; i++) { Asn1Node tt = n.GetChildNode(i); if (tt.MaskedTag != Asn1Tag.SET || tt.ChildNodeCount != 1) { throw new InvalidX509Data(); } tt = tt.GetChildNode(0); if (tt.MaskedTag != Asn1Tag.SEQUENCE || tt.ChildNodeCount != 2) { throw new InvalidX509Data(); } Asn1Node oi = tt.GetChildNode(0); Asn1Node txt = tt.GetChildNode(1); if (oi.MaskedTag != Asn1Tag.OBJECT_IDENTIFIER || !( (txt.MaskedTag == Asn1Tag.PRINTABLE_STRING) || (txt.MaskedTag == Asn1Tag.UTF8_STRING) || (txt.MaskedTag == Asn1Tag.IA5_STRING))) { throw new InvalidX509Data(); } var xoid = new LipingShare.LCLib.Asn1Processor.Oid(); string oiName = xoid.Decode(oi.Data); var enc = new System.Text.UTF8Encoding(); switch (oiName) { case "2.5.4.6": // countryName Country = enc.GetString(txt.Data); break; case "2.5.4.10": // organizationName Organization = enc.GetString(txt.Data); break; case "2.5.4.11": // organizationalUnit OrganizationalUnit = enc.GetString(txt.Data); break; case "2.5.4.3": // commonName CommonName = enc.GetString(txt.Data); break; case "2.5.4.5": // serial number SerialNumber = Asn1Util.ToHexString(txt.Data); break; case "2.5.4.46": // dnq Dnq = enc.GetString(txt.Data); break; case "2.5.4.8": // state State = enc.GetString(txt.Data); break; } } } }