001/*
002 * nimbus-jose-jwt
003 *
004 * Copyright 2012-2016, Connect2id Ltd.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.jose;
019
020
021import com.nimbusds.jose.util.Base64URL;
022import net.jcip.annotations.ThreadSafe;
023
024import java.text.ParseException;
025import java.util.Objects;
026
027
028/**
029 * Unsecured (plain / {@code alg=none}) JOSE object with
030 * <a href="https://datatracker.ietf.org/doc/html/rfc7515#section-7.1">compact
031 * serialisation</a>.
032 *
033 * <p>This class is thread-safe.
034 *
035 * @author Vladimir Dzhuvinov
036 * @version 2024-04-20
037 */
038@ThreadSafe
039public class PlainObject extends JOSEObject {
040
041
042        private static final long serialVersionUID = 1L;
043
044
045        /**
046         * The header.
047         */
048        private final PlainHeader header;
049
050
051        /**
052         * Creates a new unsecured JOSE object with a default {@link
053         * PlainHeader} and the specified payload.
054         *
055         * @param payload The payload. Must not be {@code null}.
056         */
057        public PlainObject(final Payload payload) {
058
059                setPayload(Objects.requireNonNull(payload));
060                header = new PlainHeader();
061        }
062
063
064        /**
065         * Creates a new unsecured JOSE object with the specified header and
066         * payload.
067         *
068         * @param header  The unsecured header. Must not be {@code null}.
069         * @param payload The payload. Must not be {@code null}.
070         */
071        public PlainObject(final PlainHeader header, final Payload payload) {
072
073                this.header = Objects.requireNonNull(header);
074                setPayload(Objects.requireNonNull(payload));
075        }
076
077
078        /**
079         * Creates a new unsecured JOSE object with the specified
080         * Base64URL-encoded parts.
081         *
082         * @param firstPart  The first part, corresponding to the unsecured
083         *                   header. Must not be {@code null}.
084         * @param secondPart The second part, corresponding to the payload. 
085         *                   Must not be {@code null}.
086         *
087         * @throws ParseException If parsing of the serialised parts failed.
088         */
089        public PlainObject(final Base64URL firstPart, final Base64URL secondPart)
090                throws ParseException {
091
092                try {
093                        header = PlainHeader.parse(Objects.requireNonNull(firstPart));
094
095                } catch (ParseException e) {
096
097                        throw new ParseException("Invalid unsecured header: " + e.getMessage(), 0);
098                }
099
100                setPayload(new Payload(Objects.requireNonNull(secondPart)));
101
102                setParsedParts(firstPart, secondPart, null);
103        }
104
105
106        @Override
107        public PlainHeader getHeader() {
108
109                return header;
110        }
111
112
113        /**
114         * Serialises this unsecured JOSE object to its compact format
115         * consisting of Base64URL-encoded parts delimited by period ('.') 
116         * characters.
117         *
118         * <pre>
119         * [header-base64url].[payload-base64url].[]
120         * </pre>
121         *
122         * @return The serialised unsecured JOSE object.
123         */
124        @Override
125        public String serialize() {
126
127                return header.toBase64URL().toString() + '.' + getPayload().toBase64URL().toString() + '.';
128        }
129
130
131        /**
132         * Parses an unsecured JOSE object from the specified string in compact
133         * format.
134         *
135         * @param s The string to parse. Must not be {@code null}.
136         *
137         * @return The unsecured JOSE object.
138         *
139         * @throws ParseException If the string couldn't be parsed to a valid 
140         *                        unsecured JOSE object.
141         */
142        public static PlainObject parse(final String s)
143                throws ParseException {
144
145                Base64URL[] parts = JOSEObject.split(s);
146
147                if (! parts[2].toString().isEmpty()) {
148                        
149                        throw new ParseException("Unexpected third Base64URL part", 0);
150                }
151
152                return new PlainObject(parts[0], parts[1]);
153        }
154}