/// <summary> /// Validates the options and also ensures that all <c>null</c> properties are /// initialized to their default values. /// </summary> /// <param name="clusterDefinition">The cluster definition.</param> /// <exception cref="ClusterDefinitionException">Thrown if the definition is not valid.</exception> public void Validate(ClusterDefinition clusterDefinition) { Covenant.Requires <ArgumentNullException>(clusterDefinition != null, nameof(clusterDefinition)); var acmeIssuerPrefix = $"{nameof(AcmeIssuer)}"; if (string.IsNullOrEmpty(Server)) { Server = "https://acme-v02.api.letsencrypt.org/directory"; } Solvers = Solvers ?? new List <AcmeChallengeSolver>(); if (!Solvers.Any(solver => solver.Dns01?.Webhook?.SolverName == "neoncluster_io")) { var neonWebhookSolver = new AcmeIssuerDns01ProviderWebhook() { Config = new Dictionary <string, object>() { { "Registrar", "route53" } }, GroupName = "acme.neoncloud.io", SolverName = "neoncluster_io" }; Solvers.Add(new AcmeChallengeSolver() { Dns01 = new AcmeChallengeSolverDns01() { Webhook = neonWebhookSolver }, Selector = new CertificateDnsNameSelector() { DnsZones = new List <string>() { "neoncluster.io" } } }); } foreach (var solver in Solvers) { solver.Validate(clusterDefinition); } PrivateKeySecretRef = PrivateKeySecretRef ?? new AcmeSecretKeySelector() { Name = "neon-acme-issuer-account-key", Key = "tls.key" }; if (ExternalAccountBinding != null) { ExternalAccountBinding.Validate(clusterDefinition); } }
public async Task <AccountDetails> CreateAccountAsync( IEnumerable <string> contacts, string eabKeyId, string eabHmacKey, bool termsOfServiceAgreed = false, bool throwOnExistingAccount = false, CancellationToken cancel = default(CancellationToken) ) { var header = new Dictionary <string, object> { ["alg"] = "HS256", ["url"] = new Uri(_http.BaseAddress, Directory.NewAccount), ["kid"] = eabKeyId, }; var headerJson = JsonConvert.SerializeObject(header, Formatting.None); var protectedHeaderBase64 = CryptoHelper.Base64.UrlEncode(headerJson); var accountKeyBase64 = CryptoHelper.Base64.UrlEncode( JsonConvert.SerializeObject(Signer.ExportJwk(), Formatting.None)); var signingBytes = System.Text.Encoding.ASCII.GetBytes( $"{protectedHeaderBase64}.{accountKeyBase64}"); // eab signature is the hash of the header and account key, using the eab key byte[] signatureHash; switch (header["alg"]) { case "HS512": using (var hs512 = new HMACSHA512( CryptoHelper.Base64.UrlDecode(eabHmacKey))) signatureHash = hs512.ComputeHash(signingBytes); break; case "HS384": using (var hs384 = new HMACSHA384( CryptoHelper.Base64.UrlDecode(eabHmacKey))) signatureHash = hs384.ComputeHash(signingBytes); break; default: using (var hs256 = new HMACSHA256( CryptoHelper.Base64.UrlDecode(eabHmacKey))) signatureHash = hs256.ComputeHash(signingBytes); break; } var signatureBase64 = CryptoHelper.Base64.UrlEncode(signatureHash); var externalAccountBinding = new ExternalAccountBinding { Protected = protectedHeaderBase64, Payload = accountKeyBase64, Signature = signatureBase64 }; return(await CreateAccountAsync(contacts, termsOfServiceAgreed, externalAccountBinding, throwOnExistingAccount, cancel)); }