Skip to content

Prepwork for EKM integration - #395

Merged
tomholub merged 14 commits into
masterfrom
feature/issue-385-prepwork-ekm-integration
Jul 23, 2021
Merged

Prepwork for EKM integration#395
tomholub merged 14 commits into
masterfrom
feature/issue-385-prepwork-ekm-integration

Conversation

@ekievsky

@ekievskyekievsky commented Jul 15, 2021

Copy link
Copy Markdown
Contributor

This PR:
Created org rules permission services.
Checking org rules permission on setup.
Added method for getting private keys from EKM.

close#385


Tests :

  • Tests will be added later in this PR

To be filled by reviewers

I have reviewed that this PR... (tick whichever items you personally focused on during this review):

  • addresses the issue it closes (if any)
  • code is readable and understandable
  • is accompanied with tests, or tests are not needed
  • is free of vulnerabilities
  • is documented clearly and usefully, or doesn't need documentation

Checking org rules permission on setup;
Added method for getting private keys from EKM;
@ekievsky
ekievsky marked this pull request as draft July 15, 2021 13:18
@ekievsky

Copy link
Copy Markdown
ContributorAuthor

@tomholub

  1. GET <ekm>/v1/keys/private returns 500 right now.
  2. Could you help with messages for errors? (please check Localizable.string updates)

@tomholub

tomholub commented Jul 15, 2021 via email

Copy link
Copy Markdown
Collaborator

@ekievsky

Copy link
Copy Markdown
ContributorAuthor

what exactly does the error say? there’s an error string and stack trace in the response

On Thursday, July 15, 2021, Evgenii Kievsky @.***> wrote: @tomholubhttps://github.com/tomholub 1. GET /v1/keys/private returns 500 right now. 2. Could you help with messages for errors? (please check Localizable.string updates) — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#395 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABQDZEKXOZLEKRYSIGY4W7LTX3N5RANCNFSM5ANREBIQ .
-- -- Tom James Holub http://holub.me/

I mean the errors for checking OrgRules fields. Now I just copy pasted from issue:

"organisational_rules_autoimport_or_autogen_with_private_key_manager_error" = "Combination of rules (key_manager_url set but PRV_AUTOIMPORT_OR_AUTOGEN is missing) is not supported on this platform";
"organisational_rules_autogen_passphrase_quitely_error" = "Combination of rules (PRV_AUTOIMPORT_OR_AUTOGEN + PASS_PHRASE_QUIET_AUTOGEN) is not supported on this platform";
"organisational_rules_forbid_storing_passphrase_error" = "Combination of rules (PRV_AUTOIMPORT_OR_AUTOGEN + missing FORBID_STORING_PASS_PHRASE) is not supported on this platform";
"organisational_rules_must_submit_attester_error" = "Combination of rules (PRV_AUTOIMPORT_OR_AUTOGEN + ENFORCE_ATTESTER_SUBMIT) is not supported on this platform";
"organisational_rules_can_create_keys_error" = "Combination of rules (PRV_AUTOIMPORT_OR_AUTOGEN + missing NO_PRV_CREATE) is not supported on this platform";

@tomholub

tomholub commented Jul 15, 2021 via email

Copy link
Copy Markdown
Collaborator

@ekievsky

ekievsky commented Jul 15, 2021

Copy link
Copy Markdown
ContributorAuthor

