Skip to content

Commit d962125

Browse files
author
Karl Rieb
committed
Fix pinned certificate parsing to properly handle comments.
The SDK would fail to initialize on Java 6 JREs because comments in certificate chains were not properly ignored. Fixes T98008
1 parent a56e829 commit d962125

File tree

2 files changed

+76
-1
lines changed

2 files changed

+76
-1
lines changed

ChangeLog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
2.0.5
22
---------------------------------------------
33
- Allow old locale formats for APIv2 requests.
4+
- Fix ExceptionInInitializationError caused by CertificateParsingException when using Java 6 JREs.
45

56
2.0.4 (2016-05-31)
67
---------------------------------------------

src/main/java/com/dropbox/core/http/SSLConfig.java

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import java.io.ByteArrayInputStream;
77
import java.io.DataInputStream;
8+
import java.io.FilterInputStream;
89
import java.io.IOException;
910
import java.io.InputStream;
1011
import java.net.InetAddress;
@@ -341,7 +342,8 @@ private static void loadKeyStore(KeyStore keyStore, InputStream in)
341342

342343
Collection<X509Certificate> certs;
343344
try {
344-
certs = (Collection<X509Certificate>) x509CertFactory.generateCertificates(in);
345+
certs = (Collection<X509Certificate>) x509CertFactory
346+
.generateCertificates(new CommentFilterInputStream(in));
345347
} catch (CertificateException ex) {
346348
throw new LoadException("Error loading certificate: " + ex.getMessage(), ex);
347349
}
@@ -355,4 +357,76 @@ private static void loadKeyStore(KeyStore keyStore, InputStream in)
355357
}
356358
}
357359
}
360+
361+
362+
/**
363+
* Strips '#' comments from DER-encoded cert file. Java 7+ handles skipping comments that aren't
364+
* within certificate blocks. Java 6, however, will fail to parse the cert file if it contains
365+
* anything other than certificate blocks.
366+
*/
367+
private static final class CommentFilterInputStream extends FilterInputStream {
368+
private boolean isLineStart;
369+
370+
public CommentFilterInputStream(InputStream in) {
371+
super(in);
372+
this.isLineStart = true;
373+
}
374+
375+
@Override
376+
public int read() throws IOException {
377+
int ord = super.read();
378+
379+
// only filter at start of line
380+
if (!isLineStart) {
381+
return ord;
382+
}
383+
384+
while (ord == '#') {
385+
// chomp the comment
386+
do {
387+
ord = super.read();
388+
} while (!isLineFeed(ord) && ord != -1);
389+
390+
// now chomp the line feeds
391+
while (isLineFeed(ord) && ord != -1) {
392+
ord = super.read();
393+
}
394+
isLineStart = true;
395+
}
396+
397+
return ord;
398+
}
399+
400+
@Override
401+
public int read(byte [] b) throws IOException {
402+
return read(b, 0, b.length);
403+
}
404+
405+
@Override
406+
public int read(byte [] b, int off, int len) throws IOException {
407+
if (b == null) {
408+
throw new NullPointerException("b");
409+
}
410+
if (off < 0 || len < 0 || len > (b.length - off)) {
411+
throw new IndexOutOfBoundsException();
412+
}
413+
414+
int count = 0;
415+
for (int i = 0; i < len; ++i) {
416+
int ord = read();
417+
if (ord == -1) {
418+
break;
419+
}
420+
421+
b[off + i] = (byte) ord;
422+
++count;
423+
}
424+
425+
return count == 0 ? -1 : count;
426+
}
427+
428+
private static boolean isLineFeed(int ord) {
429+
return ord == '\n' || ord == '\r';
430+
}
431+
}
358432
}

0 commit comments

Comments
 (0)