Esempio n. 1
0
        public void TestParseDirectory()
        {
            var eid = EntityIdentifier.FromString($"dir:{_testGuidString}");

            Assert.AreEqual(eid.Id, _testGuid);
            Assert.AreEqual(eid.Type, EntityType.Directory);
        }
Esempio n. 2
0
        public void TestParseService()
        {
            var eid = EntityIdentifier.FromString($"svc:{_testGuidString}");

            Assert.AreEqual(eid.Id, _testGuid);
            Assert.AreEqual(eid.Type, EntityType.Service);
        }
Esempio n. 3
0
        public void TestParseOrg()
        {
            var eid = EntityIdentifier.FromString($"org:{_testGuidString}");

            Assert.AreEqual(eid.Id, _testGuid);
            Assert.AreEqual(eid.Type, EntityType.Organization);
        }
Esempio n. 4
0
        public void TestEncodeAndDecode()
        {
            var eid1    = new EntityIdentifier(EntityType.Organization, _testGuid);
            var eid1Str = eid1.ToString();
            var eid2    = EntityIdentifier.FromString(eid1Str);

            Assert.AreEqual(eid1, eid2);
        }
        public IServerSentEvent HandleServerSentEvent(Dictionary <string, List <string> > headers, string body, string method = null, string path = null)
        {
            var iovHeader     = GetFirstHeader(headers, IOV_JWT_HEADER);
            var contentHeader = GetFirstHeader(headers, "Content-Type");

            try
            {
                // pull out the key id
                var jwtData = _jwtService.GetJWTData(iovHeader);

                // get public key associated with the id. may have to fetch it!
                var publicKey = FetchPublicKeyWithId(jwtData.KeyId);

                // decode and verify the JWT.
                // note we do not store the result -- its not needed. Just want the decoder to throw an exception
                // if there is a validation issue
                // we also dont verify our private claims here, as they are not present or relevant
                var jwtObject = _jwtService.Decode(publicKey.KeyData, _issuer.ToString(), null, GetCurrentTime(), iovHeader);
                ValidatePrivateClaimsForServerSentRequest(method, path, body, jwtObject.Request);

                // if this is not application/jose, it is a service session end response
                if (contentHeader == "application/jose")
                {
                    var requestingEntity = EntityIdentifier.FromString(jwtData.Audience);
                    var decryptedBody    = _jweService.Decrypt(body);

                    if (decryptedBody.Contains("DEVICE_LINK_COMPLETION") == true)
                    {
                        DeviceLinkCompletion deviceLinkCompletion = DecodeResponse <DeviceLinkCompletion>(decryptedBody);
                        return(new ServerSentEventDeviceLinked(deviceLinkCompletion));
                    }
                    else
                    {
                        Guid     authorizationRequestId;
                        var      core = DecodeResponse <ServiceV3AuthsGetResponseCore>(decryptedBody);
                        bool     response;
                        string   deviceId;
                        string[] servicePins;
                        string   type;
                        string   reason;
                        string   denialreason;
                        AuthPolicy.JWEAuthPolicy authPolicy;
                        AuthPolicy.AuthMethod[]  authMethods;

                        if (core.JweEncryptedDeviceResponse != null)
                        {
                            var decryptedDeviceData = _jweService.Decrypt(core.JweEncryptedDeviceResponse);
                            var deviceResponse      = DecodeResponse <ServiceV3AuthsGetResponseDeviceJWE>(decryptedDeviceData);
                            authorizationRequestId = deviceResponse.AuthorizationRequestId;
                            response     = deviceResponse.Type == "AUTHORIZED";
                            deviceId     = deviceResponse.DeviceId;
                            servicePins  = deviceResponse.ServicePins;
                            type         = deviceResponse.Type;
                            reason       = deviceResponse.Reason;
                            denialreason = deviceResponse.DenialReason;
                            authPolicy   = deviceResponse.AuthPolicy;
                            authMethods  = deviceResponse.AuthMethods;
                        }
                        else
                        {
                            var bodyJweHeaders = _jweService.GetHeaders(body);
                            if (!bodyJweHeaders.ContainsKey("kid"))
                            {
                                throw new InvalidRequestException("JWE headers does not include a key id");
                            }
                            var privateKey                = _keyMap.GetKey(requestingEntity, bodyJweHeaders["kid"]);
                            var encryptedDeviceData       = Convert.FromBase64String(core.EncryptedDeviceResponse);
                            var decryptedDeviceData       = _crypto.DecryptRSA(encryptedDeviceData, privateKey);
                            var decryptedDeviceDataString = Encoding.UTF8.GetString(decryptedDeviceData);
                            var deviceResponse            = DecodeResponse <ServiceV3AuthsGetResponseDevice>(decryptedDeviceDataString);
                            authorizationRequestId = deviceResponse.AuthorizationRequestId;
                            response     = deviceResponse.Response;
                            deviceId     = deviceResponse.DeviceId;
                            servicePins  = deviceResponse.ServicePins;
                            type         = null;
                            reason       = null;
                            denialreason = null;
                            authPolicy   = null;
                            authMethods  = null;
                        }
                        return(new ServerSentEventAuthorizationResponse(
                                   requestingEntity,
                                   EntityIdentifier.FromString(jwtData.Subject).Id,
                                   core.ServiceUserHash,
                                   core.OrgUserHash,
                                   core.UserPushId,
                                   authorizationRequestId,
                                   response,
                                   deviceId,
                                   servicePins,
                                   type,
                                   reason,
                                   denialreason,
                                   authPolicy,
                                   authMethods
                                   ));
                    }
                }
                else
                {
                    return(_jsonDecoder.DecodeObject <ServerSentEventUserServiceSessionEnd>(body));
                }
            }
            catch (JwtError ex)
            {
                throw new InvalidRequestException("JWT error while processing event", ex);
            }
            catch (JweException ex)
            {
                throw new InvalidRequestException("Unable to decrypt body", ex);
            }
        }
        public ServiceV3AuthsGetResponse ServiceV3AuthsGet(Guid authRequestId, EntityIdentifier subject)
        {
            var response = ExecuteRequest(HttpMethod.GET, $"/service/v3/auths/{authRequestId}", subject, null, new List <int> {
                408
            });

            if ((int)response.StatusCode == 204)
            {
                // user has not responded yet
                return(null);
            }

            if ((int)response.StatusCode == 408)
            {
                throw new AuthorizationRequestTimedOutError();
            }

            try
            {
                var coreResponse = DecryptResponse <ServiceV3AuthsGetResponseCore>(response);
                var jwtHeader    = response.Headers[IOV_JWT_HEADER];
                var jwtData      = _jwtService.GetJWTData(jwtHeader);
                var audience     = EntityIdentifier.FromString(jwtData.Audience);
                var key          = _keyMap.GetKey(audience, coreResponse.PublicKeyId);

                bool     authResponse = false;
                string   deviceId     = null;
                string[] servicePins  = null;
                string   type;
                string   reason;
                string   denialReason;
                AuthPolicy.JWEAuthPolicy authPolicy;
                AuthPolicy.AuthMethod[]  authMethods;



                try
                {
                    if (coreResponse.JweEncryptedDeviceResponse != null)
                    {
                        var decryptedResponse = DecryptJweData(coreResponse.JweEncryptedDeviceResponse);
                        var deviceResponse    = DecodeResponse <ServiceV3AuthsGetResponseDeviceJWE>(decryptedResponse);
                        authResponse = deviceResponse.Type == "AUTHORIZED";
                        deviceId     = deviceResponse.DeviceId;
                        servicePins  = deviceResponse.ServicePins;
                        type         = deviceResponse.Type;
                        reason       = deviceResponse.Reason;
                        denialReason = deviceResponse.DenialReason;
                        authPolicy   = deviceResponse.AuthPolicy;
                        authMethods  = deviceResponse.AuthMethods;
                    }
                    else
                    {
                        var encryptedDeviceResponse = Convert.FromBase64String(coreResponse.EncryptedDeviceResponse);
                        var decryptedResponse       = _crypto.DecryptRSA(encryptedDeviceResponse, key);
                        var decryptedResponseString = Encoding.UTF8.GetString(decryptedResponse);
                        var deviceResponse          = _jsonDecoder.DecodeObject <ServiceV3AuthsGetResponseDevice>(decryptedResponseString);
                        authResponse = deviceResponse.Response;
                        deviceId     = deviceResponse.DeviceId;
                        servicePins  = deviceResponse.ServicePins;
                        type         = null;
                        reason       = null;
                        denialReason = null;
                        authPolicy   = null;
                        authMethods  = null;
                    }

                    return(new ServiceV3AuthsGetResponse(
                               audience,
                               subject.Id,
                               coreResponse.ServiceUserHash,
                               coreResponse.OrgUserHash,
                               coreResponse.UserPushId,
                               authRequestId,
                               authResponse,
                               deviceId,
                               servicePins,
                               type,
                               reason,
                               denialReason,
                               authPolicy,
                               authMethods
                               ));
                }
                catch (Exception ex)
                {
                    throw new CryptographyError("Error decrypting device response", ex);
                }
            }
            catch (JwtError ex)
            {
                throw new CryptographyError("Unable to parse JWT to get key info", ex);
            }
        }
        public void Initialize()
        {
            HttpResponse = new Mock <HttpResponse>();
            HttpResponse.Object.StatusCode = HttpStatusCode.NoContent;
            HttpResponse.Object.Headers    = new WebHeaderCollection
            {
                { "X-IOV-KEY-ID", "d2:8e:16:91:39:5b:9d:24:73:0e:36:0a:9a:ef:7e:de" },
                { "X-IOV-JWT", "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImQyOjhlOjE2OjkxOjM5OjViOjlkOjI0OjczOjBlOjM2OjBhOjlhOmVmOjdlOmRlIn0.eyJhdWQiOiJzdmM6ZjgzMjllMGUtZGQ3YS0xMWU3LTk4YjQtNDY5MTU4NDY3YjFhIiwiaXNzIjoibGthIiwiY3R5IjoiYXBwbGljYXRpb24vanNvbiIsIm5iZiI6MTUxNTA1MTcwMSwianRpIjoiMjJkYWU0MjUzMTY1NDk1YThlZDU2YzM0YzRkMDUwY2UiLCJleHAiOjE1MTUwNTE3MDYsImlhdCI6MTUxNTA1MTcwMSwicmVzcG9uc2UiOnsic3RhdHVzIjoyMDAsImhhc2giOiI0YzViODBlZDhlNTRhZWIwNDkwODFiYTBjMWE0ZDViMjkwNzhkMjIzM2NhZTkxZDg5ODUyMjUwYTFkMWQ1OWEyIiwiZnVuYyI6IlMyNTYifSwic3ViIjoic3ZjOmY4MzI5ZTBlLWRkN2EtMTFlNy05OGI0LTQ2OTE1ODQ2N2IxYSJ9.NFhztQSep7f0QT8j7KIfK4yFwdHvL24r8qdYKZz3M3Y2kyQYT0ECBPXnXgr2KbU5gntWdjVUOySUQbDnF2aL8QDyWPQHGy6jX7n4rO2VdeYuROz-3dbx7taSJEUUlDSvoDAerL26P02xU6LbZno1TCl4pYMQn4k41xwBvYdf8vvN1ixLhCJE_S2V18bT4YKTqwxE-XnbubdAdvhkPdl-7Khja4r1MpktRTZAMWJECLXI3JJILm-3HudO9KS5uAAHkxGbW1ovZfxOcKv9fcwoZ4mSn1pXA7k1aAt7DJdk4EuOtLmxb5rIKTDvQcBZIPyO_N3repWeD8ghCIFgWOSHqUE7cM1koUvUZzDiTvPA9o2C46zD26QaljSWfsxYPKtyzZsyglPYc1bcmzJZWzfHFCOoKA8uxe7HLiqNyzry3Cyg0_kPiwwtJ_FBRAnN3MVhAczaXbEPHtrm3vLafw14_M2svtL6f6RsObFroBJE_VDmgdiKtiJiYQ1UEpx_LcwK_OB-BagOnXUFGtveKQIJvABZoRwrxS6TebhVMAU1cGurF2sJmlSO3oi1CC-GSgtVDMmh_a2oA9E5UrG3W5nmB-ThCGBpKfTIYB19rwsOd6RYNUaOEj65_KN_EFHH_7dLAeDDlPWqFCUfML9pjeRUK289c_ByDDOX3N3iTrnCt1o" }
            };
            HttpClient = new Mock <IHttpClient>();
            HttpClient.Setup(client => client.ExecuteRequest(It.IsAny <HttpMethod>(), It.IsAny <String>(), It.IsAny <String>(), It.IsAny <Dictionary <string, String> >()))
            .Returns(HttpResponse.Object);
            Crypto = new Mock <ICrypto>();
            Crypto.Setup(c => c.DecryptRSA(It.IsAny <byte[]>(), It.IsAny <RSA>())).Returns(System.Text.Encoding.ASCII.GetBytes("Decrypted"));
            Crypto.Setup(c => c.Sha256(It.IsAny <byte[]>())).Returns(new byte[] { 255 });
            PublicKeyCache = new Mock <ICache>();
            PublicKeyCache.Setup(c => c.Get(It.IsAny <String>())).Returns("Public Key");
            Issuer     = new EntityIdentifier(EntityType.Directory, default(Guid));
            JwtService = new Mock <IJwtService>();
            JwtService.Setup(s => s.Encode(It.IsAny <String>(), It.IsAny <String>(), It.IsAny <String>(), It.IsAny <DateTime>(), It.IsAny <String>(), It.IsAny <String>(), It.IsAny <String>(), It.IsAny <String>()))
            .Returns("JWT Encoded");
            JwtClaims         = new Mock <JwtClaims>();
            JwtClaimsResponse = new Mock <JwtClaimsResponse>();
            JwtClaimsResponse.Object.StatusCode           = 204;
            JwtClaimsResponse.Object.LocationHeader       = null;
            JwtClaimsResponse.Object.CacheControlHeader   = null;
            JwtClaimsResponse.Object.ContentHash          = "ff";
            JwtClaimsResponse.Object.ContentHashAlgorithm = "S256";

            JwtClaims.Object.Response = JwtClaimsResponse.Object;

            JwtService.Setup(s => s.Decode(It.IsAny <RSA>(), It.IsAny <string>(), It.IsAny <String>(), It.IsAny <DateTime>(), It.IsAny <String>()))
            .Returns(JwtClaims.Object);
            JwtService.Setup(s => s.GetJWTData(It.IsAny <String>()))
            .Returns(new JwtData("lka", "svc:8c3c0268-f692-11e7-bd2e-7692096aba47", "svc:8c3c0268-f692-11e7-bd2e-7692096aba47", "Key ID"));
            JweService = new Mock <IJweService>();
            JweService.Setup(s => s.Decrypt(It.IsAny <String>())).Returns("Decrypted JWE");
            JweService.Setup(s => s.Encrypt(It.IsAny <String>(), It.IsAny <RSA>(), It.IsAny <String>(), It.IsAny <String>()))
            .Returns("Encrypted JWE");
            JsonEncoder = new Mock <IJsonEncoder>();
            JsonEncoder.Setup(e => e.EncodeObject(It.IsAny <Object>())).Returns("JSON Encoded");
            JsonEncoder.Setup(e => e.DecodeObject <PublicV3PingGetResponse>(It.IsAny <String>())).Returns(new Mock <PublicV3PingGetResponse>().Object);
            AuthsGetResponseCore = new Mock <ServiceV3AuthsGetResponseCore>();
            AuthsGetResponseCore.Object.EncryptedDeviceResponse    = Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes("Encrypted Device Response"));
            AuthsGetResponseCore.Object.JweEncryptedDeviceResponse = null;
            AuthsGetResponseCore.Object.ServiceUserHash            = "Service User Hash";
            AuthsGetResponseCore.Object.OrgUserHash = "Org User Hash";
            AuthsGetResponseCore.Object.UserPushId  = "User Push ID";
            AuthsGetResponseCore.Object.PublicKeyId = "Response Public Key";
            JsonEncoder.Setup(e => e.DecodeObject <ServiceV3AuthsGetResponseCore>(It.IsAny <String>())).Returns(AuthsGetResponseCore.Object);
            DeviceResponse = new Mock <ServiceV3AuthsGetResponseDevice>();
            JsonEncoder.Setup(e => e.DecodeObject <ServiceV3AuthsGetResponseDevice>(It.IsAny <String>())).Returns(DeviceResponse.Object);
            KeyMap = new Mock <EntityKeyMap>();
            KeyMap.Object.AddKey(EntityIdentifier.FromString("svc:8c3c0268-f692-11e7-bd2e-7692096aba47"), "Response Public Key", new Mock <RSA>().Object);
            Transport = new WebClientTransport(
                HttpClient.Object,
                Crypto.Object,
                PublicKeyCache.Object,
                BaseUrl,
                Issuer,
                JwtService.Object,
                JweService.Object,
                0,
                0,
                KeyMap.Object,
                JsonEncoder.Object);
        }
