Unable to compute signature, Signature XMLObject does not have the XMLSignature created during marshalling,

114 Views Asked by At

I am not able to generate SAMLResponse, receiving errors; "Unable to compute signature, Signature XMLObject does not have the XMLSignature created during marshalling", "XMLObject does not have an XMLSignature instance, unable to compute signature".

I also tried logging the input stream of the public key by inStream.read(), It prints "inStream: -1", which I believe is returned when the input file is empty, which is definitely not empty, I am confused, is this is the error or what?

Receiving following lines of error logs;

{ role=ADMIN } - Unable to compute signature, Signature XMLObject does not have the XMLSignature created during marshalling
{ role=ADMIN } - XMLObject does not have an XMLSignature instance, unable to compute signature
{ role=ADMIN } - XMLObject does not have an XMLSignature instance, unable to compute signature
{ role=ADMIN } - org.opensaml.xml.signature.SignatureException: XMLObject does not have an XMLSignature instance, unable to compute signature
{ role=ADMIN } - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException: null // at the mentioned error point

Code:

package HIE.utils;


public class SSOSAMLResponse1 {

    public Response createSAMLResponse(final String subjectId, final HashMap<String, List<String>> attributes, String issuer) {
        try {
            DefaultBootstrap.bootstrap();
            DateTime datetime = new DateTime(Utilities.getCurrentTimeStamp());

            Issuer responseIssuer = null;
            Issuer assertionIssuer = null;
            Subject subject = null;
            AttributeStatement attributeStatement = null;

            Status status = createStatus();

            if (!Utilities.isNull(issuer)) {
                responseIssuer = createIssuer(issuer);
                assertionIssuer = createIssuer(issuer);
            }

            if (!Utilities.isNull(subjectId)) {
                subject = createSubject(subjectId);
            }

            if (!Utilities.isNull(attributes) && attributes.size() != 0) {
                attributeStatement = createAttributeStatement(attributes);
            }

            Conditions conditions = createConditions(datetime);

            AuthnStatement authnStatement = createAuthnStatement(datetime);

            Assertion assertion = createAssertion(datetime, subject, assertionIssuer, authnStatement, attributeStatement, conditions);

            Signature signature = createSignature();
            assertion.setSignature(signature);
            Signer.signObject(signature); // point of error

            return createResponse(datetime, responseIssuer, status, assertion);

        } catch(Throwable t) {
            log.warn(t.getMessage());
            log.warn(t.getLocalizedMessage());
            log.warn(t.toString());
            t.printStackTrace();
            return null;
        }
    }

    // skipping other defined functions

    private Signature createSignature() throws Throwable {
        String absolutePath = "C:/Users/USER/Desktop/office-projects/medicalservice/src/main/resources/sso/";
        String privateKeyLocation = absolutePath + "x509_priv.pem";
        String publicKeyLocation =  absolutePath + "x509_cert.crt";

        SignatureBuilder builder = new SignatureBuilder();
        Signature signature = builder.buildObject();
        Credential credential = getSigningCredential(publicKeyLocation, privateKeyLocation);
        signature.setSigningCredential(credential);
        signature.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA1);
        signature.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS);

        return signature;
    }

    public Credential getSigningCredential(String publicKeyLocation, String privateKeyLocation) throws Throwable {
        // create public key (cert) portion of credential
        InputStream inStream = new FileInputStream(publicKeyLocation);
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate x509Certificate = (X509Certificate) cf.generateCertificate(inStream);
        log.info("inStream: {}", inStream.read());
        inStream.close();

        // create private key
        File file = new File(privateKeyLocation);
        String key = new String(Files.readAllBytes(file.toPath()), Charset.defaultCharset());

        String privateKeyPEM = key
                .replace("-----BEGIN RSA PRIVATE KEY-----", "")
                .replaceAll(System.lineSeparator(), "")
                .replace("-----END RSA PRIVATE KEY-----", "");

        log.info("privateKeyPEM {}", privateKeyPEM);

        byte[] encoded = Base64.decodeBase64(privateKeyPEM);

        PKCS8EncodedKeySpec kSpec = new PKCS8EncodedKeySpec(encoded);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = kf.generatePrivate(kSpec);

        // create credential and initialize
        BasicX509Credential credential = new BasicX509Credential();
        credential.setEntityCertificate(x509Certificate);
        credential.setPrivateKey(privateKey);

        return credential;
    }

}
1

There are 1 best solutions below

0
Ali Azlan On

just add these lines after creating Signature, createSignature();

        assertion.setSignature(signature);
        ResponseMarshaller marshaller = new ResponseMarshaller();
        Element element = marshaller.marshall(response);
        
        if (signature != null) {
            Signer.signObject(signature);
        }
        
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        XMLHelper.writeNode(element, baos);