jarsigner verification using only trusted certificates? - keytool

I noticed that in the keytool documentation it reads
"jarsigner [...] checks whether or not the public key of that certificate is 'trusted', i.e., is contained in the specified keystore."
whereas the jarsigner manpage states
"A keystore is not required when verifying [...]", and that the utility will always verify against the certificate supplied with the jar.
In the way I see it that would kind of defeat the purpose, since it would only certify that the jar was not altered since it was signed but not that it was signed by some specific authority/supplier.
Is there some way to make the verification fail if the certificate used to sign the jar is not known/trusted on the runtime system?
Or do I have to use a script to call
jarsigner -verify -verbose -keystore ...
and parse the output to see whether there is an entry for the signing certificate in the local (runtime) keystore?
Confused,
Peter

jarsigner utility is quite useless for JAR signature verification, as it does not verify the signer certificate, does not check trusted timestamps on the signature and does not provide usable result (parsing console output is not a good solution).
To avoid this limitations we have chosen to write our own verify_jar utility.

Related

How can I specify a SHA-256 algorithm for signing the certificate?

I built an Apereo CAS demo server with a WAR overlay (with which
different services should be authenticated).
I have set up delegated authentication with SAML2 (for integrating
with italian SPID system), following this guide
https://apereo.github.io/2019/02/25/cas61-delegate-authn-saml2-idp/
I copied the SP metadata to a IDP configuration.
This IDP is a test IDP instance, meant to check if SP metadata and the SAML request are ok.
When I run the server and I browse it,
I can see the second login form, but when I click it, the validation checks shows some errors.
Among them there is the following:
"The certificate must be signed with a valid algorithm."
"The certificate must not be signed using the SHA1 algorithm (deprecated)."
I am pretty sure that SHA-256 would be fine with the IDP validator.
In the documentation
https://apereo.github.io/cas/development/integration/Delegate-Authentication-SAML.html
I see that the following parameter should be in charge of specifying
the signing certificate algorithm:
cas.authn.pac4j.saml[].signature-algorithms:
Its description is
# Required: false
# Type: java.util.List<String>
# Owner: org.apereo.cas.configuration.model.support.pac4j.saml.Pac4jSamlClientProperties
# Module: cas-server-support-pac4j-webflow
# Collection of signing signature algorithms, if any, to override the global defaults.
# cas.authn.pac4j.saml[].signature-algorithms:
I don't know what values are allowed there. I googled a lot but with no luck.
I have tried to set that list like this
cas.authn.pac4j.saml[0].signature-algorithms=["sha256WithRSAEncryption"],
cas.authn.pac4j.saml[0].signature-algorithms=["SHA256withRSA"] but,
after clicking the SAML login button, I always get the following
error:
org.pac4j.saml.exceptions.SAMLException: org.pac4j.saml.exceptions.SAMLException: Could not determine the signature parameters
at org.pac4j.saml.crypto.DefaultSignatureSigningParametersProvider.build(DefaultSignatureSigningParametersProvider.java:60)
...
How can I specify a SHA-256 algorithm for signing the certificate?

Can't verify signatures with nuget

I have a package that I signed with my own certificate, issued by my own CA.
I signed a nuget package with the certificate.
When I add the root CA in the trust store of the machine, I can verify the signature successfully with nuget, using
nuget verify test.nupkg -Signatures
But, if I remove the root from the trust store, and instead, I add the thumbprint of my certificate as a trusted signers, in nuget, setting allowUntrustedRoot to true, I cannot verify the signature, for some reason.
> nuget trusted-signers
Registered trusted signers:
1. MyCert [author]
Certificate fingerprint(s):
[U] SHA256 - 39544DEE346D61EB2FF5CF4A35EF4B42DE5B4641E1B9AAA098A2A5291F683631
But
> nuget verify test.nupkg -Signatures
Verifying Test
C:\test.nupkg
Signature Hash Algorithm: SHA256
WARNING: NU3027: The signature should be timestamped to enable long-term signature validity after the certificate has expired.
Signature type: Author
Verifying the author primary signature with certificate:
Subject Name: CN=Test Certificate, OU=Test, C=BE
SHA1 hash: 679B1E503720C69D981B9CC4F0199D5D8593375A
SHA256 hash: 39544DEE346D61EB2FF5CF4A35EF4B42DE5B4641E1B9AAA098A2A5291F683631
Issued by: CN=Test Root, OU=Test, O=Test, C=BE
Valid from: 10/31/2019 10:29:54 AM to 9/24/2023 11:37:39 AM
NU3018: The author primary signature found a chain building issue: A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.
WARNING: NU3018: The author primary signature found a chain building issue: The revocation function was unable to check revocation because the revocation server could not be reached. For more information, visit https://aka.ms/certificateRevocationMode.
WARNING: NU3018: The author primary signature found a chain building issue: The revocation function was unable to check revocation for the certificate.
Finished with 1 errors and 3 warnings.
Package signature validation failed.
What's the point of adding a trusted signer and setting allowUntrustedRoot to true if the signature is not verify. I mean, it's apparently enough to add the root certificate to the trust store for the signature to be verified, without doing anything with the configuration.
I would like, if possible, to be able to not import the root CA in the trust store, and only use the configuration of Nuget to verify successfully the signature.
Thanks.
Our belief is that if you tried to use that package in a project with those trust policy settings appropriately in nuget.configs, restore will succeed.
Please confirm that.
Next, nuget verify has a -config switch -- please try passing in the path to your nuget.config.
If the first test works, and the second test doesn't, nuget may have a bug in the verify command. If so, please file an issue at https://github.com/nuget/home/issues/
-Rob Relyea (NuGet Client Team)

