예제 #1
0
        /// <summary>
        /// Computes a thumbprint of the JWK using the argument Hash Algorithm
        /// as per <see href="https://tools.ietf.org/html/rfc7638">RFC 7638</see>,
        /// JSON Web Key (JWK) Thumbprint.
        /// </summary>
        public static byte[] ComputeThumbprint(IJwsTool signer, HashAlgorithm algor)
        {
            // As per RFC 7638 Section 3, we export the JWK in a canonical form
            // and then produce a JSON object with no whitespace or line breaks

            var jwkCanon = signer.ExportJwk(true);
            var jwkJson  = JsonConvert.SerializeObject(jwkCanon, Formatting.None);
            var jwkBytes = Encoding.UTF8.GetBytes(jwkJson);
            var jwkHash  = algor.ComputeHash(jwkBytes);

            return(jwkHash);
        }
        // TODO: handle "Change of TOS" error response
        //    https://tools.ietf.org/html/draft-ietf-acme-acme-12#section-7.3.4


        /// <summary>
        /// Rotates the current Public key that is associated with this Account by the
        /// target ACME CA with a new Public key.  If successful, updates the current
        /// Account key pair registered with the client.
        /// </summary>
        /// <remarks>
        /// https://tools.ietf.org/html/draft-ietf-acme-acme-12#section-7.3.6
        /// </remarks>
        public async Task <AccountDetails> ChangeAccountKeyAsync(IJwsTool newSigner,
                                                                 CancellationToken cancel = default(CancellationToken))
        {
            var requUrl = new Uri(_http.BaseAddress, Directory.KeyChange);
            var message = new KeyChangeRequest
            {
                Account = Account.Kid,
                NewKey  = newSigner.ExportJwk(),
            };
            var innerPayload = ComputeAcmeSigned(message, requUrl.ToString(),
                                                 signer: newSigner, includePublicKey: true, excludeNonce: true);
            var resp = await SendAcmeAsync(
                requUrl,
                method : HttpMethod.Post,
                message : innerPayload,
                cancel : cancel);

            Signer = newSigner;

            return(await DecodeAccountResponseAsync(resp, existing : Account));
        }