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 java.text.ParseException;
022
023import net.jcip.annotations.ThreadSafe;
024
025import com.nimbusds.jose.util.Base64URL;
026
027
028/**
029 * Unsecured (plain / {@code alg=none}) JOSE object. This class is thread-safe.
030 *
031 * @author Vladimir Dzhuvinov
032 * @version 2014-04-08
033 */
034@ThreadSafe
035public class PlainObject extends JOSEObject {
036
037
038        private static final long serialVersionUID = 1L;
039
040
041        /**
042         * The header.
043         */
044        private final PlainHeader header;
045
046
047        /**
048         * Creates a new unsecured JOSE object with a default {@link
049         * PlainHeader} and the specified payload.
050         *
051         * @param payload The payload. Must not be {@code null}.
052         */
053        public PlainObject(final Payload payload) {
054
055                if (payload == null) {
056                        throw new IllegalArgumentException("The payload must not be null");
057                }
058
059                setPayload(payload);
060
061                header = new PlainHeader();
062        }
063
064
065        /**
066         * Creates a new unsecured JOSE object with the specified header and
067         * payload.
068         *
069         * @param header  The unsecured header. Must not be {@code null}.
070         * @param payload The payload. Must not be {@code null}.
071         */
072        public PlainObject(final PlainHeader header, final Payload payload) {
073
074                if (header == null) {
075
076                        throw new IllegalArgumentException("The unsecured header must not be null");
077                }
078
079                this.header = header;
080
081                if (payload == null) {
082
083                        throw new IllegalArgumentException("The payload must not be null");
084                }
085
086                setPayload(payload);
087        }
088
089
090        /**
091         * Creates a new unsecured JOSE object with the specified
092         * Base64URL-encoded parts.
093         *
094         * @param firstPart  The first part, corresponding to the unsecured
095         *                   header. Must not be {@code null}.
096         * @param secondPart The second part, corresponding to the payload. 
097         *                   Must not be {@code null}.
098         *
099         * @throws ParseException If parsing of the serialised parts failed.
100         */
101        public PlainObject(final Base64URL firstPart, final Base64URL secondPart)
102                throws ParseException {
103
104                if (firstPart == null) {
105
106                        throw new IllegalArgumentException("The first part must not be null");
107                }
108
109                try {
110                        header = PlainHeader.parse(firstPart);
111
112                } catch (ParseException e) {
113
114                        throw new ParseException("Invalid unsecured header: " + e.getMessage(), 0);
115                }
116
117                if (secondPart == null) {
118
119                        throw new IllegalArgumentException("The second part must not be null");
120                }
121
122                setPayload(new Payload(secondPart));
123
124                setParsedParts(firstPart, secondPart, null);
125        }
126
127
128        @Override
129        public PlainHeader getHeader() {
130
131                return header;
132        }
133
134
135        /**
136         * Serialises this unsecured JOSE object to its compact format
137         * consisting of Base64URL-encoded parts delimited by period ('.') 
138         * characters.
139         *
140         * <pre>
141         * [header-base64url].[payload-base64url].[]
142         * </pre>
143         *
144         * @return The serialised unsecured JOSE object.
145         */
146        @Override
147        public String serialize() {
148
149                return header.toBase64URL().toString() + '.' + getPayload().toBase64URL().toString() + '.';
150        }
151
152
153        /**
154         * Parses an unsecured JOSE object from the specified string in compact
155         * format.
156         *
157         * @param s The string to parse. Must not be {@code null}.
158         *
159         * @return The unsecured JOSE object.
160         *
161         * @throws ParseException If the string couldn't be parsed to a valid 
162         *                        unsecured JOSE object.
163         */
164        public static PlainObject parse(final String s)
165                throws ParseException {
166
167                Base64URL[] parts = JOSEObject.split(s);
168
169                if (! parts[2].toString().isEmpty()) {
170                        
171                        throw new ParseException("Unexpected third Base64URL part", 0);
172                }
173
174                return new PlainObject(parts[0], parts[1]);
175        }
176}