package org.bouncycastle.asn1.x500.style;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Vector;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1String;
import org.bouncycastle.asn1.DERObject;
import org.bouncycastle.asn1.DERUniversalString;
import org.bouncycastle.asn1.x500.AttributeTypeAndValue;
import org.bouncycastle.asn1.x500.RDN;
import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.X500NameStyle;
import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Hex;
public class IETFUtils
{
public static RDN[] rDNsFromString(String name, X500NameStyle x500Style)
{
X500NameTokenizer nTok = new X500NameTokenizer(name);
X500NameBuilder builder = new X500NameBuilder(x500Style);
while (nTok.hasMoreTokens())
{
String token = nTok.nextToken();
int index = token.indexOf('=');
if (index == -1)
{
throw new IllegalArgumentException("badly formated directory string");
}
String attr = token.substring(0, index);
String value = token.substring(index + 1);
ASN1ObjectIdentifier oid = x500Style.attrNameToOID(attr);
if (value.indexOf('+') > 0)
{
X500NameTokenizer vTok = new X500NameTokenizer(value, '+');
String v = vTok.nextToken();
Vector oids = new Vector();
Vector values = new Vector();
oids.addElement(oid);
values.addElement(v);
while (vTok.hasMoreTokens())
{
String sv = vTok.nextToken();
int ndx = sv.indexOf('=');
String nm = sv.substring(0, ndx);
String vl = sv.substring(ndx + 1);
oids.addElement(x500Style.attrNameToOID(nm));
values.addElement(vl);
}
builder.addMultiValuedRDN(toOIDArray(oids), toValueArray(values));
}
else
{
builder.addRDN(oid, value);
}
}
return builder.build().getRDNs();
}
private static String[] toValueArray(Vector values)
{
String[] tmp = new String[values.size()];
for (int i = 0; i != tmp.length; i++)
{
tmp[i] = (String)values.elementAt(i);
}
return tmp;
}
private static ASN1ObjectIdentifier[] toOIDArray(Vector oids)
{
ASN1ObjectIdentifier[] tmp = new ASN1ObjectIdentifier[oids.size()];
for (int i = 0; i != tmp.length; i++)
{
tmp[i] = (ASN1ObjectIdentifier)oids.elementAt(i);
}
return tmp;
}
public static ASN1ObjectIdentifier decodeAttrName(
String name,
Hashtable lookUp)
{
if (Strings.toUpperCase(name).startsWith("OID."))
{
return new ASN1ObjectIdentifier(name.substring(4));
}
else if (name.charAt(0) >= '0' && name.charAt(0) <= '9')
{
return new ASN1ObjectIdentifier(name);
}
ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier)lookUp.get(Strings.toLowerCase(name));
if (oid == null)
{
throw new IllegalArgumentException("Unknown object id - " + name + " - passed to distinguished name");
}
return oid;
}
public static ASN1Encodable valueFromHexString(
String str,
int off)
throws IOException
{
str = Strings.toLowerCase(str);
byte[] data = new byte[(str.length() - off) / 2];
for (int index = 0; index != data.length; index++)
{
char left = str.charAt((index * 2) + off);
char right = str.charAt((index * 2) + off + 1);
if (left < 'a')
{
data[index] = (byte)((left - '0') << 4);
}
else
{
data[index] = (byte)((left - 'a' + 10) << 4);
}
if (right < 'a')
{
data[index] |= (byte)(right - '0');
}
else
{
data[index] |= (byte)(right - 'a' + 10);
}
}
return ASN1Object.fromByteArray(data);
}
public static void appendTypeAndValue(
StringBuffer buf,
AttributeTypeAndValue typeAndValue,
Hashtable oidSymbols)
{
String sym = (String)oidSymbols.get(typeAndValue.getType());
if (sym != null)
{
buf.append(sym);
}
else
{
buf.append(typeAndValue.getType().getId());
}
buf.append('=');
buf.append(valueToString(typeAndValue.getValue()));
}
public static String valueToString(ASN1Encodable value)
{
StringBuffer vBuf = new StringBuffer();
if (value instanceof ASN1String && !(value instanceof DERUniversalString))
{
String v = ((ASN1String)value).getString();
if (v.length() > 0 && v.charAt(0) == '#')
{
vBuf.append("\\" + v);
}
else
{
vBuf.append(v);
}
}
else
{
vBuf.append("#" + bytesToString(Hex.encode(value.getDERObject().getDEREncoded())));
}
int end = vBuf.length();
int index = 0;
if (vBuf.length() >= 2 && vBuf.charAt(0) == '\\' && vBuf.charAt(1) == '#')
{
index += 2;
}
while (index != end)
{
if ((vBuf.charAt(index) == ',')
|| (vBuf.charAt(index) == '"')
|| (vBuf.charAt(index) == '\\')
|| (vBuf.charAt(index) == '+')
|| (vBuf.charAt(index) == '=')
|| (vBuf.charAt(index) == '<')
|| (vBuf.charAt(index) == '>')
|| (vBuf.charAt(index) == ';'))
{
vBuf.insert(index, "\\");
index++;
end++;
}
index++;
}
return vBuf.toString();
}
private static String bytesToString(
byte[] data)
{
char[] cs = new char[data.length];
for (int i = 0; i != cs.length; i++)
{
cs[i] = (char)(data[i] & 0xff);
}
return new String(cs);
}
public static String canonicalize(String s)
{
String value = Strings.toLowerCase(s.trim());
if (value.length() > 0 && value.charAt(0) == '#')
{
DERObject obj = decodeObject(value);
if (obj instanceof ASN1String)
{
value = Strings.toLowerCase(((ASN1String)obj).getString().trim());
}
}
value = stripInternalSpaces(value);
return value;
}
private static ASN1Object decodeObject(String oValue)
{
try
{
return ASN1Object.fromByteArray(Hex.decode(oValue.substring(1)));
}
catch (IOException e)
{
throw new IllegalStateException("unknown encoding in name: " + e);
}
}
public static String stripInternalSpaces(
String str)
{
StringBuffer res = new StringBuffer();
if (str.length() != 0)
{
char c1 = str.charAt(0);
res.append(c1);
for (int k = 1; k < str.length(); k++)
{
char c2 = str.charAt(k);
if (!(c1 == ' ' && c2 == ' '))
{
res.append(c2);
}
c1 = c2;
}
}
return res.toString();
}
}