All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.oltu.jose.jws.JWS Maven / Gradle / Ivy

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.oltu.jose.jws;

import org.apache.oltu.commons.encodedtoken.TokenDecoder;
import org.apache.oltu.commons.json.CustomizableBuilder;
import org.apache.oltu.jose.jws.io.JWSHeaderWriter;
import org.apache.oltu.jose.jws.signature.SignatureMethod;
import org.apache.oltu.jose.jws.signature.SigningKey;
import org.apache.oltu.jose.jws.signature.VerifyingKey;

public class JWS {
    
    /**
     * The raw JWS String
     */
    private String rawString;

    /**
     * The JWS Header.
     */
    private final Header header;

    /**
     * The JWS Payload.
     */
    private final String payload;

    /**
     * The JWS Signature.
     */
    private final String signature;

    JWS(Header header, String payload, String signature) {
        this(null, header, payload, signature);
    }
    
    JWS(String rawString, Header header, String payload, String signature) {
        this.rawString = rawString;
        this.header = header;
        this.payload = payload;
        this.signature = signature;
    }

    public Header getHeader() {
        return header;
    }

    public String getPayload() {
        return payload;
    }

    public String getSignature() {
        return signature;
    }

    public  boolean acceptAlgorithm(SignatureMethod method) {
        if (method == null) {
            throw new IllegalArgumentException("A signature method is required in order to verify the signature.");
        }
        if (header == null || header.getAlgorithm() == null) {
            throw new IllegalStateException("JWS token must have a valid JSON header with specified algorithm.");
        }

        return header.getAlgorithm().equalsIgnoreCase(method.getAlgorithm());
    }

    public  boolean validate(SignatureMethod method,
                                                                             VK verifyingKey) {
        if (!acceptAlgorithm(method)) {
            throw new IllegalArgumentException("Impossible to verify current JWS signature with algorithm '"
                                               + method.getAlgorithm()
                                               + "', JWS header specifies message has been signed with '"
                                               + header.getAlgorithm()
                                               + "' algorithm.");
        }

        if (verifyingKey == null) {
            throw new IllegalArgumentException("A verifying key is required in order to verify the signature.");
        }

        if (payload == null) {
            throw new IllegalStateException("JWS token must have a payload.");
        }
        if (signature == null) {
            throw new IllegalStateException("JWS token must have a signature to be verified.");
        }
        
        if (rawString == null) {
            return method.verify(signature, TokenDecoder.base64Encode(new JWSHeaderWriter().write(header)), TokenDecoder.base64Encode(payload), verifyingKey);
        } else {
            String jwt[] = rawString.split("\\.");
            return method.verify(jwt[2], jwt[0], jwt[1], verifyingKey);
        }
    }

    public static final class Builder extends CustomizableBuilder {
        
        public Builder(){}
        
        public Builder(String rawString) {
            this.rawString = rawString;
        }
        
        /**
         * The raw JWS String
         */
        private String rawString;

        /**
         * The {@code alg} JWS Header parameter.
         */
        private String algorithm;

        /**
         * The {@code jku} JWS Header parameter.
         */
        private String jwkSetUrl;

        /**
         * The {@code jwk} JWS Header parameter.
         */
        private String jsonWebKey;

        /**
         * The {@code x5u} JWS Header parameter.
         */
        private String x509url;

        /**
         * The {@code x5t} JWS Header parameter.
         */
        private String x509CertificateThumbprint;

        /**
         * The {@code x5c} JWS Header parameter.
         */
        private String x509CertificateChain;

        /**
         * The {@code kid} JWS Header parameter.
         */
        private String keyId;

        /**
         * The {@code typ} JWS Header parameter.
         */
        private String type;

        /**
         * The {@code cty} JWS Header parameter.
         */
        private String contentType;

        /**
         * The {@code crit} JWS Header parameter.
         */
        private String[] critical;

        /**
         * The JWS Payload.
         */
        private String payload;

        /**
         * The JWS Signature.
         */
        private String signature;

        public Builder setAlgorithm(String algorithm) {
            this.algorithm = algorithm;
            return this;
        }

        public Builder setJwkSetUrl(String jwkSetUrl) {
            this.jwkSetUrl = jwkSetUrl;
            return this;
        }

        public Builder setJsonWebKey(String jsonWebKey) {
            this.jsonWebKey = jsonWebKey;
            return this;
        }

        public Builder setX509url(String x509url) {
            this.x509url = x509url;
            return this;
        }

        public Builder setX509CertificateThumbprint(String x509CertificateThumbprint) {
            this.x509CertificateThumbprint = x509CertificateThumbprint;
            return this;
        }

        public Builder setX509CertificateChain(String x509CertificateChain) {
            this.x509CertificateChain = x509CertificateChain;
            return this;
        }

        public Builder setKeyId(String keyId) {
            this.keyId = keyId;
            return this;
        }

        public Builder setType(String type) {
            this.type = type;
            return this;
        }

        public Builder setContentType(String contentType) {
            this.contentType = contentType;
            return this;
        }

        public Builder setCritical(String[] critical) {
            this.critical = critical;
            return this;
        }

        public Builder setPayload(String payload) {
            this.payload = payload;
            return this;
        }

        public Builder setSignature(String signature) {
            this.signature = signature;
            return this;
        }

        public  Builder sign(SignatureMethod method,
                                                                             SK signingKey) {
            if (method == null) {
                throw new IllegalArgumentException("A signature method is required in order to calculate the signature.");
            }
            if (signingKey == null) {
                throw new IllegalArgumentException("A signing key is required in order to calculate the signature.");
            }
            if (payload == null) {
                throw new IllegalStateException("Payload needs to be set in order to sign the current JWT");
            }
            setAlgorithm(method.getAlgorithm());
            
            String header = new JWSHeaderWriter().write(new Header(algorithm,
                                      jwkSetUrl,
                                      jsonWebKey,
                                      x509url,
                                      x509CertificateThumbprint,
                                      x509CertificateChain,
                                      keyId, type,
                                      contentType,
                                      critical,
                                      getCustomFields())); 
            
            return setSignature(method.calculate(TokenDecoder.base64Encode(header), TokenDecoder.base64Encode(payload), signingKey));
        }

        public JWS build() {
            return new JWS(rawString, new Header(algorithm,
                                      jwkSetUrl,
                                      jsonWebKey,
                                      x509url,
                                      x509CertificateThumbprint,
                                      x509CertificateChain,
                                      keyId, type,
                                      contentType,
                                      critical,
                                      getCustomFields()),
                           payload,
                           signature);
        }

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy