# HG changeset patch # User weijun # Date 1291603698 -28800 # Node ID 78a87adede1e73ff7e84c2deb9aa48b1a22fe5c0 # Parent 16d2b5e6517a3f94caae8a0284b6889cf4310f49 6896700: Validation of signatures succeed when it should fail Reviewed-by: wetmore diff -r 16d2b5e6517a -r 78a87adede1e jdk/src/share/classes/sun/security/rsa/RSASignature.java --- a/jdk/src/share/classes/sun/security/rsa/RSASignature.java Mon Dec 06 10:46:26 2010 +0800 +++ b/jdk/src/share/classes/sun/security/rsa/RSASignature.java Mon Dec 06 10:48:18 2010 +0800 @@ -185,6 +185,11 @@ // verify the data and return the result. See JCA doc protected boolean engineVerify(byte[] sigBytes) throws SignatureException { + if (sigBytes.length != RSACore.getByteLength(publicKey)) { + throw new SignatureException("Signature length not correct: got " + + sigBytes.length + " but was expecting " + + RSACore.getByteLength(publicKey)); + } byte[] digest = getDigestValue(); try { byte[] decrypted = RSACore.rsa(sigBytes, publicKey); diff -r 16d2b5e6517a -r 78a87adede1e jdk/test/sun/security/rsa/InvalidBitString.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/rsa/InvalidBitString.java Mon Dec 06 10:48:18 2010 +0800 @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2010, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @summary Validation of signatures succeed when it should fail + * @bug 6896700 + */ + +import java.io.InputStream; +import java.io.ByteArrayInputStream; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import java.security.PublicKey; +import java.security.SignatureException; + +public class InvalidBitString { + + // Test cert for CN=CA + static String signerCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIIBtDCCAR2gAwIBAgIEemxRHjANBgkqhkiG9w0BAQUFADANMQswCQYDVQQDEwJDQTAeFw0xMDA2\n" + + "MDMwODA2MjlaFw0xMDA5MDEwODA2MjlaMA0xCzAJBgNVBAMTAkNBMIGfMA0GCSqGSIb3DQEBAQUA\n" + + "A4GNADCBiQKBgQCp2G7pGwMOw4oM7zFFeRKrByuPLNAXClGsh+itdRiOeUgEby6OB9IAgXm93086\n" + + "Z9dWCfRYbzJbDRSnUE7FS1iQsIRIeOEuFMIMogcBK+sOf364ONwMXsI4gtYVmxn4BaaajVWt6C/g\n" + + "FBGZQxp81aORDyUIrlCkMIxhZBSsNPIJYwIDAQABoyEwHzAdBgNVHQ4EFgQUKrvzNhJmdKoqq2li\n" + + "utCzKkwA1N0wDQYJKoZIhvcNAQEFBQADgYEAEIaegsW7fWWjXk4YOMlcl893vx6tnU8ThuQSjwGI\n" + + "rIs93sBYuY7lQIpQw8+XM89WT1XuBB6R2SsnxeW+gHtsU/EE6iJJAEMeCILwEGUL02blwHBQWmpa\n" + + "i3YeGXw+IFe/4OAysPT7ZRbUb7mPt37Ht6hIjain71ShR5anXIuawVE=\n" + + "-----END CERTIFICATE-----\n"; + // Test cert for CN=A, happens to have a zero at the beginning of signature + static String normalCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIIB1DCCAT2gAwIBAgIEae+u1TANBgkqhkiG9w0BAQUFADANMQswCQYDVQQDEwJDQTAeFw0xMDA2\n" + + "MDMwODA2NTNaFw0xMDA5MDEwODA2NTNaMAwxCjAIBgNVBAMTAUEwgZ8wDQYJKoZIhvcNAQEBBQAD\n" + + "gY0AMIGJAoGBAKZ7C6bC8AJmXIRNwuPJcgIPW1ygN3rE5PIKPAkeK/dYnPmUJNuiSxOFPJCrLMuL\n" + + "sweQh82Dq/viu+KBb27xVzJ4pK02fbcWdJDo7cIms0Wm+HckK5myA6xmqnpmPOjb/vWCLE6pN2Xg\n" + + "pJyrdeWV77eBvqE9OiCsMTP8WgHI9zLvAgMBAAGjQjBAMB0GA1UdDgQWBBTtIKqCHnL9QeFn+YrX\n" + + "+k00NUk9mjAfBgNVHSMEGDAWgBQqu/M2EmZ0qiqraWK60LMqTADU3TANBgkqhkiG9w0BAQUFAAOB\n" + + "gQAAOcQsEruDAY/z3eXJ7OtWSZlLC0yTVNVdUVNLQ58xNqPrmKNBXNpj/72N8xrTB++ApW+DLgLy\n" + + "cwGU5PVRtsYeiV6prUkpqUf62SQgwI4guAQy1ileeP1CNQJI3cHQExMAHvQT8fJtlD0WZD3nfesq\n" + + "mmQDOpoJLkmO/73Z7IibVA==\n" + + "-----END CERTIFICATE-----\n"; + // normalCertStr with an extra zero at the beginning of signature + static String longerCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIIB1TCCAT2gAwIBAgIEae+u1TANBgkqhkiG9w0BAQUFADANMQswCQYDVQQDEwJDQTAeFw0xMDA2\n" + + "MDMwODA2NTNaFw0xMDA5MDEwODA2NTNaMAwxCjAIBgNVBAMTAUEwgZ8wDQYJKoZIhvcNAQEBBQAD\n" + + "gY0AMIGJAoGBAKZ7C6bC8AJmXIRNwuPJcgIPW1ygN3rE5PIKPAkeK/dYnPmUJNuiSxOFPJCrLMuL\n" + + "sweQh82Dq/viu+KBb27xVzJ4pK02fbcWdJDo7cIms0Wm+HckK5myA6xmqnpmPOjb/vWCLE6pN2Xg\n" + + "pJyrdeWV77eBvqE9OiCsMTP8WgHI9zLvAgMBAAGjQjBAMB0GA1UdDgQWBBTtIKqCHnL9QeFn+YrX\n" + + "+k00NUk9mjAfBgNVHSMEGDAWgBQqu/M2EmZ0qiqraWK60LMqTADU3TANBgkqhkiG9w0BAQUFAAOB\n" + + "ggAAADnELBK7gwGP893lyezrVkmZSwtMk1TVXVFTS0OfMTaj65ijQVzaY/+9jfMa0wfvgKVvgy4C\n" + + "8nMBlOT1UbbGHoleqa1JKalH+tkkIMCOILgEMtYpXnj9QjUCSN3B0BMTAB70E/HybZQ9FmQ9533r\n" + + "KppkAzqaCS5Jjv+92eyIm1Q=\n" + + "-----END CERTIFICATE-----\n"; + // normalCertStr without the initial zero at the beginning of signature + static String shorterCertStr = + "-----BEGIN CERTIFICATE-----\n" + + "MIIB0zCCAT2gAwIBAgIEae+u1TANBgkqhkiG9w0BAQUFADANMQswCQYDVQQDEwJDQTAeFw0xMDA2\n" + + "MDMwODA2NTNaFw0xMDA5MDEwODA2NTNaMAwxCjAIBgNVBAMTAUEwgZ8wDQYJKoZIhvcNAQEBBQAD\n" + + "gY0AMIGJAoGBAKZ7C6bC8AJmXIRNwuPJcgIPW1ygN3rE5PIKPAkeK/dYnPmUJNuiSxOFPJCrLMuL\n" + + "sweQh82Dq/viu+KBb27xVzJ4pK02fbcWdJDo7cIms0Wm+HckK5myA6xmqnpmPOjb/vWCLE6pN2Xg\n" + + "pJyrdeWV77eBvqE9OiCsMTP8WgHI9zLvAgMBAAGjQjBAMB0GA1UdDgQWBBTtIKqCHnL9QeFn+YrX\n" + + "+k00NUk9mjAfBgNVHSMEGDAWgBQqu/M2EmZ0qiqraWK60LMqTADU3TANBgkqhkiG9w0BAQUFAAOB\n" + + "gAA5xCwSu4MBj/Pd5cns61ZJmUsLTJNU1V1RU0tDnzE2o+uYo0Fc2mP/vY3zGtMH74Clb4MuAvJz\n" + + "AZTk9VG2xh6JXqmtSSmpR/rZJCDAjiC4BDLWKV54/UI1AkjdwdATEwAe9BPx8m2UPRZkPed96yqa\n" + + "ZAM6mgkuSY7/vdnsiJtU\n" + + "-----END CERTIFICATE-----\n"; + + public static void main(String args[]) throws Exception { + + Certificate signer = generate(signerCertStr); + + // the valid certificate + Certificate normal = generate(normalCertStr); + // the invalid certificate with extra signature bits + Certificate longer = generate(longerCertStr); + // the invalid certificate without enough signature bits + Certificate shorter = generate(shorterCertStr); + + if (!test(normal, signer, " normal", true) || + !test(longer, signer, " longer", false) || + !test(shorter, signer, "shorter", false)) { + throw new Exception("Test failed."); + } + } + + private static Certificate generate(String certStr) throws Exception { + InputStream is = null; + try { + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + is = new ByteArrayInputStream(certStr.getBytes()); + return cf.generateCertificate(is); + } finally { + if (is != null) { + is.close(); + } + } + } + + private static boolean test(Certificate target, Certificate signer, + String title, boolean expected) throws Exception { + System.out.print("Checking " + title + ": expected: " + + (expected ? " verified" : "NOT verified")); + boolean actual; + try { + PublicKey pubKey = signer.getPublicKey(); + target.verify(pubKey); + actual = true; + } catch (SignatureException se) { + actual = false; + } + System.out.println(", actual: " + + (actual ? " verified" : "NOT verified")); + return actual == expected; + } + +} diff -r 16d2b5e6517a -r 78a87adede1e jdk/test/sun/security/rsa/TestKeyPairGenerator.java --- a/jdk/test/sun/security/rsa/TestKeyPairGenerator.java Mon Dec 06 10:46:26 2010 +0800 +++ b/jdk/test/sun/security/rsa/TestKeyPairGenerator.java Mon Dec 06 10:48:18 2010 +0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, 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 @@ -85,8 +85,12 @@ sig.initVerify(kp2.getPublic()); sig.update(data); // verify needs to return false and not throw an Exception - if (sig.verify(signature)) { - throw new Exception("verification unexpectedly succeeded"); + try { + if (sig.verify(signature)) { + throw new Exception("verification unexpectedly succeeded"); + } + } catch (SignatureException se) { + // Yet another kind of failure, OK. } }