Esempio n. 8
0
        public void Initialize()
        {
            HttpResponse = new Mock <HttpResponse>();
            HttpResponse.Object.StatusCode = HttpStatusCode.OK;
            HttpResponse.Object.Headers    = new WebHeaderCollection
            {
                ["X-IOV-JWT"] = "IOV JWT"
            };
            HttpClient = new Mock <IHttpClient>();
            HttpClient.Setup(client => client.ExecuteRequest(It.IsAny <HttpMethod>(), It.IsAny <String>(), It.IsAny <String>(), It.IsAny <Dictionary <string, String> >()))
            .Returns(HttpResponse.Object);
            Crypto = new Mock <ICrypto>();
            Crypto.Setup(c => c.DecryptRSA(It.IsAny <byte[]>(), It.IsAny <RSA>())).Returns(System.Text.Encoding.ASCII.GetBytes("Decrypted"));
            Crypto.Setup(c => c.Sha256(It.IsAny <byte[]>())).Returns(new byte[] { 255 });
            PublicKeyCache = new Mock <ICache>();
            PublicKeyCache.Setup(c => c.Get(It.IsAny <String>())).Returns("Public Key");
            Issuer     = new EntityIdentifier(EntityType.Directory, default(Guid));
            JwtService = new Mock <IJwtService>();
            JwtService.Setup(s => s.Encode(It.IsAny <String>(), It.IsAny <String>(), It.IsAny <String>(), It.IsAny <DateTime>(), It.IsAny <String>(), It.IsAny <String>(), It.IsAny <String>(), It.IsAny <String>()))
            .Returns("JWT Encoded");
            JwtClaims         = new Mock <JwtClaims>();
            JwtClaimsResponse = new Mock <JwtClaimsResponse>();
            JwtClaimsResponse.Object.StatusCode           = 200;
            JwtClaimsResponse.Object.LocationHeader       = null;
            JwtClaimsResponse.Object.CacheControlHeader   = null;
            JwtClaimsResponse.Object.ContentHash          = "ff";
            JwtClaimsResponse.Object.ContentHashAlgorithm = "S256";

            JwtClaimsRequest = new Mock <JwtClaimsRequest>();
            JwtClaimsRequest.Object.ContentHash          = "ff";
            JwtClaimsRequest.Object.ContentHashAlgorithm = "S256";
            JwtClaimsRequest.Object.Method = "POST";
            JwtClaimsRequest.Object.Path   = "/webhook";


            JwtClaims.Object.Response = JwtClaimsResponse.Object;
            JwtClaims.Object.Request  = JwtClaimsRequest.Object;

            JwtService.Setup(s => s.Decode(It.IsAny <RSA>(), It.IsAny <string>(), It.IsAny <String>(), It.IsAny <DateTime>(), It.IsAny <String>()))
            .Returns(JwtClaims.Object);
            JwtService.Setup(s => s.GetJWTData(It.IsAny <String>()))
            .Returns(new JwtData("lka", "svc:8c3c0268-f692-11e7-bd2e-7692096aba47", "svc:8c3c0268-f692-11e7-bd2e-7692096aba47", "Key ID"));
            JweService = new Mock <IJweService>();
            JweService.Setup(s => s.Decrypt(It.IsAny <String>())).Returns("Decrypted JWE");
            JweService.Setup(s => s.Encrypt(It.IsAny <String>(), It.IsAny <RSA>(), It.IsAny <String>(), It.IsAny <String>()))
            .Returns("Encrypted JWE");
            JweHeaders = new Dictionary <string, string>
            {
                ["kid"] = "Public Key ID"
            };
            JweService.Setup(s => s.GetHeaders(It.IsAny <String>())).Returns(JweHeaders);
            JsonEncoder = new Mock <IJsonEncoder>();
            JsonEncoder.Setup(e => e.EncodeObject(It.IsAny <Object>())).Returns("JSON Encoded");
            JsonEncoder.Setup(e => e.DecodeObject <PublicV3PingGetResponse>(It.IsAny <String>())).Returns(new Mock <PublicV3PingGetResponse>().Object);
            AuthsGetResponseCore = new Mock <ServiceV3AuthsGetResponseCore>();
            AuthsGetResponseCore.Object.EncryptedDeviceResponse    = Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes("Encrypted Device Response"));
            AuthsGetResponseCore.Object.JweEncryptedDeviceResponse = null;
            AuthsGetResponseCore.Object.ServiceUserHash            = "Service User Hash";
            AuthsGetResponseCore.Object.OrgUserHash = "Org User Hash";
            AuthsGetResponseCore.Object.UserPushId  = "User Push ID";
            AuthsGetResponseCore.Object.PublicKeyId = "Public Key ID";
            JsonEncoder.Setup(e => e.DecodeObject <ServiceV3AuthsGetResponseCore>(It.IsAny <String>())).Returns(AuthsGetResponseCore.Object);
            DeviceResponse = new Mock <ServiceV3AuthsGetResponseDevice>();
            JsonEncoder.Setup(e => e.DecodeObject <ServiceV3AuthsGetResponseDevice>(It.IsAny <String>())).Returns(DeviceResponse.Object);
            ServiceSessionEnd = new Mock <ServerSentEventUserServiceSessionEnd>();
            JsonEncoder.Setup(e => e.DecodeObject <ServerSentEventUserServiceSessionEnd>(It.IsAny <String>())).Returns(ServiceSessionEnd.Object);
            KeyMap = new Mock <EntityKeyMap>();
            KeyMap.Object.AddKey(EntityIdentifier.FromString("svc:8c3c0268-f692-11e7-bd2e-7692096aba47"), "Public Key ID", new Mock <RSA>().Object);
            Transport = new WebClientTransport(
                HttpClient.Object,
                Crypto.Object,
                PublicKeyCache.Object,
                BaseUrl,
                Issuer,
                JwtService.Object,
                JweService.Object,
                0,
                0,
                KeyMap.Object,
                JsonEncoder.Object);
        }