1
0
flewkey.com/posts/2020-07-12-nds-constraint.md
Ryan Fox 1684c21dd4
Add OpenSSL version disclaimer
I need to update this page at some point.
2022-08-21 18:47:40 -07:00

211 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

template: post
title: nds-constraint
author: flewkey
timestamp: 1594525504
license: CC-BY
Once upon a time, shutterbug2000 discovered nds-constraint: a bug in Nintendos
NTR SSL library that allowed its 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-constraint 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 Ill 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-constraint, the Wii client certificate is signed by Nintendo and
considered valid. Therefore, we can use its key to sign whatever we want. You
_could_ grab it from a Wii, but it is much easier to download it from
[Larsenvs 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 cant 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 dont 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
[shouldnt 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
havent 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-constraint. 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 shouldnt 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-constraint. 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-constraint, 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.