Typically, when software needs to perform cryptographic tasks, developers use libraries or APIs that abstract many details away from them. They don't need to fully understand how TLS handshakes work to create a TLS socket, nor do they need to understand the cryptographic primitives used to encrypt SSH traffic when making SSH connections. However, some abstractions are leaky, and a better understanding is required to get things right. One example is validation of certificate chains, which is required when using APIs like Google SafetyNet or Android Protected Confirmation.
Applied cryptography can be hard even when using cryptographic libraries. For example, many cryptographic libraries make it difficult or non-obvious to properly validate certificate chains. Generally speaking, it's not because of defects in the library, but rather the difficulty of designing usable cryptographic APIs and providing clear, unambiguous documentation. There's also a lot of incorrect advice on the internet when it comes to implementing common cryptographic workflows. Advice on validating certificate chains is no exception. Oftentimes, this advice instructs the developer to (unknowingly) add untrusted intermediates as trusted roots when building certificate chains, which breaks the chain of trust. This allows an attacker to provide an otherwise valid certificate chain that chains up to a fake root, which will cause certificate chain validation to succeed when it shouldn't.
In this talk, we explore the implications of poor cryptographic API design, how insecure certificate chain validation implementations can be exploited, and how widespread usage of APIs like Android SafetyNet are in certain verticals. We also propose recommendations for both implementers and cryptographic API authors, like choosing misuse-resistant cryptographic APIs and what to do when faced with misuse-prone cryptographic primitives.