?? ava.java
字號:
if (format == RFC2253) { if (specialChars2253.indexOf((char)c) != -1) { throw new IOException ("Character '" + (char)c + "' in AVA appears without escape"); } } } // add embedded hex bytes before next char if (embeddedHex.size() > 0) { // add space(s) before embedded hex bytes for (int i = 0; i < spaceCount; i++) { temp.append(" "); } spaceCount = 0; String hexString = getEmbeddedHexString(embeddedHex); temp.append(hexString); embeddedHex.clear(); } // check for non-PrintableString chars isPrintableString &= DerValue.isPrintableStringChar((char)c); if (c == ' ' && escape == false) { // do not add non-escaped spaces yet // (non-escaped trailing spaces are ignored) spaceCount++; } else { // add space(s) for (int i = 0; i < spaceCount; i++) { temp.append(" "); } spaceCount = 0; temp.append((char)c); } c = in.read(); leadingChar = false; } while (isTerminator(c, format) == false); if (format == RFC2253 && spaceCount > 0) { throw new IOException("Incorrect AVA RFC2253 format - " + "trailing space must be escaped"); } // add trailing embedded hex bytes if (embeddedHex.size() > 0) { String hexString = getEmbeddedHexString(embeddedHex); temp.append(hexString); embeddedHex.clear(); } // encode as PrintableString unless value contains // non-PrintableString chars if (this.oid.equals(PKCS9Attribute.EMAIL_ADDRESS_OID)) { // EmailAddress must be IA5String return new DerValue(DerValue.tag_IA5String, temp.toString()); } else if (isPrintableString) { return new DerValue(temp.toString()); } else { return new DerValue(DerValue.tag_UTF8String, temp.toString()); } } private static Byte getEmbeddedHexPair(int c1, Reader in) throws IOException { if (hexDigits.indexOf(Character.toUpperCase((char)c1)) >= 0) { int c2 = readChar(in, "unexpected EOF - " + "escaped hex value must include two valid digits"); if (hexDigits.indexOf(Character.toUpperCase((char)c2)) >= 0) { int hi = Character.digit((char)c1, 16); int lo = Character.digit((char)c2, 16); return new Byte((byte)((hi<<4) + lo)); } else { throw new IOException ("escaped hex value must include two valid digits"); } } return null; } private static String getEmbeddedHexString(ArrayList hexList) throws IOException { byte[] hexBytes = new byte[hexList.size()]; for (int i = 0; i < hexList.size(); i++) { hexBytes[i] = ((Byte)hexList.get(i)).byteValue(); } return new String(hexBytes, "UTF8"); } private static boolean isTerminator(int ch, int format) { switch (ch) { case -1: case '+': case ',': return true; case ';': case '>': return format != RFC2253; default: return false; } } private static int readChar(Reader in, String errMsg) throws IOException { int c = in.read(); if (c == -1) { throw new IOException(errMsg); } return c; } private static boolean trailingSpace(Reader in) throws IOException { boolean trailing = false; if (!in.markSupported()) { // oh well return true; } else { // make readAheadLimit huge - // in practice, AVA was passed a StringReader from X500Name, // and StringReader ignores readAheadLimit anyways in.mark(9999); while (true) { int nextChar = in.read(); if (nextChar == -1) { trailing = true; break; } else if (nextChar == ' ') { continue; } else if (nextChar == '\\') { int followingChar = in.read(); if (followingChar != ' ') { trailing = false; break; } } else { trailing = false; break; } } in.reset(); return trailing; } } AVA(DerValue derval) throws IOException { // Individual attribute value assertions are SEQUENCE of two values. // That'd be a "struct" outside of ASN.1. if (derval.tag != DerValue.tag_Sequence) { throw new IOException("AVA not a sequence"); } oid = X500Name.intern(derval.data.getOID()); value = derval.data.getDerValue(); if (derval.data.available() != 0) { throw new IOException("AVA, extra bytes = " + derval.data.available()); } } AVA(DerInputStream in) throws IOException { this(in.getDerValue()); } public boolean equals(Object obj) { if (this == obj) { return true; } if (obj instanceof AVA == false) { return false; } AVA other = (AVA)obj; return this.toRFC2253CanonicalString().equals (other.toRFC2253CanonicalString()); } /** * Returns a hashcode for this AVA. * * @return a hashcode for this AVA. */ public int hashCode() { return toRFC2253CanonicalString().hashCode(); } /* * AVAs are encoded as a SEQUENCE of two elements. */ public void encode(DerOutputStream out) throws IOException { derEncode(out); } /** * DER encode this object onto an output stream. * Implements the <code>DerEncoder</code> interface. * * @param out * the output stream on which to write the DER encoding. * * @exception IOException on encoding error. */ public void derEncode(OutputStream out) throws IOException { DerOutputStream tmp = new DerOutputStream(); DerOutputStream tmp2 = new DerOutputStream(); tmp.putOID(oid); value.encode(tmp); tmp2.write(DerValue.tag_Sequence, tmp); out.write(tmp2.toByteArray()); } private String toKeyword(int format) { return AVAKeyword.getKeyword(oid, format); } /** * Returns a printable form of this attribute, using RFC 1779 * syntax for individual attribute/value assertions. */ public String toString() { return toKeywordValueString(toKeyword(DEFAULT)); } /** * Returns a printable form of this attribute, using RFC 1779 * syntax for individual attribute/value assertions. It only * emits standardised keywords. */ public String toRFC1779String() { return toKeywordValueString(toKeyword(RFC1779)); } /** * Returns a printable form of this attribute, using RFC 2253 * syntax for individual attribute/value assertions. It only * emits standardised keywords. */ public String toRFC2253String() { /* * Section 2.3: The AttributeTypeAndValue is encoded as the string * representation of the AttributeType, followed by an equals character * ('=' ASCII 61), followed by the string representation of the * AttributeValue. The encoding of the AttributeValue is given in * section 2.4. */ StringBuffer typeAndValue = new StringBuffer(100); typeAndValue.append(toKeyword(RFC2253)); typeAndValue.append('='); /* * Section 2.4: Converting an AttributeValue from ASN.1 to a String. * If the AttributeValue is of a type which does not have a string * representation defined for it, then it is simply encoded as an * octothorpe character ('#' ASCII 35) followed by the hexadecimal * representation of each of the bytes of the BER encoding of the X.500 * AttributeValue. This form SHOULD be used if the AttributeType is of * the dotted-decimal form. */ if ((typeAndValue.charAt(0) >= '0' && typeAndValue.charAt(0) <= '9') || !isDerString(value, false)) { byte[] data = null; try { data = value.toByteArray(); } catch (IOException ie) { throw new IllegalArgumentException("DER Value conversion"); } typeAndValue.append('#'); for (int j = 0; j < data.length; j++) { byte b = data[j]; typeAndValue.append(Character.forDigit(0xF & (b >>> 4), 16)); typeAndValue.append(Character.forDigit(0xF & b, 16)); } } else { /* * 2.4 (cont): Otherwise, if the AttributeValue is of a type which * has a string representation, the value is converted first to a * UTF-8 string according to its syntax specification. * * NOTE: this implementation only emits DirectoryStrings of the * types returned by isDerString(). */ String valStr = null; try { valStr = new String(value.getDataBytes(), "UTF8"); } catch (IOException ie) { throw new IllegalArgumentException("DER Value conversion"); } /* * 2.4 (cont): If the UTF-8 string does not have any of the * following characters which need escaping, then that string can be * used as the string representation of the value. * * o a space or "#" character occurring at the beginning of the * string * o a space character occurring at the end of the string * o one of the characters ",", "+", """, "\", "<", ">" or ";" * * Implementations MAY escape other characters. * * NOTE: this implementation also recognizes "=" and "#" as * characters which need escaping. * * If a character to be escaped is one of the list shown above, then * it is prefixed by a backslash ('\' ASCII 92). * * Otherwise the character to be escaped is replaced by a backslash * and two hex digits, which form a single byte in the code of the * character. */ final String escapees = ",=+<>#;\"\\"; StringBuffer sbuffer = new StringBuffer(); for (int i = 0; i < valStr.length(); i++) { char c = valStr.charAt(i); if (DerValue.isPrintableStringChar(c) || escapees.indexOf(c) >= 0) { // escape escapees if (escapees.indexOf(c) >= 0) { sbuffer.append('\\'); } // append printable/escaped char sbuffer.append(c); } else if (debug != null && Debug.isOn("ava")) { // embed non-printable/non-escaped char // as escaped hex pairs for debugging byte[] valueBytes = null; try { valueBytes = Character.toString(c).getBytes("UTF8"); } catch (IOException ie) { throw new IllegalArgumentException ("DER Value conversion"); } for (int j = 0; j < valueBytes.length; j++) { sbuffer.append('\\'); char hexChar = Character.forDigit (0xF & (valueBytes[j] >>> 4), 16); sbuffer.append(Character.toUpperCase(hexChar)); hexChar = Character.forDigit (0xF & (valueBytes[j]), 16); sbuffer.append(Character.toUpperCase(hexChar)); } } else { // append non-printable/non-escaped char sbuffer.append(c); } } char[] chars = sbuffer.toString().toCharArray(); sbuffer = new StringBuffer(); // Find leading and trailing whitespace. int lead; // index of first char that is not leading whitespace for (lead = 0; lead < chars.length; lead++) { if (chars[lead] != ' ' && chars[lead] != '\r') { break; } } int trail; // index of last char that is not trailing whitespace for (trail = chars.length - 1; trail >= 0; trail--) { if (chars[trail] != ' ' && chars[trail] != '\r') { break; } } // escape leading and trailing whitespace for (int i = 0; i < chars.length; i++) { char c = chars[i]; if (i < lead || i > trail) { sbuffer.append('\\'); } sbuffer.append(c); } typeAndValue.append(sbuffer.toString()); } return new String(typeAndValue); } public String toRFC2253CanonicalString() { /* * Section 2.3: The AttributeTypeAndValue is encoded as the string * representation of the AttributeType, followed by an equals character * ('=' ASCII 61), followed by the string representation of the * AttributeValue. The encoding of the AttributeValue is given in * section 2.4. */ StringBuffer typeAndValue = new StringBuffer(40); typeAndValue.append(toKeyword(RFC2253)); typeAndValue.append('='); /* * Section 2.4: Converting an AttributeValue from ASN.1 to a String. * If the AttributeValue is of a type which does not have a string * representation defined for it, then it is simply encoded as an * octothorpe character ('#' ASCII 35) followed by the hexadecimal * representation of each of the bytes of the BER encoding of the X.500 * AttributeValue. This form SHOULD be used if the AttributeType is of * the dotted-decimal form. */ if ((typeAndValue.charAt(0) >= '0' && typeAndValue.charAt(0) <= '9') || !isDerString(value, true)) { byte[] data = null; try { data = value.toByteArray();
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -