Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update cert reading from file to use current bouncycastle #244

Merged
merged 4 commits into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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");
pdowler marked this conversation as resolved.
Show resolved Hide resolved
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) {
pdowler marked this conversation as resolved.
Show resolved Hide resolved
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
Loading