@@ -127,7 +127,7 @@ void Account::update() {
127127 if (state != STATE_IDLE || !certsReadyForRenewal ()) return ;
128128
129129 if (directory.isNull ()) state = STATE_GET_DIR;
130- else if (kid.empty ()) state = STATE_REGISTER;
130+ else if (kid.empty ()) state = STATE_REGISTER;
131131 else {
132132 currentKeyCert = 0 ;
133133 state = STATE_NEW_ORDER;
@@ -171,7 +171,8 @@ string Account::getURL(const string &url) const {
171171
172172
173173string Account::getThumbprint () const {
174- return URLBase64 ().encode (Digest::hash (getJWK ()->toString (), " sha256" ));
174+ string jwk = getJWK ()->toString (0 , true ); // No indent, compact
175+ return URLBase64 ().encode (Digest::hash (jwk, " sha256" ));
175176}
176177
177178
@@ -183,24 +184,30 @@ string Account::getKeyAuthorization() const {
183184JSON::ValuePtr Account::getJWK () const {
184185 auto d = SmartPtr (new JSON::Dict);
185186
187+ // Insert order matters (lexicographical by key)
186188 if (key.isRSA ()) {
187- // Insert order matters
188189 d->insert (" e" , URLBase64 ().encode (key.getRSA_E ().toBinString ()));
189190 d->insert (" kty" , " RSA" );
190191 d->insert (" n" , URLBase64 ().encode (key.getRSA_N ().toBinString ()));
191192
193+ } else if (key.isEC ()) {
194+ d->insert (" crv" , " P-256" );
195+ d->insert (" kty" , " EC" );
196+ d->insert (" x" , URLBase64 ().encode (key.getEC_X ().toBinString ()));
197+ d->insert (" y" , URLBase64 ().encode (key.getEC_Y ().toBinString ()));
198+
192199 } else THROW (" Unsupported key type" );
193200
194201 return d;
195202}
196203
197204
198205string Account::getProtected (const URI &uri) const {
199- // TODO Implement ES256 (RFC7518 Section 3.1) and EdDSA var. Ed25519 (RFC8037)
200- // signature algorithms. See IETF ACME draft "Request Authentication".
201-
206+ // See IETF ACME draft "Request Authentication".
202207 auto d = SmartPtr (new JSON::Dict);
203- d->insert (" alg" , " RS256" );
208+
209+ if (key.isRSA ()) d->insert (" alg" , " RS256" );
210+ else if (key.isEC ()) d->insert (" alg" , " ES256" );
204211
205212 if (!kid.empty ()) d->insert (" kid" , kid);
206213 else d->insert (" jwk" , getJWK ());
@@ -215,14 +222,17 @@ string Account::getProtected(const URI &uri) const {
215222
216223string Account::getSignedRequest (const URI &uri, const string &payload) const {
217224 string protected64 = URLBase64 ().encode (getProtected (uri));
218- string payload64 = URLBase64 ().encode (payload);
219- string signed64 =
220- URLBase64 ().encode (key.signSHA256 (protected64 + " ." + payload64));
225+ string payload64 = URLBase64 ().encode (payload);
226+ string hash = Digest::hash (protected64 + " ." + payload64, " sha256" );
227+
228+ string sig;
229+ if (key.isRSA ()) sig = key.sign (hash);
230+ else if (key.isEC ()) sig = key.signECP1363 (hash);
221231
222232 auto d = SmartPtr (new JSON::Dict);
223233 d->insert (" protected" , protected64);
224- d->insert (" payload" , payload64);
225- d->insert (" signature" , signed64 );
234+ d->insert (" payload" , payload64);
235+ d->insert (" signature" , URLBase64 (). encode (sig) );
226236 return d->toString ();
227237}
228238
0 commit comments