public static async Task <string> CreateDeviceAuthChallengeResponseAsync(IDictionary <string, string> challengeData)
        {
            string      authHeaderTemplate = "PKeyAuth {0}, Context=\"{1}\", Version=\"{2}\"";
            Certificate certificate        = null;

            try
            {
                certificate = await FindCertificate(challengeData).ConfigureAwait(false);
            }
            catch (AdalException ex)
            {
                if (ex.ErrorCode == AdalError.DeviceCertificateNotFound)
                {
                    return(await Task.FromResult(string.Format(CultureInfo.InvariantCulture, @"PKeyAuth Context=""{0}"",Version=""{1}""", challengeData["Context"], challengeData["Version"])).ConfigureAwait(false));
                }
            }
            DeviceAuthJWTResponse response = new DeviceAuthJWTResponse(challengeData["SubmitUrl"],
                                                                       challengeData["nonce"], Convert.ToBase64String(certificate.GetCertificateBlob().ToArray()));
            IBuffer input = CryptographicBuffer.ConvertStringToBinary(response.GetResponseToSign(),
                                                                      BinaryStringEncoding.Utf8);
            CryptographicKey keyPair = await
                                       PersistedKeyProvider.OpenKeyPairFromCertificateAsync(certificate, HashAlgorithmNames.Sha256,
                                                                                            CryptographicPadding.RsaPkcs1V15).AsTask().ConfigureAwait(false);

            IBuffer signed = await CryptographicEngine.SignAsync(keyPair, input).AsTask().ConfigureAwait(false);

            string signedJwt = string.Format(CultureInfo.InvariantCulture, "{0}.{1}", response.GetResponseToSign(),
                                             Base64UrlEncoder.Encode(signed.ToArray()));
            string authToken = string.Format(CultureInfo.InvariantCulture, " AuthToken=\"{0}\"", signedJwt);

            return(string.Format(CultureInfo.InvariantCulture, authHeaderTemplate, authToken, challengeData["Context"], challengeData["Version"]));
        }
        public static async Task <string> CreateDeviceAuthChallengeResponseAsync(IDictionary <string, string> challengeData)
        {
            string authHeaderTemplate = "PKeyAuth {0}, Context=\"{1}\", Version=\"{2}\"";

            X509Certificate2      certificate = FindCertificate(challengeData);
            DeviceAuthJWTResponse response    = new DeviceAuthJWTResponse(challengeData["SubmitUrl"],
                                                                          challengeData["nonce"], Convert.ToBase64String(certificate.GetRawCertData()));
            CngKey key = CryptographyHelper.GetCngPrivateKey(certificate);

            byte[] sig = null;
            using (RSACng rsa = new RSACng(key))
            {
                rsa.SignatureHashAlgorithm = CngAlgorithm.Sha256;
                sig = rsa.SignData(response.GetResponseToSign().ToByteArray());
            }

            string signedJwt = string.Format(CultureInfo.InvariantCulture, "{0}.{1}", response.GetResponseToSign(),
                                             Base64UrlEncoder.Encode(sig));
            string        authToken  = string.Format(CultureInfo.InvariantCulture, " AuthToken=\"{0}\"", signedJwt);
            Task <string> resultTask =
                Task.Factory.StartNew(
                    () =>
            {
                return(string.Format(CultureInfo.InvariantCulture, authHeaderTemplate, authToken,
                                     challengeData["Context"],
                                     challengeData["Version"]));
            });

            return(await resultTask.ConfigureAwait(false));
        }
        public bool TryCreateDeviceAuthChallengeResponseAsync(HttpResponseHeaders responseHeaders, Uri endpointUri, out string responseHeader)
        {
            responseHeader = string.Empty;
            string           authHeaderTemplate = "PKeyAuth {0}, Context=\"{1}\", Version=\"{2}\"";
            X509Certificate2 certificate        = null;

            if (!DeviceAuthHelper.IsDeviceAuthChallenge(responseHeaders))
            {
                return(false);
            }
            if (!DeviceAuthHelper.CanOSPerformPKeyAuth())
            {
                responseHeader = DeviceAuthHelper.GetBypassChallengeResponse(responseHeaders);
                return(true);
            }

            IDictionary <string, string> challengeData = DeviceAuthHelper.ParseChallengeData(responseHeaders);

            if (!challengeData.ContainsKey("SubmitUrl"))
            {
                challengeData["SubmitUrl"] = endpointUri.AbsoluteUri;
            }

            try
            {
                certificate = FindCertificate(challengeData);
            }
            catch (MsalException ex)
            {
                if (ex.ErrorCode == MsalError.DeviceCertificateNotFound)
                {
                    responseHeader = DeviceAuthHelper.GetBypassChallengeResponse(responseHeaders);
                    return(true);
                }
            }

            DeviceAuthJWTResponse responseJWT = new DeviceAuthJWTResponse(challengeData["SubmitUrl"],
                                                                          challengeData["nonce"], Convert.ToBase64String(certificate.GetRawCertData()));

            CngKey key = NetDesktopCryptographyManager.GetCngPrivateKey(certificate);

            byte[] sig = null;
            using (Native.RSACng rsa = new Native.RSACng(key))
            {
                rsa.SignatureHashAlgorithm = CngAlgorithm.Sha256;
                sig = rsa.SignData(responseJWT.GetResponseToSign().ToByteArray());
            }

            string signedJwt = string.Format(CultureInfo.InvariantCulture, "{0}.{1}", responseJWT.GetResponseToSign(),
                                             Base64UrlHelpers.Encode(sig));
            string authToken = string.Format(CultureInfo.InvariantCulture, " AuthToken=\"{0}\"", signedJwt);

            responseHeader = string.Format(CultureInfo.InvariantCulture, authHeaderTemplate, authToken,
                                           challengeData["Context"],
                                           challengeData["Version"]);

            return(true);
        }
Beispiel #4
0
        private void FormatResponseHeader(
            DeviceAuthJWTResponse responseJWT,
            byte[] signedResponse,
            IDictionary <string, string> challengeData,
            out string responseHeader)
        {
            string signedJwt = $"{responseJWT.GetResponseToSign()}.{Base64UrlHelpers.Encode(signedResponse)}";
            string authToken = $"AuthToken=\"{signedJwt}\"";

            responseHeader = $"PKeyAuth {authToken}, Context=\"{challengeData["Context"]}\", Version=\"{challengeData["Version"]}\"";
        }
        public bool TryCreateDeviceAuthChallengeResponseAsync(HttpResponseHeaders headers, Uri endpointUri, out string responseHeader)
        {
            responseHeader = string.Empty;
            Certificate certificate        = null;
            string      authHeaderTemplate = "PKeyAuth {0}, Context=\"{1}\", Version=\"{2}\"";

            if (!DeviceAuthHelper.IsDeviceAuthChallenge(headers))
            {
                return(false);
            }
            if (!DeviceAuthHelper.CanOSPerformPKeyAuth())
            {
                responseHeader = DeviceAuthHelper.GetBypassChallengeResponse(headers);
                return(false);
            }

            IDictionary <string, string> challengeData = DeviceAuthHelper.ParseChallengeData(headers);

            if (!challengeData.ContainsKey("SubmitUrl"))
            {
                challengeData["SubmitUrl"] = endpointUri.AbsoluteUri;
            }

            try
            {
                certificate = Task.FromResult(FindCertificateAsync(challengeData)).Result.Result;
            }
            catch (MsalException ex)
            {
                if (ex.ErrorCode == MsalError.DeviceCertificateNotFound)
                {
                    responseHeader = DeviceAuthHelper.GetBypassChallengeResponse(headers);
                    return(true);
                }
            }

            DeviceAuthJWTResponse responseJWT = new DeviceAuthJWTResponse(challengeData["SubmitUrl"],
                                                                          challengeData["nonce"], Convert.ToBase64String(certificate.GetCertificateBlob().ToArray()));
            IBuffer input = CryptographicBuffer.ConvertStringToBinary(responseJWT.GetResponseToSign(),
                                                                      BinaryStringEncoding.Utf8);
            CryptographicKey keyPair =
                Task.FromResult(PersistedKeyProvider.OpenKeyPairFromCertificateAsync(certificate, HashAlgorithmNames.Sha256, CryptographicPadding.RsaPkcs1V15)).Result.GetResults();

            IBuffer signed = Task.FromResult(CryptographicEngine.SignAsync(keyPair, input)).Result.GetResults();

            string signedJwt = string.Format(CultureInfo.InvariantCulture, "{0}.{1}", responseJWT.GetResponseToSign(),
                                             Base64UrlHelpers.Encode(signed.ToArray()));
            string authToken = string.Format(CultureInfo.InvariantCulture, " AuthToken=\"{0}\"", signedJwt);

            responseHeader = string.Format(CultureInfo.InvariantCulture, authHeaderTemplate, authToken, challengeData["Context"], challengeData["Version"]);
            return(true);
        }
Beispiel #6
0
        protected override byte[] SignWithCertificate(DeviceAuthJWTResponse responseJwt, X509Certificate2 certificate)
        {
            CngKey key = NetDesktopCryptographyManager.GetCngPrivateKey(certificate);

            byte[] signedData = null;
            using (Native.RSACng rsa = new Native.RSACng(key))
            {
                rsa.SignatureHashAlgorithm = CngAlgorithm.Sha256;
                signedData = rsa.SignData(responseJwt.GetResponseToSign().ToByteArray());
            }

            return(signedData);
        }
Beispiel #7
0
        public bool TryCreateDeviceAuthChallengeResponse(HttpResponseHeaders responseHeaders, Uri endpointUri, out string responseHeader)
        {
            responseHeader = string.Empty;
            X509Certificate2 certificate = null;

            if (!DeviceAuthHelper.IsDeviceAuthChallenge(responseHeaders))
            {
                return(false);
            }
            if (!DeviceAuthHelper.CanOSPerformPKeyAuth())
            {
                responseHeader = DeviceAuthHelper.GetBypassChallengeResponse(responseHeaders);
                return(true);
            }

            IDictionary <string, string> challengeData = DeviceAuthHelper.ParseChallengeData(responseHeaders);

            if (!challengeData.TryGetValue("SubmitUrl", out string submitUrl))
            {
                submitUrl = endpointUri.AbsoluteUri;
            }

            try
            {
                certificate = FindCertificate(challengeData);
            }
            catch (MsalException ex)
            {
                if (ex.ErrorCode == MsalError.DeviceCertificateNotFound)
                {
                    responseHeader = DeviceAuthHelper.GetBypassChallengeResponse(responseHeaders);
                    return(true);
                }
            }

            DeviceAuthJWTResponse responseJWT = GetDeviceAuthJwtResponse(submitUrl, challengeData["nonce"], certificate);

            byte[] signedResponse = SignWithCertificate(responseJWT, certificate);

            FormatResponseHeader(responseJWT, signedResponse, challengeData, out responseHeader);

            return(true);
        }
Beispiel #8
0
 protected override byte[] SignWithCertificate(DeviceAuthJWTResponse responseJwt, X509Certificate2 certificate)
 {
     return(new NetStandard13CryptographyManager().SignWithCertificate(responseJwt.GetResponseToSign(), certificate));
 }
Beispiel #9
0
 protected abstract byte[] SignWithCertificate(DeviceAuthJWTResponse responseJwt, X509Certificate2 certificate);