[PATCH] 8165751: NPE in Signature with java.security.debug=provider
Adam Petcher
adam.petcher at oracle.com
Tue Dec 13 18:43:49 UTC 2016
Here is the latest diff that simply adds a null check to the existing
code. When the provider is null, the debug output will be "...algorithm
from: (no provider)". The test code is the same as the last diff.
diff --git a/src/java.base/share/classes/java/security/Signature.java
b/src/java.base/share/classes/java/security/Signature.java
--- a/src/java.base/share/classes/java/security/Signature.java
+++ b/src/java.base/share/classes/java/security/Signature.java
@@ -452,6 +452,10 @@
return this.provider;
}
+ private String getProviderName() {
+ return (provider == null) ? "(no provider)" : provider.getName();
+ }
+
void chooseFirstProvider() {
// empty, overridden in Delegate
}
@@ -473,7 +477,7 @@
if (!skipDebug && pdebug != null) {
pdebug.println("Signature." + algorithm +
- " verification algorithm from: " +
this.provider.getName());
+ " verification algorithm from: " + getProviderName());
}
}
@@ -522,7 +526,7 @@
if (!skipDebug && pdebug != null) {
pdebug.println("Signature." + algorithm +
- " verification algorithm from: " +
this.provider.getName());
+ " verification algorithm from: " + getProviderName());
}
}
@@ -543,7 +547,7 @@
if (!skipDebug && pdebug != null) {
pdebug.println("Signature." + algorithm +
- " signing algorithm from: " + this.provider.getName());
+ " signing algorithm from: " + getProviderName());
}
}
@@ -566,7 +570,7 @@
if (!skipDebug && pdebug != null) {
pdebug.println("Signature." + algorithm +
- " signing algorithm from: " + this.provider.getName());
+ " signing algorithm from: " + getProviderName());
}
}
diff --git a/test/java/security/Signature/NoProvider.java
b/test/java/security/Signature/NoProvider.java
new file mode 100644
--- /dev/null
+++ b/test/java/security/Signature/NoProvider.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2016, 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
+ * @bug 8165751
+ * @summary Verify that that a subclass of Signature that does not
contain a
+ * provider can be used verify.
+ * @run main/othervm -Djava.security.debug=provider NoProvider
+ */
+
+import java.security.*;
+
+public class NoProvider {
+
+ private static class NoProviderPublicKey implements PublicKey {
+
+ public String getAlgorithm() {
+ return "NoProvider";
+ }
+ public String getFormat() {
+ return "none";
+ }
+ public byte[] getEncoded() {
+ return new byte[1];
+ }
+ }
+
+ private static class NoProviderSignature extends Signature {
+
+ public NoProviderSignature() {
+ super("NoProvider");
+ }
+
+ protected void engineInitVerify(PublicKey publicKey)
+ throws InvalidKeyException {
+ // do nothing
+ }
+
+ protected void engineInitSign(PrivateKey privateKey)
+ throws InvalidKeyException {
+ // do nothing
+ }
+
+ protected void engineUpdate(byte b) throws SignatureException {
+ // do nothing
+ }
+
+ protected void engineUpdate(byte[] b, int off, int len)
+ throws SignatureException {
+ // do nothing
+ }
+
+ protected byte[] engineSign() throws SignatureException {
+ return new byte[1];
+ }
+
+ protected boolean engineVerify(byte[] sigBytes)
+ throws SignatureException {
+ return false;
+ }
+
+ @Deprecated
+ protected void engineSetParameter(String param, Object value)
+ throws InvalidParameterException {
+ // do nothing
+ }
+
+ @Deprecated
+ protected Object engineGetParameter(String param)
+ throws InvalidParameterException {
+ return null;
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ new NoProviderSignature().initVerify(new NoProviderPublicKey());
+ }
+}
On 12/13/2016 11:56 AM, Sean Mullan wrote:
> On 12/13/16 11:30 AM, Adam Petcher wrote:
>> Thanks for the review.
>>
>> After thinking about this some more, I don't like the idea of using
>> Optional for a member variable due to the limitations of this class and
>> the lack of support for this usage of it. I'll send out a new diff that
>> uses a standard null check.
>>
>> See below for other comments.
>>
>>
>> On 12/12/2016 9:20 PM, Wang Weijun wrote:
>>> Hi Adam
>>>
>>> The only behavior change is with the debug output, right?
>> Yes. This will be more obvious in my next diff.
>>>
>>> Is this a new pattern that internal optional fields should be defined
>>> as an Optional?
>>>
>>> And, when there is no provider the string form "from: " looks strange,
>>> I would rather make it "from nowhere". I would also move the space
>>> before "from" to where the method is called, say, " verification
>>> algorithm " + getProvidedByString().
>> It doesn't print the "from: " when there is no provider. So the string
>> will look like "Signature.DSA verification algorithm" in this case. I
>> don't have a strong opinion on whether we should print "from: no
>> provider" (for example), but Sean expressed a preference for leaving
>> this entire part blank when there is no provider (as it is in my last
>> diff).
>
> Maybe "from: (no provider)" would be better. I think a previous
> version had "from: none", but thinking about it more, "from: (no
> provider)" is probably better than not printing anything for a null
> provider.
>
> --Sean
>
>>>
>>> Thanks
>>> Max
>>>
>>>> On Dec 13, 2016, at 4:05 AM, Adam Petcher <adam.petcher at oracle.com>
>>>> wrote:
>>>>
>>>> Okay. I changed getProvider() to return this.provider.orElse(null),
>>>> which will allow this method to return null. For consistency, I allow
>>>> all other providers (in Instance and Service) to be null using
>>>> Optional.ofNullable(). Hopefully, I found and fixed all the
>>>> whitespace issues, too. Here is the corrected diff:
>>>>
>>>> diff --git a/src/java.base/share/classes/java/security/Signature.java
>>>> b/src/java.base/share/classes/java/security/Signature.java
>>>> --- a/src/java.base/share/classes/java/security/Signature.java
>>>> +++ b/src/java.base/share/classes/java/security/Signature.java
>>>> @@ -134,7 +134,7 @@
>>>> private String algorithm;
>>>>
>>>> // The provider
>>>> - Provider provider;
>>>> + Optional<Provider> provider = Optional.empty();
>>>>
>>>> /**
>>>> * Possible {@link #state} value, signifying that
>>>> @@ -266,7 +266,7 @@
>>>> SignatureSpi spi = (SignatureSpi)instance.impl;
>>>> sig = new Delegate(spi, algorithm);
>>>> }
>>>> - sig.provider = instance.provider;
>>>> + sig.provider = Optional.ofNullable(instance.provider);
>>>> return sig;
>>>> }
>>>>
>>>> @@ -449,13 +449,17 @@
>>>> */
>>>> public final Provider getProvider() {
>>>> chooseFirstProvider();
>>>> - return this.provider;
>>>> + return this.provider.orElse(null);
>>>> }
>>>>
>>>> void chooseFirstProvider() {
>>>> // empty, overridden in Delegate
>>>> }
>>>>
>>>> + private String getProvidedByString() {
>>>> + return provider.map(x -> " from: " + x.getName()).orElse("");
>>>> + }
>>>> +
>>>> /**
>>>> * Initializes this object for verification. If this method is
>>>> called
>>>> * again with a different argument, it negates the effect
>>>> @@ -473,7 +477,7 @@
>>>>
>>>> if (!skipDebug && pdebug != null) {
>>>> pdebug.println("Signature." + algorithm +
>>>> - " verification algorithm from: " +
>>>> this.provider.getName());
>>>> + " verification algorithm" + getProvidedByString());
>>>> }
>>>> }
>>>>
>>>> @@ -522,7 +526,7 @@
>>>>
>>>> if (!skipDebug && pdebug != null) {
>>>> pdebug.println("Signature." + algorithm +
>>>> - " verification algorithm from: " +
>>>> this.provider.getName());
>>>> + " verification algorithm" + getProvidedByString());
>>>> }
>>>> }
>>>>
>>>> @@ -543,7 +547,7 @@
>>>>
>>>> if (!skipDebug && pdebug != null) {
>>>> pdebug.println("Signature." + algorithm +
>>>> - " signing algorithm from: " +
>>>> this.provider.getName());
>>>> + " signing algorithm" + getProvidedByString());
>>>> }
>>>> }
>>>>
>>>> @@ -566,7 +570,7 @@
>>>>
>>>> if (!skipDebug && pdebug != null) {
>>>> pdebug.println("Signature." + algorithm +
>>>> - " signing algorithm from: " +
>>>> this.provider.getName());
>>>> + " signing algorithm" + getProvidedByString());
>>>> }
>>>> }
>>>>
>>>> @@ -1087,7 +1091,7 @@
>>>> }
>>>> try {
>>>> sigSpi = newInstance(s);
>>>> - provider = s.getProvider();
>>>> + provider =
>>>> Optional.ofNullable(s.getProvider());
>>>> // not needed any more
>>>> firstService = null;
>>>> serviceIterator = null;
>>>> @@ -1132,7 +1136,7 @@
>>>> try {
>>>> SignatureSpi spi = newInstance(s);
>>>> init(spi, type, key, random);
>>>> - provider = s.getProvider();
>>>> + provider =
>>>> Optional.ofNullable(s.getProvider());
>>>> sigSpi = spi;
>>>> firstService = null;
>>>> serviceIterator = null;
>>>> diff --git a/test/java/security/Signature/NoProvider.java
>>>> b/test/java/security/Signature/NoProvider.java
>>>> new file mode 100644
>>>> --- /dev/null
>>>> +++ b/test/java/security/Signature/NoProvider.java
>>>> @@ -0,0 +1,99 @@
>>>> +/*
>>>> + * Copyright (c) 2016, 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
>>>> + * @bug 8165751
>>>> + * @summary Verify that that a subclass of Signature that does not
>>>> contain a
>>>> + * provider can be used verify.
>>>> + * @run main/othervm -Djava.security.debug=provider NoProvider
>>>> + */
>>>> +
>>>> +import java.security.*;
>>>> +
>>>> +public class NoProvider {
>>>> +
>>>> + private static class NoProviderPublicKey implements PublicKey {
>>>> +
>>>> + public String getAlgorithm() {
>>>> + return "NoProvider";
>>>> + }
>>>> + public String getFormat() {
>>>> + return "none";
>>>> + }
>>>> + public byte[] getEncoded() {
>>>> + return new byte[1];
>>>> + }
>>>> + }
>>>> +
>>>> + private static class NoProviderSignature extends Signature {
>>>> +
>>>> + public NoProviderSignature() {
>>>> + super("NoProvider");
>>>> + }
>>>> +
>>>> + protected void engineInitVerify(PublicKey publicKey)
>>>> + throws InvalidKeyException {
>>>> + // do nothing
>>>> + }
>>>> +
>>>> + protected void engineInitSign(PrivateKey privateKey)
>>>> + throws InvalidKeyException {
>>>> + // do nothing
>>>> + }
>>>> +
>>>> + protected void engineUpdate(byte b) throws
>>>> SignatureException {
>>>> + // do nothing
>>>> + }
>>>> +
>>>> + protected void engineUpdate(byte[] b, int off, int len)
>>>> + throws SignatureException {
>>>> + // do nothing
>>>> + }
>>>> +
>>>> + protected byte[] engineSign() throws SignatureException {
>>>> + return new byte[1];
>>>> + }
>>>> +
>>>> + protected boolean engineVerify(byte[] sigBytes)
>>>> + throws SignatureException {
>>>> + return false;
>>>> + }
>>>> +
>>>> + @Deprecated
>>>> + protected void engineSetParameter(String param, Object value)
>>>> + throws InvalidParameterException {
>>>> + // do nothing
>>>> + }
>>>> +
>>>> + @Deprecated
>>>> + protected Object engineGetParameter(String param)
>>>> + throws InvalidParameterException {
>>>> + return null;
>>>> + }
>>>> + }
>>>> +
>>>> + public static void main(String[] args) throws Exception {
>>>> + new NoProviderSignature().initVerify(new
>>>> NoProviderPublicKey());
>>>> + }
>>>> +}
>>>>
>>>>
>>>> On 12/12/2016 1:44 PM, Sean Mullan wrote:
>>>>> On 12/8/16 11:17 AM, Adam Petcher wrote:
>>>>>> Subclasses of Signature may have a null provider. In this case, the
>>>>>> debug logging code will throw a NPE when attempting to call
>>>>>> getName() on
>>>>>> it. Since this member may be null, I would like to change its
>>>>>> type to
>>>>>> Optional to ensure that code checks whether it is present before
>>>>>> using
>>>>>> it. I have assumed that getProvider() methods (in both Signature and
>>>>>> Service) always return non-null---if this assumption is incorrect,
>>>>>> then
>>>>>> I'll need to change some of the uses of Optional in/around these
>>>>>> methods.
>>>>> I think we would want to preserve the current behavior of
>>>>> getProvider returning null for one of these subclasses (even though
>>>>> it isn't specified that null is an acceptable return value). Better
>>>>> to be safe here, otherwise NoSuchElementException would be thrown
>>>>> which would be unexpected and not specified by getProvider.
>>>>>
>>>>> Other than that, just a minor style comment on a few lines of the
>>>>> test:
>>>>>
>>>>>> + private static class NoProviderPublicKey implements PublicKey{
>>>>> space before "{"
>>>>>
>>>>> --Sean
>>>>>
>>>>>> Note that this issue of missing null checks for providers exists in
>>>>>> several classes (e.g. Cipher, MessageDigest). Once this patch is
>>>>>> reviewed and committed, I will apply the same solution to all other
>>>>>> affected classes.
>>>>>>
>>>>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8165751
>>>>>>
>>>>>> Diff:
>>>>>>
>>>>>> diff --git
>>>>>> a/src/java.base/share/classes/java/security/Signature.java
>>>>>> b/src/java.base/share/classes/java/security/Signature.java
>>>>>> --- a/src/java.base/share/classes/java/security/Signature.java
>>>>>> +++ b/src/java.base/share/classes/java/security/Signature.java
>>>>>> @@ -134,7 +134,7 @@
>>>>>> private String algorithm;
>>>>>>
>>>>>> // The provider
>>>>>> - Provider provider;
>>>>>> + Optional<Provider> provider = Optional.empty();
>>>>>>
>>>>>> /**
>>>>>> * Possible {@link #state} value, signifying that
>>>>>> @@ -266,7 +266,7 @@
>>>>>> SignatureSpi spi = (SignatureSpi)instance.impl;
>>>>>> sig = new Delegate(spi, algorithm);
>>>>>> }
>>>>>> - sig.provider = instance.provider;
>>>>>> + sig.provider = Optional.of(instance.provider);
>>>>>> return sig;
>>>>>> }
>>>>>>
>>>>>> @@ -449,13 +449,17 @@
>>>>>> */
>>>>>> public final Provider getProvider() {
>>>>>> chooseFirstProvider();
>>>>>> - return this.provider;
>>>>>> + return this.provider.get();
>>>>>> }
>>>>>>
>>>>>> void chooseFirstProvider() {
>>>>>> // empty, overridden in Delegate
>>>>>> }
>>>>>>
>>>>>> + private String getProvidedByString(){
>>>>>> + return provider.map(x -> " from: " +
>>>>>> x.getName()).orElse("");
>>>>>> + }
>>>>>> +
>>>>>> /**
>>>>>> * Initializes this object for verification. If this method is
>>>>>> called
>>>>>> * again with a different argument, it negates the effect
>>>>>> @@ -473,7 +477,7 @@
>>>>>>
>>>>>> if (!skipDebug && pdebug != null) {
>>>>>> pdebug.println("Signature." + algorithm +
>>>>>> - " verification algorithm from: " +
>>>>>> this.provider.getName());
>>>>>> + " verification algorithm" + getProvidedByString());
>>>>>> }
>>>>>> }
>>>>>>
>>>>>> @@ -522,7 +526,7 @@
>>>>>>
>>>>>> if (!skipDebug && pdebug != null) {
>>>>>> pdebug.println("Signature." + algorithm +
>>>>>> - " verification algorithm from: " +
>>>>>> this.provider.getName());
>>>>>> + " verification algorithm" + getProvidedByString());
>>>>>> }
>>>>>> }
>>>>>>
>>>>>> @@ -543,7 +547,7 @@
>>>>>>
>>>>>> if (!skipDebug && pdebug != null) {
>>>>>> pdebug.println("Signature." + algorithm +
>>>>>> - " signing algorithm from: " +
>>>>>> this.provider.getName());
>>>>>> + " signing algorithm" + getProvidedByString());
>>>>>> }
>>>>>> }
>>>>>>
>>>>>> @@ -566,7 +570,7 @@
>>>>>>
>>>>>> if (!skipDebug && pdebug != null) {
>>>>>> pdebug.println("Signature." + algorithm +
>>>>>> - " signing algorithm from: " +
>>>>>> this.provider.getName());
>>>>>> + " signing algorithm" + getProvidedByString());
>>>>>> }
>>>>>> }
>>>>>>
>>>>>> @@ -1087,7 +1091,7 @@
>>>>>> }
>>>>>> try {
>>>>>> sigSpi = newInstance(s);
>>>>>> - provider = s.getProvider();
>>>>>> + provider = Optional.of(s.getProvider());
>>>>>> // not needed any more
>>>>>> firstService = null;
>>>>>> serviceIterator = null;
>>>>>> @@ -1132,7 +1136,7 @@
>>>>>> try {
>>>>>> SignatureSpi spi = newInstance(s);
>>>>>> init(spi, type, key, random);
>>>>>> - provider = s.getProvider();
>>>>>> + provider = Optional.of(s.getProvider());
>>>>>> sigSpi = spi;
>>>>>> firstService = null;
>>>>>> serviceIterator = null;
>>>>>> diff --git a/test/java/security/Signature/NoProvider.java
>>>>>> b/test/java/security/Signature/NoProvider.java
>>>>>> new file mode 100644
>>>>>> --- /dev/null
>>>>>> +++ b/test/java/security/Signature/NoProvider.java
>>>>>> @@ -0,0 +1,99 @@
>>>>>> +/*
>>>>>> + * Copyright (c) 2016, 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
>>>>>> + * @bug 8165751
>>>>>> + * @summary Verify that that a subclass of Signature that does not
>>>>>> contain a
>>>>>> + * provider can be used verify.
>>>>>> + * @run main/othervm -Djava.security.debug=provider NoProvider
>>>>>> + */
>>>>>> +
>>>>>> +import java.security.*;
>>>>>> +
>>>>>> +public class NoProvider {
>>>>>> +
>>>>>> + private static class NoProviderPublicKey implements PublicKey{
>>>>>> + public String getAlgorithm(){
>>>>>> + return "NoProvider";
>>>>>> + }
>>>>>> + public String getFormat(){
>>>>>> + return "none";
>>>>>> + }
>>>>>> + public byte[] getEncoded(){
>>>>>> + return new byte[1];
>>>>>> + }
>>>>>> + }
>>>>>> +
>>>>>> + private static class NoProviderSignature extends Signature{
>>>>>> +
>>>>>> + public NoProviderSignature(){
>>>>>> + super("NoProvider");
>>>>>> + }
>>>>>> +
>>>>>> + protected void engineInitVerify(PublicKey publicKey)
>>>>>> + throws InvalidKeyException{
>>>>>> + // do nothing
>>>>>> + }
>>>>>> +
>>>>>> + protected void engineInitSign(PrivateKey privateKey)
>>>>>> + throws InvalidKeyException{
>>>>>> + // do nothing
>>>>>> + }
>>>>>> +
>>>>>> + protected void engineUpdate(byte b) throws
>>>>>> SignatureException{
>>>>>> + // do nothing
>>>>>> + }
>>>>>> +
>>>>>> + protected void engineUpdate(byte[] b, int off, int len)
>>>>>> + throws SignatureException{
>>>>>> + // do nothing
>>>>>> + }
>>>>>> +
>>>>>> + protected byte[] engineSign() throws SignatureException{
>>>>>> + return new byte[1];
>>>>>> + }
>>>>>> +
>>>>>> + protected boolean engineVerify(byte[] sigBytes)
>>>>>> + throws SignatureException{
>>>>>> + return false;
>>>>>> + }
>>>>>> +
>>>>>> + @Deprecated
>>>>>> + protected void engineSetParameter(String param, Object
>>>>>> value)
>>>>>> + throws InvalidParameterException{
>>>>>> + // do nothing
>>>>>> + }
>>>>>> +
>>>>>> + @Deprecated
>>>>>> + protected Object engineGetParameter(String param)
>>>>>> + throws InvalidParameterException{
>>>>>> + return null;
>>>>>> + }
>>>>>> +
>>>>>> + }
>>>>>> +
>>>>>> + public static void main(String[] args) throws Exception {
>>>>>> + new NoProviderSignature().initVerify(new
>>>>>> NoProviderPublicKey());
>>>>>> + }
>>>>>> +}
>>
More information about the security-dev
mailing list