diff --git a/src/share/classes/sun/security/util/DerInputStream.java b/src/share/classes/sun/security/util/DerInputStream.java index f513c93c4a3c85670ef43a28e37de296fc6895a4..ad5d6da273f0067f16ac975a3e86631d045efc69 100644 --- a/src/share/classes/sun/security/util/DerInputStream.java +++ b/src/share/classes/sun/security/util/DerInputStream.java @@ -191,7 +191,7 @@ public class DerInputStream { if (buffer.read() != DerValue.tag_Integer) { throw new IOException("DER input, Integer tag error"); } - return buffer.getInteger(getLength(buffer)); + return buffer.getInteger(getDefiniteLength(buffer)); } /** @@ -203,7 +203,7 @@ public class DerInputStream { if (buffer.read() != DerValue.tag_Integer) { throw new IOException("DER input, Integer tag error"); } - return buffer.getBigInteger(getLength(buffer), false); + return buffer.getBigInteger(getDefiniteLength(buffer), false); } /** @@ -217,7 +217,7 @@ public class DerInputStream { if (buffer.read() != DerValue.tag_Integer) { throw new IOException("DER input, Integer tag error"); } - return buffer.getBigInteger(getLength(buffer), true); + return buffer.getBigInteger(getDefiniteLength(buffer), true); } /** @@ -229,7 +229,7 @@ public class DerInputStream { if (buffer.read() != DerValue.tag_Enumerated) { throw new IOException("DER input, Enumerated tag error"); } - return buffer.getInteger(getLength(buffer)); + return buffer.getInteger(getDefiniteLength(buffer)); } /** @@ -240,7 +240,7 @@ public class DerInputStream { if (buffer.read() != DerValue.tag_BitString) throw new IOException("DER input not an bit string"); - return buffer.getBitString(getLength(buffer)); + return buffer.getBitString(getDefiniteLength(buffer)); } /** @@ -248,15 +248,21 @@ public class DerInputStream { * not be byte-aligned. */ public BitArray getUnalignedBitString() throws IOException { - if (buffer.read() != DerValue.tag_BitString) + if (buffer.read() != DerValue.tag_BitString) { throw new IOException("DER input not a bit string"); + } + + int length = getDefiniteLength(buffer); - int length = getLength(buffer) - 1; + if (length == 0) { + return new BitArray(0); + } /* * First byte = number of excess bits in the last octet of the * representation. */ + length--; int excessBits = buffer.read(); if (excessBits < 0) { throw new IOException("Unused bits of bit string invalid"); @@ -282,7 +288,7 @@ public class DerInputStream { if (buffer.read() != DerValue.tag_OctetString) throw new IOException("DER input not an octet string"); - int length = getLength(buffer); + int length = getDefiniteLength(buffer); byte[] retval = new byte[length]; if ((length != 0) && (buffer.read(retval) != length)) throw new IOException("Short read of DER octet string"); @@ -397,7 +403,7 @@ public class DerInputStream { if (tag != buffer.read()) throw new IOException("Indefinite length encoding" + " not supported"); - len = DerInputStream.getLength(buffer); + len = DerInputStream.getDefiniteLength(buffer); } if (len == 0) @@ -514,7 +520,7 @@ public class DerInputStream { throw new IOException("DER input not a " + stringName + " string"); - int length = getLength(buffer); + int length = getDefiniteLength(buffer); byte[] retval = new byte[length]; if ((length != 0) && (buffer.read(retval) != length)) throw new IOException("Short read of DER " + @@ -529,7 +535,7 @@ public class DerInputStream { public Date getUTCTime() throws IOException { if (buffer.read() != DerValue.tag_UtcTime) throw new IOException("DER input, UTCtime tag invalid "); - return buffer.getUTCTime(getLength(buffer)); + return buffer.getUTCTime(getDefiniteLength(buffer)); } /** @@ -538,7 +544,7 @@ public class DerInputStream { public Date getGeneralizedTime() throws IOException { if (buffer.read() != DerValue.tag_GeneralizedTime) throw new IOException("DER input, GeneralizedTime tag invalid "); - return buffer.getGeneralizedTime(getLength(buffer)); + return buffer.getGeneralizedTime(getDefiniteLength(buffer)); } /* @@ -618,6 +624,24 @@ public class DerInputStream { return value; } + int getDefiniteLength() throws IOException { + return getDefiniteLength(buffer); + } + + /* + * Get a length from the input stream. + * + * @return the length + * @exception IOException on parsing error or if indefinite length found. + */ + static int getDefiniteLength(InputStream in) throws IOException { + int len = getLength(in); + if (len < 0) { + throw new IOException("Indefinite length encoding not supported"); + } + return len; + } + /** * Mark the current position in the buffer, so that * a later call to reset will return here. diff --git a/src/share/classes/sun/security/util/DerValue.java b/src/share/classes/sun/security/util/DerValue.java index 9aab6a18cdb75c8a1864a70f9f116a4b088bff74..3950dfd95a82db1b74a769b30b2343c46963d0ba 100644 --- a/src/share/classes/sun/security/util/DerValue.java +++ b/src/share/classes/sun/security/util/DerValue.java @@ -271,7 +271,7 @@ public class DerValue { if (tag != inbuf.read()) throw new IOException ("Indefinite length encoding not supported"); - length = DerInputStream.getLength(inbuf); + length = DerInputStream.getDefiniteLength(inbuf); buffer = inbuf.dup(); buffer.truncate(length); data = new DerInputStream(buffer); @@ -403,7 +403,7 @@ public class DerValue { if (tag != in.read()) throw new IOException ("Indefinite length encoding not supported"); - length = DerInputStream.getLength(in); + length = DerInputStream.getDefiniteLength(in); } if (fullyBuffered && in.available() != length) diff --git a/src/share/classes/sun/security/util/ObjectIdentifier.java b/src/share/classes/sun/security/util/ObjectIdentifier.java index cfa50b616650d6dabeda0270f885524786b796ec..01667ea43183fc5848d58e54fdb9b676b973ab6c 100644 --- a/src/share/classes/sun/security/util/ObjectIdentifier.java +++ b/src/share/classes/sun/security/util/ObjectIdentifier.java @@ -259,7 +259,7 @@ class ObjectIdentifier implements Serializable + " (tag = " + type_id + ")" ); - int len = in.getLength(); + int len = in.getDefiniteLength(); if (len > in.available()) { throw new IOException("ObjectIdentifier() -- length exceeds" + "data available. Length: " + len + ", Available: " + diff --git a/test/java/security/cert/X509Certificate/X509BadCertificate.java b/test/java/security/cert/X509Certificate/X509BadCertificate.java index b2a6c6923fad411804e1a2dff3a23aff1c5dfd0a..c2b4a8832ccfd72225e2d2ecca61fe4b3ccfcaad 100644 --- a/test/java/security/cert/X509Certificate/X509BadCertificate.java +++ b/test/java/security/cert/X509Certificate/X509BadCertificate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /** * @test - * @bug 8028431 + * @bug 8028431 8028591 * @summary Make sure that proper CertificateException is thrown * when loading bad x509 certificate * @author Artem Smotrakov @@ -39,6 +39,7 @@ public class X509BadCertificate { public static void main(String[] args) throws Exception { test("bad-cert-1.pem"); + test("bad-cert-2.pem"); } /** diff --git a/test/java/security/cert/X509Certificate/bad-cert-2.pem b/test/java/security/cert/X509Certificate/bad-cert-2.pem new file mode 100644 index 0000000000000000000000000000000000000000..6b92ced2e097ea275df810f973589998552cd76c --- /dev/null +++ b/test/java/security/cert/X509Certificate/bad-cert-2.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIJAJYB3qu9C2kiMA0GCSqGSIb3DQEBBQUAMEoxDTALBgNV +BAMMBFRlc3QxDTALBgNVBAsMBEphdmExDzANBgNVBAoMBk9yYWNsZTEMMAoGA1UE +BwwDU1BCMQswCQYDVQQGEwJSVTAeFw0xMzEyMjMwNzA4MDhaFw0yMzEyMjEwNzA4 +MDhaMEoxDTALBgNVBAMMBFRlc3QxDTALBgNVBAsMBEphdmExDzANBgNVBAoMBk9y +YWNsZTEMMAoGA1UEBwwDU1BCMQswCQYDVQQGEwJSVTCCASIwDQYJKoZIhvcNAQEB +BQADgGEPADCCAQoCggEBAOqiCN4gFxehl547Q7/VNGbGApr+wszLdanHPucAH6Wf +LtcRhKNUSqtBAQxEpFrTpMNEqm2GElAjiPa6m48qIjLVSvOb/9w3G/yXB8zyZbIm +/Nfp2sT4OEaa1JSEZSpolhS4FfqYzjGQp5cn4Xn4zKjDgiceHgfLls5x2dRydQZO +Yf91qSIioZxVHUtlo8yztkieiSaqPWt3nJ4PIwhFbsu1HVmWaYZD+nBYCKgVHqrS +cueO98Ca4Doz73O27X1dVbQBdLS0JI7qVAG8LD388iPL8qbsOkgWPzmEQ+kLRKO4 +g7RpuwlXuwaMSh95NWaxlu4Ob6GRJQmpconYoe13+7ECAwEAAaNQME4wHQYDVR0O +BBYEFIG8TPobXcbNbDi+zKudd9whpxoNMB8GA1UdIwQYMBaAFIG8TPobXcbNbDi+ +zKudd9whpxoNMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAynN+e7 +h+ufT5SBKN/gBuJAnF1mKIPESiipuv5KoYUGZOY8ShgYLcwY+qnbuHYFUlvq6Zns +K4/e+x/16h32vD7dEPkNvukbvER4YJQQiN6osDfXpTPzixYftWdmtX0u8xQfwb/g +R8DS7bazz99jVXk+jTK4yWBY+gMwEat+LyNQ5cyq8Qhi1oBKUbGRbiOts19B97fn +Rv8TsyXN3INLGYhdVxZoD7E5tyG1ydSFmOMadulAC2epBXDHOXZnz2UWauJc0XW5 +1L/YQVri47VkdHS3tisBzELEJdLmdMDb+5tAU+lItXmTXe2/PB53WIvsEIb4t+eQ +wY0hCj9lVJlajTQ= +-----END CERTIFICATE-----