Skip to content

Implement an iOS platform certificate verifier.#2638

Merged
RyanTheOptimist merged 23 commits intoenvoyproxy:mainfrom
RyanTheOptimist:ios_verifier
Nov 6, 2022
Merged

Implement an iOS platform certificate verifier.#2638
RyanTheOptimist merged 23 commits intoenvoyproxy:mainfrom
RyanTheOptimist:ios_verifier

Conversation

@RyanTheOptimist
Copy link
Contributor

Implement an iOS platform certificate verifier
and Swift builder APIs for enabling it.

Risk Level: Low
Testing: Help?
Docs Changes: N/A
Release Notes: Updated version_history.txt

Signed-off-by: Ryan Hamilton rch@google.com

Signed-off-by: Ryan Hamilton <rch@google.com>
Signed-off-by: Ryan Hamilton <rch@google.com>
@RyanTheOptimist RyanTheOptimist marked this pull request as draft October 27, 2022 21:36
Signed-off-by: Ryan Hamilton <rch@google.com>
Signed-off-by: Ryan Hamilton <rch@google.com>
Signed-off-by: Ryan Hamilton <rch@google.com>
Signed-off-by: Ryan Hamilton <rch@google.com>
Signed-off-by: Ryan Hamilton <rch@google.com>
Signed-off-by: Ryan Hamilton <rch@google.com>
Signed-off-by: Ryan Hamilton <rch@google.com>
Signed-off-by: Ryan Hamilton <rch@google.com>
Signed-off-by: Ryan Hamilton <rch@google.com>
Signed-off-by: Ryan Hamilton <rch@google.com>
Signed-off-by: Ryan Hamilton <rch@google.com>
Signed-off-by: Ryan Hamilton <rch@google.com>
@RyanTheOptimist RyanTheOptimist marked this pull request as ready for review November 2, 2022 16:34
@RyanTheOptimist
Copy link
Contributor Author

/assign @jpsim

@RyanTheOptimist
Copy link
Contributor Author

@jpsim this is finally passing CI. Woo hoo! I'm 100% confident that it needs work, but I'm not clear enough on how iOS work in Envoy Mobile to really have a good sense for where this code should go/what it should look like. So this is really more of rough draft than a ready-to-review PR, but if you could take a look, I would appreciate it.

private var enableBrotli: Bool = false
private var enableInterfaceBinding: Bool = false
private var enforceTrustChainVerification: Bool = true
private var enablePlatformCertificateValidation: Bool = true
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this default to false until it's been vetted in a production experiment?

Suggested change
private var enablePlatformCertificateValidation: Bool = true
private var enablePlatformCertificateValidation: Bool = false

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, definitely! This was a hack to make sure this new code would be run though CI to help make sure it works. Do you have a suggestion for how to write a test for this code? Or alternatively, a suggestion for some place I could explicitly enable in, maybe in the experimental app?

@jpsim
Copy link
Contributor

jpsim commented Nov 2, 2022

It's great to see this @RyanTheOptimist! My main thought is if it's possible to move the bulk of this into the library/common layer since the iOS platform APIs are in C.

I look forward to being able to stop bundling certs with Envoy Mobile in the long run!

Copy link
Contributor Author

@RyanTheOptimist RyanTheOptimist left a comment

Choose a reason for hiding this comment

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

Thanks for the review!

private var enableBrotli: Bool = false
private var enableInterfaceBinding: Bool = false
private var enforceTrustChainVerification: Bool = true
private var enablePlatformCertificateValidation: Bool = true
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, definitely! This was a hack to make sure this new code would be run though CI to help make sure it works. Do you have a suggestion for how to write a test for this code? Or alternatively, a suggestion for some place I could explicitly enable in, maybe in the experimental app?

Update library/objective-c/EnvoyConfiguration.m
Fix test constant
Fix Test
revert .bazelrc

Co-authored-by: JP Simard <jp@jpsim.com>
Signed-off-by: Ryan Hamilton <rch@google.com>
Signed-off-by: Ryan Hamilton <rch@google.com>
Signed-off-by: Ryan Hamilton <rch@google.com>
Signed-off-by: Ryan Hamilton <rch@google.com>
Copy link
Contributor

@jpsim jpsim left a comment

Choose a reason for hiding this comment

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

This is really shaping up! Did you want to hook this up in the C++ builder in this PR or as a followup?

@jpsim
Copy link
Contributor

jpsim commented Nov 4, 2022

I think I'm seeing a crash with this enabled:

