Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Security support for new .net 5 platforms #101

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions accepted/2020/mono-convergence/security-support-new-platforms.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Security support for new .NET 5 platforms

## Overview
Currently in .NET Core, we have a solid [strategy](https://github.com/dotnet/corefx/blob/master/Documentation/architecture/cross-platform-cryptography.md) for dealing with cryptography on Linux and OSX. At the native level, `System.Security.Cryptography.Native` relies upon OpenSSL for Linux and `System.Security.Cryptography.Native.Apple` relies upon platform specific API’s for OSX.
steveisok marked this conversation as resolved.
Show resolved Hide resolved

With the introduction of Android, iOS, and Wasm workloads, there are implications to consider that may alter our strategy and require additional work. This document seeks to describe the implications and what options we may have.

## Security Dependencies
For `System.Security.Cryptography.Native` (Linux):

[src/libraries/Native/Unix/System.Security.Cryptography.Native] (https://github.com/dotnet/runtime/tree/master/src/libraries/Native/Unix/System.Security.Cryptography.Native)

For `System.Security.Cryptography.Native.Apple` (OSX):

[src/libraries/Native/Unix/System.Security.Cryptography.Native.Apple] (https://github.com/dotnet/runtime/tree/master/src/libraries/Native/Unix/System.Security.Cryptography.Native.Apple)

### Android
There is currently no platform level API’s that can work with Android, so any native dependency we take must be bundled with the individual application.

**System.Security.Cryptography.Native**

The current dependency on OpenSSL could work as there seems to be support for building on Android. This is nice because it would seemingly ‘just fit’ with what we already have. However, there are some things to take into consideration:
steveisok marked this conversation as resolved.
Show resolved Hide resolved

* Do we fork a copy of OpenSSL and build from that?
* What is our process for shipping security vulnerability updates?
Copy link
Member

Choose a reason for hiding this comment

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

If we have to ship something with an app, don't these questions/concerns apply to any choice?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep - I'll try to restate.

Copy link
Member

Choose a reason for hiding this comment

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

I was aware that Google Play Services includes cronet & boringSSL, but they seem to only be exposed via a Java cronet API - https://developer.android.com/guide/topics/connectivity/cronet - which probably doesn't help us.

Copy link
Member

Choose a reason for hiding this comment

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

Last I knew, Google's documented stance on BoringSSL was that it was unsupported, could change its ABI at any time, etc... exactly what you want when taking a dependency on a security library ;-) If there's a supported/maintained variant, that's then more interesting.

Copy link
Member

Choose a reason for hiding this comment

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

We really, really, really want to avoid shipping a cryptography library with the product. AFAIK, it adds a whole lot of government paperwork; and it creates a very complicated servicing model for both us and the applications built using it.

If there's any library in the box that we can reliably use, that's the best choice almost without regard to how painful it is to initially use it.

Copy link
Member

Choose a reason for hiding this comment

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

I think you'd need to use the conscrypt APIs - which are higher level http APIs.
This may help: https://groups.google.com/forum/#!topic/conscrypt/T4c2YCY91qc.

* Should we consider alternatives?
* [https://tls.mbed.org/](https://tls.mbed.org/) - only solves the TLS part
* Any others?

**System.Net.Security.Native**

For authentication scenarios, we’ve relied on libgss to do the work. It is currently unknown if we *can* support it on Android. Some initial [discovery](https://github.com/dotnet/runtime/issues/32680#issuecomment-599307356) has been started by a community member and would need to be expanded on / validated.

To move forward, we should try to decide on the best approach.

Do we:
* Investigate libgss further and flush out all the dependencies / challenges?
* Bring most / all functionality into a managed implementation? What does that look like? Who would do it?
Copy link
Member

Choose a reason for hiding this comment

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

What does Xamarin do today?

Copy link
Member Author

Choose a reason for hiding this comment

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

We now use SocketsHttpHandler as the default, so the same as corefx. The previous way was a custom implementation that is pretty old.

Copy link
Member

@stephentoub stephentoub Mar 25, 2020

Choose a reason for hiding this comment

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

This isn't just about HttpClient, this is about NegotateStream as well (though maybe we don't care about it for these workloads?). More generally for this doc, it's about System.Security.Cryptography, System.Net.Security, etc.

The previous way was a custom implementation that is pretty old.

Is that would it would look like to bring it into a managed implementation? What are its dependencies? Is it doing cryptographic work?


## iOS/tvOS
iOS, similar to OSX, has platform level API’s that System.Security.Cryptography.Native.Apple hooks into. Thankfully, we have found that most just work and so we would need to decide what to do about the set that a does not (simply PNSE?).

Note: There are probably more API’s that we need to find as the build gives up after a while. This just gives you a rough idea:

**Available on a certain API version**
[src/libraries/Native/Unix/System.Security.Cryptography.Native.Apple/pal_sec.c](https://github.com/dotnet/runtime/blob/master/src/libraries/Native/Unix/System.Security.Cryptography.Native.Apple/pal_sec.c)

```'SecCopyErrorMessageString' is only available on iOS 11.3 or newer```

**Unavailable on iOS**
[src/libraries/Native/Unix/System.Security.Cryptography.Native.Apple/pal_keychain.h](https://github.com/dotnet/runtime/blob/master/src/libraries/Native/Unix/System.Security.Cryptography.Native.Apple/pal_keychain.h)
```
SecKeychainRef
SecKeychainItemRef

PALEXPORT int32_t AppleCryptoNative_SecKeychainItemCopyKeychain(SecKeychainItemRef item, SecKeychainRef* pKeychainOut);
PALEXPORT int32_t AppleCryptoNative_SecKeychainDelete(SecKeychainRef keychain);
PALEXPORT int32_t AppleCryptoNative_SecKeychainCopyDefault(SecKeychainRef* pKeychainOut);
PALEXPORT int32_t AppleCryptoNative_SecKeychainOpen(const char* pszKeychainPath, SecKeychainRef* pKeychainOut);
PALEXPORT int32_t AppleCryptoNative_SecKeychainUnlock(SecKeychainRef keychain,
uint32_t passphraseLength,
const uint8_t* passphraseUtf8);
PALEXPORT int32_t AppleCryptoNative_SetKeychainNeverLock(SecKeychainRef keychain);
PALEXPORT int32_t
AppleCryptoNative_SecKeychainEnumerateCerts(SecKeychainRef keychain, CFArrayRef* pCertsOut, int32_t* pOSStatus);
PALEXPORT int32_t AppleCryptoNative_SecKeychainEnumerateIdentities(SecKeychainRef keychain,CFArrayRef* pIdentitiesOut,int32_t* pOSStatus);
PALEXPORT int32_t AppleCryptoNative_X509StoreAddCertificate(CFTypeRef certOrIdentity, SecKeychainRef keychain, int32_t* pOSStatus);
PALEXPORT int32_t AppleCryptoNative_X509StoreRemoveCertificate(CFTypeRef certOrIdentity, SecKeychainRef keychain, uint8_t isReadOnlyMode, int32_t* pOSStatus);
```

[src/libraries/Native/Unix/System.Security.Cryptography.Native.Apply/pal_seckey.h](https://github.com/dotnet/runtime/blob/master/src/libraries/Native/Unix/System.Security.Cryptography.Native.Apple/pal_seckey.h)
```
SecExternalItemType

OSStatus ExportImportKey(SecKeyRef* key, SecExternalItemType type);
```

[src/libraries/Native/Unix/System.Security.Cryptography.Native.Apply/pal_rsa.c](https://github.com/dotnet/runtime/blob/master/src/libraries/Native/Unix/System.Security.Cryptography.Native.Apple/pal_rsa.c)
```
SecTransformRef
kSecUseKeychain

static int32_t ExecuteCFDataTransform(SecTransformRef xform, uint8_t* pbData, int32_t cbData, CFDataRef* pDataOut, CFErrorRef* pErrorOut);

/* kSecUseKeyChain not supported on iOS and is used in the function */
int32_t AppleCryptoNative_RsaGenerateKey(int32_t keySizeBits, SecKeychainRef tempKeychain, SecKeyRef* pPublicKey, SecKeyRef* pPrivateKey, int32_t* pOSStatus)
```

## WebAssembly
Once we have solution for Android we could use similar approach for WebAssembly which also does not have any security APIs available. This might be a trickier than Android in the sense that any advanced libc like functionality might not be fully supported in emscripten.