/// <summary> /// Changes the registration key. /// </summary> /// <param name="account">The account.</param> /// <param name="newKey">The new registration key.</param> /// <returns>The awaitable.</returns> public async Task ChangeKey(AcmeAccount account, KeyInfo newKey) { var keyPair = new AccountKey(newKey); var body = new { account = account.Location, newKey = keyPair.JsonWebKey, }; var jws = new JwsSigner(keyPair.SignatureKey); var payload = jws.Sign(body); var payloadWithResourceType = new { payload.Payload, payload.Protected, payload.Signature, Resource = ResourceTypes.KeyChange }; var uri = await this.handler.GetResourceUri(ResourceTypes.KeyChange); var result = await this.handler.Post(uri, payloadWithResourceType, key); ThrowIfError(result); this.key = keyPair; }
/// <summary> /// Computes the key authorization string for <paramref name="challenge"/>. /// </summary> /// <param name="challenge">The challenge.</param> /// <param name="key">The key.</param> /// <returns>The key authorization string.</returns> public static string ComputeKeyAuthorization(this Challenge challenge, IAccountKey key) { var jwkThumbprint = key.GenerateThumbprint(); var jwkThumbprintEncoded = JwsConvert.ToBase64String(jwkThumbprint); var token = challenge.Token; return($"{token}.{jwkThumbprintEncoded}"); }
private async Task <StringContent> GenerateRequestContent(object entity, IAccountKey keyPair) { var nonce = await this.GetNonce(); var body = Encode(entity, keyPair, nonce); var bodyJson = JsonConvert.SerializeObject(body, Formatting.None, jsonSettings); return(new StringContent(bodyJson, Encoding.UTF8, MimeJson)); }
/// <summary> /// Generates the thumbprint for the given account <paramref name="key"/>. /// </summary> /// <param name="key">The account key.</param> /// <returns>The thumbprint.</returns> public static byte[] GenerateThumbprint(this IAccountKey key) { var jwk = key.Jwk; var json = JsonConvert.SerializeObject(jwk, Formatting.None, thumbprintSettings); var bytes = Encoding.UTF8.GetBytes(json); var hashed = key.ComputeHash(bytes); return(hashed); }
/// <summary> /// Performs HTTP POST to <paramref name="uri"/>. /// </summary> /// <typeparam name="T">The resource entity type.</typeparam> /// <param name="uri">The URI.</param> /// <param name="entity">The entity.</param> /// <param name="keyPair">The signing key pair.</param> /// <returns>The ACME response.</returns> public async Task <AcmeResponse <T> > Post <T>(Uri uri, T entity, IAccountKey keyPair) { await FetchDirectory(false); var content = await GenerateRequestContent(entity, keyPair); var resp = await http.PostAsync(uri, content); var result = await ReadResponse <T>(resp, (entity as EntityBase)?.Resource); return(result); }
/// <summary> /// Computes the DNS value for the <paramref name="challenge"/>. /// </summary> /// <param name="challenge">The challenge.</param> /// <param name="key">The key.</param> /// <returns>The value for the text DNS record.</returns> public static string ComputeDnsValue(this ChallengeEntity challenge, IAccountKey key) { var keyAuthString = challenge.ComputeKeyAuthorization(key); var keyAuthBytes = Encoding.UTF8.GetBytes(keyAuthString); var sha256 = new Sha256Digest(); var hashed = new byte[sha256.GetDigestSize()]; sha256.BlockUpdate(keyAuthBytes, 0, keyAuthBytes.Length); sha256.DoFinal(hashed, 0); var dnsValue = JwsConvert.ToBase64String(hashed); return(dnsValue); }
/// <summary> /// Uses the specified account key data. /// </summary> /// <param name="keyData">The account key data.</param> public void Use(KeyInfo keyData) { this.key = new AccountKey(keyData); }
/// <summary> /// Encodes the specified entity for ACME requests. /// </summary> /// <param name="entity">The entity.</param> /// <param name="keyPair">The key pair.</param> /// <param name="nonce">The nonce.</param> /// <returns>The encoded JSON.</returns> private static object Encode(object entity, IAccountKey keyPair, string nonce) { var encoder = new JwsSigner(keyPair.SignatureKey); return(encoder.Sign(entity, nonce)); }
/// <summary> /// Generates the base64 encoded thumbprint for the given account <paramref name="key"/>. /// </summary> /// <param name="key">The account key.</param> /// <returns>The thumbprint.</returns> public static string Thumbprint(this IAccountKey key) => key.SignatureKey.Thumbprint();
/// <summary> /// Generates the thumbprint for the given account <paramref name="key"/>. /// </summary> /// <param name="key">The account key.</param> /// <returns>The thumbprint.</returns> public static byte[] GenerateThumbprint(this IAccountKey key) => key.GenerateThumbprint();
/// <summary> /// Generates key authorization string. /// </summary> /// <param name="key">The key.</param> /// <param name="token">The challenge token.</param> /// <returns></returns> public static string KeyAuthorization(this IAccountKey key, string token) => $"{token}.{key.Thumbprint()}";
/// <summary> /// Initializes a new instance of the <see cref="JwsSigner"/> class. /// </summary> /// <param name="keyPair">The keyPair.</param> public JwsSigner(IAccountKey keyPair) { this.keyPair = keyPair; }
/// <summary> /// Computes the key authorization string for <paramref name="challenge"/>. /// </summary> /// <param name="challenge">The challenge.</param> /// <param name="key">The key.</param> /// <returns>The key authorization string.</returns> public static string ComputeKeyAuthorization(this ChallengeEntity challenge, IAccountKey key) => $"{challenge.Token}.{key.Thumbprint()}";