📄 mekeytool.java
字号:
throw new RuntimeException(e.toString()); } } else { name.append(TLV.hexEncode(buffer, value.valueOffset, value.length, -1)); } attribute = attribute.next; } return name.toString(); }}/** * Used to represent each Type, Length, Value structure in a DER buffer. */class TLV { /** ASN context specific flag used in types (0x80). */ static final int CONTEXT = 0x80; /** ASN constructed flag used in types (0x20). */ static final int CONSTRUCTED = 0x20; /** ASN constructed flag used in types (0x20). */ static final int EXPLICIT = CONSTRUCTED; /** ANY_STRING type used as a place holder. [UNIVERSAL 0] */ static final int ANY_STRING_TYPE = 0x00; // our own hack /** ASN BOOLEAN type used in certificate parsing. [UNIVERSAL 1] */ static final int BOOLEAN_TYPE = 1; /** ASN INTEGER type used in certificate parsing. [UNIVERSAL 2] */ static final int INTEGER_TYPE = 2; /** ASN BIT STRING type used in certificate parsing. [UNIVERSAL 3] */ static final int BITSTRING_TYPE = 3; /** ASN OCTET STRING type used in certificate parsing. [UNIVERSAL 4] */ static final int OCTETSTR_TYPE = 4; /** ASN NULL type used in certificate parsing. [UNIVERSAL 5] */ static final int NULL_TYPE = 5; /** ASN OBJECT ID type used in certificate parsing. [UNIVERSAL 6] */ static final int OID_TYPE = 6; /** ASN UTF8String type used in certificate parsing. [UNIVERSAL 12] */ static final int UTF8STR_TYPE = 12; /** * ASN SEQUENCE type used in certificate parsing. * [UNIVERSAL CONSTRUCTED 16] */ static final int SEQUENCE_TYPE = CONSTRUCTED + 16; /** * ASN SET type used in certificate parsing. * [UNIVERSAL CONSTRUCTED 17] */ static final int SET_TYPE = CONSTRUCTED + 17; /** ASN PrintableString type used in certificate parsing. [UNIVERSAL 19] */ static final int PRINTSTR_TYPE = 19; /** ASN TELETEX STRING type used in certificate parsing. [UNIVERSAL 20] */ static final int TELETEXSTR_TYPE = 20; /** ASN IA5 STRING type used in certificate parsing. [UNIVERSAL 22] */ static final int IA5STR_TYPE = 22; // Used for EmailAddress /** ASN UCT time type used in certificate parsing [UNIVERSAL 23] */ static final int UCT_TIME_TYPE = 23; /** * ASN Generalized time type used in certificate parsing. * [UNIVERSAL 24] */ static final int GEN_TIME_TYPE = 24; /** * ASN UniversalString type used in certificate parsing. * [UNIVERSAL 28]. */ static final int UNIVSTR_TYPE = 28; /** ASN BIT STRING type used in certificate parsing. [UNIVERSAL 30] */ static final int BMPSTR_TYPE = 30; /** * Context specific explicit type for certificate version. * [CONTEXT EXPLICIT 0] */ static final int VERSION_TYPE = CONTEXT + EXPLICIT + 0; /** * Context specific explicit type for certificate extensions. * [CONTEXT EXPLICIT 3] */ static final int EXTENSIONS_TYPE = CONTEXT + EXPLICIT + 3; /** * Checks if two byte arrays match. * <P /> * @param a first byte array * @param aOff starting offset for comparison within a * @param aLen number of bytes of a to be compared * @param b second byte array * @param bOff starting offset for comparison within b * @param bLen number of bytes of b to be compared * @return true if aLen == bLen and the sequence of aLen bytes in a * starting at * aOff matches those in b starting at bOff, false otherwise */ static boolean byteMatch(byte[] a, int aOff, int aLen, byte[] b, int bOff, int bLen) { if ((aLen != bLen) || (a.length < aOff + aLen) || (b.length < bOff + bLen)) { return false; } for (int i = 0; i < aLen; i++) { if (a[i + aOff] != b[i + bOff]) { return false; } } return true; } /** * Converts a subsequence of bytes into a printable OID, * a string of decimal digits, each separated by a ".". * * @param buffer byte array containing the bytes to be converted * @param offset starting offset of the byte subsequence inside b * @param length number of bytes to be converted * * @return printable OID */ static String OIDtoString(byte[] buffer, int offset, int length) { StringBuffer result; int end; int t; int x; int y; if (length == 0) { return ""; } result = new StringBuffer(40); end = offset + length; /* * first byte (t) always represents the first 2 values (x, y). * t = (x * 40) + y; */ t = buffer[offset++] & 0xff; x = t / 40; y = t - (x * 40); result.append(x); result.append('.'); result.append(y); x = 0; while (offset < end) { // 7 bit per byte, bit 8 = 0 means the end of a value x = x << 7; t = buffer[offset++]; if (t >= 0) { x += t; result.append('.'); result.append(x); x = 0; } else { x += t & 0x7f; } } return result.toString(); } /** Hexadecimal digits. */ static char[] hc = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; /** * Converts a subsequence of bytes in a byte array into a * corresponding string of hexadecimal digits, each separated by a ":". * * @param b byte array containing the bytes to be converted * @param off starting offset of the byte subsequence inside b * @param len number of bytes to be converted * @param max print a single "+" instead of the bytes after max, * -1 for no max. * @return a string of corresponding hexadecimal digits or * an error string */ static String hexEncode(byte[] b, int off, int len, int max) { char[] r; int v; int i; int j; if ((b == null) || (len == 0)) { return ""; } if ((off < 0) || (len < 0)) { throw new ArrayIndexOutOfBoundsException(); } r = new char[len * 3]; for (i = 0, j = 0; ; ) { v = b[off + i] & 0xff; r[j++] = hc[v >>> 4]; r[j++] = hc[v & 0x0f]; i++; if (i >= len) { break; } if (i == max) { r[j++] = ' '; r[j++] = '+'; break; } r[j++] = ':'; } return (new String(r, 0, j)); } /** Raw DER type. */ int type; /** Number of bytes that make up the value. */ int length; /** Offset of the value. */ int valueOffset; /** Non-null for constructed types, the first child TLV. */ TLV child; /** The next TLV in the parent sequence. */ TLV next; /** * Construct a TLV structure, recursing down for constructed types. * * @param buffer DER buffer * @param offset where to start parsing * * @exception IndexOutOfBoundException if the DER is corrupt */ TLV(byte[] buffer, int offset) { boolean constructed; int size; type = buffer[offset++] & 0xff; // recurse for constructed types, bit 6 = 1 constructed = (type & 0x20) == 0x20; if ((type & 0x1f) == 0x1f) { // multi byte type, 7 bits per byte, only last byte bit 8 as zero type = 0; for (; ; ) { int temp = buffer[offset++]; type = type << 7; if (temp >= 0) { type += temp; break; } // stip off bit 8 temp = temp & 0x7f; type += temp; } } size = buffer[offset++] & 0xff; if (size >= 128) { int sizeLen = size - 128; // NOTE: for now, all sizes must fit int two bytes if (sizeLen > 2) { throw new RuntimeException("TLV size to large"); } size = 0; while (sizeLen > 0) { size = (size << 8) + (buffer[offset++] & 0xff); sizeLen--; } } length = size; valueOffset = offset; if (constructed) { int end; TLV temp; end = offset + length; child = new TLV(buffer, offset); temp = child; for (; ; ) { offset = temp.valueOffset + temp.length; if (offset >= end) { break; } temp.next = new TLV(buffer, offset); temp = temp.next; } } } /** * Print the a TLV structure, recursing down for constructed types. * * @param buffer DER buffer */ void print(byte[] buffer) { print(buffer, 0); } /** * Print the a TLV structure, recursing down for constructed types. * * @param buffer DER buffer * @param level what level this TLV is at */ private void print(byte[] buffer, int level) { for (int i = 0; i < level; i++) { System.out.print(' '); } if (child == null) { System.out.print("Type: 0x" + Integer.toHexString(type) + " length: " + length + " value: "); if (type == PRINTSTR_TYPE || type == TELETEXSTR_TYPE || type == UTF8STR_TYPE || type == IA5STR_TYPE || type == UNIVSTR_TYPE) { try { System.out.print(new String(buffer, valueOffset, length, "UTF-8")); } catch (UnsupportedEncodingException e) { // ignore } } else if (type == OID_TYPE) { System.out.print(OIDtoString(buffer, valueOffset, length)); } else { System.out.print(hexEncode(buffer, valueOffset, length, 14)); } System.out.println(""); } else { if (type == SET_TYPE) { System.out.println("Set:"); } else if (type == VERSION_TYPE) { System.out.println("Version (explicit):"); } else if (type == EXTENSIONS_TYPE) { System.out.println("Extensions (explicit):"); } else { System.out.println("Sequence:"); } child.print(buffer, level + 1); } if (next != null) { next.print(buffer, level); } }}/** * This exception is used to signal a usage error. */class UsageException extends Exception { /** * Constructs a UsageException. */ UsageException() { } /** * Constructs a UsageException. * * @param message exception message */ UsageException(String message) { super(message); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -