public static IdToken Parse(string idToken)
        {
            if (string.IsNullOrEmpty(idToken))
            {
                return(null);
            }

            IdToken idTokenBody = null;

            string[] idTokenSegments = idToken.Split(new[] { '.' });

            if (idTokenSegments.Length < 2)
            {
                throw new MsalClientException(
                          MsalError.InvalidJwtError,
                          MsalErrorMessage.IDTokenMustHaveTwoParts);
            }

            try
            {
                byte[] idTokenBytes = Base64UrlHelpers.DecodeToBytes(idTokenSegments[1]);
                idTokenBody = JsonHelper.DeserializeFromJson <IdToken>(idTokenBytes);
            }
            catch (JsonException exc)
            {
                throw new MsalClientException(
                          MsalError.JsonParseError,
                          MsalErrorMessage.FailedToParseIDToken,
                          exc);
            }

            return(idTokenBody);
        }
Esempio n. 2
0
        private void AddIosSpecificParametersToPayload(Dictionary <string, string> brokerPayload)
        {
            string encodedBrokerKey = Base64UrlHelpers.Encode(BrokerKeyHelper.GetRawBrokerKey(_logger));

            brokerPayload[iOSBrokerConstants.BrokerKey]      = encodedBrokerKey;
            brokerPayload[iOSBrokerConstants.MsgProtocolVer] = BrokerParameter.MsgProtocolVersion3;

            if (_brokerV3Installed)
            {
                _brokerRequestNonce = Guid.NewGuid().ToString();
                brokerPayload[iOSBrokerConstants.BrokerNonce] = _brokerRequestNonce;

                string applicationToken = TryReadBrokerApplicationTokenFromKeychain(brokerPayload);

                if (!string.IsNullOrEmpty(applicationToken))
                {
                    brokerPayload[iOSBrokerConstants.ApplicationToken] = applicationToken;
                }
            }

            if (brokerPayload.ContainsKey(iOSBrokerConstants.Claims))
            {
                brokerPayload[iOSBrokerConstants.SkipCache] = BrokerParameter.SkipCache;
                string claims = Base64UrlHelpers.Encode(brokerPayload[BrokerParameter.Claims]);
                brokerPayload[BrokerParameter.Claims] = claims;
            }
        }
Esempio n. 3
0
        internal static string DecryptBrokerResponse(string encryptedBrokerResponse, ICoreLogger logger)
        {
            byte[] outputBytes = Base64UrlHelpers.DecodeBytes(encryptedBrokerResponse);

            if (TryGetBrokerKey(out byte[] key))
            {
                AesManaged   algo         = null;
                CryptoStream cryptoStream = null;
                MemoryStream memoryStream = null;
                try
                {
                    memoryStream = new MemoryStream(outputBytes);
                    algo         = CreateSymmetricAlgorith(key);
                    cryptoStream = new CryptoStream(
                        memoryStream,
                        algo.CreateDecryptor(),
                        CryptoStreamMode.Read);
                    using (StreamReader srDecrypt = new StreamReader(cryptoStream))
                    {
                        string plaintext = srDecrypt.ReadToEnd();
                        return(plaintext);
                    }
                }
                finally
                {
                    memoryStream?.Dispose();
                    cryptoStream?.Dispose();
                    algo?.Dispose();
                }
            }

            throw new MsalClientException(
                      MsalError.BrokerKeyFetchFailed,
                      MsalErrorMessage.iOSBrokerKeyFetchFailed);
        }
Esempio n. 4
0
        private string CreateJwkClaim(RsaSecurityKey key, string algorithm)
        {
            var parameters = key.Rsa == null ? key.Parameters : key.Rsa.ExportParameters(false);

            //return "{\"kty\":\"RSA\",\"n\":\"" + Base64UrlEncoder.Encode(parameters.Modulus) + "\",\"e\":\"" + Base64UrlEncoder.Encode(parameters.Exponent) + "\",\"alg\":\"" + algorithm + "\"}";
            return($@"{{""e"":""{Base64UrlHelpers.Encode(parameters.Exponent)}"",""kty"":""RSA"",""n"":""{Base64UrlHelpers.Encode(parameters.Modulus)}""}}");
        }
 public CertificateAndClaimsClientCredential(X509Certificate2 certificate, IDictionary <string, string> claimsToSign, bool appendDefaultClaims)
 {
     Certificate              = certificate;
     _claimsToSign            = claimsToSign;
     _appendDefaultClaims     = appendDefaultClaims;
     _base64EncodedThumbprint = Base64UrlHelpers.Encode(certificate.GetCertHash());
 }
Esempio n. 6
0
        private string ComputeReqCnf()
        {
            // There are 4 possible formats for a JWK, but Evo supports only this one for simplicity
            var jwk = $@"{{""{JsonWebKeyParameterNames.Kid}"":""{KeyId}""}}";

            return(Base64UrlHelpers.Encode(jwk));
        }
        [InlineData("", "")]                    // Empty string
        public void DecodeToBytes_ValidBase64UrlString_ReturnsByteArray(string stringToDecode, string expectedDecodedString)
        {
            var expectedDecodedByteArray = Encoding.UTF8.GetBytes(expectedDecodedString);

            var actualDecodedByteArray = Base64UrlHelpers.DecodeBytes(stringToDecode);

            Assert.Equal(expectedDecodedByteArray, actualDecodedByteArray);
        }
        /// <summary>
        /// Creates POP tokens, i.e. tokens that are bound to an HTTP request and are digitally signed.
        /// </summary>
        /// <remarks>
        /// Currently the signing credential algorithm is hard-coded to RSA with SHA256. Extensibility should be done
        /// by integrating Wilson's SigningCredentials
        /// </remarks>
        public PoPAuthenticationScheme(HttpRequestMessage httpRequestMessage, IPoPCryptoProvider popCryptoProvider)
        {
            _httpRequestMessage = httpRequestMessage ?? throw new ArgumentNullException(nameof(httpRequestMessage));
            _popCryptoProvider  = popCryptoProvider ?? throw new ArgumentNullException(nameof(popCryptoProvider));

            _keyThumbprint = ComputeRsaThumbprint(_popCryptoProvider.CannonicalPublicKeyJwk);
            KeyId          = Base64UrlHelpers.Encode(_keyThumbprint);
        }
        /// <summary>
        /// Creates the cannonical representation of the JWK.  See https://tools.ietf.org/html/rfc7638#section-3
        /// The number of parameters as well as the lexicographic order is important, as this string will be hashed to get a thumbprint
        /// </summary>
        private static string ComputeCannonicalJwk(ECParameters ecdPublicKey)
        {
            string x = ecdPublicKey.Q.X != null?Base64UrlHelpers.Encode(ecdPublicKey.Q.X) : null;

            string y = ecdPublicKey.Q.Y != null?Base64UrlHelpers.Encode(ecdPublicKey.Q.Y) : null;

            return($@"{{""{JsonWebKeyParameterNames.Crv}"":""{GetCrvParameterValue(ecdPublicKey.Curve)}"",""{JsonWebKeyParameterNames.Kty}"":""{JsonWebKeyParameterNames.EC}"",""{JsonWebKeyParameterNames.X}"":""{x}"",""{JsonWebKeyParameterNames.Y}"":""{y}""}}");
        }
Esempio n. 10
0
 /// <summary>
 /// A key ID that uniquely describes a public / private key pair. While KeyID is not normally
 /// strict, AAD support for PoP requires that we use the base64 encoded JWK thumbprint, as described by
 /// https://tools.ietf.org/html/rfc7638
 /// </summary>
 private string GetKidFromJwk(string jwk)
 {
     using (SHA256 hash = SHA256.Create())
     {
         byte[] hashBytes = hash.ComputeHash(Encoding.UTF8.GetBytes(jwk));
         return(Base64UrlHelpers.Encode(hashBytes));
     }
 }
        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);
        }
        public string GenerateCodeVerifier()
        {
            byte[] buffer        = new byte[Constants.CodeVerifierByteSize];
            var    windowsBuffer = CryptographicBuffer.GenerateRandom((uint)buffer.Length);

            Array.Copy(windowsBuffer.ToArray(), buffer, buffer.Length);

            return(Base64UrlHelpers.Encode(buffer));
        }
