211 lines
8.4 KiB
Markdown
211 lines
8.4 KiB
Markdown
template: post
|
||
title: nds-constrain’t
|
||
author: flewkey
|
||
timestamp: 1594525504
|
||
license: CC-BY
|
||
|
||
Once upon a time, shutterbug2000 discovered nds-constrain’t: a bug in Nintendo’s
|
||
NTR SSL library that allowed it’s connections to be easily intercepted. This
|
||
made it possible to connect to alternative online services without ROM patching.
|
||
|
||
The bug itself is simple: the NDS SSL library does not care whether or not a
|
||
certificate is authorized to act as a certificate authority. This means that
|
||
— with any valid certificate — we can sign whatever we want,
|
||
including a certificate under a false hostname.
|
||
|
||
A guide to using this bug for fun and profit is now available on the
|
||
[official page](https://github.com/KaeruTeam/nds-constraint), which is much
|
||
better written than mine. However, you are free to keep reading this one.
|
||
|
||
**Update (2020-12-31):** I have corrected some mistakes in this post. There is
|
||
also information at the bottom of this post regarding OpenSSL which is important
|
||
to setting up nds-constrain’t properly.
|
||
|
||
**Update (2022-07-13):** These instructions will only work with OpenSSL 1.1.1
|
||
and lower. OpenSSL 3.0 requires [different steps](https://github.com/openssl/openssl/blob/master/doc/man7/migration_guide.pod),
|
||
and I’ll leave those for someone else to figure out.
|
||
|
||
---
|
||
|
||
### Getting the Wii client certificate
|
||
|
||
As explained in the [official page](https://github.com/KaeruTeam/nds-constraint)
|
||
for nds-constrain’t, the Wii client certificate is signed by Nintendo and
|
||
considered valid. Therefore, we can use it’s key to sign whatever we want. You
|
||
_could_ grab it from a Wii, but it is much easier to download it from
|
||
[Larsenv’s page](https://larsenv.github.io/NintendoCerts/index.html). Choose the
|
||
“Wii NWC Prod 1” key pair.
|
||
|
||
### Converting it to a useable format
|
||
|
||
The file is a PKCS12, and we can’t do anything useful with it until we extract
|
||
the certificate and the private key. Thankfully, this is pretty simple.
|
||
|
||
openssl pkcs12 -in WII_NWC_1_CERT.p12 -passin pass:alpine -passout pass:alpine -out keys.txt
|
||
|
||
That command will export the X.509 certificate and private key from the archive,
|
||
and store the output in keys.txt. They can then be copied into their appropriate
|
||
files, which I will name NWC.crt and NWC.key.
|
||
|
||
### Signing your certificate
|
||
|
||
Instructions for this are listed on the [official guide](https://github.com/KaeruTeam/nds-constraint).
|
||
I have copied them for reference.
|
||
|
||
openssl genrsa -out server.key 1024
|
||
openssl req -new -key server.key -out server.csr
|
||
openssl x509 -req -in server.csr -CA NWC.crt -CAkey NWC.key -CAcreateserial -out server.crt -days 3650 -sha1
|
||
|
||
**Update (2021-05-07):** The second command will prompt you for values to be
|
||
used in your certificate. The Common Name in this certificate should be the
|
||
domain name that it will be valid for (e.g. “flipnote.hatena.com”). Most people
|
||
will want to set it to “\*.\*.\*” (without the quotes), which will make it valid
|
||
for all subdomains. See [this paste](https://pastebin.com/WQNEQwi8) for
|
||
reference.
|
||
|
||
NGINX users need to create a file for the certificate chain as well.
|
||
|
||
cat server.crt NWC.crt > server-chain.crt
|
||
|
||
### Using your phony certificate
|
||
|
||
Once the SSL certificate is installed, you may run into issues connecting with
|
||
your DS. This because your NDS only knows how to use SSLv3, with either the
|
||
RC4-SHA or RC4-MD5 cipher set. Webservers don’t support this by default, so this
|
||
requires special configuration.
|
||
|
||
### NGINX configuration
|
||
|
||
First, you need to compile a custom version of NGINX that supports SSLv3 and
|
||
the RC4 ciphers. Instructions on how to do this are included further down this
|
||
page.
|
||
|
||
Then, add the following lines to your NGINX configuration.
|
||
|
||
ssl_protocols SSLv3;
|
||
ssl_ciphers RC4-SHA:RC4-MD5:@SECLEVEL=0;
|
||
|
||
Assuming that you have added your certificate chain and key, your DS should be
|
||
able to connect. It is worth noting that most services for Nintendo consoles
|
||
make liberal use of headers, and some headers (e.g. `http_x_gamecd`) contain
|
||
underscores, which
|
||
[shouldn’t be in the header field](https://tools.ietf.org/html/rfc7230#section-3.2.6).
|
||
You should also configure NGINX to pass request headers to your server if you
|
||
haven’t already.
|
||
|
||
underscores_in_headers on;
|
||
proxy_pass_request_headers on;
|
||
|
||
### Apache configuration
|
||
|
||
First, you need to compile a custom version of Apache that supports SSLv3
|
||
and the RC4 ciphers. Instructions on how to do this are included further down
|
||
this page.
|
||
|
||
Then, use the following SSL settings.
|
||
|
||
SSLProtocol SSLv3
|
||
SSLCipherSuite RC4-SHA:RC4-MD5
|
||
|
||
Unfortunately, because lowering the
|
||
[security level](https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_security_level.html)
|
||
of OpenSSL in the cipher string results in an error in Apache, Apache users must
|
||
also modify their OpenSSL configuration. This is usually located in
|
||
`/etc/ssl/openssl.cnf`. However, since we are using a custom version of OpenSSL,
|
||
we will make the change in `/usr/local/ssl/openssl.cnf` instead.
|
||
|
||
At the top, add the following:
|
||
|
||
openssl_conf = default_conf
|
||
|
||
At the bottom, add the following:
|
||
|
||
[default_conf]
|
||
ssl_conf = ssl_sect
|
||
|
||
[ssl_sect]
|
||
system_default = system_default_sect
|
||
|
||
[system_default_sect]
|
||
CipherString = DEFAULT:@SECLEVEL=0
|
||
|
||
Working around this in Apache is a bit more difficult. For information about
|
||
working around invalid headers in Apache, see
|
||
[this example](http://httpd.apache.org/docs/trunk/env.html#fixheader). If you
|
||
continue having issues with NDS connectivity, please contact me.
|
||
|
||
### Having fun
|
||
|
||
The possibilities are infinite. Want to run services through a debugging proxy?
|
||
Implement WFC protocols? Make a Flipnote Studio server? All of this is possible
|
||
without ROM patches!
|
||
|
||
---
|
||
|
||
### The issue with OpenSSL
|
||
|
||
By default, modern versions of OpenSSL disable SSLv3 and the RC4 ciphers. We
|
||
need those to talk to the Nintendo DS, so we need to compile a custom version of
|
||
OpenSSL to use with the webserver.
|
||
|
||
### NGINX with custom OpenSSL
|
||
|
||
Download and extract the [OpenSSL](https://www.openssl.org/source/) and
|
||
[nginx](https://nginx.org/en/download.html) sources. Then, configure NGINX like
|
||
so:
|
||
|
||
./configure --with-http_ssl_module --with-openssl=/path/to/openssl/src \
|
||
--with-openssl-opt=enable-ssl3 --with-openssl-opt=enable-ssl3-method \
|
||
--with-openssl-opt=enable-weak-ssl-ciphers
|
||
|
||
Run “make” and “sudo make install” like usual. Be sure that you run the version
|
||
of NGINX in /usr/local for nds-constrain’t. You might want to uninstall any
|
||
existing versions of NGINX to avoid confusion.
|
||
|
||
Gentoo users can add the “sslv3” and “weak-ssl-ciphers” USE flags to OpenSSL
|
||
and rebuild it. Since there is no weak-ssl-ciphers USE flag at the time of
|
||
writing, you might want to add my
|
||
[flewkey-overlay](https://git.sdf.org/flewkey/flewkey-overlay) and unmask
|
||
`dev-libs/openssl::flewkey-overlay`. After that, install NGINX as usual.
|
||
|
||
### Apache with custom OpenSSL
|
||
|
||
Download and extract the [OpenSSL](https://www.openssl.org/source/) and
|
||
[Apache](https://httpd.apache.org/download.cgi) sources. Then, we must configure
|
||
OpenSSL like so:
|
||
|
||
./config enable-ssl3 enable-ssl3-method enable-weak-ssl-ciphers
|
||
|
||
After this, run “make” and “sudo make install”. OpenSSL will install in
|
||
/usr/local and /usr/local/ssl by default, so it shouldn’t interfere with the
|
||
version currently installed on your system. You will also need to make the
|
||
OpenSSL configuration change made in the “Apache configuration”
|
||
|
||
Next, we need to actually configure Apache, specifying the location of OpenSSL
|
||
like so:
|
||
|
||
./configure --enable-ssl --with-ssl=/usr/local
|
||
|
||
Run “make” and “sudo make install” like usual. Be sure that you use the version
|
||
of Apache in /usr/local for nds-constrain’t. You might want to uninstall any
|
||
existing versions of Apache to avoid confusion.
|
||
|
||
Gentoo users can add the “sslv3” and “weak-ssl-ciphers” USE flags to OpenSSL
|
||
and rebuild it. Since there is no weak-ssl-ciphers USE flag at the time of
|
||
writing, you might want to add my
|
||
[flewkey-overlay](https://git.sdf.org/flewkey/flewkey-overlay) and unmask
|
||
`dev-libs/openssl::flewkey-overlay`. After that, install Apache as usual.
|
||
|
||
---
|
||
|
||
### Contributions
|
||
|
||
Thanks to [shutterbug2000](https://github.com/shutterbug2000) for discovering
|
||
nds-constrain’t, as well as [Lauren Kelly](https://muffinti.me/) and
|
||
[jaames](https://jamesdaniel.dev/) for their work on the official guide. These
|
||
individuals have contributed a lot to the Nintendo and Flipnote Studio
|
||
communities in general.
|
||
|
||
Greetings to [Adam Gilbert](https://i-am.djelectro.me/),
|
||
[MeGaMoV](https://megamov.fr/) and Brandon Serpas.
|