Skip to content

Commit

Permalink
Merge pull request #244 from pdowler/bc177
Browse files Browse the repository at this point in the history
update cert reading from file to use current bouncycastle
  • Loading branch information
pdowler authored Feb 22, 2024
2 parents fd3af59 + 5f86fb1 commit f76240f
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 484 deletions.
6 changes: 3 additions & 3 deletions cadc-util/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ sourceCompatibility = 1.8

group = 'org.opencadc'

version = '1.10.7'
version = '1.11.0'

description = 'OpenCADC core utility library'
def git_url = 'https://github.com/opencadc/core'
Expand All @@ -33,12 +33,12 @@ dependencies {
compile 'org.apache.logging.log4j:log4j-core:2.17.2'
compile 'org.apache.logging.log4j:log4j:2.17.2'

compile 'org.bouncycastle:bcprov-jdk15on:1.46'
compile 'org.bouncycastle:bcprov-jdk18on:[1.70,2.0)'
compile 'org.bouncycastle:bcpkix-jdk18on:[1.70,2.0)'
compile 'javax.servlet:javax.servlet-api:3.1.0'
compile 'org.json:json:20231013'
compile 'xerces:xercesImpl:[2.12.2,)'
compile 'org.jdom:jdom2:2.0.6.1'
//compile 'org.springframework:spring-jdbc:5.2.22.RELEASE'
compile 'org.springframework:spring-jdbc:5.2.24.RELEASE'
compile 'org.apache.commons:commons-dbcp2:[2.8.0,2.9.0)'

Expand Down
225 changes: 66 additions & 159 deletions cadc-util/src/intTest/java/ca/nrc/cadc/auth/SSLUtilTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
******************* CANADIAN ASTRONOMY DATA CENTRE *******************
************** CENTRE CANADIEN DE DONNÉES ASTRONOMIQUES **************
*
* (c) 2016. (c) 2016.
* (c) 2024. (c) 2024.
* Government of Canada Gouvernement du Canada
* National Research Council Conseil national de recherches
* Ottawa, Canada, K1A 0R6 Ottawa, Canada, K1A 0R6
Expand Down Expand Up @@ -81,6 +81,7 @@
import java.security.cert.CertificateNotYetValidException;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Set;
import javax.net.SocketFactory;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLHandshakeException;
Expand All @@ -106,62 +107,6 @@ public class SSLUtilTest
private static String TEST_PEM_FN = "proxy.pem";
private static File SSL_PEM;

private static final String KEY_512 =
"-----BEGIN RSA PRIVATE KEY-----\n" +
"MIIBOgIBAAJBAOvm3yk/tr7/8ZaT584T54tOviYIpoWWRfwDgd176c0kTfTj43+C\n" +
"BgxFcequf5mY51mgD7v38krRA3+xXi/igfsCAwEAAQJBAMqVrQXGcpDaScVPZV1j\n" +
"WJAY4lDVUvQb1iQTev4SwPjqUy8H/f0Zt+Bezwf1LaxcHcCFA6QnDxHw6l99/5zw\n" +
"p7kCIQD+4rfjcZyYUKwF0C2deKEgvZUjpiLYVyh/G4qKfT2sPwIhAOzu598CHLLn\n" +
"LSZoBRJtjuhAr1zUrfkoBsNHQwTKi6tFAiBOpKtyXPKhOHrrTEFWzgqBLJ2gozkr\n" +
"ITFYjqnfcycdRwIgbMW1L31hvYRCBxrEEVS4wclIeJ6vC+6jRC1ICEAQZN0CIFe+\n" +
"Az22zN/URBRVBK32tI2axHy/j80Asysh+hxalp1F\n" +
"-----END RSA PRIVATE KEY-----\n";
private static final String KEY_1024 =
"-----BEGIN RSA PRIVATE KEY-----\n" +
"MIICXQIBAAKBgQDIcNIXiBAPuOjTNWJUbsI+TR1FSXNGM2bv2naU7pKQ0OWI+DDs\n" +
"K1xlctgTi5WrfsMjPKoM+0zpVT5qjUrHyFatbTu9tYjLblPmi/yzOEOIloqZ8lF1\n" +
"hrkUG98f8IBbgx4BbkXscVKdP9awngEpIYrZt3QXLUwUP+oF2PCGH5f+nwIDAQAB\n" +
"AoGBAI5gVVuRspb4aaldSjNfWWqXrCsDOXasHHpTW9f+fu2O9PyOD3Iyerc1FHcN\n" +
"t4rRyBrHhKMj/kXf3y4gnvW6QJY8MM+lHx7oubS8O5aqVexKa8dawQNHvMfLz9PU\n" +
"OuN7X2+rvLS3+qPUtL2LiklCSsrr137M4OBNdfTcZKqAEaLBAkEA/QWsVzhx526D\n" +
"HCBaJ6cgfo6Ravqjg17DDe/yt5iC+dQzGMozWJdHjOS/066aZNF4Els4iSVWdIT5\n" +
"KqBmgjBFZQJBAMrMub59uqqHFGQzWgtOdQamiyeEwr48+a3xHUYy5p+1h7TWetHR\n" +
"OQTFOwGfpv8h7RGd2TS3fxzK+G5LKIUChbMCQQDF+rpvROtbe017pJTmkg8K9+Mx\n" +
"IgzvriZRsX7pyZwyf6e7rfufRj/mLtcqe2SznnOlaVtDdMPBSIrun7OWCs9BAkB6\n" +
"V2b2dALYPQUgLZp0l7AhgvcPsBeLjF1TgdGXN73JO0nS3lDZos4zAojGQfoMj/rk\n" +
"VcVi+A/G3utgHhcjppHhAkBpxQmU1fAB2wKVNtTh2puPmKt+g1wob1yZASRJEadZ\n" +
"5QR7EgNAJtdlouvJcdnTXHJS9JazpcS3061+u2TfgIvx\n" +
"-----END RSA PRIVATE KEY-----\n";
private static final String KEY_2048 =
"-----BEGIN RSA PRIVATE KEY-----\n" +
"MIIEpgIBAAKCAQEA4Sa+glBzaztCbgZ90uFm5sfjSWUtZCGTw1UwcIFsQtkBa1ut\n" +
"gn1b2LtGevctPoXMreMq4f/5TNAtJuBOHP+2Xv+mIBBbm+zJwTAfk9I0/6wcNlkS\n" +
"FKhSqkpvwSv6+ecQ6R5zUrQv1aMwI392GyAiY8Jo4J6UVGKe7+YY1yvWraVFZYzB\n" +
"FeCNb9Qlo4X+uyZRjz0JJmJZE8H6USmrAa1DPQoWRBpJPJ/sIM1ejTz6lLyC3A54\n" +
"e0Nh+z8dPfUVzBySOgPzypPbuyEaVEFlmm+PqyrfoSIgNQNeOY0SbyhN374xpSHz\n" +
"PBPUPgy5qwidQB4+XN6YQlumz/i4+UnPdvR8jwIDAQABAoIBAQCmGGn0QptS4O2Z\n" +
"s0pBNq0t1QoUTAKXWrniIMdSR/fwvJvycjhnCkmmckmFTzFebWBYazxoauijxPN6\n" +
"OYEGnZIRNPF9t/OM7LrNvM2exDT65CIP6dePy7joDW+yBtroXpC4GRGkUm7zYKaT\n" +
"mWUsj6EvDO1Hv1TXh8WOXqW2no2JnP7OgCcVCGSR4/o6vBaDlUUBSiA3HIG7LWwW\n" +
"uin3LdZ8Z6CuwwlSdc758LIRlE5cGwU4Q4GH34KsMHJU0xkTaeSoYWFWo9xBTlQ1\n" +
"KuLgrYHeomKItiQTeXmuD8hepqhBkrH7tgfPcDrwmOlgarrJ1YK5Ve+i2nyHWVlP\n" +
"/g8DyrgxAoGBAP+08fzjxht5P7wW1E3QY+79NG5vO9uc+joG5X2U0Yu/98UWa1P5\n" +
"d6cbHQQuML0g7MfgRK52h80x+0xPcNewOmCX8vkYLpOqW++UOxH0Czam6igxeprV\n" +
"5WIYg5RB1QhbhQ5rRc4O+l61Yi9hdQBnJNfFbSqU373JLZpD6T5wdCXnAoGBAOFo\n" +
"1I8PEZaxiNz3qGb5LHEeSHRqQHKBQMoUcjAThA8T/Dx7uo3EkrKptyxJdpNeJbnE\n" +
"/GJsjXrElAHJqST1wmQzC3KLhgmKZliB4Ewk1foIfid36T0w/+RrlW2kwqinkr+H\n" +
"UOCSKnsQE8+xeGZ68WxmrBDmGnf5AtS9dfa6cc8ZAoGBAItxhoFNSSyUS3Br1qz0\n" +
"lnqutBgBKthRW5enSSDZtggK0Lg2yKLLqTeErqcn9UY+HUHGiE3Hr7jzp8HulG/a\n" +
"14rzcfnq+QNn5Kja4fehaTgNgCYZDW5AdM2w5phD6kObfQzm7PM48coSChAiimaE\n" +
"2O+d5zFQbE8X1XmJzTlSo9RDAoGBAKA/BXXasZdfCTyF+DuUgwq8C6hvbPe6edPv\n" +
"6ynQhf6uJ5DcKUjl6aCIVQdwBpNHyCwkJYTXRVF09P+8XLpA2Pyg6U96b0TTFmVv\n" +
"l4SqX1CMvxrR/YeaESFTdnznN9fsob/1tAKjBv5L9LmfokfAuWdmKocs/r4x0dhq\n" +
"BLXt4EDpAoGBAKN61XJ+kwO6FkxuyTlbv458Bc9toFyPqSaafJeEp/p3KdLMlphr\n" +
"0GzdeGNkrNfseVbSAjnlO2zmmhVe6Oz3oIR4d/5Hb8QEZi8f7nOZboufITyGTtYG\n" +
"LfVRkN/AuTrxRxWQDbZOo55ACoJA3DH7/BMOXhf9RikjrvESLtCWzsf2\n" +
"-----END RSA PRIVATE KEY-----\n";


/**
* @throws java.lang.Exception
*/
Expand All @@ -171,22 +116,7 @@ public static void setUpBeforeClass() throws Exception
Log4jInit.setLevel("ca.nrc.cadc.auth", Level.INFO);
SSL_PEM = FileUtil.getFileFromResource(TEST_PEM_FN, SSLUtilTest.class);
}

