1d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) 2d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 3d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpackage org.xbill.DNS; 4d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 5d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.io.*; 6d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.security.PublicKey; 7d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 8d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.xbill.DNS.utils.*; 9d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 10d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 11d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * The base class for KEY/DNSKEY records, which have identical formats 12d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 13d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @author Brian Wellington 14d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 15d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 16d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenabstract class KEYBase extends Record { 17d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 18d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate static final long serialVersionUID = 3469321722693285454L; 19d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 20d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprotected int flags, proto, alg; 21d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprotected byte [] key; 22d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprotected int footprint = -1; 23d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprotected PublicKey publicKey = null; 24d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 25d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprotected 26d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenKEYBase() {} 27d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 28d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic 29d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenKEYBase(Name name, int type, int dclass, long ttl, int flags, int proto, 30d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int alg, byte [] key) 31d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen{ 32d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen super(name, type, dclass, ttl); 33d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.flags = checkU16("flags", flags); 34d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.proto = checkU8("proto", proto); 35d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.alg = checkU8("alg", alg); 36d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.key = key; 37d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 38d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 39d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenvoid 40d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenrrFromWire(DNSInput in) throws IOException { 41d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen flags = in.readU16(); 42d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen proto = in.readU8(); 43d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen alg = in.readU8(); 44d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (in.remaining() > 0) 45d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen key = in.readByteArray(); 46d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 47d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 48d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** Converts the DNSKEY/KEY Record to a String */ 49d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenString 50d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenrrToString() { 51d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen StringBuffer sb = new StringBuffer(); 52d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sb.append(flags); 53d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sb.append(" "); 54d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sb.append(proto); 55d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sb.append(" "); 56d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sb.append(alg); 57d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (key != null) { 58d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (Options.check("multiline")) { 59d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sb.append(" (\n"); 60d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sb.append(base64.formatString(key, 64, "\t", true)); 61d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sb.append(" ; key_tag = "); 62d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sb.append(getFootprint()); 63d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else { 64d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sb.append(" "); 65d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sb.append(base64.toString(key)); 66d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 67d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 68d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return sb.toString(); 69d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 70d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 71d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 72d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the flags describing the key's properties 73d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 74d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic int 75d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetFlags() { 76d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return flags; 77d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 78d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 79d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 80d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the protocol that the key was created for 81d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 82d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic int 83d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetProtocol() { 84d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return proto; 85d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 86d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 87d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 88d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the key's algorithm 89d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 90d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic int 91d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetAlgorithm() { 92d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return alg; 93d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 94d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 95d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 96d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the binary data representing the key 97d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 98d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic byte [] 99d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetKey() { 100d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return key; 101d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 102d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 103d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 104d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the key's footprint (after computing it) 105d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 106d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic int 107d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetFootprint() { 108d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (footprint >= 0) 109d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return footprint; 110d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 111d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int foot = 0; 112d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 113d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen DNSOutput out = new DNSOutput(); 114d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen rrToWire(out, null, false); 115d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen byte [] rdata = out.toByteArray(); 116d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 117d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (alg == DNSSEC.Algorithm.RSAMD5) { 118d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int d1 = rdata[rdata.length - 3] & 0xFF; 119d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int d2 = rdata[rdata.length - 2] & 0xFF; 120d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen foot = (d1 << 8) + d2; 121d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 122d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else { 123d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int i; 124d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (i = 0; i < rdata.length - 1; i += 2) { 125d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int d1 = rdata[i] & 0xFF; 126d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int d2 = rdata[i + 1] & 0xFF; 127d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen foot += ((d1 << 8) + d2); 128d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 129d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (i < rdata.length) { 130d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int d1 = rdata[i] & 0xFF; 131d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen foot += (d1 << 8); 132d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 133d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen foot += ((foot >> 16) & 0xFFFF); 134d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 135d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen footprint = (foot & 0xFFFF); 136d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return footprint; 137d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 138d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 139d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 140d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns a PublicKey corresponding to the data in this key. 141d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws DNSSEC.DNSSECException The key could not be converted. 142d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 143d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic PublicKey 144d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetPublicKey() throws DNSSEC.DNSSECException { 145d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (publicKey != null) 146d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return publicKey; 147d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 148d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen publicKey = DNSSEC.toPublicKey(this); 149d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return publicKey; 150d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 151d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 152d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenvoid 153d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenrrToWire(DNSOutput out, Compression c, boolean canonical) { 154d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen out.writeU16(flags); 155d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen out.writeU8(proto); 156d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen out.writeU8(alg); 157d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (key != null) 158d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen out.writeByteArray(key); 159d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 160d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 161d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 162