Changeset 0bacbbc


Ignore:
Timestamp:
Aug 9, 2014 5:55:17 PM (6 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
22a7757
Parents:
03d8314
Message:

SigType?: Add static isAvailable() methods
SU3File:

  • Add -x option to bypass signature verification
  • Add -k option to use specified private key cert for verification
  • Don't verify signature in showversion
Location:
core/java/src/net/i2p/crypto
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • core/java/src/net/i2p/crypto/SU3File.java

    r03d8314 r0bacbbc  
    1616import java.security.PrivateKey;
    1717import java.security.PublicKey;
     18import java.security.cert.CertificateFactory;
     19import java.security.cert.X509Certificate;
    1820import java.util.ArrayList;
    1921import java.util.Arrays;
     
    5658    private boolean _headerVerified;
    5759    private SigType _sigType;
     60    private boolean _verifySignature = true;
     61    private File _certFile;
    5862
    5963    public static final String MAGIC = "I2Psu3";
     
    131135    }
    132136
     137    /**
     138     *  Should the signature be verified? Default true
     139     *  @since 0.9.15
     140     */
     141    public void setVerifySignature(boolean shouldVerify) {
     142        _verifySignature = shouldVerify;
     143    }
     144
     145    /**
     146     *  Use this X.509 cert file for verification instead of $I2P/certificates/content_type/foo_at_mail.i2p
     147     *  @since 0.9.15
     148     */
     149    private void setPublicKeyCertificate(File certFile) {
     150        _certFile = certFile;
     151    }
     152
     153    /**
     154     *  This does not check the signature, but it will fail if the signer is unknown,
     155     *  unless setVerifySignature(false) has been called.
     156     */
    133157    public String getVersionString() throws IOException {
    134158        verifyHeader();
     
    136160    }
    137161
     162    /**
     163     *  This does not check the signature, but it will fail if the signer is unknown,
     164     *  unless setVerifySignature(false) has been called.
     165     */
    138166    public String getSignerString() throws IOException {
    139167        verifyHeader();
     
    142170
    143171    /**
     172     *  This does not check the signature, but it will fail if the signer is unknown,
     173     *  unless setVerifySignature(false) has been called.
     174     *
    144175     *  @return null if unknown
    145176     *  @since 0.9.9
     
    151182
    152183    /**
     184     *  This does not check the signature, but it will fail if the signer is unknown,
     185     *  unless setVerifySignature(false) has been called.
     186     *
    153187     *  @return -1 if unknown
    154188     *  @since 0.9.9
     
    160194
    161195    /**
     196     *  This does not check the signature, but it will fail if the signer is unknown,
     197     *  unless setVerifySignature(false) has been called.
     198     *
    162199     *  @return -1 if unknown
    163200     *  @since 0.9.15
     
    169206
    170207    /**
     208     *  This does not check the signature, but it will fail if the signer is unknown,
     209     *  unless setVerifySignature(false) has been called.
     210     *
    171211     *  Throws IOE if verify vails.
    172212     */
     
    246286        _signer = DataHelper.getUTF8(data);
    247287
    248         KeyRing ring = new DirKeyRing(new File(_context.getBaseDir(), "certificates"));
    249         try {
    250             _signerPubkey = ring.getKey(_signer, _contentType.getName(), _sigType);
    251         } catch (GeneralSecurityException gse) {
    252             IOException ioe = new IOException("keystore error");
    253             ioe.initCause(gse);
    254             throw ioe;
    255         }
    256 
    257         if (_signerPubkey == null)
    258             throw new IOException("unknown signer: " + _signer + " for content type: " + _contentType.getName());
     288        if (_verifySignature) {
     289            if (_certFile != null) {
     290                _signerPubkey = loadKey(_certFile);
     291            } else {
     292                KeyRing ring = new DirKeyRing(new File(_context.getBaseDir(), "certificates"));
     293                try {
     294                    _signerPubkey = ring.getKey(_signer, _contentType.getName(), _sigType);
     295                } catch (GeneralSecurityException gse) {
     296                    IOException ioe = new IOException("keystore error");
     297                    ioe.initCause(gse);
     298                    throw ioe;
     299                }
     300                if (_signerPubkey == null)
     301                    throw new IOException("unknown signer: " + _signer + " for content type: " + _contentType.getName());
     302            }
     303        }
    259304        _headerVerified = true;
    260305    }
     
    325370            else
    326371                skip(in, getContentOffset());
    327             if (_signerPubkey == null)
    328                 throw new IOException("unknown signer: " + _signer + " for content type: " + _contentType.getName());
     372            if (_verifySignature) {
     373                if (_signerPubkey == null)
     374                    throw new IOException("unknown signer: " + _signer + " for content type: " + _contentType.getName());
     375            }
    329376            if (migrateTo != null)  // else verify only
    330377                out = new FileOutputStream(migrateTo);
     
    339386                tot += read;
    340387            }
    341             byte[] sha = md.digest();
    342             din.on(false);
    343             Signature signature = new Signature(_sigType);
    344             signature.readBytes(in);
    345             SimpleDataStructure hash = _sigType.getHashInstance();
    346             hash.setData(sha);
    347             //System.out.println("hash\n" + HexDump.dump(sha));
    348             //System.out.println("sig\n" + HexDump.dump(signature.getData()));
    349             rv = _context.dsa().verifySignature(signature, hash, _signerPubkey);
     388            if (_verifySignature) {
     389                byte[] sha = md.digest();
     390                din.on(false);
     391                Signature signature = new Signature(_sigType);
     392                signature.readBytes(in);
     393                SimpleDataStructure hash = _sigType.getHashInstance();
     394                hash.setData(sha);
     395                //System.out.println("hash\n" + HexDump.dump(sha));
     396                //System.out.println("sig\n" + HexDump.dump(signature.getData()));
     397                rv = _context.dsa().verifySignature(signature, hash, _signerPubkey);
     398            } else {
     399                rv = true;
     400            }
    350401        } catch (DataFormatException dfe) {
    351402            IOException ioe = new IOException("foo");
     
    462513            String ctype = null;
    463514            String ftype = null;
     515            String kfile = null;
    464516            boolean error = false;
    465             Getopt g = new Getopt("SU3File", args, "t:c:f:");
     517            boolean shouldVerify = true;
     518            Getopt g = new Getopt("SU3File", args, "t:c:f:k:x");
    466519            int c;
    467520            while ((c = g.getopt()) != -1) {
     
    477530                case 'f':
    478531                    ftype = g.getOptarg();
     532                    break;
     533
     534                case 'k':
     535                    kfile = g.getOptarg();
     536                    break;
     537
     538                case 'x':
     539                    shouldVerify = false;
    479540                    break;
    480541
     
    506567                ok = bulkSignCLI(stype, ctype, a.get(0), a.get(1), a.get(2), a.get(3));
    507568            } else if ("verifysig".equals(cmd)) {
    508                 ok = verifySigCLI(a.get(0));
     569                ok = verifySigCLI(a.get(0), kfile);
    509570            } else if ("keygen".equals(cmd)) {
    510571                ok = genKeysCLI(stype, a.get(0), a.get(1), a.get(2));
    511572            } else if ("extract".equals(cmd)) {
    512                 ok = extractCLI(a.get(0), a.get(1));
     573                ok = extractCLI(a.get(0), a.get(1), shouldVerify);
    513574            } else {
    514575                showUsageCLI();
     
    528589        System.err.println("       SU3File bulksign     [-t type|code] [-c type|code] directory keystore.ks version you@mail.i2p");
    529590        System.err.println("       SU3File showversion  signedFile.su3");
    530         System.err.println("       SU3File verifysig    signedFile.su3");
    531         System.err.println("       SU3File extract      signedFile.su3 outFile");
     591        System.err.println("       SU3File verifysig    [-k file.crt] signedFile.su3  ## -k use this pubkey cert for verification");
     592        System.err.println("       SU3File extract      [-x] [-k file.crt] signedFile.su3 outFile   ## -x don't check sig");
    532593        System.err.println(dumpTypes());
    533594    }
     
    580641        try {
    581642            SU3File file = new SU3File(signedFile);
     643            file.setVerifySignature(false);
    582644            String versionString = file.getVersionString();
    583645            if (versionString.equals(""))
     
    727789
    728790    /** @return valid */
    729     private static final boolean verifySigCLI(String signedFile) {
     791    private static final boolean verifySigCLI(String signedFile, String pkFile) {
    730792        InputStream in = null;
    731793        try {
    732794            SU3File file = new SU3File(signedFile);
     795            if (pkFile != null)
     796                file.setPublicKeyCertificate(new File(pkFile));
    733797            boolean isValidSignature = file.verify();
    734798            if (isValidSignature)
     
    748812     *  @since 0.9.9
    749813     */
    750     private static final boolean extractCLI(String signedFile, String outFile) {
     814    private static final boolean extractCLI(String signedFile, String outFile, boolean verifySig) {
    751815        InputStream in = null;
    752816        try {
    753817            SU3File file = new SU3File(signedFile);
     818            file.setVerifySignature(verifySig);
    754819            File out = new File(outFile);
    755820            boolean ok = file.verifyAndMigrate(out);
     
    837902        return true;
    838903    }
     904
     905    /**
     906     *  For the -k CLI option
     907     *  @return non-null, throws IOE on all errors
     908     *  @since 0.9.15
     909     */
     910    private static PublicKey loadKey(File kd) throws IOException {
     911        InputStream fis = null;
     912        try {
     913            fis = new FileInputStream(kd);
     914            CertificateFactory cf = CertificateFactory.getInstance("X.509");
     915            X509Certificate cert = (X509Certificate)cf.generateCertificate(fis);
     916            cert.checkValidity();
     917            return cert.getPublicKey();
     918        } catch (GeneralSecurityException gse) {
     919            IOException ioe = new IOException("cert error");
     920            ioe.initCause(gse);
     921            throw ioe;
     922        } finally {
     923            try { if (fis != null) fis.close(); } catch (IOException foo) {}
     924        }
     925    }
    839926}
  • core/java/src/net/i2p/crypto/SigType.java

    r03d8314 r0bacbbc  
    179179    }
    180180
     181    /**
     182     *  @return true if supported in this JVM
     183     *  @since 0.9.15
     184     */
     185    public static boolean isAvailable(int code) {
     186        SigType type = getByCode(code);
     187        if (type == null)
     188            return false;
     189        return type.isAvailable();
     190    }
     191
     192    /**
     193     *  @param stype number or name
     194     *  @return true if supported in this JVM
     195     *  @since 0.9.15
     196     */
     197    public static boolean isAvailable(String stype) {
     198        SigType type = parseSigType(stype);
     199        if (type == null)
     200            return false;
     201        return type.isAvailable();
     202    }
     203
    181204    private static final Map<Integer, SigType> BY_CODE = new HashMap<Integer, SigType>();
    182205
Note: See TracChangeset for help on using the changeset viewer.