99import info .weboftrust .ldsignatures .adapter .JWSSignerAdapter ;
1010import info .weboftrust .ldsignatures .adapter .JWSVerifierAdapter ;
1111import org .bitcoinj .core .ECKey ;
12+ import org .erdtman .jcs .JsonCanonicalizer ;
1213
14+ import java .io .IOException ;
1315import java .security .interfaces .RSAPrivateKey ;
1416import java .security .interfaces .RSAPublicKey ;
1517import java .util .Map ;
@@ -33,10 +35,15 @@ public JwtObject(JWTClaimsSet payload, JWSObject jwsObject, String compactSerial
3335 * Sign
3436 */
3537
36- private String sign (JWSSigner jwsSigner , JWSAlgorithm alg ) throws JOSEException {
38+ private String sign (JWSSigner jwsSigner , JWSAlgorithm alg , String kid , boolean canonicalize ) throws JOSEException {
3739
38- JWSHeader jwsHeader = new JWSHeader .Builder (alg ).build ();
39- JWSObject jwsObject = new EscapedSlashWorkaroundJWSObject (jwsHeader , this .getPayload ());
40+ JWSHeader .Builder jwsHeaderBuilder = new JWSHeader .Builder (alg );
41+ jwsHeaderBuilder .type (JOSEObjectType .JWT );
42+ if (kid != null ) jwsHeaderBuilder .keyID (kid );
43+
44+ JWSHeader jwsHeader = jwsHeaderBuilder .build ();
45+
46+ JWSObject jwsObject = new EscapedSlashWorkaroundJWSObject (jwsHeader , this .getPayload (), canonicalize );
4047
4148 jwsObject .sign (jwsSigner );
4249
@@ -46,102 +53,119 @@ private String sign(JWSSigner jwsSigner, JWSAlgorithm alg) throws JOSEException
4653 return this .compactSerialization ;
4754 }
4855
56+ public String sign_RSA_RS256 (ByteSigner signer , String kid , boolean canonicalize ) throws JOSEException {
57+ return this .sign (new JWSSignerAdapter (signer , JWSAlgorithm .RS256 ), JWSAlgorithm .RS256 , kid , canonicalize );
58+ }
59+
4960 public String sign_RSA_RS256 (ByteSigner signer ) throws JOSEException {
61+ return this .sign_RSA_RS256 (signer , null , true );
62+ }
5063
51- return this .sign (new JWSSignerAdapter (signer , JWSAlgorithm .RS256 ), JWSAlgorithm .RS256 );
64+ public String sign_RSA_RS256 (RSAPrivateKey privateKey , String kid , boolean canonicalize ) throws JOSEException {
65+ return this .sign_RSA_RS256 (new RSA_RS256_PrivateKeySigner (privateKey ), kid , canonicalize );
5266 }
5367
5468 public String sign_RSA_RS256 (RSAPrivateKey privateKey ) throws JOSEException {
69+ return this .sign_RSA_RS256 (privateKey , null , true );
70+ }
5571
56- return this .sign_RSA_RS256 (new RSA_RS256_PrivateKeySigner (privateKey ));
72+ public String sign_RSA_RS256 (com .nimbusds .jose .jwk .RSAKey privateKey , String kid , boolean canonicalize ) throws JOSEException {
73+ return this .sign (new com .nimbusds .jose .crypto .RSASSASigner (privateKey ), JWSAlgorithm .RS256 , kid , canonicalize );
5774 }
5875
5976 public String sign_RSA_RS256 (com .nimbusds .jose .jwk .RSAKey privateKey ) throws JOSEException {
77+ return this .sign_RSA_RS256 (privateKey , null , true );
78+ }
6079
61- return this .sign (new com .nimbusds .jose .crypto .RSASSASigner (privateKey ), JWSAlgorithm .RS256 );
80+ public String sign_Ed25519_EdDSA (ByteSigner signer , String kid , boolean canonicalize ) throws JOSEException {
81+ return this .sign (new JWSSignerAdapter (signer , JWSAlgorithm .EdDSA ), JWSAlgorithm .EdDSA , kid , canonicalize );
6282 }
6383
6484 public String sign_Ed25519_EdDSA (ByteSigner signer ) throws JOSEException {
85+ return this .sign_Ed25519_EdDSA (signer , null , true );
86+ }
6587
66- return this .sign (new JWSSignerAdapter (signer , JWSAlgorithm .EdDSA ), JWSAlgorithm .EdDSA );
88+ public String sign_Ed25519_EdDSA (byte [] privateKey , String kid , boolean canonicalize ) throws JOSEException {
89+ return this .sign_Ed25519_EdDSA (new Ed25519_EdDSA_PrivateKeySigner (privateKey ), kid , canonicalize );
6790 }
6891
6992 public String sign_Ed25519_EdDSA (byte [] privateKey ) throws JOSEException {
93+ return this .sign_Ed25519_EdDSA (privateKey , null , true );
94+ }
7095
71- return this .sign_Ed25519_EdDSA (new Ed25519_EdDSA_PrivateKeySigner (privateKey ));
96+ public String sign_Ed25519_EdDSA (com .nimbusds .jose .jwk .OctetKeyPair privateKey , String kid , boolean canonicalize ) throws JOSEException {
97+ return this .sign (new com .nimbusds .jose .crypto .Ed25519Signer (privateKey ), JWSAlgorithm .EdDSA , kid , canonicalize );
7298 }
7399
74100 public String sign_Ed25519_EdDSA (com .nimbusds .jose .jwk .OctetKeyPair privateKey ) throws JOSEException {
101+ return this .sign_Ed25519_EdDSA (privateKey , null , true );
102+ }
75103
76- return this .sign (new com .nimbusds .jose .crypto .Ed25519Signer (privateKey ), JWSAlgorithm .EdDSA );
104+ public String sign_secp256k1_ES256K (ByteSigner signer , String kid , boolean canonicalize ) throws JOSEException {
105+ return this .sign (new JWSSignerAdapter (signer , JWSAlgorithm .ES256K ), JWSAlgorithm .ES256K , kid , canonicalize );
77106 }
78107
79108 public String sign_secp256k1_ES256K (ByteSigner signer ) throws JOSEException {
109+ return this .sign_secp256k1_ES256K (signer , null , true );
110+ }
80111
81- return this .sign (new JWSSignerAdapter (signer , JWSAlgorithm .ES256K ), JWSAlgorithm .ES256K );
112+ public String sign_secp256k1_ES256K (ECKey privateKey , String kid , boolean canonicalize ) throws JOSEException {
113+ return this .sign_secp256k1_ES256K (new secp256k1_ES256K_PrivateKeySigner (privateKey ));
82114 }
83115
84116 public String sign_secp256k1_ES256K (ECKey privateKey ) throws JOSEException {
117+ return this .sign_secp256k1_ES256K (privateKey , null , true );
118+ }
85119
86- return this .sign_secp256k1_ES256K (new secp256k1_ES256K_PrivateKeySigner (privateKey ));
120+ public String sign_secp256k1_ES256K (com .nimbusds .jose .jwk .ECKey privateKey , String kid , boolean canonicalize ) throws JOSEException {
121+ return this .sign (new com .nimbusds .jose .crypto .ECDSASigner (privateKey ), JWSAlgorithm .ES256K , kid , canonicalize );
87122 }
88123
89124 public String sign_secp256k1_ES256K (com .nimbusds .jose .jwk .ECKey privateKey ) throws JOSEException {
90-
91- return this .sign (new com .nimbusds .jose .crypto .ECDSASigner (privateKey ), JWSAlgorithm .ES256K );
125+ return this .sign_secp256k1_ES256K (privateKey , null , true );
92126 }
93127
94128 /*
95129 * Verify
96130 */
97131
98132 private boolean verify (JWSVerifier jwsVerifier ) throws JOSEException {
99-
100133 return this .jwsObject .verify (jwsVerifier );
101134 }
102135
103136 public boolean verify_RSA_RS256 (ByteVerifier verifier ) throws JOSEException {
104-
105137 return this .verify (new JWSVerifierAdapter (verifier , JWSAlgorithm .RS256 ));
106138 }
107139
108140 public boolean verify_RSA_RS256 (RSAPublicKey publicKey ) throws JOSEException {
109-
110141 return this .verify_RSA_RS256 (new RSA_RS256_PublicKeyVerifier (publicKey ));
111142 }
112143
113144 public boolean verify_RSA_RS256 (com .nimbusds .jose .jwk .RSAKey publicKey ) throws JOSEException {
114-
115145 return this .verify (new com .nimbusds .jose .crypto .RSASSAVerifier (publicKey ));
116146 }
117147
118148 public boolean verify_Ed25519_EdDSA (ByteVerifier verifier ) throws JOSEException {
119-
120149 return this .verify (new JWSVerifierAdapter (verifier , JWSAlgorithm .EdDSA ));
121150 }
122151
123152 public boolean verify_Ed25519_EdDSA (byte [] publicKey ) throws JOSEException {
124-
125153 return this .verify_Ed25519_EdDSA (new Ed25519_EdDSA_PublicKeyVerifier (publicKey ));
126154 }
127155
128156 public boolean verify_Ed25519_EdDSA (com .nimbusds .jose .jwk .OctetKeyPair publicKey ) throws JOSEException {
129-
130157 return this .verify (new com .nimbusds .jose .crypto .Ed25519Verifier (publicKey ));
131158 }
132159
133160 public boolean verify_secp256k1_ES256K (ByteVerifier verifier ) throws JOSEException {
134-
135161 return this .verify (new JWSVerifierAdapter (verifier , JWSAlgorithm .ES256K ));
136162 }
137163
138164 public boolean verify_secp256k1_ES256K (ECKey publicKey ) throws JOSEException {
139-
140165 return this .verify_secp256k1_ES256K (new secp256k1_ES256K_PublicKeyVerifier (publicKey ));
141166 }
142167
143168 public boolean verify_secp256k1_ES256K (com .nimbusds .jose .jwk .ECKey publicKey ) throws JOSEException {
144-
145169 return this .verify (new com .nimbusds .jose .crypto .ECDSAVerifier (publicKey ));
146170 }
147171
@@ -153,13 +177,22 @@ private static class EscapedSlashWorkaroundJWSObject extends JWSObject {
153177
154178 private static final long serialVersionUID = -587898962717783109L ;
155179
156- public EscapedSlashWorkaroundJWSObject (final JWSHeader jwsHeader , final JWTClaimsSet jwtClaimsSet ) {
157- super (jwsHeader , makePayload (jwtClaimsSet ));
180+ public EscapedSlashWorkaroundJWSObject (final JWSHeader jwsHeader , final JWTClaimsSet jwtClaimsSet , boolean canonicalize ) {
181+ super (jwsHeader , makePayload (jwtClaimsSet , canonicalize ));
158182 }
159183
160- private static Payload makePayload (JWTClaimsSet jwtClaimsSet ) {
184+ private static Payload makePayload (JWTClaimsSet jwtClaimsSet , boolean canonicalize ) {
161185 Map <String , Object > jsonObject = jwtClaimsSet .toJSONObject ();
162- return new Payload (JSONObjectUtils .toJSONString (jsonObject ).replace ("\\ /" , "/" ));
186+ String payloadString = JSONObjectUtils .toJSONString (jsonObject );
187+ if (canonicalize ) {
188+ try {
189+ payloadString = new JsonCanonicalizer (payloadString ).getEncodedString ();
190+ } catch (IOException ex ) {
191+ throw new IllegalArgumentException (ex .getMessage (), ex );
192+ }
193+ }
194+ payloadString = payloadString .replace ("\\ /" , "/" );
195+ return new Payload (payloadString );
163196 }
164197 }
165198
0 commit comments