1 // Copyright (c) 1999-2004 Brian Wellington (bwelling (at) xbill.org) 2 3 package org.xbill.DNS; 4 5 import java.io.*; 6 import org.xbill.DNS.utils.*; 7 8 /** 9 * Certificate Record - Stores a certificate associated with a name. The 10 * certificate might also be associated with a KEYRecord. 11 * @see KEYRecord 12 * 13 * @author Brian Wellington 14 */ 15 16 public class CERTRecord extends Record { 17 18 public static class CertificateType { 19 /** Certificate type identifiers. See RFC 4398 for more detail. */ 20 21 private CertificateType() {} 22 23 /** PKIX (X.509v3) */ 24 public static final int PKIX = 1; 25 26 /** Simple Public Key Infrastructure */ 27 public static final int SPKI = 2; 28 29 /** Pretty Good Privacy */ 30 public static final int PGP = 3; 31 32 /** URL of an X.509 data object */ 33 public static final int IPKIX = 4; 34 35 /** URL of an SPKI certificate */ 36 public static final int ISPKI = 5; 37 38 /** Fingerprint and URL of an OpenPGP packet */ 39 public static final int IPGP = 6; 40 41 /** Attribute Certificate */ 42 public static final int ACPKIX = 7; 43 44 /** URL of an Attribute Certificate */ 45 public static final int IACPKIX = 8; 46 47 /** Certificate format defined by URI */ 48 public static final int URI = 253; 49 50 /** Certificate format defined by OID */ 51 public static final int OID = 254; 52 53 private static Mnemonic types = new Mnemonic("Certificate type", 54 Mnemonic.CASE_UPPER); 55 56 static { 57 types.setMaximum(0xFFFF); 58 types.setNumericAllowed(true); 59 60 types.add(PKIX, "PKIX"); 61 types.add(SPKI, "SPKI"); 62 types.add(PGP, "PGP"); 63 types.add(PKIX, "IPKIX"); 64 types.add(SPKI, "ISPKI"); 65 types.add(PGP, "IPGP"); 66 types.add(PGP, "ACPKIX"); 67 types.add(PGP, "IACPKIX"); 68 types.add(URI, "URI"); 69 types.add(OID, "OID"); 70 } 71 72 /** 73 * Converts a certificate type into its textual representation 74 */ 75 public static String 76 string(int type) { 77 return types.getText(type); 78 } 79 80 /** 81 * Converts a textual representation of an certificate type into its 82 * numeric code. Integers in the range 0..65535 are also accepted. 83 * @param s The textual representation of the algorithm 84 * @return The algorithm code, or -1 on error. 85 */ 86 public static int 87 value(String s) { 88 return types.getValue(s); 89 } 90 } 91 92 /** PKIX (X.509v3) */ 93 public static final int PKIX = CertificateType.PKIX; 94 95 /** Simple Public Key Infrastructure */ 96 public static final int SPKI = CertificateType.SPKI; 97 98 /** Pretty Good Privacy */ 99 public static final int PGP = CertificateType.PGP; 100 101 /** Certificate format defined by URI */ 102 public static final int URI = CertificateType.URI; 103 104 /** Certificate format defined by IOD */ 105 public static final int OID = CertificateType.OID; 106 107 private static final long serialVersionUID = 4763014646517016835L; 108 109 private int certType, keyTag; 110 private int alg; 111 private byte [] cert; 112 113 CERTRecord() {} 114 115 Record 116 getObject() { 117 return new CERTRecord(); 118 } 119 120 /** 121 * Creates a CERT Record from the given data 122 * @param certType The type of certificate (see constants) 123 * @param keyTag The ID of the associated KEYRecord, if present 124 * @param alg The algorithm of the associated KEYRecord, if present 125 * @param cert Binary data representing the certificate 126 */ 127 public 128 CERTRecord(Name name, int dclass, long ttl, int certType, int keyTag, 129 int alg, byte [] cert) 130 { 131 super(name, Type.CERT, dclass, ttl); 132 this.certType = checkU16("certType", certType); 133 this.keyTag = checkU16("keyTag", keyTag); 134 this.alg = checkU8("alg", alg); 135 this.cert = cert; 136 } 137 138 void 139 rrFromWire(DNSInput in) throws IOException { 140 certType = in.readU16(); 141 keyTag = in.readU16(); 142 alg = in.readU8(); 143 cert = in.readByteArray(); 144 } 145 146 void 147 rdataFromString(Tokenizer st, Name origin) throws IOException { 148 String certTypeString = st.getString(); 149 certType = CertificateType.value(certTypeString); 150 if (certType < 0) 151 throw st.exception("Invalid certificate type: " + 152 certTypeString); 153 keyTag = st.getUInt16(); 154 String algString = st.getString(); 155 alg = DNSSEC.Algorithm.value(algString); 156 if (alg < 0) 157 throw st.exception("Invalid algorithm: " + algString); 158 cert = st.getBase64(); 159 } 160 161 /** 162 * Converts rdata to a String 163 */ 164 String 165 rrToString() { 166 StringBuffer sb = new StringBuffer(); 167 sb.append (certType); 168 sb.append (" "); 169 sb.append (keyTag); 170 sb.append (" "); 171 sb.append (alg); 172 if (cert != null) { 173 if (Options.check("multiline")) { 174 sb.append(" (\n"); 175 sb.append(base64.formatString(cert, 64, "\t", true)); 176 } else { 177 sb.append(" "); 178 sb.append(base64.toString(cert)); 179 } 180 } 181 return sb.toString(); 182 } 183 184 /** 185 * Returns the type of certificate 186 */ 187 public int 188 getCertType() { 189 return certType; 190 } 191 192 /** 193 * Returns the ID of the associated KEYRecord, if present 194 */ 195 public int 196 getKeyTag() { 197 return keyTag; 198 } 199 200 /** 201 * Returns the algorithm of the associated KEYRecord, if present 202 */ 203 public int 204 getAlgorithm() { 205 return alg; 206 } 207 208 /** 209 * Returns the binary representation of the certificate 210 */ 211 public byte [] 212 getCert() { 213 return cert; 214 } 215 216 void 217 rrToWire(DNSOutput out, Compression c, boolean canonical) { 218 out.writeU16(certType); 219 out.writeU16(keyTag); 220 out.writeU8(alg); 221 out.writeByteArray(cert); 222 } 223 224 } 225