<div dir="ltr"><div><div><div><div>I now have this working; there were two things to change:<br><br></div>- The signing code now looks like:<br><br> Signature signature = (Signature)Configuration.getBuilderFactory().getBuilder(Signature. DEFAULT_ELEMENT_NAME).buildObject(Signature.DEFAULT_ELEMENT_NAME);<br> signature.setSigningCredential(credential);<br> SecurityConfiguration securityConfiguration = Configuration.getGlobalSecurityConfiguration();<br> SecurityHelper.prepareSignatureParams(signature, credential, securityConfiguration, null);<br> r.setSignature(signature);<br> Configuration.getMarshallerFactory().getMarshaller(r).marshall(r);<br> Signer.signObject(signature);<br><br></div>This correctly adds the DS:X509 section to the generated XML<br><br></div>- Adding metadata for the SP to the IdP (I haven't written my Metadata export yet, but had expected signed requests to be treated the same way as unsigned ones at the IdP, rather than throwing (IMHO) a misleading "org.opensaml.messaging.handler.MessageHandlerException: Validation of protocol message signature failed" when the message is intact but the IdP lacks metadata.<br><br></div><div>Everything now looks good, although I'm not convinced that there aren't higher level functions I should be using.<br><br></div><div>Phil<br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Nov 6, 2015 at 12:26 PM, Phil Lello <span dir="ltr"><<a href="mailto:phil@dunlop-lello.uk" target="_blank">phil@dunlop-lello.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div><div><div><div>Hi all,<br><br></div>I've been trying to write an SP implementation, first with core Java, and now with OpenSAML after I hit a roadblock. Unfortunately, I'm getting stuck in the same place; I can sign assertions, but the signatures are invalid.<br><br></div>My current code is as follows:<br><br> AuthnRequestBuilder rb = new AuthnRequestBuilder();<br> AuthnRequest r = rb.buildObject();<br> IssuerBuilder ib = new IssuerBuilder();<br> Issuer i = ib.buildObject();<br> i.setValue(this.url);<br> r.setIssuer(i);<br> r.setIssueInstant(new DateTime());<br> r.setID(generateId());<br> r.setAssertionConsumerServiceURL(url+"sp/acs");<br> r.setDestination(IdP);<br> r.setProtocolBinding("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST");<br> NameIDPolicyBuilder nb = new NameIDPolicyBuilder();<br> NameIDPolicy nameIDPolicy = nb.buildObject();<br> nameIDPolicy.setAllowCreate(true);<br> nameIDPolicy.setFormat("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent");<br> r.setNameIDPolicy(nameIDPolicy);<br><br> BasicX509Credential credential = new BasicX509Credential();<br> JcaPEMKeyConverter kc = new JcaPEMKeyConverter().setProvider("BC");<br> credential.setEntityCertificate(getCertificate());<br> credential.setPrivateKey(kc.getPrivateKey(getPrivateKeyInfo()));<br> KeyInfoGeneratorFactory kigf = new X509KeyInfoGeneratorFactory();<br> KeyInfo ki = kigf.newInstance().generate(credential);<br><br> Signature signature = (Signature)Configuration.getBuilderFactory().getBuilder(Signature. DEFAULT_ELEMENT_NAME).buildObject(Signature.DEFAULT_ELEMENT_NAME);<br> signature.setSigningCredential(credential);<br> signature.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1);<br> signature.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);<br> signature.setKeyInfo(ki);<br> r.setSignature(signature);<br> Configuration.getMarshallerFactory().getMarshaller(r).marshall(r);<br> Signer.signObject(signature);<br><br> MarshallerFactory mf = Configuration.getMarshallerFactory();<br> Marshaller m = mf.getMarshaller(r);<br><br> DOMSource source = new DOMSource(m.marshall(r));<br> TransformerFactory tf = TransformerFactory.newInstance();<br> Transformer t = tf.newTransformer();<br> StringWriter sw = new StringWriter();<br> StreamResult result = new StreamResult(sw);<br> t.transform(source, result);<br> byte[] encodedBytes = Base64.encodeBase64(sw.toString().getBytes());<br><br></div>And the certificate/key reading functions are:<br><br> protected X509Certificate getCertificate() throws IOException, CertificateException<br> {<br> Path x509crtfile = dataDir.resolve("cert.pem");<br> PEMParser pem = new PEMParser(Files.newBufferedReader(x509crtfile, Charset.forName("UTF8")));<br> return new JcaX509CertificateConverter().setProvider("BC").getCertificate((X509CertificateHolder)pem. readObject());<br> }<br><br> protected PrivateKeyInfo getPrivateKeyInfo() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException<br> {<br><br> Path x509keyfile = dataDir.resolve("key.pem");<br> Security.addProvider(new BouncyCastleProvider());<br> PEMParser pem = new PEMParser(Files.newBufferedReader(x509keyfile, Charset.forName("UTF8")));<br> return (PrivateKeyInfo)pem.readObject();<br> }<br><br></div>Any pointers on where I'm going wrong, or perhaps a reference to a working signed AuthnRequest example greatly appreciated.<br><br></div>The cert/key were generated by "openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 3650 -nodes"; I can share the files if it will help.<span class="HOEnZb"><font color="#888888"><br><br></font></span></div><span class="HOEnZb"><font color="#888888">Phil<br><div><br></div></font></span></div>
</blockquote></div><br></div>