{"code":500,"message":"Unrecognized token 'ɭ': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')\n at [Source: (String)\"ɭ�\"; line: 1, column: 2]","details":"com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'ɭ': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')\n at [Source: (String)\"ɭ�\"; line: 1, column: 2]\n\tat com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:2337)\n\tat com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:720)\n\tat com.fasterxml.jackson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2903)\n\tat com.fasterxml.jackson.core.json.ReaderBasedJsonParser._handleOddValue(ReaderBasedJsonParser.java:1949)\n\tat com.fasterxml.jackson.core.json.ReaderBasedJsonParser.nextToken(ReaderBasedJsonParser.java:781)\n\tat com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:4684)\n\tat com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4586)\n\tat com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3548)\n\tat com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3516)\n\tat io.javalin.plugin.json.JavalinJackson.fromJson(JavalinJackson.kt:47)\n\tat com.flowcrypt.shared.utils.KtJackson.fromJsonToMap(KtJackson.kt:44)\n\tat com.flowcrypt.shared.authenticator.accesstoken.AccessTokenAuthenticator.canAuthenticate(AccessTokenAuthenticator.kt:120)\n\tat com.flowcrypt.ekm.server.handlers.hooks.EkmHandlerHooks.authenticateAndAuthorize(EkmHandlerHooks.kt:81)\n\tat com.flowcrypt.ekm.server.EkmApi$2.invoke(EkmApi.kt:57)\n\tat com.flowcrypt.ekm.server.EkmApi$2.invoke(EkmApi.kt:40)\n\tat com.flowcrypt.ekm.server.EkmApi$sam$io_javalin_http_Handler$0.handle(EkmApi.kt)\n\tat io.javalin.http.JavalinServlet$service$2$1.invoke(JavalinServlet.kt:42)\n\tat io.javalin.http.JavalinServlet$service$2$1.invoke(JavalinServlet.kt:24)\n\tat io.javalin.http.JavalinServlet$service$1.invoke(JavalinServlet.kt:136)\n\tat io.javalin.http.JavalinServlet$service$2.invoke(JavalinServlet.kt:40)\n\tat io.javalin.http.JavalinServlet.service(JavalinServlet.kt:81)\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:790)\n\tat io.javalin.websocket.JavalinWsServlet.service(JavalinWsServlet.kt:51)\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:790)\n\tat org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:791)\n\tat org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:550)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)\n\tat org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233)\n\tat io.javalin.core.JavalinServer$start$wsAndHttpHandler$1.doHandle(JavalinServer.kt:49)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188)\n\tat org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501)\n\tat org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186)\n\tat org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1350)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)\n\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)\n\tat org.eclipse.jetty.server.Server.handle(Server.java:516)\n\tat org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:388)\n\tat org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:633)\n\tat org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:380)\n\tat org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)\n\tat org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)\n\tat org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)\n\tat org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)\n\tat org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)\n\tat org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)\n\tat org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)\n\tat org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129)\n\tat org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:383)\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:882)\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1036)\n\tat java.base/java.lang.Thread.run(Thread.java:829)\n"}

@ekievsky

Copy link
Copy Markdown
ContributorAuthor

I am not really sure is it really secure to send token through comments in github :/

@tomholub

tomholub commented Jul 15, 2021 via email

Copy link
Copy Markdown
Collaborator

@tomholub

tomholub commented Jul 15, 2021 via email

Copy link
Copy Markdown
Collaborator

@ekievsky

Copy link
Copy Markdown
ContributorAuthor

got it. looks like you accidentally submitted some http body? there should be no body

The body is empty

@tomholub

Copy link
Copy Markdown
Collaborator

Okay, I've got 200. But the weird thing was that error was saying that id token expired but session was active. I'll investigate a bit about it tomorrow, so nevermind by now. Thanks for the help!

Expiration of ID tokens is independent of your session. The ones from Google expire in 1 hour by default.

That's why you can only use them to pull keys from EKM during the setup flow, and not periodically later - it has to be immediately after login, so they don't have a chance to expire.

@tomholubtomholub left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you - notes below

Comment threadFlowCrypt/Controllers/Setup/SetupInitialViewController.swift Outdated
Comment threadFlowCrypt/Controllers/Setup/SetupInitialViewController.swift Outdated
Comment threadFlowCrypt/Models/OrganisationalRule.swift Outdated
@ekievsky

Copy link
Copy Markdown
ContributorAuthor

@tomholub Is there an email that will return a key calling /v1/keys/private?

@tomholub

tomholub commented Jul 16, 2021

Copy link
Copy Markdown
Collaborator

I've sent you email credentials for your company email evgenii@ to your email.

@seisvelas please help me log this

@ekievsky

Copy link
Copy Markdown
ContributorAuthor

I can't really how do I create private key to get it through /v1/keys/private

