use of net.i2p.data.SigningPublicKey in project i2p.i2p by i2p.
the class BlocklistEntries method verify.
public synchronized boolean verify(I2PAppContext ctx) {
if (verified)
return true;
if (signer == null || sig == null || supdated == null)
return false;
if (updated > ctx.clock().now() + MAX_FUTURE)
return false;
Log log = ctx.logManager().getLog(BlocklistEntries.class);
String[] ss = DataHelper.split(sig, ":", 2);
if (ss.length != 2) {
log.error("blocklist feed bad sig: " + sig);
return false;
}
SigType type = SigType.parseSigType(ss[0]);
if (type == null) {
log.error("blocklist feed bad sig: " + sig);
return false;
}
if (!type.isAvailable()) {
log.error("blocklist feed sigtype unavailable: " + sig);
return false;
}
byte[] bsig = Base64.decode(ss[1]);
if (bsig == null) {
log.error("blocklist feed bad sig: " + sig);
return false;
}
Signature ssig;
try {
ssig = new Signature(type, bsig);
} catch (IllegalArgumentException iae) {
log.error("blocklist feed bad sig: " + sig);
return false;
}
// look in both install dir and config dir for the signer cert
KeyRing ring = new DirKeyRing(new File(ctx.getBaseDir(), "certificates"));
PublicKey pubkey;
try {
pubkey = ring.getKey(signer, CONTENT_ROUTER, type);
} catch (IOException ioe) {
log.error("blocklist feed error", ioe);
return false;
} catch (GeneralSecurityException gse) {
log.error("blocklist feed error", gse);
return false;
}
if (pubkey == null) {
boolean diff = true;
try {
diff = !ctx.getBaseDir().getCanonicalPath().equals(ctx.getConfigDir().getCanonicalPath());
} catch (IOException ioe) {
}
if (diff) {
ring = new DirKeyRing(new File(ctx.getConfigDir(), "certificates"));
try {
pubkey = ring.getKey(signer, CONTENT_ROUTER, type);
} catch (IOException ioe) {
log.error("blocklist feed error", ioe);
return false;
} catch (GeneralSecurityException gse) {
log.error("blocklist feed error", gse);
return false;
}
}
if (pubkey == null) {
log.error("unknown signer for blocklist feed: " + signer);
return false;
}
}
SigningPublicKey spubkey;
try {
spubkey = SigUtil.fromJavaKey(pubkey, type);
} catch (GeneralSecurityException gse) {
log.error("blocklist feed bad sig: " + sig, gse);
return false;
}
StringBuilder buf = new StringBuilder(256);
buf.append(supdated).append('\n');
for (String s : entries) {
buf.append(s).append('\n');
}
for (String s : removes) {
buf.append('!').append(s).append('\n');
}
byte[] data = DataHelper.getUTF8(buf.toString());
boolean rv = ctx.dsa().verifySignature(ssig, data, spubkey);
if (rv)
log.info("blocklist feed sig ok");
else
log.error("blocklist feed sig verify fail: " + signer);
verified = rv;
return rv;
}
use of net.i2p.data.SigningPublicKey in project i2p.i2p by i2p.
the class PluginUpdateRunner method processSUD.
/**
* @since 0.9.15
* @return success
*/
private void processSUD(File f, File appDir, String url) {
TrustedUpdate up = new TrustedUpdate(_context);
File to = new File(_context.getTempDir(), "tmp" + _context.random().nextInt() + ZIP);
// extract to a zip file whether the sig is good or not, so we can get the properties file
String err = up.migrateFile(f, to);
if (err != null) {
statusDone("<b>" + err + ' ' + _t("from {0}", url) + " </b>");
f.delete();
to.delete();
return;
}
Properties props = getPluginConfig(f, to, url);
if (props == null)
return;
// ok, now we check sigs and deal with a bad sig
String pubkey = props.getProperty("key");
String signer = DataHelper.stripHTML(props.getProperty("signer"));
if (pubkey == null || signer == null || pubkey.length() != 172 || signer.length() <= 0) {
f.delete();
to.delete();
// updateStatus("<b>" + "Plugin contains an invalid key" + ' ' + pubkey + ' ' + signer + "</b>");
statusDone("<b>" + _t("Plugin from {0} contains an invalid key", url) + "</b>");
return;
}
SigningPublicKey spk;
try {
spk = new SigningPublicKey(pubkey);
} catch (DataFormatException dfe) {
f.delete();
to.delete();
statusDone("<b>" + _t("Plugin from {0} contains an invalid key", url) + "</b>");
return;
}
// add all existing plugin keys, so any conflicts with existing keys
// will be discovered and rejected
Map<String, String> existingKeys = PluginStarter.getPluginKeys(_context);
for (Map.Entry<String, String> e : existingKeys.entrySet()) {
// ignore dups/bad keys
up.addKey(e.getKey(), e.getValue());
}
// add all trusted plugin keys, so any conflicts with trusted keys
// will be discovered and rejected
Map<String, String> trustedKeys = TrustedPluginKeys.getKeys();
for (Map.Entry<String, String> e : trustedKeys.entrySet()) {
// ignore dups/bad keys
up.addKey(e.getKey(), e.getValue());
}
if (up.haveKey(pubkey)) {
// the key is already in the TrustedUpdate keyring
// verify the sig and verify that it is signed by the signer in the plugin.config file
// Allow "" as the previously-known signer
boolean ok = up.verify(f, spk);
String signingKeyName = up.getKeys().get(spk);
if ((!ok) || !(signer.equals(signingKeyName) || "".equals(signingKeyName))) {
f.delete();
to.delete();
if (signingKeyName == null)
_log.error("Failed to verify plugin signature, corrupt plugin or bad signature, signed by: " + signer);
else
_log.error("Plugin signer \"" + signer + "\" does not match existing signer in plugin.config file \"" + signingKeyName + "\"");
statusDone("<b>" + _t("Plugin signature verification of {0} failed", url) + "</b>");
return;
}
} else if (_context.getBooleanProperty(PROP_ALLOW_NEW_KEYS)) {
// add to keyring...
if (!up.addKey(pubkey, signer)) {
// bad or duplicate key
f.delete();
to.delete();
_log.error("Bad key or key mismatch - Failed to add plugin key \"" + pubkey + "\" for plugin signer \"" + signer + "\"");
statusDone("<b>" + _t("Plugin signature verification of {0} failed", url) + "</b>");
return;
}
// ...and try the verify again
// verify the sig and verify that it is signed by the signer in the plugin.config file
String signingKeyName = up.verifyAndGetSigner(f);
if (!signer.equals(signingKeyName)) {
f.delete();
to.delete();
if (signingKeyName == null)
_log.error("Failed to verify plugin signature, corrupt plugin or bad signature, signed by: " + signer);
else
// shouldn't happen
_log.error("Plugin signer \"" + signer + "\" does not match new signer in plugin.config file \"" + signingKeyName + "\"");
statusDone("<b>" + _t("Plugin signature verification of {0} failed", url) + "</b>");
return;
}
} else {
// unknown key
f.delete();
to.delete();
_log.error("Untrusted plugin key \"" + pubkey + "\" for plugin signer \"" + signer + "\"");
// don't display signer, we're really checking the key not the signer name
statusDone("<b>" + _t("Plugin not installed - signer is untrusted") + "</b>");
return;
}
String sudVersion = TrustedUpdate.getVersionString(f);
f.delete();
processFinal(to, appDir, url, props, sudVersion, pubkey, signer);
}
use of net.i2p.data.SigningPublicKey in project i2p.i2p by i2p.
the class SelfSignedGenerator method renew.
/**
* @param cert the old cert to be replaced
* @param jpriv the private key
*
* @return length 4 array:
* rv[0] is a Java PublicKey, from cert as passed in
* rv[1] is a Java PrivateKey, jpriv as passed in
* rv[2] is a Java X509Certificate, new one
* rv[3] is a Java X509CRL, new one
*
* @since 0.9.34 added altNames param
*/
public static Object[] renew(X509Certificate cert, PrivateKey jpriv, int validDays) throws GeneralSecurityException {
String cname = CertUtil.getSubjectValue(cert, "CN");
if (cname == null)
cname = "localhost";
String ou = CertUtil.getSubjectValue(cert, "OU");
String o = CertUtil.getSubjectValue(cert, "O");
String l = CertUtil.getSubjectValue(cert, "L");
String st = CertUtil.getSubjectValue(cert, "ST");
String c = CertUtil.getSubjectValue(cert, "C");
Set<String> altNames = CertUtil.getSubjectAlternativeNames(cert);
SigningPrivateKey priv = SigUtil.fromJavaKey(jpriv);
SigType type = priv.getType();
SigningPublicKey pub = KeyGenerator.getSigningPublicKey(priv);
PublicKey jpub = SigUtil.toJavaKey(pub);
if (type == null)
throw new GeneralSecurityException("Unsupported: " + jpriv);
return generate(jpub, jpriv, priv, type, cname, altNames, ou, o, l, st, c, validDays);
}
use of net.i2p.data.SigningPublicKey in project i2p.i2p by i2p.
the class I2PClientImpl method createDestination.
/**
* Create the destination with the given payload and write it out along with
* the PrivateKey and SigningPrivateKey to the destKeyStream
*
* If cert is a KeyCertificate, the signing keypair will be of the specified type.
* The KeyCertificate data must be .............................
* The padding if any will be randomized. The extra key data if any will be set in the
* key cert.
*
* 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}
*/
public Destination createDestination(OutputStream destKeyStream, Certificate cert) throws I2PException, IOException {
Destination d = new Destination();
Object[] keypair = KeyGenerator.getInstance().generatePKIKeypair();
PublicKey publicKey = (PublicKey) keypair[0];
PrivateKey privateKey = (PrivateKey) keypair[1];
SimpleDataStructure[] signingKeys;
if (cert.getCertificateType() == Certificate.CERTIFICATE_TYPE_KEY) {
KeyCertificate kcert = cert.toKeyCertificate();
SigType type = kcert.getSigType();
try {
signingKeys = KeyGenerator.getInstance().generateSigningKeys(type);
} catch (GeneralSecurityException gse) {
throw new I2PException("keygen fail", gse);
}
} else {
signingKeys = KeyGenerator.getInstance().generateSigningKeys();
}
SigningPublicKey signingPubKey = (SigningPublicKey) signingKeys[0];
SigningPrivateKey signingPrivKey = (SigningPrivateKey) signingKeys[1];
d.setPublicKey(publicKey);
d.setSigningPublicKey(signingPubKey);
if (cert.getCertificateType() == Certificate.CERTIFICATE_TYPE_KEY) {
// fix up key certificate or padding
KeyCertificate kcert = cert.toKeyCertificate();
SigType type = kcert.getSigType();
int len = type.getPubkeyLen();
if (len < 128) {
byte[] pad = new byte[128 - len];
RandomSource.getInstance().nextBytes(pad);
d.setPadding(pad);
} else if (len > 128) {
System.arraycopy(signingPubKey.getData(), 128, kcert.getPayload(), KeyCertificate.HEADER_LENGTH, len - 128);
}
}
d.setCertificate(cert);
d.writeBytes(destKeyStream);
privateKey.writeBytes(destKeyStream);
signingPrivKey.writeBytes(destKeyStream);
destKeyStream.flush();
return d;
}
use of net.i2p.data.SigningPublicKey in project i2p.i2p by i2p.
the class DSAEngine method altVerifySig.
/**
* Generic verify any type.
*
* @throws GeneralSecurityException if algorithm unvailable or on other errors
* @since 0.9.9 added off/len 0.9.12
*/
private boolean altVerifySig(Signature signature, byte[] data, int offset, int len, SigningPublicKey verifyingKey) throws GeneralSecurityException {
SigType type = signature.getType();
if (type != verifyingKey.getType())
throw new IllegalArgumentException("type mismatch sig=" + type + " key=" + verifyingKey.getType());
if (type == SigType.DSA_SHA1)
return altVerifySigSHA1(signature, data, offset, len, verifyingKey);
PublicKey pubKey = SigUtil.toJavaKey(verifyingKey);
byte[] sigbytes = SigUtil.toJavaSig(signature);
boolean rv;
if (type.getBaseAlgorithm() == SigAlgo.EdDSA) {
// take advantage of one-shot mode
EdDSAEngine jsig = new EdDSAEngine(type.getDigestInstance());
jsig.initVerify(pubKey);
rv = jsig.verifyOneShot(data, offset, len, sigbytes);
} else {
java.security.Signature jsig = java.security.Signature.getInstance(type.getAlgorithmName());
jsig.initVerify(pubKey);
jsig.update(data, offset, len);
rv = jsig.verify(sigbytes);
}
return rv;
}
Aggregations