001package com.bitbucket.thinbus.srp6.js;
002
003import java.math.BigInteger;
004import java.nio.charset.Charset;
005import java.nio.file.Files;
006import java.nio.file.Paths;
007import java.security.MessageDigest;
008import java.util.List;
009import java.util.regex.Matcher;
010import java.util.regex.Pattern;
011
012import com.nimbusds.srp6.SRP6Routines;
013
014/**
015 * A class to parse the output of 'openssl dhparam -text bits' where bits is the
016 * prime number bit length. Will output 'N', 'g', 'k' in bases 10, 10, 16
017 * respectively. Note that k is derived from 'N' and 'g' but Nimbus 1.4.x
018 * currently uses a the byte array constructor of BigInteger to computes 'k'
019 * which is not available in Javascript so the value genenerated by Java needs
020 * to be configure in the Javascript.
021 */
022public class OpenSSLCryptoConfig {
023        public static void main(String[] args) throws Exception {
024                System.out.println(String.format("attempting to open a openssl dhparam text file at: %s", args[0]));
025
026                List<String> lines = Files.readAllLines(Paths.get(args[0]), Charset.forName("UTF8"));
027
028                StringBuilder hexparts = new StringBuilder();
029
030                int bits = 0;
031                int generator = 0;
032
033                for (String line : lines) {
034                        if (line.startsWith("Diffie-Hellman-Parameters:")) {
035                                try {
036                                        bits = bits(line);
037                                } catch (Exception e) {
038                                        throw new AssertionError("could not parse 'xxxx bit' number out of line beginning 'Diffie-Hellman-Parameters'");
039                                }
040                        } else if (line.endsWith("prime:")) {
041                                // skip this one
042                        } else if (line.endsWith(":")) {
043                                hexparts.append(line.trim());
044                        } else if (line.contains("generator")) {
045                                try {
046                                        generator = generator(line);
047                                } catch (Exception e) {
048                                        throw new AssertionError("could not parse 'generator: x' number out of line containing 'generator'");
049                                }
050                        }
051                }
052
053                if (bits <= 0) {
054                        throw new AssertionError("could not parse 'xxxx bit' number out of line beginning 'Diffie-Hellman-Parameters'");
055                }
056
057                if (generator <= 0) {
058                        throw new AssertionError("could not parse 'generator: x' number out of line containing 'generator'");
059                }
060
061                String primeHex = hexparts.toString().replace(":", "");
062
063                System.out.println("bits:" + bits);
064
065                BigInteger N = new BigInteger(primeHex, 16);
066                BigInteger g = new BigInteger(generator + "");
067
068                System.out.println("hashing to create 'k' using " + args[1]);
069
070                MessageDigest digest = MessageDigest.getInstance(args[1]);
071                BigInteger k = SRP6Routines.computeK(digest, N, g);
072
073                System.out.println("computing");
074                System.out.println("N base10: " + N.toString(10));
075                System.out.println("g base10: " + g.toString(10));
076                System.out.println("k base16: " + k.toString(16));
077        }
078
079        static Pattern generatorPattern = Pattern.compile(".*generator: (\\d*) \\(.*");
080
081        private static int generator(String line) {
082                Matcher matcher = generatorPattern.matcher(line);
083                matcher.matches();
084                String number = matcher.group(1);
085                return Integer.valueOf(number);
086        }
087
088        static Pattern bitsPattern = Pattern.compile(".*\\((\\d*) bit\\).*");
089
090        private static int bits(String line) {
091                Matcher matcher = bitsPattern.matcher(line);
092                matcher.matches();
093                String number = matcher.group(1);
094                return Integer.valueOf(number);
095        }
096
097}