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}