/dev/net/ssl
Handles SSL/TLS over TCP. Used for NUS/EC activities, also may be used by games if they want to do encrypted communication.
Ioctl Listing
All arguments should be 32-byte aligned (can be either MEM1 or MEM2), most are specified as 32 bytes long but only the first 4 bytes are relevant. The easiest way to do this in code is (for each argument) declare an aligned array of 8 ints then use the first element only. /dev/net/ssl can remain open between ioctls but it's probably better to open/close it for each command. All commands should be issued as ioctlvs, even if they have only one input and/or output argument. The ioctlv result should be 0 unless there is a problem with the parameters (incorrect alignment, size, etc.) and the response values should generally be 0 for success and negative for failure.
NOTE: if the input/output arguments seem backwards, it's because they are. Somebody goofed!
Request number | Name | Input | Output | Notes |
---|---|---|---|---|
1 | SSL_NEW | s32 ssl_context[8] | u32 verify_options[8], u8 CN[256] | Generates a new ssl context returned in ssl_context[0]. CN should match the name of the website. verify_options[0] relates to client authentication, observed values are 0 (default), 2 and 11. |
2 | SSL_CONNECT | s32 response[8] | s32 ssl_context[8], s32 socket[8] | Initialize a SSL connection. ssl_context[0] holds a ssl context id, socket[0] is the fd for an open socket that has already been connect()ed to the host. The socket should not be set to non-blocking mode. |
3 | SSL_HANDSHAKE | s32 response[8] | s32 ssl_context[8] | Attempt an SSL handshake. ssl_context[0] holds a ssl context id. Possible error responses are -2 (socket is non-blocking?), -9 (host certificate doesn't match CN given to SSL_NEW) or -10 (unable to validate host's identity). |
4 | SSL_READ | s32 response[8], void buffer[length] | s32 ssl_context[8] | Read at most length bytes from the connection in buffer. The number of bytes actually read is returned in response[0]. The maximum value for length is 32768. |
5 | SSL_WRITE | s32 response[8] | s32 ssl_context[8], const void buffer[length] | Attempt to write length bytes from buffer to the connected host. The number of bytes actually written is returned in response[0]. |
6 | SSL_SHUTDOWN | s32 response[8] | s32 ssl_context[8] | Destroys an ssl context. The context id must be in ssl_context[0]. Returns an error if there are pending operations (i.e. there's data waiting to be SSL_READ()ed). |
7 | SSL_SETCLIENTCERT | #1 | #3 | Unknown, probably allows associating a client certificate with an ssl context for authentication. |
8 | SSL_SETCLIENTCERTDEFAULT? | ? | ? | ? |
9 | SSL_REMOVECLIENTCERT | ? | ? | Unknown, probably disassociates a previously set client certificate. |
10 | SSL_SETROOTCA | s32 response[8] | s32 ssl_context[8], const void root[length] | Associates a certificate for a Root CA with an ssl context. The certificate should be in binary der format. |
11 | SSL_SETROOTCADEFAULT | ? | ? | ? |
12 | SSL_DOHANDSHAKEEX | ? | ? | ? |
13 | SSL_SETBUILTINROOTCA | s32 response[8] | s32 ssl_context[8], s32 index[8] | Use one of the built-in certificates as the Root CA for this context. index[0] specifies which built-in root cert to use. |
14 | SSL_SETBUILTINCLIENTCERT | s32 response[8] | s32 ssl_context[8], s32 index[8] | Use one of the default client certificates for authentication (if required). index[0] specifies which built-in client cert to use. |
15 | SSL_DISABLEVERIFYOPTIONFORDEBUG | s32 response[8] | s32 ssl_context[8], ? | |
20 | SSL_DEBUGGETVERSION | ? | ? | |
21 | SSL_DEBUGGETTIME | ? | ? |
Normal process for establishing a connection and communicating over SSL:
- Initialize network
- Create a regular (blocking) TCP socket using net_socket()
- Connect the socket to the desired SSL port on the host using net_connect()
- Create a new SSL context using SSL_NEW, specify 0 for verify options unless you figure out/want to use client certificate authentication
- Use SSL_SETBUILTINCLIENTCERT with index 0 (or set a specific client cert using SSL_SETCLIENTCERT)
- Use SSL_SETROOTCA with a certificate that can be used to validate the host you're connecting to (or call SSL_SETBUILTINCLIENTCERT with index 0 if you can somehow get Nintendo to validate your site's cert)
- Use SSL_CONNECT
- Use SSL_HANDSHAKE. If response[0]==-9, your site's cert doesn't match the identity given to SSL_NEW. If response[0]==-10, your site's identity couldn't be validated (wasn't signed by Root CA, expired cert, etc.)
- Use SSL_READ/SSL_WRITE as much as you want
- Use SSL_SHUTDOWN
- Call net_close() to clean-up the TCP socket
For the C code of the SSL functions used here go to /dev/net/ssl/code.