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