Handles SSL/TLS over TCP. Used for NUS/EC activities, also may be used by games if they want to do encrypted communication.
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!
|1||SSL_NEW||s32 ssl_context||u32 verify_options, u8 CN||Generates a new ssl context returned in ssl_context. CN should match the name of the website. verify_options relates to client authentication, observed values are 0 (default), 2 and 11.|
|2||SSL_CONNECT||s32 response||s32 ssl_context, s32 socket||Initialize a SSL connection. ssl_context holds a ssl context id, socket 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||s32 ssl_context||Attempt an SSL handshake. ssl_context 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, void buffer[length]||s32 ssl_context||Read at most length bytes from the connection in buffer. The number of bytes actually read is returned in response. The maximum value for length is 32768.|
|5||SSL_WRITE||s32 response||s32 ssl_context, 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.|
|6||SSL_SHUTDOWN||s32 response||s32 ssl_context||Destroys an ssl context. The context id must be in ssl_context. 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.|
|9||SSL_REMOVECLIENTCERT||?||?||Unknown, probably disassociates a previously set client certificate.|
|10||SSL_SETROOTCA||s32 response||s32 ssl_context, const void root[length]||Associates a certificate for a Root CA with an ssl context. The certificate should be in binary der format.|
|13||SSL_SETBUILTINROOTCA||s32 response||s32 ssl_context, s32 index||Use one of the built-in certificates as the Root CA for this context. index specifies which built-in root cert to use.|
|14||SSL_SETBUILTINCLIENTCERT||s32 response||s32 ssl_context, s32 index||Use one of the default client certificates for authentication (if required). index specifies which built-in client cert to use.|
|15||SSL_DISABLEVERIFYOPTIONFORDEBUG||s32 response||s32 ssl_context, ?|
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==-9, your site's cert doesn't match the identity given to SSL_NEW. If response==-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.