Esempio n. 13
0
        public string GenerateCodeVerifier()
        {
            byte[] buffer = new byte[Constants.CodeVerifierByteSize];
            using (var randomSource = RandomNumberGenerator.Create())
            {
                randomSource.GetBytes(buffer);
            }

            return(Base64UrlHelpers.Encode(buffer));
        }
        public void CreateString_NonUTF8Bytes_ReturnsInvalidString(string stringToCreate)
        {
            var resultString = Base64UrlHelpers.CreateString(Encoding.UTF32.GetBytes(stringToCreate));

            Assert.NotEqual(stringToCreate, resultString);

            resultString = Base64UrlHelpers.CreateString(Encoding.Unicode.GetBytes(stringToCreate));

            Assert.NotEqual(stringToCreate, resultString);
        }
        public void DecodeToBytes_InvalidBase64UrlStringLength_ThrowsException()
        {
            var stringToDecodeWithInvalidLength = "MTIzNDU21";

            Action decodeAction = () => Base64UrlHelpers.DecodeToBytes(stringToDecodeWithInvalidLength);

            var exception = Assert.Throws <ArgumentException>(decodeAction);

            Assert.Equal("Illegal base64url string! (Parameter 'arg')", exception.Message);
        }
Esempio n. 16
0
        private IdToken GetIdToken(
            string oid,
            string subject,
            string upn,
            string email)
        {
            var idTokenJson = JObject.Parse($"{{'oid': '{oid}', 'sub': '{subject}', 'upn': '{upn}', 'email': '{email}'}}");

            return(new IdToken($".{Base64UrlHelpers.Encode(idTokenJson.ToString())}."));
        }
        private string GetModulusFromPopToken(string popToken)
        {
            var handler   = new JwtSecurityTokenHandler();
            var jsonToken = handler.ReadJwtToken(popToken);

            var jwtDecoded = Base64UrlHelpers.Decode(jsonToken.EncodedPayload);
            var jObj       = JObject.Parse(jsonToken.Payload.First().Value.ToString());

            return(jObj["jwk"]["n"].ToString());
        }
        public string GenerateCodeVerifier()
        {
            byte[] buffer = new byte[Constants.CodeVerifierByteSize];
            using (RNGCryptoServiceProvider randomSource = new RNGCryptoServiceProvider())
            {
                randomSource.GetBytes(buffer);
            }

            return(Base64UrlHelpers.Encode(buffer));
        }
        public void DecodeToBytes_InvalidBase64UrlStringLength_ThrowsException()
        {
            var stringToDecodeWithInvalidLength = "MTIzNDU21";

            Action decodeAction = () => Base64UrlHelpers.DecodeBytes(stringToDecodeWithInvalidLength);

            var exception = Assert.Throws <ArgumentException>(decodeAction);

            Assert.Equal(IDWebErrorMessage.InvalidBase64UrlString + " (Parameter 'str')", exception.Message);
        }
Esempio n. 20
0
        private string CreateJwk()
        {
            RSACryptoServiceProvider rsa        = new RSACryptoServiceProvider(2048);
            RSAParameters            rsaKeyInfo = rsa.ExportParameters(false);

            string modulus = Base64UrlHelpers.Encode(rsaKeyInfo.Modulus);
            string exp     = Base64UrlHelpers.Encode(rsaKeyInfo.Exponent);
            string jwk     = $"{{\"kty\":\"RSA\", \"n\":\"{modulus}\", \"e\":\"{exp}\"}}";

            return(jwk);
        }
Esempio n. 21
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"]}\"";
        }
        private static string GetSignedClientAssertionUsingMsalInternal(string clientId, IDictionary <string, string> claims)
        {
#if NET_CORE
            var manager = new Client.Platforms.netcore.NetCoreCryptographyManager();
#else
            var manager = new Client.Platforms.net45.NetDesktopCryptographyManager();
#endif
            var jwtToken = new Client.Internal.JsonWebToken(manager, clientId, TestConstants.ClientCredentialAudience, claims);
            var cert     = ConfidentialAppSettings.GetSettings(Cloud.Public).GetCertificate();

            return(jwtToken.Sign(cert, Base64UrlHelpers.Encode(cert.GetCertHash()), true));
        }
Esempio n. 23
0
        public void SignWithCertificate()
        {
            //Tests the cryptography libraries used by MSAL to sign with certificates
            var cert = new X509Certificate2("testCert.crtfile", "passw0rd!");
            CryptographyHelper helper = new CryptographyHelper();

            byte[] result = helper.SignWithCertificate("TEST", cert);
            string value  = Base64UrlHelpers.Encode(result);

            Assert.IsNotNull(value);
            Assert.AreEqual("MrknKHbOAVu2iuLHMFSk2SK773H1ysxaAjAPcTXYSfH4P2fUfvzP6aIb9MkBknjoE_aBYtTnQ7jOAvyQETvogdeSH7pRDPhCk2aX_8VIQw0bjo_zBZj5yJYVWQDLIu8XvbuzIGEvVaXKz4jJ1nYM6toun4tM74rEHvwa0ferafmqHWOd5puPhlKH1VVK2RPuNOoKNLWBprVBaAQVJVFOdRcd3iR0INBHykxtOsG0pgo0Q2uQBlKP7KQb7Ox8i_sw-M21BuUzdIdGs_oeUYh0B8s-eIGf34JmHRWMwWCnRWzZgY9YuIjRoaWNqlWYb8ASjKOxzvk99x8eFEYKOjgAcA", value);
        }