* thread #14, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  * frame #0: 0x00000001052583b0 app`Envoy::Extensions::TransportSockets::Tls::PlatformBridgeCertValidator::PendingValidation::postVerifyResultAndCleanUp(this=0x00006000019f4ef0, success=true, error_details="", tls_alert='.', error_counter=OptRef<Envoy::Stats::Counter> @ 0x000000016d9567c8) at platform_bridge_cert_validator.cc:142:21
    frame #1: 0x000000010525821c app`Envoy::Extensions::TransportSockets::Tls::PlatformBridgeCertValidator::verifyCertChainByPlatform(this=0x00006000000c61c0, cert_chain=size=0, host_name="", subject_alt_names=size=1, pending_validation=0x00006000019f4ef0) at platform_bridge_cert_validator.cc:125:22
    frame #2: 0x0000000105257360 app`Envoy::Extensions::TransportSockets::Tls::PlatformBridgeCertValidator::PendingValidation::verifyCertsByPlatform(this=0x00006000019f4ef0) at platform_bridge_cert_validator.cc:130:11
    frame #3: 0x0000000105263864 app`decltype(__f=0x00006000032291a8, __a0=0x00006000032291b8)).*fp()) std::__1::__invoke<void (Envoy::Extensions::TransportSockets::Tls::PlatformBridgeCertValidator::PendingValidation::*)(), Envoy::Extensions::TransportSockets::Tls::PlatformBridgeCertValidator::PendingValidation*, void>(void (Envoy::Extensions::TransportSockets::Tls::PlatformBridgeCertValidator::PendingValidation::*&&)(), Envoy::Extensions::TransportSockets::Tls::PlatformBridgeCertValidator::PendingValidation*&&) at type_traits:3859:1
    frame #4: 0x00000001052637ac app`void std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (Envoy::Extensions::TransportSockets::Tls::PlatformBridgeCertValidator::PendingValidation::*)(), Envoy::Extensions::TransportSockets::Tls::PlatformBridgeCertValidator::PendingValidation*, 2ul>(__t=size=3, (null)=__tuple_indices<2> @ 0x000000016d956f7f)(), Envoy::Extensions::TransportSockets::Tls::PlatformBridgeCertValidator::PendingValidation*>&, std::__1::__tuple_indices<2ul>) at thread:287:5
    frame #5: 0x0000000105262f38 app`void* std::__1::__thread_proxy<std::__1::tuple<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void (Envoy::Extensions::TransportSockets::Tls::PlatformBridgeCertValidator::PendingValidation::*)(), Envoy::Extensions::TransportSockets::Tls::PlatformBridgeCertValidator::PendingValidation*> >(__vp=0x00006000032291a0) at thread:298:5
    frame #6: 0x00000001cba8f4e4 libsystem_pthread.dylib`_pthread_start + 116

@jpsim
Copy link
Contributor

jpsim commented Nov 4, 2022

The crash happened when I was stepping through code in lldb breakpoints, so it may have influenced the crash. I haven't seen the crash since running without stopping at a breakpoint.

Can you add this to the experimental app so we get some integration test coverage?

Signed-off-by: Ryan Hamilton <rch@google.com>
@RyanTheOptimist
Copy link
Contributor Author

This is really shaping up! Did you want to hook this up in the C++ builder in this PR or as a followup?

I'd prefer to hook up in a followup, just to keep this smaller, if that works for you?

@RyanTheOptimist
Copy link
Contributor Author

The crash happened when I was stepping through code in lldb breakpoints, so it may have influenced the crash. I haven't seen the crash since running without stopping at a breakpoint.

Can you add this to the experimental app so we get some integration test coverage?

Is the experimental all the same thing as hello_world? I enabled it there, hoping that's what you're looking for, but maybe not?

Copy link
Contributor Author

@RyanTheOptimist RyanTheOptimist left a comment

Choose a reason for hiding this comment

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

Thanks for the review!

@jpsim
Copy link
Contributor

jpsim commented Nov 4, 2022

Is the experimental all the same thing as hello_world? I enabled it there, hoping that's what you're looking for, but maybe not?

No, we try to keep the "hello world" type apps focused, the "baseline" apps as using the default engine builder configurations and the "experimental" apps using non-default engine builder configurations.

Can you set .enablePlatformCertificateValidation(true) here?

Signed-off-by: Ryan Hamilton <rch@google.com>
@RyanTheOptimist
Copy link
Contributor Author

Is the experimental all the same thing as hello_world? I enabled it there, hoping that's what you're looking for, but maybe not?

No, we try to keep the "hello world" type apps focused, the "baseline" apps as using the default engine builder configurations and the "experimental" apps using non-default engine builder configurations.

Can you set .enablePlatformCertificateValidation(true) here?

Oh, I see. Done!

)

cc_library(
name = "ios_platform_verifier",
Copy link
Contributor

@jpsim jpsim Nov 4, 2022

Choose a reason for hiding this comment

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

Nit: can we call this apple_cert_verifier since "verifier" could imply it verifies a lot of things, and this applies to all Apple platforms, not just iOS, and mirrors the naming of the apple_dns_resolver.

Suggested change
name = "ios_platform_verifier",
name = "apple_platform_cert_verifier",

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea. Done.

],
"//conditions:default": [],
}),
) No newline at end of file
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add a trailing newline to match unix conventions?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Not sure how that crept back :/ (Also not sure why clang-format didn't fix it. But c'est la vie)

Signed-off-by: Ryan Hamilton <rch@google.com>
jpsim
jpsim previously approved these changes Nov 4, 2022
Copy link
Contributor

@jpsim jpsim left a comment

Choose a reason for hiding this comment

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

Hooray, great job setting this up.

Signed-off-by: Ryan Hamilton <rch@google.com>
jpsim
jpsim previously approved these changes Nov 4, 2022
Signed-off-by: Ryan Hamilton <rch@google.com>
@RyanTheOptimist RyanTheOptimist merged commit c0ef4d4 into envoyproxy:main Nov 6, 2022
RyanTheOptimist added a commit that referenced this pull request Nov 7, 2022
…2663)

Signed-off-by: Ryan Hamilton rch@google.com

Was set to true inadvertently in #2638.
jpsim added a commit that referenced this pull request Nov 14, 2022
…builder-function

* origin/main:
  ci: hopefully fixing bes timeout failures (#2666)
  Update Envoy (#2660)
  bazel: update rules_jvm_external to 4.5 (#2665)
  Remove note about DWARF patch being required (#2645)
  Bump Lyft Support Rotation (#2661)
  build: remove alwayslink
  set enablePlatformCertificateValidation to false on iOS by default (#2663)
  bump Envoy dep (#2659)
  Implement an iOS platform certificate verifier. (#2638)

Signed-off-by: JP Simard <jp@jpsim.com>
Sign up for free to 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.

2 participants