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