Search in sources :

Example 1 with SigningPublicKey

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;
}
Also used : SigningPublicKey(net.i2p.data.SigningPublicKey) Log(net.i2p.util.Log) PublicKey(java.security.PublicKey) SigningPublicKey(net.i2p.data.SigningPublicKey) GeneralSecurityException(java.security.GeneralSecurityException) IOException(java.io.IOException) SigType(net.i2p.crypto.SigType) DirKeyRing(net.i2p.crypto.DirKeyRing) KeyRing(net.i2p.crypto.KeyRing) DirKeyRing(net.i2p.crypto.DirKeyRing) Signature(net.i2p.data.Signature) File(java.io.File)

Example 2 with SigningPublicKey

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);
}
Also used : SigningPublicKey(net.i2p.data.SigningPublicKey) DataFormatException(net.i2p.data.DataFormatException) TrustedUpdate(net.i2p.crypto.TrustedUpdate) OrderedProperties(net.i2p.util.OrderedProperties) Properties(java.util.Properties) SecureFile(net.i2p.util.SecureFile) SU3File(net.i2p.crypto.SU3File) File(java.io.File) Map(java.util.Map)

Example 3 with SigningPublicKey

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);
}
Also used : SigningPrivateKey(net.i2p.data.SigningPrivateKey) SigningPublicKey(net.i2p.data.SigningPublicKey) SigningPublicKey(net.i2p.data.SigningPublicKey) PublicKey(java.security.PublicKey) DHPublicKey(javax.crypto.interfaces.DHPublicKey) GeneralSecurityException(java.security.GeneralSecurityException)

Example 4 with SigningPublicKey

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;
}
Also used : I2PException(net.i2p.I2PException) Destination(net.i2p.data.Destination) SigningPublicKey(net.i2p.data.SigningPublicKey) PrivateKey(net.i2p.data.PrivateKey) SigningPrivateKey(net.i2p.data.SigningPrivateKey) SigningPublicKey(net.i2p.data.SigningPublicKey) PublicKey(net.i2p.data.PublicKey) GeneralSecurityException(java.security.GeneralSecurityException) SigType(net.i2p.crypto.SigType) SigningPrivateKey(net.i2p.data.SigningPrivateKey) KeyCertificate(net.i2p.data.KeyCertificate) SimpleDataStructure(net.i2p.data.SimpleDataStructure)

Example 5 with SigningPublicKey

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;
}
Also used : EdDSAEngine(net.i2p.crypto.eddsa.EdDSAEngine) PublicKey(java.security.PublicKey) SigningPublicKey(net.i2p.data.SigningPublicKey)

Aggregations

SigningPublicKey (net.i2p.data.SigningPublicKey)36 SigningPrivateKey (net.i2p.data.SigningPrivateKey)13 IOException (java.io.IOException)12 DataFormatException (net.i2p.data.DataFormatException)11 SigType (net.i2p.crypto.SigType)10 Signature (net.i2p.data.Signature)10 PublicKey (net.i2p.data.PublicKey)9 File (java.io.File)8 GeneralSecurityException (java.security.GeneralSecurityException)8 PublicKey (java.security.PublicKey)7 PrivateKey (net.i2p.data.PrivateKey)6 SimpleDataStructure (net.i2p.data.SimpleDataStructure)6 BigInteger (java.math.BigInteger)5 ECPoint (java.security.spec.ECPoint)5 Certificate (net.i2p.data.Certificate)5 Destination (net.i2p.data.Destination)5 NativeBigInteger (net.i2p.util.NativeBigInteger)5 FileInputStream (java.io.FileInputStream)3 StringWriter (java.io.StringWriter)3 CertificateTest (net.i2p.data.CertificateTest)3