public void RefreshAuthorizeChallenge(AuthorizationState authzState, string type, bool useRootUrl = false) { AssertInit(); AssertRegistration(); var c = authzState.Challenges.FirstOrDefault(x => x.Type == type); if (c == null) { throw new ArgumentOutOfRangeException("no challenge found matching requested type"); } var requUri = new Uri(c.Uri); if (useRootUrl) { requUri = new Uri(RootUrl, requUri.PathAndQuery); } var resp = RequestHttpGet(requUri); var cp = JsonConvert.DeserializeObject <ChallengePart>(resp.ContentAsString); c.Type = cp.Type; c.Uri = cp.Uri; c.Token = cp.Token; c.Status = cp.Status; c.Tls = cp.Tls; }
public AuthorizeChallenge SubmitAuthorizeChallengeAnswer(AuthorizationState authzState, string type, bool useRootUrl = false) { AssertInit(); AssertRegistration(); var c = authzState.Challenges.FirstOrDefault(x => x.Type == type); if (c == null) { throw new ArgumentException("no challenge found matching requested type"); } if (c.ChallengeAnswer.Key == null || c.ChallengeAnswer.Value == null || c.ChallengeAnswerMessage == null) { throw new InvalidOperationException("challenge answer has not been generated"); } var requUri = new Uri(c.Uri); if (useRootUrl) { requUri = new Uri(RootUrl, requUri.PathAndQuery); } var resp = RequestHttpPost(requUri, c.ChallengeAnswerMessage); if (resp.IsError) { throw new AcmeWebException(resp.Error as WebException, "Unexpected error", resp); } return(c); }
public AuthorizationState AuthorizeIdentifier(string dnsIdentifier) { AssertInit(); AssertRegistration(); var requMsg = new NewAuthzRequest { Identifier = new IdentifierPart { Type = AcmeProtocol.IDENTIFIER_TYPE_DNS, Value = dnsIdentifier } }; var resp = RequestHttpPost(new Uri(RootUrl, Directory[AcmeServerDirectory.RES_NEW_AUTHZ]), requMsg); if (resp.IsError) { throw new AcmeWebException(resp.Error as WebException, "Unexpected error", resp); } var uri = resp.Headers[AcmeProtocol.HEADER_LOCATION]; if (string.IsNullOrEmpty(uri)) { throw new AcmeProtocolException("Response is missing an identifier authorization resource URI", resp); } var respMsg = JsonConvert.DeserializeObject <NewAuthzResponse>(resp.ContentAsString); var authzState = new AuthorizationState { IdentifierType = respMsg.Identifier.Type, Identifier = respMsg.Identifier.Value, Uri = uri, Status = respMsg.Status, Expires = respMsg.Expires, Combinations = respMsg.Combinations, // Simple copy/conversion from one form to another Challenges = respMsg.Challenges.Select(x => new AuthorizeChallenge { Type = x.Type, Status = x.Status, Uri = x.Uri, Token = x.Token, Tls = x.Tls, ValidationRecord = x.ValidationRecord, }), }; return(authzState); }
public void Test0140_HandleHttpChallenge() { using (var signer = new RS256Signer()) { signer.Init(); using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open)) { signer.Load(fs); } AcmeRegistration reg; using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open)) { reg = AcmeRegistration.Load(fs); } using (var client = BuildClient()) { client.RootUrl = _rootUrl; client.Signer = signer; client.Registration = reg; client.Init(); client.GetDirectory(true); AuthorizationState authzState; using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz.acmeAuthz", FileMode.Open)) { authzState = AuthorizationState.Load(fs); } var authzChallenge = client.GenerateAuthorizeChallengeAnswer(authzState, "simpleHttp"); using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz-ChallengeAnswersHandleHttp.acmeAuthz", FileMode.Create)) { authzState.Save(fs); } var wsFilePath = authzChallenge.ChallengeAnswer.Key; var wsFileBody = authzChallenge.ChallengeAnswer.Value; var wsInfo = WebServerInfo.Load(File.ReadAllText("webServerInfo.json")); using (var s = new MemoryStream(Encoding.UTF8.GetBytes(wsFileBody))) { var fileUrl = new Uri($"http://{authzState.Identifier}/{wsFilePath}"); wsInfo.Provider.UploadFile(fileUrl, s); } } } Thread.Sleep(90 * 1000); }
public void Test0130_HandleDnsChallenge() { using (var signer = new RS256Signer()) { signer.Init(); using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open)) { signer.Load(fs); } AcmeRegistration reg; using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open)) { reg = AcmeRegistration.Load(fs); } using (var client = BuildClient()) { client.RootUrl = _rootUrl; client.Signer = signer; client.Registration = reg; client.Init(); client.GetDirectory(true); AuthorizationState authzState; using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz.acmeAuthz", FileMode.Open)) { authzState = AuthorizationState.Load(fs); } var authzChallenge = client.GenerateAuthorizeChallengeAnswer(authzState, "dns"); using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz-ChallengeAnswersHandleDns.acmeAuthz", FileMode.Create)) { authzState.Save(fs); } var dnsName = authzChallenge.ChallengeAnswer.Key; var dnsValue = Regex.Replace(authzChallenge.ChallengeAnswer.Value, "\\s", ""); var dnsValues = Regex.Replace(dnsValue, "(.{100,100})", "$1\n").Split('\n'); var dnsInfo = DnsInfo.Load(File.ReadAllText("dnsInfo.json")); dnsInfo.Provider.EditTxtRecord(dnsName, dnsValues); } } Thread.Sleep(90 * 1000); }
public AuthorizeChallenge GenerateAuthorizeChallengeAnswer(AuthorizationState authzState, string type) { AssertInit(); AssertRegistration(); var c = authzState.Challenges.FirstOrDefault(x => x.Type == type); if (c == null) { throw new ArgumentOutOfRangeException("no challenge found matching requested type"); } switch (type) { case "dns": c.ChallengeAnswer = c.GenerateDnsChallengeAnswer(authzState.Identifier, Signer); c.ChallengeAnswerMessage = new AnswerDnsChallengeRequest { ClientPublicKey = Signer.ExportJwk(), Validation = new { header = new { alg = Signer.JwsAlg }, payload = JwsHelper.Base64UrlEncode(JsonConvert.SerializeObject(new { type = "dns", token = c.Token })), signature = c.ChallengeAnswer.Value } }; break; case "simpleHttp": var tls = c.Tls.GetValueOrDefault(true); c.ChallengeAnswer = c.GenerateHttpChallengeAnswer(authzState.Identifier, Signer, tls); c.ChallengeAnswerMessage = new AnswerHttpChallengeRequest { Tls = tls }; break; default: throw new ArgumentException("unsupported challenge type", nameof(type)); } return(c); }
public AuthorizationState RefreshIdentifierAuthorization(AuthorizationState authzState, bool useRootUrl = false) { AssertInit(); AssertRegistration(); var requUri = new Uri(authzState.Uri); if (useRootUrl) { requUri = new Uri(RootUrl, requUri.PathAndQuery); } var resp = RequestHttpGet(requUri); if (resp.IsError) { throw new AcmeWebException(resp.Error as WebException, "Unexpected error", resp); } var respMsg = JsonConvert.DeserializeObject <AuthzStatusResponse>(resp.ContentAsString); var authzStatusState = new AuthorizationState { IdentifierType = respMsg.Identifier.Type, Identifier = respMsg.Identifier.Value, Status = respMsg.Status, Expires = respMsg.Expires, Challenges = respMsg.Challenges.Select(x => new AuthorizeChallenge { Type = x.Type, Status = x.Status, Uri = x.Uri, Token = x.Token, Tls = x.Tls, ValidationRecord = x.ValidationRecord, }), }; return(authzStatusState); }
public void Test0145_SubmitHttpChallengeAnswers() { using (var signer = new RS256Signer()) { signer.Init(); using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open)) { signer.Load(fs); } AcmeRegistration reg; using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open)) { reg = AcmeRegistration.Load(fs); } using (var client = BuildClient()) { client.RootUrl = _rootUrl; client.Signer = signer; client.Registration = reg; client.Init(); client.GetDirectory(true); AuthorizationState authzState; using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz-ChallengeAnswersHandleHttp.acmeAuthz", FileMode.Open)) { authzState = AuthorizationState.Load(fs); } client.GenerateAuthorizeChallengeAnswer(authzState, "simpleHttp"); client.SubmitAuthorizeChallengeAnswer(authzState, "simpleHttp", true); using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz-HttpChallengeAnswered.acmeAuthz", FileMode.Create)) { authzState.Save(fs); } } } }
public void Test0100_RefreshAuthzDnsChallenge() { using (var signer = new RS256Signer()) { signer.Init(); using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open)) { signer.Load(fs); } AcmeRegistration reg; using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open)) { reg = AcmeRegistration.Load(fs); } using (var client = BuildClient()) { client.RootUrl = _rootUrl; client.Signer = signer; client.Registration = reg; client.Init(); client.GetDirectory(true); AuthorizationState authzState; using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz.acmeAuthz", FileMode.Open)) { authzState = AuthorizationState.Load(fs); } client.RefreshAuthorizeChallenge(authzState, "dns", true); using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz-DnsChallengeRefreshed.acmeAuthz", FileMode.Create)) { authzState.Save(fs); } } } }
public void Test0095_RefreshIdentifierAuthorization() { using (var signer = new RS256Signer()) { signer.Init(); using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeSigner", FileMode.Open)) { signer.Load(fs); } AcmeRegistration reg; using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestRegister.acmeReg", FileMode.Open)) { reg = AcmeRegistration.Load(fs); } using (var client = BuildClient()) { client.RootUrl = _rootUrl; client.Signer = signer; client.Registration = reg; client.Init(); client.GetDirectory(true); AuthorizationState authzState; using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz.acmeAuthz", FileMode.Open)) { authzState = AuthorizationState.Load(fs); } var authzRefreshState = client.RefreshIdentifierAuthorization(authzState, true); using (var fs = new FileStream($"{BASE_LOCAL_STORE}TestAuthz-Refresh.acmeAuthz", FileMode.Create)) { authzRefreshState.Save(fs); } } } }
public AuthorizeChallenge SubmitAuthorizeChallengeAnswer(AuthorizationState authzState, string type, bool useRootUrl = false) { AssertInit(); AssertRegistration(); var c = authzState.Challenges.FirstOrDefault(x => x.Type == type); if (c == null) throw new ArgumentOutOfRangeException("no challenge found matching requested type"); if (c.ChallengeAnswer.Key == null || c.ChallengeAnswer.Value == null || c.ChallengeAnswerMessage == null) throw new InvalidOperationException("challenge answer has not been generated"); var requUri = new Uri(c.Uri); if (useRootUrl) requUri = new Uri(RootUrl, requUri.PathAndQuery); var resp = RequestHttpPost(requUri, c.ChallengeAnswerMessage); if (resp.IsError) { throw new AcmeWebException(resp.Error as WebException, "Unexpected error", resp); } return c; }
public AuthorizationState RefreshIdentifierAuthorization(AuthorizationState authzState, bool useRootUrl = false) { AssertInit(); AssertRegistration(); var requUri = new Uri(authzState.Uri); if (useRootUrl) requUri = new Uri(RootUrl, requUri.PathAndQuery); var resp = RequestHttpGet(requUri); if (resp.IsError) { throw new AcmeWebException(resp.Error as WebException, "Unexpected error", resp); } var respMsg = JsonConvert.DeserializeObject<AuthzStatusResponse>(resp.ContentAsString); var authzStatusState = new AuthorizationState { IdentifierType = respMsg.Identifier.Type, Identifier = respMsg.Identifier.Value, Status = respMsg.Status, Expires = respMsg.Expires, Challenges = respMsg.Challenges.Select(x => new AuthorizeChallenge { Type = x.Type, Status = x.Status, Uri = x.Uri, Token = x.Token, Tls = x.Tls, ValidationRecord = x.ValidationRecord, }), }; return authzStatusState; }
public void RefreshAuthorizeChallenge(AuthorizationState authzState, string type, bool useRootUrl = false) { AssertInit(); AssertRegistration(); var c = authzState.Challenges.FirstOrDefault(x => x.Type == type); if (c == null) throw new ArgumentOutOfRangeException("no challenge found matching requested type"); var requUri = new Uri(c.Uri); if (useRootUrl) requUri = new Uri(RootUrl, requUri.PathAndQuery); var resp = RequestHttpGet(requUri); var cp = JsonConvert.DeserializeObject<ChallengePart>(resp.ContentAsString); c.Type = cp.Type; c.Uri = cp.Uri; c.Token = cp.Token; c.Status = cp.Status; c.Tls = cp.Tls; }
public AuthorizeChallenge GenerateAuthorizeChallengeAnswer(AuthorizationState authzState, string type) { AssertInit(); AssertRegistration(); var c = authzState.Challenges.FirstOrDefault(x => x.Type == type); if (c == null) throw new ArgumentOutOfRangeException("no challenge found matching requested type"); switch (type) { case AcmeProtocol.CHALLENGE_TYPE_LEGACY_DNS: case AcmeProtocol.CHALLENGE_TYPE_DNS: c.ChallengeAnswer = c.GenerateDnsChallengeAnswer(authzState.Identifier, Signer); c.ChallengeAnswerMessage = new AnswerLegacyDnsChallengeRequest { ClientPublicKey = Signer.ExportJwk(), Validation = new { header = new { alg = Signer.JwsAlg }, payload = JwsHelper.Base64UrlEncode(JsonConvert.SerializeObject(new { type = type, token = c.Token })), signature = c.ChallengeAnswer.Value, } }; break; case AcmeProtocol.CHALLENGE_TYPE_LEGACY_HTTP: var tls = c.Tls.GetValueOrDefault(true); c.ChallengeAnswer = c.GenerateLegacyHttpChallengeAnswer(authzState.Identifier, Signer, tls); c.ChallengeAnswerMessage = new AnswerLegacyHttpChallengeRequest { Tls = tls }; break; case AcmeProtocol.CHALLENGE_TYPE_HTTP: c.ChallengeAnswer = c.GenerateHttpChallengeAnswer(authzState.Identifier, Signer); c.ChallengeAnswerMessage = new AnswerHttpChallengeRequest { KeyAuthorization = c.ChallengeAnswer.Value, }; break; case AcmeProtocol.CHALLENGE_TYPE_LEGACY_DVSNI: case AcmeProtocol.CHALLENGE_TYPE_LEGACY_PRIORKEY: case AcmeProtocol.CHALLENGE_TYPE_SNI: case AcmeProtocol.CHALLENGE_TYPE_PRIORKEY: throw new ArgumentException("unimplemented or unsupported challenge type", nameof(type)); default: throw new ArgumentException("unknown challenge type", nameof(type)); } return c; }
public AuthorizationState AuthorizeIdentifier(string dnsIdentifier) { AssertInit(); AssertRegistration(); var requMsg = new NewAuthzRequest { Identifier = new IdentifierPart { Type = AcmeProtocol.IDENTIFIER_TYPE_DNS, Value = dnsIdentifier } }; var resp = RequestHttpPost(new Uri(RootUrl, Directory[AcmeServerDirectory.RES_NEW_AUTHZ]), requMsg); if (resp.IsError) { throw new AcmeWebException(resp.Error as WebException, "Unexpected error", resp); } var uri = resp.Headers[AcmeProtocol.HEADER_LOCATION]; if (string.IsNullOrEmpty(uri)) throw new AcmeProtocolException("Response is missing an identifier authorization resource URI", resp); var respMsg = JsonConvert.DeserializeObject<NewAuthzResponse>(resp.ContentAsString); var authzState = new AuthorizationState { IdentifierType = respMsg.Identifier.Type, Identifier = respMsg.Identifier.Value, Uri = uri, Status = respMsg.Status, Expires = respMsg.Expires, Combinations = respMsg.Combinations, // Simple copy/conversion from one form to another Challenges = respMsg.Challenges.Select(x => new AuthorizeChallenge { Type = x.Type, Status = x.Status, Uri = x.Uri, Token = x.Token, Tls = x.Tls, ValidationRecord = x.ValidationRecord, }), }; return authzState; }
public AuthorizeChallenge GenerateAuthorizeChallengeAnswer(AuthorizationState authzState, string type) { AssertInit(); AssertRegistration(); var c = authzState.Challenges.FirstOrDefault(x => x.Type == type); if (c == null) throw new ArgumentOutOfRangeException("no challenge found matching requested type"); switch (type) { case "dns": c.ChallengeAnswer = c.GenerateDnsChallengeAnswer(authzState.Identifier, Signer); c.ChallengeAnswerMessage = new AnswerDnsChallengeRequest { ClientPublicKey = Signer.ExportJwk(), Validation = new { header = new { alg = Signer.JwsAlg }, payload = JwsHelper.Base64UrlEncode(JsonConvert.SerializeObject(new { type = "dns", token = c.Token })), signature = c.ChallengeAnswer.Value } }; break; case "simpleHttp": var tls = c.Tls.GetValueOrDefault(true); c.ChallengeAnswer = c.GenerateHttpChallengeAnswer(authzState.Identifier, Signer, tls); c.ChallengeAnswerMessage = new AnswerHttpChallengeRequest { Tls = tls }; break; default: throw new ArgumentException("unsupported challenge type", nameof(type)); } return c; }
public AuthorizationState AuthorizeIdentifier(string dnsIdentifier) { AssertInit(); AssertRegistration(); var requMsg = new NewAuthzRequest { Identifier = new IdentifierPart { Type = "dns", Value = dnsIdentifier } }; var resp = RequestHttpPost(new Uri(RootUrl, Directory[AcmeServerDirectory.RES_NEW_AUTHZ]), requMsg); if (resp.IsError) { throw new AcmeWebException(resp.Error as WebException, "Unexpected error", resp); } var respMsg = JsonConvert.DeserializeObject<NewAuthzResponse>(resp.ContentAsString); var authzState = new AuthorizationState { Identifier = respMsg.Identifier.Value, Status = respMsg.Status, Combinations = respMsg.Combinations, // Simple copy/conversion from one form to another Challenges = respMsg.Challenges.Select(x => new AuthorizeChallenge { Type = x.Type, Status = x.Status, Uri = x.Uri, Token = x.Token, Tls = x.Tls, }), }; return authzState; }
public AuthorizeChallenge GenerateAuthorizeChallengeAnswer(AuthorizationState authzState, string type) { AssertInit(); AssertRegistration(); var c = authzState.Challenges.FirstOrDefault(x => x.Type == type); if (c == null) { throw new ArgumentOutOfRangeException("no challenge found matching requested type"); } switch (type) { case AcmeProtocol.CHALLENGE_TYPE_LEGACY_DNS: case AcmeProtocol.CHALLENGE_TYPE_DNS: c.ChallengeAnswer = c.GenerateDnsChallengeAnswer(authzState.Identifier, Signer); c.ChallengeAnswerMessage = new AnswerLegacyDnsChallengeRequest { ClientPublicKey = Signer.ExportJwk(), Validation = new { header = new { alg = Signer.JwsAlg }, payload = JwsHelper.Base64UrlEncode(JsonConvert.SerializeObject(new { type = type, token = c.Token })), signature = c.ChallengeAnswer.Value, } }; break; case AcmeProtocol.CHALLENGE_TYPE_LEGACY_HTTP: var tls = c.Tls.GetValueOrDefault(true); c.ChallengeAnswer = c.GenerateLegacyHttpChallengeAnswer(authzState.Identifier, Signer, tls); c.ChallengeAnswerMessage = new AnswerLegacyHttpChallengeRequest { Tls = tls }; break; case AcmeProtocol.CHALLENGE_TYPE_HTTP: c.ChallengeAnswer = c.GenerateHttpChallengeAnswer(authzState.Identifier, Signer); c.ChallengeAnswerMessage = new AnswerHttpChallengeRequest { KeyAuthorization = c.ChallengeAnswer.Value, }; break; case AcmeProtocol.CHALLENGE_TYPE_LEGACY_DVSNI: case AcmeProtocol.CHALLENGE_TYPE_LEGACY_PRIORKEY: case AcmeProtocol.CHALLENGE_TYPE_SNI: case AcmeProtocol.CHALLENGE_TYPE_PRIORKEY: throw new ArgumentException("unimplemented or unsupported challenge type", nameof(type)); default: throw new ArgumentException("unknown challenge type", nameof(type)); } return(c); }