When .net says "certificate valid", what is it checking?

I'm using the SignedXml.CheckSignature(X509Certificate2, boolean) method. I would like to know what checks are performed when deciding the validity of the certificate. I have verified that the Current User/Not Trusted list is checked. The documentation says it will use the "address book" store, searching by subject key identifier, to build the certificate chain. I imagine this means the Local Machine and Current User certificate stores?
Am I right to think that certificate revocation and signature timestamp are not checked? To do an OCSP check for certificate revocation, am I obliged to use Bouncy Castle?
In the remarks in the msdn article you link to one finds:
In version 1.1 of the .NET Framework, the X.509 certificate is not verified.
In version 2.0 and later, the X.509 certificate is verified.
In version 2.0 and later of the .NET Framework, the CheckSignature method will search the "AddressBook" store for certificates suitable for the verification. For example, if the certificate is referenced by a Subject Key Identifier (SKI), the CheckSignature method will select certificates with this SKI and try them one after another until it can verify the certificate.
Thus, first of all the behavior of that method has changed in different .NET framework versions. So for reproducible results, you had better not count on that method even check the certificate at all.
Furthermore, the formulation try them one after another until it can verify the certificate sounds like there just might be the mathematical test whether or not the certificate is signed by its alleged issuer.
https://referencesource.microsoft.com/#System.Security/system/security/cryptography/xml/signedxml.cs,b9518cc2212419a2
It checks
The certificate has no Key Usage extension, or the Key Usage extension has either Digital Signature or Non Repudiation usages enabled
The certificate chains up to a trusted root authority
The certificate has not been revoked
The certificate was not expired when you called this method
It doesn't know when the document was signed, so it doesn't answer that question.
That none of the certificates in the chain are explicitly prohibited by the user or system configuration.

Get a .p7b file from a .jks file

I have a .Net SAML implementation that verifies assertions' signatures against a PKCS 7 certificate in a .p7b file.
I have a customer who have a Java based identity provider. They can only provide their certificate in a Java key store .jks file.
I can verify the assertions that their identity provider sends, but I can't check that those assertions were signed by a trusted provider without verifying them against the certificates in the Java key store.
I can find lots online on how to add a .p7b certificate to a .jks file, but nothing on how to reverse the process.
How do I get a .p7b certificate (that .Net and Windows can open) from a supplied .jks file?
Alternatively I'm loading the .p7b into .Net using the native X509Chain implementation. If I can't convert the .jks is there any way to load it in .Net in a way that lets me check the assertions' signatures?
It turns out that there is a command line utility in Java that do what I need. In the Java runtime directory (C:\Program Files (x86)\Java\jre7\bin on my machine) there is a utility called keytool (my newlines for readability):
>keytool -importkeystore
-srckeystore clientStore.jks -srcstoretype JKS
-destkeystore outputStore.p12 -deststoretype PKCS12
This produces an output store called outputStore.p12 that I can load in .Net with X509Certificate2Collection.Import()

Signing .Jar file

Im sitting with a bit of a problem. Im busy creating a php/html website (intranet) for our support team to make life a bit easier when support linux machines.
I have a .jar app called mindterm (the free version) and want to run it as an applet in the site.
However according to their site you have to have the .jar file signed before loading it as an applet otherwise it cant open tcp connections.
So i did as much research as i could in the time i had and came up with the jarsigner.exe and keytool.exe files provided in the JDK installation.
However i do not have a clue how to go about signing this app so that i can actually use it.
Any help?
Thanks
First create a key-pair using keytool.
keytool -genkey -alias somekeyname
Then use jarsigner to sign it with the key you just created.
jarsigner /path/to/jar somekeyname
Note, you need to use the same alias (somekeyname here) as the one you create the key with.
Now, since the certificate is self-signed, the user of your applet will be prompted to approve the certificate. Once they do so, your tcp connections should work.
Since I assume you're only using the applet internally in your organization, self-signed certs should be fine. Otherwise you will have to pay for a certificate. In that case, your users will not need to accept the certificates after the first time (if they choose Always Allow").
You can sign jars using :
Install this Eclipse plugin
Eclipse Webstart Plugin.
You will just need to export as "Webstart". It will prompt you to sign the jars.
DEMO
Combined the top answer with some useful hints to get completely unattanded script:
keytool -genkey -noprompt -alias Alias -dname "CN=Hostname, OU=OrganizationalUnit, O=Organization, L=City, S=State, C=Country" -keystore path.to.keystore -storepass password -keypass password -validity 3650
jarsigner -keystore path.to.keystore -storepass password -keypass password -signedjar signed.jar unsigned.jar Alias
This is a somewhat complex area, and you essentially need to know what you are doing, and you may have to pay real money for a signing certificate.
The Sun Java Tutorial cover the topic well: http://docs.oracle.com/javase/tutorial/deployment/jar/signing.html
If the intent is to give the support people a ssh client, there might be better solutions.