Possibility to request the full certificate chain programmatically
Is your feature request related to a problem or specific use case? Please describe.
I try to get client-side hashing signing working, in my current use-case using JSign.
In the framework JSign is providing, before the actual signing the certificate chain is needed.
But the only way I found is to do a dummy-signing first, getting the signer certificate from the signing result.
And even then as far as I have seen, there is only the signer certificate itself, not the full certificate chain.
It would be nice if I could somehow get from the PlainSigner the full certificate chain via the "REST Interface", without triggering an actual signing process.
Describe the solution you'd like
I want to be able to get the full certificate chain programmatically that will be used for signing when I subsequently do a request to https://signserver.company.com/signserver/rest/v1/workers/PlainSigner/process.
Describe alternatives you've considered n/a
Product deployment Please complete the following information:
- Deployment format: container
- Version 6.3.0.Final
Is it still required in Jsign to get the certificate before signing? Do you know why that is?
"Still" like since I requested this 3 weeks ago? :-D Yes, it is still like that. I have no idea why, I just contributed SignServer support and had to do the dummy-signing to get the certificate chain in time, which of course also makes the signing twice as slow as it should be. Maybe @ebourg could answer that. But even if Jsign would be refactored to not need the chain up-front, it would probably still be usefull to have this ability.
Signing before getting the certificate? I have to think about it, but that's probably difficult because knowing the key algorithm is required beforehand and the certificate is a convenient way to retrieve it.
"Still" like since I requested this 3 weeks ago? :-D'
Hehe :) I mean because I saw there was many updates to the PR but did not have a chance to look into the details so I thought (hoped) that maybe that was not a real requirement and had changed along the way.
Note that, depending on the configuration and environment, it is not guaranteed that two calls to SignServer would return a signature using the same key and certificate. For instance if a load balancer is used in front of SignServer the request could go to an other SignServer instance potentially using different certificate and even different key. Also the certificate might not exist before the signing request comes in, if the 'one-time key and certificate feature' is used where a key is generated on demand and a new short-lived certificate is issued just for this signing request. Sure this are special cases but just to give an idea.
In #108 it is mentioned that Jsign has the option to let the user (?) choose which signature algorithm to use. If that is used, then it could be up to the user to provide the correct algorithm that matches what SignServer would then use. That way the certificate should not be needed before signing (at least not if it is only to get the algorithm) and only one call to SignServer (assuming the right algorithm is chosen). A check after signing (when the certificate is also returned) could be made to give a clear error message to the user about what was the expected algorithm.
Load balancing the signature endpoint and serving different keys is a bit surprising, but why not if there is a use case for that. It's nice if SignServer is very flexible but I don't think Jsign has to support every possible configuration. Jsign focuses on code signing and in this scenario SignServer is likely to be used as a proxy for a USB token delivered by a CA with a fixed long-lived key and certificate, and the user will simply configure the signer as Jsign expects. In this case the full certificate chain is probably not stored on the token anyway, so SignServer can't really do better, unless PlainSigner is modified to allow an external chain to be specified in the configuration.
Is it still required in Jsign to get the certificate before signing? Do you know why that is?
I got a look, when signing NuGet files there is a required signed attribute derived from the certificate (the RFC 5035 SigningCertificateV2 attribute containing the SHA-256 hash of the certificate, the name of the issuer and its serial number), so the certificate has to be know before signing.
NuGet put aside, I'm not sure Bouncy Castle's CMSSignedDataGenerator works if the certificate is known after signing. It holds a SignerInfoGenerator which is built by providing the content signer (referencing the key) and the certificate (it may just need the certificate serial number and the issuer though).
Okey, yes for those advanced signatures where the signature covers also the certificate than we can not get away from having the certificate before creating the plain signature.
Workaround for now is to to a "dummy" signature call first. Possible improvements could be to introduce a concept of dry-run signature which would be that same call but the actual signing would not be carried out. I guess only benefit with that would be to not perform signature creation twice. Third option would be to introduce a similar separate call that would require the same credentials but not the data to be signed and which would just return the certificate chain but not a signature.
I am looking into adding new REST endpoint(s) that hopefully could also address this issue.
The draft idea right now is to add the following ones for listing certificates, from any accessible worker or from a specific worker:
- GET /workers/certificates
- GET /workers/{idOrName}/certificates
You would call them using the same credentials as for the signing/process call and internally each worker configured to be visible in this way would have its Authorizer being invoked to check the authorization.
There could also be a new endpoint for specifying a specific certificate to use when signing (only needed if there are multiple certificates to choose from):
- POST /workers/{idOrName}/certificates/{certId}/process
Example of a get response:
[
{
"base64CertChain": [
"MIIEojCCAoqgAwIBAgIIDeDA2hFfJkwwDQYJKoZIhvcNAQELBQAwTTEXMBUGA1UEAwwORFNTIFJvb3QgQ0EgMTAxEDAOBgNVBAsMB1Rlc3RpbmcxEzARBgNVBAoMClNpZ25TZXJ2ZXIxCzAJBgNVBAYTAlNFMB4XDTE2MDMwMzA4MzEwNloXDTM2MDIyNzA4MzEwNlowSDESMBAGA1UEAwwJY29kZTAwMDAxMRAwDgYDVQQLDAdUZXN0aW5nMRMwEQYDVQQKDApTaWduU2VydmVyMQswCQYDVQQGEwJTRTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxzgH5vnC/yMFMRY4RowIYh1LIRmfyA9HOT9O+xrdRhHQRDzocZsnFcoGlYvuBwgfSK+8tk2jMpeBnPlkpp2+gs87QKvwSV7eM/q/pxKodp9/7DQuiuMcusPqa9BGc+p5bkKt+ZFno3pZ4bgakzmWx4vb1WR2ipl+Fa7MTBfHccxBvdWtzGwGjgJcmaahampmmUVC5goCnnE/HhZNdE7mwnRufY/UJBzywPRrJtJ0nlCzN3XtlRp/gtKA4IN4HR+cKR9+ol7LnkJmjxRDx1wlwH6q2OtI8ktJdWSywrU09ooN67fPg3LiCbHZsodN5VVx6jk43QeW1oIVo+IDvWLDsCAwEAAaOBijCBhzAdBgNVHQ4EFgQUnbFJH0kzSTwIPzz+XiWsPRDA6x4wDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBQgeiHe6K27Aqj7cVikCWK52FgFojAOBgNVHQ8BAf8EBAMCBeAwJwYDVR0lBCAwHgYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDBDANBgkqhkiG9w0BAQsFAAOCAgEAWZxx9dgtzBtcBOabI/yz65otvNSgHrcwXtzYhliGq+KiPTfKjilJ0nC1oqNZt8kvVV2JPC0ZebcdmH7lRpJmXiLdirUX7c627dMjWjfHSDDw2LVQBYH1i79Ztb8rKTl7oc2CxkUyoXdOYReS4b7sjpW2tdtP30UcM8ZGn2kmvsQd9BGvZyMqI+Q8VNc8sPYQUYlokbaIu+y/8wjskFtB3LbwvXW74eU6SSxPYvAa/2XxkzW/uyiX8BA1EoWrdQKv1X/DoiLYOq4/njtPvN1u8dy3ydOPDA8Y7RHn/dxkbrbtF3J0Ouz/HlXwsAHLus7fP8EpSxAIjhcPnZV9i7FERrPF2yta/31XQik3qK3Mkb1wTae6/pgmhySfVM+i/U4f/I8ldG0JQtaVZ4JGi3+x2Z9rqaFn7d2UVVE2H3bOqbqrN1YCnMHibm+8fm3Aza0Om1srQjzC217GLU4JsrVJysDzHrPP82REDoUPfVaLhUncYGyF+nNaTVaTEyFidjGXT/bS9qXj19e9Kks5C3BAQHDS3iY2GHxPIoGwGRVvaseiCMLiVj14dM5mwIG9NChqjPDIhsesMeDwMNAPOdXihEypw4lKDTpe3hJMnBCCT8xFF2jWVARLtey9l1InYuE9T2ssfUR9RyDBy7CnKaHYTPjSUx0T2iiUkfgpWeIUrfA=",
"MIIFfzCCA2egAwIBAgIIMk1BOK8CwTwwDQYJKoZIhvcNAQELBQAwTTEXMBUGA1UEAwwORFNTIFJvb3QgQ0EgMTAxEDAOBgNVBAsMB1Rlc3RpbmcxEzARBgNVBAoMClNpZ25TZXJ2ZXIxCzAJBgNVBAYTAlNFMB4XDTExMDUyNzA4MTQyN1oXDTM2MDUyNzA4MTQyN1owTTEXMBUGA1UEAwwORFNTIFJvb3QgQ0EgMTAxEDAOBgNVBAsMB1Rlc3RpbmcxEzARBgNVBAoMClNpZ25TZXJ2ZXIxCzAJBgNVBAYTAlNFMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAgblgjTTkMp1QAhgWDprhvqE9zX1Ux/A/RTOu4G4f6CTkd6JEEkbdKZv+CKv4cRoVCtfO3wnOokFRw/1JMmHHiQ1Z//uDoDjo8jk8nek0ArFE9R5NT02wMJCQa/mP1wU9ZSl1tx3jQRUFB+rTNeCcPTft+1FL7UjYMdkRzl261IOlmXzDMA+EYIGJ2c2wYhOv2DqfQygNz5GOf0EFqlQZIt/pzopSS+0K8mNb53ROhg9GJujwzugSH5Z+r0fsVHbCV0QUkZBfkRo9KMcdaDEPa8xpYTjsFPqU6RcnGkVABhn8OS8SIWw2re1f+htj6p9EGbk1m0I9pWGBA9ktWnrqlqDXV+tEhhh1O4f+LHieoxiscrF7RXxlYqyam6oabfXsX3VAC0M1UkwIciE8wA1Sj/+dgoSMqvEDNDfwpEYt6l8Z8czDTWDi7MM2u5VY0nP3+A+PepKrOtrdaGSP396f4a7A3un1o6nQWHsyWQ7kc8GIn8zN5nykQaghGyYlHHYe1XUSPtHmxjbdsyztrkIis3cfjFne0XgPAiQuYx3T/B+po9BhGIUwCV0Qi/gWVN6NkydsbzMeRXELQYyK+lHgIGiEaBzQRRtXbnB+wQXi2IacJNdKqICwDsl/PvvcZI9ZV6pB/KIzB+8IJm0CLY24K0OXJs3Bqij8gmpvbI+o0wUCAwEAAaNjMGEwHQYDVR0OBBYEFCB6Id7orbsCqPtxWKQJYrnYWAWiMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUIHoh3uituwKo+3FYpAliudhYBaIwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQAxFvpOZF6Kol48cQeKWQ48VAe+h5dmyKMfDLDZX51IRzfKKsHLpFPxzGNw4t9Uv4YOR0CD9z81dR+c93t1lwwIpKbx9Qmq8jViHEHKYD9FXThM+cVpsT25pg35m3ONeUX/b++l2d+2QNNTWMvdsCtaQdybZqbYFIk0IjPwLLqdsA8Io60kuES4JnQahPdLkfm70rgAdmRDozOfSDaaWHY20DovkfvKUYjPR6MGAPD5w9dEb4wp/ZjATblyZnH+LTflwfftUAonmAw46E0Zgg143sO6RfOOnbwjXEc+KXd/KQ6kTQ560mlyRd6q7EIDYRfD4n4agKV2R5gvVPhMD0+IK7kagqKNfWa9z8Ue2N3MedyWnb9wv4wC69qFndGaIfYADkUykoOyLsVVteJ70PVJPXO7s66LucfD2R0wo2MpuOYCsTOm7HHS+uZ9VjHl2qQ0ZQG89Xn+AXnzPbk1INe2z0lq3hzCW5DTYBKsJEexErzMpLwiEqUYJUfR9EeCM8UPMtLSqz1utdPoIYhULGzt5lSJEpMHMbquYfWJxQiKCbvfxQsP5dLUMEIqTgjNdo98OlM7Z7zjYH9Kimz3wgAKSAIoQZr7Oy1dMHO5GK4jBtZ8wgsyyQ6DzQQ7R68XFVKarIW8SATeyubAP+WjdMwk/ZXzsDjMZEtENaBXzAefYA=="
],
"certId": "9c221307cdafa8540c8c3e6ca74d227a295c83246079621619876f6f7a269a81",
"links": {
"process": "/workers/301/certificates/9c221307cdafa8540c8c3e6ca74d227a295c83246079621619876f6f7a269a81/process",
"certificate": "/workers/301/certificates/9c221307cdafa8540c8c3e6ca74d227a295c83246079621619876f6f7a269a81"
},
"workerDescription": "First PlainSigner accessible by Admin 4.",
"workerIdOrName": "301"
}
]
Note the certificate chain in base64CertChain and the certId that can be used when posting and also for convenience a link called "process" containing the location to post to.
Let me know if you have any feedback on the above.