@tomholub

Copy link
Copy Markdown
Collaborator

You already have a keypair set up on your company email. When you call that endpoint with ID Token of that account, it will respond with your keypair.

Download the FlowCrypt browser extension and set it up on that account - it will automatically load your private key from the EKM. This is what the iOS app should also do. If you're not sure, in the browser, open the network tab and evaluate the requests between browser extension and the ekm during setup.

image

@ekievsky
ekievsky marked this pull request as ready for review July 16, 2021 16:09

@tomholubtomholub left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you - this is what I wanted, looking at the code.

Please update based on comments. Thanks!

Comment threadFlowCrypt/Controllers/Setup/SetupInitialViewController.swift Outdated
Comment threadFlowCrypt/Controllers/Setup/SetupInitialViewController.swift
Comment threadFlowCrypt/Core/Models/DecryptedPrivateKey.swift Outdated
let urlString = urlRequest.url?.absoluteString ?? "??"
let message = "URLSession.call status:\(status) ms:\(trace.finish()) \(urlMethod) \(urlString)"
let headers = urlRequest.allHTTPHeaderFields ?? [:]
let message = "URLSession.call status:\(status) ms:\(trace.finish()) \(urlMethod) \(urlString), headers: \(headers)"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if printing request headers here would leak user credentials somewhere dangerous. @martgil is this a problem on iOS?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should not be any printing on production build, we need to check that in our Logger.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would highly suggest getting rid of the debug information on a production build. Printing the request headers alone even it contains sensitive information isn't a threat yet. An attacker needs physical access or required a network listener to exploit it. Nevertheless, @ekievsky is correct that there shouldn't be any debug logs on the production build.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ekievsky by "should not be printing" did you mean it does not print any in production build, or that it would be bad if it printed?

We'll have to be very clear about this - I'm making an issue to verify that it in fact does not print it in a production build.

ykyivskyi-gd added 2 commits July 17, 2021 15:38
…om:FlowCrypt/flowcrypt-ios into feature/issue-385-prepwork-ekm-integration

@tomholubtomholub left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see updated comments. Errors or missing values should not be ignored by substituting them with empty strings. The errors should be dealt with directly.

Comment threadFlowCrypt/Controllers/Setup/SetupInitialViewController.swift Outdated
Comment threadFlowCrypt/Functionality/Services/EmailKeyManagerApi.swift
Comment threadFlowCrypt/Functionality/Services/EmailKeyManagerApi.swift Outdated
@tomholub
tomholub marked this pull request as draft July 19, 2021 07:55
@tomholub

tomholub commented Jul 19, 2021 via email

Copy link
Copy Markdown
Collaborator

@ekievsky

Copy link
Copy Markdown
ContributorAuthor

yeah, you are right, we just got the request from back end using this url

Comment threadFlowCrypt/Functionality/Services/AttesterApi.swift
@ekievsky
ekievsky marked this pull request as ready for review July 19, 2021 20:26

@tomholubtomholub left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good - thank you. I'll test this

@tomholubtomholub left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I log in with flowcrypt.compatibility account, it tells me that I have a wrong combination of OrgRules key_manager_url set but PRV_AUTOIMPORT_OR_AUTOGEN is missing).

But that is definitely wrong, because that is an account on Gmail domain. Accounts on Gmail domain are supposed to receive default empty OrgRules, just {flags: []}, which does not have key_manager_url set.

Comment threadFlowCrypt/Controllers/Setup/SetupInitialViewController.swift Outdated
tomholub
tomholub previously approved these changes Jul 23, 2021

@tomholubtomholub left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've renamed various methods for easier comprehension. Otherwise functionality looks correct, except #408 which I think was already present before.

@tomholub
tomholub enabled auto-merge (squash) July 23, 2021 12:18
@tomholub
tomholub merged commit 4cb8a8d into masterJul 23, 2021
@tomholub
tomholub deleted the feature/issue-385-prepwork-ekm-integration branch July 23, 2021 12:54
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

prepwork for EKM integration during setup

4 participants

@ekievsky@tomholub@martgil@flowcrypt-machine-user