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

Dev/more node tls compliant ios #208

Open
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

vricosti
Copy link
Contributor

@vricosti vricosti commented Feb 10, 2025

Hi,
As I already did for the android part here is the last part for iOS that allows to pass a digital identity(cert + private key) that will be used during TLS client authentication.
I implemented this because I am working on a react-native-androidtv-remote and it was mandatory.

So basically for a client to authenticate it can pass a cert/key either as a pem string or directly as a file:

const options = {
  port: port,
  host: '127.0.0.1',
  androidKeyStore: 'AndroidKeyStore'
  cert: require('client-cert.pem'),
  key: require('client-key.pem'),
  certAlias: 'myCert',
  keyAlias: 'myKey',
};

or

const cert = `
-----BEGIN CERTIFICATE-----
MII.......
-----END CERTIFICATE-----`;

const key= `
-----BEGIN PRIVATE KEY-----
MII.......
-----END PRIVATE KEY-----`;
`
const options = {
  port: port,
  host: '127.0.0.1',
  androidKeyStore: 'AndroidKeyStore'
  cert: cert,
  key: key,
  certAlias: 'myCert',
  keyAlias: 'myKey',
};

I have implemented getPeerCertificate() and getCertificate() but since on iOS there is no ASN1 decoder that can be easily used I have only implemented the fields I was interested in ie:
-exponent
-modulus
-pubkey
-subject/CN
-issuer/CN

if some people needs more fields a solution is to add the libder library (https://github.com/Apple-FOSS-Mirror/CommonCrypto/tree/master/Source/libDER) and to use it to decode all fields as in the node implementation.
One drawback of not using a proper asn1 decoder is the fact that on iOS we can only insert keys of 2048 bits when using key in PKCS8 format (-----BEGIN PRIVATE KEY-----), if you need to use another key length you can use PKCS1 format (-----BEGIN RSA PRIVATE KEY-----).

If you provide a cert/key with it's corresponding alias you can then check if the digital identity has been inserted inside the keystore through TLS.hasIdentity and in this case for the next connection if you only provide certAlias/keyAlias without the key/cert then it will take the certificate directly from the keystore without having to insert it everytime.
Please not that on Android when you do not provide the androidKeyStore key, the certificate/key will not be stored permanentlty (only in memory). Maybe later it could be interesting to use AndroidKeyStore to have the same behavior as iOS by default.

Finally I have also include a fix about timeout because it was fixing my timeout issues.

@vricosti vricosti force-pushed the dev/more-node-tls-compliant-ios branch from 5a3280d to f1ab919 Compare February 21, 2025 18:01
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.

1 participant