/** * Up-convert this to a KeyCertificate * * @throws DataFormatException if cert type != CERTIFICATE_TYPE_KEY * @since 0.9.12 */ public KeyCertificate toKeyCertificate() throws DataFormatException { if (_type != CERTIFICATE_TYPE_KEY) throw new DataFormatException("type"); return new KeyCertificate(this); }
@Override public String toString() { StringBuilder buf = new StringBuilder(64); buf.append("[Certificate: type: Key certificate"); if (_payload == null) { buf.append(" null payload"); } else { buf.append("\n\tCrypto type: ").append(getCryptoTypeCode()); buf.append("\n\tSig type: ").append(getSigTypeCode()) .append(" (").append(getSigType()).append(')'); if (_payload.length > HEADER_LENGTH) buf.append("\n\tKey data: ").append(_payload.length - HEADER_LENGTH).append(" bytes"); } buf.append("]"); return buf.toString(); }
/** * Signing Key extra data, if any. * * @return null if unset or none * @throws UnsupportedOperationException if the sig type is unsupported */ public byte[] getExtraSigningKeyData() { // we assume no crypto key data if (_payload == null || _payload.length <= HEADER_LENGTH) return null; SigType type = getSigType(); if (type == null) throw new UnsupportedOperationException("unknown sig type"); int extra = Math.max(0, type.getPubkeyLen() - 128); if (_payload.length == HEADER_LENGTH + extra) return getExtraKeyData(); byte[] rv = new byte[extra]; System.arraycopy(_payload, HEADER_LENGTH, rv, 0, extra); return rv; }
if (_data == null) throw new IllegalStateException(); SigType newType = kcert.getSigType(); if (_type == newType) return this; return new SigningPublicKey(null, _data); int newLen = newType.getPubkeyLen(); int ctype = kcert.getCryptoTypeCode(); if (ctype == 0) { if (newLen > KEYSIZE_BYTES) sz += newLen - KEYSIZE_BYTES; if (kcert.size() != sz) throw new IllegalArgumentException("Excess data in key certificate"); System.arraycopy(kcert.getPayload(), KeyCertificate.HEADER_LENGTH, newData, _data.length, newLen - _data.length);
@Test public void testFromP256Payload() throws DataFormatException { KeyCertificate cert = new KeyCertificate(P256_PAYLOAD); assertThat(cert.getSigTypeCode(), is(equalTo(SigType.ECDSA_SHA256_P256.getCode()))); assertThat(cert.getCryptoTypeCode(), is(equalTo(EncType.EC_P256.getCode()))); assertThat(cert.getExtraSigningKeyData(), is(nullValue())); }
if (dest == null) throw new IllegalArgumentException("Dest is null"); KeyCertificate c = new KeyCertificate(type); SimpleDataStructure signingKeys[]; try { newdest.setPadding(pad); } else if (len > 128) { System.arraycopy(signingPubKey.getData(), 128, c.getPayload(), KeyCertificate.HEADER_LENGTH, len - 128);
try { KeyCertificate kc = c.toKeyCertificate(); SigType type = kc.getSigType(); if (type == null || !type.isAvailable() || type.getBaseAlgorithm() == SigAlgo.RSA) { failPermanently(d); String stype = (type != null) ? type.toString() : Integer.toString(kc.getSigTypeCode()); if (_log.shouldLog(Log.WARN)) _log.warn("Unsupported sig type " + stype + " for destination " + h); try { KeyCertificate kc = c.toKeyCertificate(); SigType type = kc.getSigType(); if (type == null || !type.isAvailable()) { String stype = (type != null) ? type.toString() : Integer.toString(kc.getSigTypeCode()); _context.banlist().banlistRouterForever(h, "Unsupported signature type " + stype); if (_log.shouldLog(Log.WARN))
/** * @return null if unset or unknown */ public SigType getSigType() { return SigType.getByCode(getSigTypeCode()); }
if (cert.getCertificateType() == Certificate.CERTIFICATE_TYPE_KEY) { KeyCertificate kcert = cert.toKeyCertificate(); SigType type = kcert.getSigType(); try { signingKeys = KeyGenerator.getInstance().generateSigningKeys(type); SigType type = kcert.getSigType(); int len = type.getPubkeyLen(); if (len < 128) { d.setPadding(pad); } else if (len > 128) { System.arraycopy(signingPubKey.getData(), 128, kcert.getPayload(), KeyCertificate.HEADER_LENGTH, len - 128);
/** * Get the portion of this (type 0) SPK that is really padding based on the Key Cert type given, * if any * * @return leading padding length > 0 or null if no padding or type is unknown * @throws IllegalArgumentException if this is already typed to a different type * @since 0.9.12 */ public byte[] getPadding(KeyCertificate kcert) { if (_data == null) throw new IllegalStateException(); SigType newType = kcert.getSigType(); if (_type == newType || newType == null) return null; if (_type != SigType.DSA_SHA1) throw new IllegalStateException("Cannot convert " + _type + " to " + newType); int newLen = newType.getPubkeyLen(); if (newLen >= KEYSIZE_BYTES) return null; int padLen = KEYSIZE_BYTES - newLen; byte[] pad = new byte[padLen]; System.arraycopy(_data, 0, pad, 0, padLen); return pad; }
@Test public void testFromEd25519Payload() throws DataFormatException { KeyCertificate cert = new KeyCertificate(P521_PAYLOAD); assertThat(cert.getSigTypeCode(), is(equalTo(SigType.ECDSA_SHA512_P521.getCode()))); assertThat(cert.getCryptoTypeCode(), is(equalTo(EncType.ELGAMAL_2048.getCode()))); assertThat(cert.getExtraSigningKeyData().length, is(4)); } }
/** * @return null if not set or unknown * @since 0.9.17 */ public SigType getSigType() { if (_certificate == null) return null; if (_certificate.getCertificateType() == Certificate.CERTIFICATE_TYPE_KEY) { try { KeyCertificate kcert = _certificate.toKeyCertificate(); return kcert.getSigType(); } catch (DataFormatException dfe) {} } return SigType.DSA_SHA1; }
/** * Create a destination with the given signature type. * It will have a null certificate for DSA 1024/160 and KeyCertificate otherwise. * This is not bound to the I2PClient, you must supply the data back again * in createSession(). * * Caller must close stream. * * @param destKeyStream location to write out the destination, PrivateKey, and SigningPrivateKey, * format is specified in {@link net.i2p.data.PrivateKeyFile PrivateKeyFile} * @since 0.9.12 */ public Destination createDestination(OutputStream destKeyStream, SigType type) throws I2PException, IOException { Certificate cert; if (type == SigType.DSA_SHA1) { cert = Certificate.NULL_CERT; } else { cert = new KeyCertificate(type); } return createDestination(destKeyStream, cert); }
/** * Only called at startup via LoadRouterInfoJob and RebuildRouterInfoJob. * Not called by periodic RepublishLocalRouterInfoJob. * We don't want to change the cert on the fly as it changes the router hash. * RouterInfo.isHidden() checks the capability, but RouterIdentity.isHidden() checks the cert. * There's no reason to ever add a hidden cert? * * @return the certificate for a new RouterInfo - probably a null cert. * @since 0.9.16 moved from Router */ static Certificate createCertificate(RouterContext ctx, SigningPublicKey spk) { if (spk.getType() != SigType.DSA_SHA1) return new KeyCertificate(spk); if (ctx.getBooleanProperty(Router.PROP_HIDDEN)) return new Certificate(Certificate.CERTIFICATE_TYPE_HIDDEN, null); return Certificate.NULL_CERT; } }
return new KeyCertificate(payload); } catch (DataFormatException dfe) { throw new IllegalArgumentException(dfe);
/** * If null, P256 key, or Ed25519 key cert, return immutable static instance, else create new * @since 0.8.3 */ public static Certificate create(InputStream in) throws DataFormatException, IOException { // EOF will be thrown in next read int type = in.read(); int length = (int) DataHelper.readLong(in, 2); if (type == 0 && length == 0) return NULL_CERT; // from here down roughly the same as readBytes() below if (length == 0) return new Certificate(type, null); byte[] payload = new byte[length]; int read = DataHelper.read(in, payload); if (read != length) throw new DataFormatException("Not enough bytes for the payload (read: " + read + " length: " + length + ')'); if (type == CERTIFICATE_TYPE_KEY) { if (length == 4) { if (Arrays.equals(payload, KeyCertificate.Ed25519_PAYLOAD)) return KeyCertificate.ELG_Ed25519_CERT; if (Arrays.equals(payload, KeyCertificate.ECDSA256_PAYLOAD)) return KeyCertificate.ELG_ECDSA256_CERT; } return new KeyCertificate(payload); } return new Certificate(type, payload); }
SigningPublicKey signingPubKey = (SigningPublicKey) signingKeys[0]; SigningPrivateKey signingPrivKey = (SigningPrivateKey) signingKeys[1]; KeyCertificate cert = new KeyCertificate(signingPubKey); Destination d = new Destination(); d.setPublicKey(pub);