Esempio n. 24
0
        /// <summary>
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            StringBuilder stringBuilder = new StringBuilder();

            stringBuilder.Append(Base64UrlHelpers.Encode(Environment));
            stringBuilder.Append(CacheKeyDelimiter);
            stringBuilder.Append(Base64UrlHelpers.Encode(ClientId));
            stringBuilder.Append(CacheKeyDelimiter);
            stringBuilder.Append(Base64UrlHelpers.Encode(UserIdentifier));

            return(stringBuilder.ToString());
        }
        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);
        }
        public void CreateFromJson_ValidJson_ReturnsClientInfo()
        {
            var clientInfoResult = ClientInfo.CreateFromJson(Base64UrlHelpers.Encode(_decodedJson));

            Assert.NotNull(clientInfoResult);
            Assert.Equal(Uid, clientInfoResult.UniqueObjectIdentifier);
            Assert.Equal(Utid, clientInfoResult.UniqueTenantIdentifier);

            clientInfoResult = ClientInfo.CreateFromJson(Base64UrlHelpers.Encode(_decodedEmptyJson));
            Assert.NotNull(clientInfoResult);
            Assert.Null(clientInfoResult.UniqueObjectIdentifier);
            Assert.Null(clientInfoResult.UniqueTenantIdentifier);
        }
        public string CreateBase64UrlEncodedSha256Hash(string input)
        {
            if (string.IsNullOrEmpty(input))
            {
                return(null);
            }

            using (SHA256Managed sha = new SHA256Managed())
            {
                UTF8Encoding encoding = new UTF8Encoding();
                return(Base64UrlHelpers.Encode(sha.ComputeHash(encoding.GetBytes(input))));
            }
        }
        private void AddIosSpecificParametersToPayload(Dictionary <string, string> brokerPayload)
        {
            string encodedBrokerKey = Base64UrlHelpers.Encode(BrokerKeyHelper.GetRawBrokerKey(_serviceBundle.DefaultLogger));

            brokerPayload[iOSBrokerConstants.BrokerKey]      = encodedBrokerKey;
            brokerPayload[iOSBrokerConstants.MsgProtocolVer] = BrokerParameter.MsgProtocolVersion3;

            if (brokerPayload.ContainsKey(iOSBrokerConstants.Claims))
            {
                brokerPayload.Add(iOSBrokerConstants.SkipCache, BrokerParameter.SkipCache);
                string claims = Base64UrlHelpers.Encode(brokerPayload[BrokerParameter.Claims]);
                brokerPayload[BrokerParameter.Claims] = claims;
            }
        }
Esempio n. 29
0
        /// <summary>
        /// Creates a JWS (json web signature) as per: https://tools.ietf.org/html/rfc7515
        /// Format: header.payload.signed_payload
        /// </summary>
        private string CreateJWS(string payload, string header)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append(Base64UrlHelpers.Encode(Encoding.UTF8.GetBytes(header)));
            sb.Append(".");
            sb.Append(Base64UrlHelpers.Encode(payload));
            string headerAndPayload = sb.ToString();

            sb.Append(".");
            sb.Append(Base64UrlHelpers.Encode(_popCryptoProvider.Sign(Encoding.UTF8.GetBytes(headerAndPayload))));

            return(sb.ToString());
        }
Esempio n. 30
0
        public void CreateString_UTF8Bytes_ReturnsValidString()
        {
            var stringToCreate = "123456";

            var resultString = Base64UrlHelpers.CreateString(Encoding.UTF8.GetBytes(stringToCreate));

            Assert.Equal(stringToCreate, resultString);

            stringToCreate = string.Empty;

            resultString = Base64UrlHelpers.CreateString(Encoding.UTF8.GetBytes(stringToCreate));

            Assert.Equal(stringToCreate, resultString);
        }