@Test
public void testReadPem() throws Exception
{
try
{
X509CertificateChain chain = SSLUtil.readPemCertificateAndKey(SSL_PEM);
Assert.assertNotNull("Null chain", chain);
}
catch (Throwable t)
{
t.printStackTrace();
Assert.fail("unexpected exception: " + t);
}
}


@Test
public void testGetSocketFactoryFromNull() throws Exception
{
Expand Down Expand Up @@ -225,113 +155,90 @@ public void testGetSocketFactoryFromFile() throws Exception
Assert.fail("unexpected exception: " + t);
}
}

@Test
public void testInitSSL() throws Exception
{
try
{
SSLUtil.initSSL(SSL_PEM);
}
catch (Throwable t)
{
t.printStackTrace();
Assert.fail("unexpected exception: " + t);
public void testReadUserCert() {
// test reading a real user cert
try {
File f = new File(System.getProperty("user.home") + "/.ssl/" + System.getProperty("user.name") + ".pem");
log.info("in: " + f.getAbsolutePath());

Subject s = SSLUtil.createSubject(f);
log.info("created: " + s);
Assert.assertFalse(s.getPrincipals().isEmpty());

Set<X509CertificateChain> cs = s.getPublicCredentials(X509CertificateChain.class);
Assert.assertFalse("chain", cs.isEmpty());
X509CertificateChain chain = cs.iterator().next();
Assert.assertNotNull(chain.getChain());
Assert.assertEquals(1, chain.getChain().length);
Assert.assertNotNull(chain.getPrivateKey());
} catch (Exception unexpected) {
log.error("unexpected exception", unexpected);
Assert.fail("unexpected exception: " + unexpected);
}
}

public void testHTTPS(URL url) throws Exception
{
HttpURLConnection.setFollowRedirects(false);

SSLSocketFactory sf = SSLUtil.getSocketFactory(SSL_PEM);
URLConnection con = url.openConnection();

log.debug("URLConnection type: " + con.getClass().getName());
HttpsURLConnection ucon = (HttpsURLConnection) con;
ucon.setSSLSocketFactory(sf);
log.debug("status: " + ucon.getResponseCode());
log.debug("content-length: " + ucon.getContentLength());
log.debug("content-type: " + ucon.getContentType());
}


@Test
public void testGoogleHTTPS() throws Exception
{
try
{
URL url = new URL("https://www.google.com/");
log.debug("test URL: " + url);
testHTTPS(url);
}
catch (Throwable t)
{
t.printStackTrace();
Assert.fail("unexpected exception: " + t);
public void testReadUserProxyCert() {
// test reading a proxy cert (usually made from user cert using openssl)
try {
File f = new File(System.getProperty("user.home") + "/.ssl/cadcproxy.pem");
log.info("in: " + f.getAbsolutePath());

Subject s = SSLUtil.createSubject(f);
log.info("created: " + s);
Assert.assertFalse(s.getPrincipals().isEmpty());

Set<X509CertificateChain> cs = s.getPublicCredentials(X509CertificateChain.class);
Assert.assertFalse("chain", cs.isEmpty());
X509CertificateChain chain = cs.iterator().next();
Assert.assertNotNull(chain.getChain());
Assert.assertEquals(2, chain.getChain().length);
Assert.assertNotNull(chain.getPrivateKey());
} catch (Exception unexpected) {
log.error("unexpected exception", unexpected);
Assert.fail("unexpected exception: " + unexpected);
}
}

@Test
public void testCadcHTTPS() throws Exception
{
try
{
URL url = new URL("https://www.cadc-ccda.hia-iha.nrc-cnrc.gc.ca/");
log.debug("test URL: " + url);
testHTTPS(url);
}
catch (Throwable t)
{
t.printStackTrace();
Assert.fail("unexpected exception: " + t);
public void testReadProxyCert() {
// test read proxy.pem found in classpath (test resources)
try {
File f = SSL_PEM;
log.info("in: " + f.getAbsolutePath());

Subject s = SSLUtil.createSubject(f);
log.info("created: " + s);
Assert.assertFalse(s.getPrincipals().isEmpty());

Set<X509CertificateChain> cs = s.getPublicCredentials(X509CertificateChain.class);
Assert.assertFalse("chain", cs.isEmpty());
X509CertificateChain chain = cs.iterator().next();
Assert.assertNotNull(chain.getChain());
Assert.assertEquals(2, chain.getChain().length);
Assert.assertNotNull(chain.getPrivateKey());
} catch (Exception unexpected) {
log.error("unexpected exception", unexpected);
Assert.fail("unexpected exception: " + unexpected);
}
}

@Test
public void testPrivateKeyParser() throws Exception
public void testInitSSL() throws Exception
{
// tests the parser with different size keys
// 512 bit
byte[] privateKey = SSLUtil.getPrivateKey(KEY_512.getBytes());
try
{
log.debug("test parsing of RSA 512 bit key: ");
SSLUtil.parseKeySpec(privateKey);
}
catch (Throwable t)
{
t.printStackTrace();
Assert.fail("unexpected exception: " + t);
}

// 1024 bit
privateKey = SSLUtil.getPrivateKey(KEY_1024.getBytes());
try
{
log.debug("test parsing of RSA 1024 bit key: ");
SSLUtil.parseKeySpec(privateKey);
}
catch (Throwable t)
{
t.printStackTrace();
Assert.fail("unexpected exception: " + t);
}

// 2048 bit
privateKey = SSLUtil.getPrivateKey(KEY_2048.getBytes());
try
{
log.debug("test parsing of RSA 2048 bit key: ");
SSLUtil.parseKeySpec(privateKey);
SSLUtil.initSSL(SSL_PEM);
}
catch (Throwable t)
{
t.printStackTrace();
Assert.fail("unexpected exception: " + t);
}

}

@Test
public void testValidSubject() throws Exception
{
Expand Down
43 changes: 2 additions & 41 deletions cadc-util/src/main/java/ca/nrc/cadc/auth/CertCmdArgUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -132,16 +132,6 @@ private static Subject initSubjectByPem(String fnPem, boolean nullOnNotFound) {
return SSLUtil.createSubject(certKeyFile);
}

private static Subject initSubjectByCertKey(String fnCert, String fnKey, boolean nullOnNotFound) {
File certFile = loadFile(fnCert, nullOnNotFound);
File keyFile = loadFile(fnKey, nullOnNotFound);
if (nullOnNotFound && certFile == null && keyFile == null) {
return null;
}

return SSLUtil.createSubject(certFile, keyFile);
}

/**
* Init a subject from the command line and throw an exception if not
* successful.
Expand Down Expand Up @@ -181,37 +171,8 @@ public static Subject initSubject(ArgumentMap argMap, boolean returnNullOnNotFou
Subject subject = null;

if (argMap.isSet(ARG_CERT)) {
if (argMap.isSet(ARG_KEY)) {
// load from cert/key
strCert = argMap.getValue(ARG_CERT);
strKey = argMap.getValue(ARG_KEY);
subject = initSubjectByCertKey(strCert, strKey, false);
} else {
// load from cert pem
strCertKey = argMap.getValue(ARG_CERT);
subject = initSubjectByPem(strCertKey, false);
}
} else {
// load from default
strCertKey = userHome + DFT_CERTKEY_FILE;
strCert = userHome + DFT_CERT_FILE;
strKey = userHome + DFT_KEY_FILE;
try {
subject = initSubjectByPem(strCertKey, returnNullOnNotFound);
} catch (RuntimeException ex1) {

// Default PEM file not exists or is not readable
if (subject == null) {
try {
subject = initSubjectByCertKey(strCert, strKey, returnNullOnNotFound);
} catch (RuntimeException ex2) {
if (!returnNullOnNotFound) {
throw new RuntimeException("Could not find valid certificate files at " + strCertKey
+ " or " + strCert + "," + strKey, ex2);
}
}
}
}
strCertKey = argMap.getValue(ARG_CERT);
subject = initSubjectByPem(strCertKey, false);
}
return subject;
}
Expand Down
Loading

0 comments on commit f76240f

Please sign in to comment.