math-dojo / user-account-service

Microservice for managing the users of the math-dojo platform
1 stars 0 forks source link

PP Function Fails to Start - Signature Verifier Key Error #40

Closed noce2 closed 3 years ago

noce2 commented 4 years ago

The function in pp fails to start with the following message in the logs, full stack trace below. The error message implies that the supplied keyId is incorrect.

Result: signature verification failed for an uknown reason
Exception: An invalid key was supplied in the creation of the HTTPRequestSignatureVerifier
Stack: java.lang.RuntimeException: An invalid key was supplied in the creation of the HTTPRequestSignatureVerifier
    at io.mathdojo.useraccountservice.security.HTTPRequestSignatureVerifier.lambda$new$0(HTTPRequestSignatureVerifier.java:60)
    at java.util.Collections$SingletonMap.forEach(Collections.java:4912)
    at io.mathdojo.useraccountservice.security.HTTPRequestSignatureVerifier.<init>(HTTPRequestSignatureVerifier.java:51)
    at io.mathdojo.useraccountservice.security.HTTPRequestSignatureVerificationEnabledHandler.createVerifier(HTTPRequestSignatureVerificationEnabledHandler.java:83)
    at io.mathdojo.useraccountservice.security.HTTPRequestSignatureVerificationEnabledHandler.getVerifier(HTTPRequestSignatureVerificationEnabledHandler.java:74)
    at io.mathdojo.useraccountservice.security.HTTPRequestSignatureVerificationEnabledHandler.handleRequest(HTTPRequestSignatureVerificationEnabledHandler.java:34)
    at io.mathdojo.useraccountservice.AccountRequestBodyUsersHandler.executePostForNewUserInOrg(AccountRequestBodyUsersHandler.java:43)

Full Trace

Result: signature verification failed for an uknown reason
Exception: An invalid key was supplied in the creation of the HTTPRequestSignatureVerifier
Stack: java.lang.RuntimeException: An invalid key was supplied in the creation of the HTTPRequestSignatureVerifier
    at io.mathdojo.useraccountservice.security.HTTPRequestSignatureVerifier.lambda$new$0(HTTPRequestSignatureVerifier.java:60)
    at java.util.Collections$SingletonMap.forEach(Collections.java:4912)
    at io.mathdojo.useraccountservice.security.HTTPRequestSignatureVerifier.<init>(HTTPRequestSignatureVerifier.java:51)
    at io.mathdojo.useraccountservice.security.HTTPRequestSignatureVerificationEnabledHandler.createVerifier(HTTPRequestSignatureVerificationEnabledHandler.java:83)
    at io.mathdojo.useraccountservice.security.HTTPRequestSignatureVerificationEnabledHandler.getVerifier(HTTPRequestSignatureVerificationEnabledHandler.java:74)
    at io.mathdojo.useraccountservice.security.HTTPRequestSignatureVerificationEnabledHandler.handleRequest(HTTPRequestSignatureVerificationEnabledHandler.java:34)
    at io.mathdojo.useraccountservice.AccountRequestBodyUsersHandler.executePostForNewUserInOrg(AccountRequestBodyUsersHandler.java:43)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.microsoft.azure.functions.worker.broker.JavaMethodInvokeInfo.invoke(JavaMethodInvokeInfo.java:22)
    at com.microsoft.azure.functions.worker.broker.JavaMethodExecutorImpl.execute(JavaMethodExecutorImpl.java:54)
    at com.microsoft.azure.functions.worker.broker.JavaFunctionBroker.invokeMethod(JavaFunctionBroker.java:57)
    at com.microsoft.azure.functions.worker.handler.InvocationRequestHandler.execute(InvocationRequestHandler.java:33)
    at com.microsoft.azure.functions.worker.handler.InvocationRequestHandler.execute(InvocationRequestHandler.java:10)
    at com.microsoft.azure.functions.worker.handler.MessageHandler.handle(MessageHandler.java:45)
    at com.microsoft.azure.functions.worker.JavaWorkerClient$StreamingMessagePeer.lambda$onNext$0(JavaWorkerClient.java:92)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: ObjectIdentifier() -- data isn't an object ID (tag = -96)
    at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:205)
    at java.security.KeyFactory.generatePublic(KeyFactory.java:334)
    at io.mathdojo.useraccountservice.security.HTTPRequestSignatureVerifier.lambda$new$0(HTTPRequestSignatureVerifier.java:56)
    ... 22 more
Caused by: java.security.InvalidKeyException: IOException: ObjectIdentifier() -- data isn't an object ID (tag = -96)
    at sun.security.x509.X509Key.decode(X509Key.java:397)
    at sun.security.x509.X509Key.decode(X509Key.java:402)
    at sun.security.rsa.RSAPublicKeyImpl.<init>(RSAPublicKeyImpl.java:86)
    at sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:298)
    at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:201)
noce2 commented 4 years ago

On investigation it appears the property https://github.com/math-dojo/user-account-service/blob/a50aed8d5621a9324fa2f8aaea8b6f40b8ac6f86/environments/pre-production.yml#L9 is actually a base64 encoding of the public certificate in DER format. This can be proved by running the following in a linux OS:

echo "${INSERT STRING HERE}" | base64 --decode > preprodcert.der
openssl x509 --inform DER --in ./preprodcert.der --pubkey --noout > pp.pub.key

The following commands succeed which indicates the provided string is not a public key, explaining why the above error is produced in the JVM.