Skip to content

Commit

Permalink
deps,test,src,doc,tools: update to OpenSSL 3.0
Browse files Browse the repository at this point in the history
This pull request updates the OpenSSL version that is statically
linked with Node.js from OpenSSl 1.1.1 to quictls OpenSSL 3.0.0+quic.

This pull request will replace the OpenSSL version that is currently
in the deps directory and when performing a normal build
OpenSSL 3.0+quic will be statically linked to the Node.js executable.
We will still be able to dynamically link to OpenSSL 1.1.1 and we have
a CI job which dynamically links to OpenSSL 1.1.1 which is run for
every pull request to make sure that we maintain backward compatibility.

PR-URL: #38512
Reviewed-By: Michael Dawson <midawson@redhat.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
  • Loading branch information
danbev committed Oct 11, 2021
1 parent 49b7ec9 commit 66da32c
Show file tree
Hide file tree
Showing 8,465 changed files with 3,975,529 additions and 1,448,370 deletions.
The diff you're trying to view is too large. We only load the first 3000 changed files.
47 changes: 42 additions & 5 deletions BUILDING.md
Expand Up @@ -764,11 +764,48 @@ as `deps/icu` (You'll have: `deps/icu/source/...`)

## Building Node.js with FIPS-compliant OpenSSL

The current version of Node.js does not support FIPS when statically linking
(the default) with OpenSSL 1.1.1 but for dynamically linking it is possible
to enable FIPS using the configuration flag `--openssl-is-fips`.
The current version of Node.js supports FIPS when statically and
dynamically linking with OpenSSL 3.0.0 by using the configuration flag
`--openssl-is-fips`.

### Configuring and building quictls/openssl for FIPS
### FIPS support when statically linking OpenSSL

FIPS can be supported by specifying the configuration flag `--openssl-is-fips`:
```console
$ ./configure --openssl-is-fips
$ make -j8
```

The above command will build and install the FIPS module into the out directory.
This includes building fips.so, running the `installfips` command that generates
the FIPS configuration file (fipsmodule.cnf), copying and updating openssl.cnf
to include the correct path to fipsmodule.cnf and finally uncomment the fips
section.

We can then run node specifying `--enable-fips`:
```console
$ ./node --enable-fips -p 'crypto.getFips()'
1
```
The above will use the Node.js default locations for OpenSSL 3.0:
```console
$ ./out/Release/openssl-cli version -m -d
OPENSSLDIR: "/nodejs/openssl/out/Release/obj.target/deps/openssl"
MODULESDIR: "/nodejs/openssl/out/Release/obj.target/deps/openssl/lib/openssl-modules"
```
The OpenSSL configuration files will be found in `OPENSSLDIR` directory above:
```console
$ ls -w 1 out/Release/obj.target/deps/openssl/*.cnf
out/Release/obj.target/deps/openssl/fipsmodule.cnf
out/Release/obj.target/deps/openssl/openssl.cnf
```
And the FIPS module will be located in the `MODULESDIR` directory:
```console
$ ls out/Release/obj.target/deps/openssl/lib/openssl-modules/
fips.so
```

### FIPS support when dynamically linking OpenSSL

For quictls/openssl 3.0 it is possible to enable FIPS when dynamically linking.
If you want to build Node.js using openssl-3.0.0+quic, you can follow these
Expand Down Expand Up @@ -811,7 +848,7 @@ find the `fipsmodule.cnf` file - let's add the following to the end of the
**alter openssl.cnf**

```text
.include fipsmodule.cnf
.include /absolute/path/to/fipsmodule.cnf
# List of providers to load
[provider_sect]
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -188,7 +188,7 @@ testclean:
.PHONY: distclean
distclean:
$(RM) -r out
$(RM) config.gypi icu_config.gypi config_fips.gypi
$(RM) config.gypi icu_config.gypi
$(RM) config.mk
$(RM) -r $(NODE_EXE) $(NODE_G_EXE)
$(RM) -r node_modules
Expand Down
7 changes: 1 addition & 6 deletions common.gypi
Expand Up @@ -28,7 +28,7 @@
'clang%': 0,
'error_on_warn%': 'false',

'openssl_fips%': '',
'openssl_product': '<(STATIC_LIB_PREFIX)openssl<(STATIC_LIB_SUFFIX)',
'openssl_no_asm%': 0,

# Don't use ICU data file (icudtl.dat) from V8, we use our own.
Expand Down Expand Up @@ -98,11 +98,6 @@
'obj_dir%': '<(PRODUCT_DIR)/obj.target',
'v8_base': '<(PRODUCT_DIR)/obj.target/tools/v8_gypfiles/libv8_snapshot.a',
}],
['openssl_fips != ""', {
'openssl_product': '<(STATIC_LIB_PREFIX)openssl<(STATIC_LIB_SUFFIX)',
}, {
'openssl_product': '<(STATIC_LIB_PREFIX)openssl<(STATIC_LIB_SUFFIX)',
}],
['OS=="mac"', {
'clang%': 1,
'obj_dir%': '<(PRODUCT_DIR)/obj.target',
Expand Down
36 changes: 11 additions & 25 deletions configure.py
Expand Up @@ -195,11 +195,6 @@
default=None,
help="Do not build optimized assembly for OpenSSL")

parser.add_argument('--openssl-fips',
action='store',
dest='openssl_fips',
help='Build OpenSSL using FIPS canister .o file in supplied folder')

parser.add_argument('--openssl-is-fips',
action='store_true',
dest='openssl_is_fips',
Expand Down Expand Up @@ -1414,8 +1409,7 @@ def configure_openssl(o):
variables['node_shared_ngtcp2'] = b(options.shared_ngtcp2)
variables['node_shared_nghttp3'] = b(options.shared_nghttp3)
variables['openssl_is_fips'] = b(options.openssl_is_fips)
variables['openssl_fips'] = ''
variables['openssl_quic'] = b(True)
variables['node_fipsinstall'] = b(False)

if options.openssl_no_asm:
variables['openssl_no_asm'] = 1
Expand All @@ -1427,8 +1421,8 @@ def without_ssl_error(option):
without_ssl_error('--shared-openssl')
if options.openssl_no_asm:
without_ssl_error('--openssl-no-asm')
if options.openssl_fips:
without_ssl_error('--openssl-fips')
if options.openssl_is_fips:
without_ssl_error('--openssl-is-fips')
if options.openssl_default_cipher_list:
without_ssl_error('--openssl-default-cipher-list')
return
Expand Down Expand Up @@ -1468,17 +1462,18 @@ def without_ssl_error(option):
if options.openssl_no_asm and options.shared_openssl:
error('--openssl-no-asm is incompatible with --shared-openssl')

if options.openssl_fips or options.openssl_fips == '':
error('FIPS is not supported in this version of Node.js')

if options.openssl_is_fips and not options.shared_openssl:
error('--openssl-is-fips is only available with --shared-openssl')

if options.openssl_is_fips:
o['defines'] += ['OPENSSL_FIPS']
variables['node_fipsinstall'] = b(True)

if options.shared_openssl:
variables['openssl_quic'] = b(getsharedopensslhasquic.get_has_quic(options.__dict__['shared_openssl_includes']))
has_quic = getsharedopensslhasquic.get_has_quic(options.__dict__['shared_openssl_includes'])
else:
has_quic = getsharedopensslhasquic.get_has_quic('deps/openssl/openssl/include')

variables['openssl_quic'] = b(has_quic)
if has_quic:
o['defines'] += ['NODE_OPENSSL_HAS_QUIC']

configure_library('openssl', o)

Expand Down Expand Up @@ -1927,15 +1922,6 @@ def make_bin_override():
del output['variables']
variables['is_debug'] = B(options.debug)

# make_global_settings for special FIPS linking
# should not be used to compile modules in node-gyp
config_fips = { 'make_global_settings' : [] }
if 'make_fips_settings' in output:
config_fips['make_global_settings'] = output['make_fips_settings']
del output['make_fips_settings']
write('config_fips.gypi', do_not_edit +
pprint.pformat(config_fips, indent=2) + '\n')

# make_global_settings should be a root level element too
if 'make_global_settings' in output:
make_global_settings = output['make_global_settings']
Expand Down
2 changes: 2 additions & 0 deletions deps/openssl/.gitignore
@@ -1 +1,3 @@
openssl/fuzz/corpora
openssl/makefile.in
openssl/Makefile.in
11 changes: 6 additions & 5 deletions deps/openssl/README.md
@@ -1,7 +1,7 @@
This has a new binding scheme in building OpenSSL-1.1.0 library with
Node.js. OpenSSL-1.1.0 uses a new build system with `Perl` for various
This has a new binding scheme in building OpenSSL-3.0.0 library with
Node.js. OpenSSL-3.0.0 uses a new build system with `Perl` for various
supported platforms. See `openssl/Configurations/README` and
`openssl/Configurations/README.design` in the OpenSSL source for
`openssl/Configurations/README-design.md` in the OpenSSL source for
details.

In order to build OpenSSL library without `Perl` in the build of Node.js
Expand All @@ -13,7 +13,7 @@ and header files ) are pre-generated and stored into the

Makefile has supported platform list and generates and copies
platform dependent files (e.g. asm files) into arch directory with
`generate_gypi.pl`. Platform dependent gypi files also created
`generate_gypi.pl`. Platform dependent gypi files are also created
obtaining build information from `configdata.pm` that is generated
with `Configure` in the OpenSSL build system.

Expand All @@ -36,7 +36,8 @@ and header files ) are pre-generated and stored into the
`bn_conf.h`, `dso_conf.h` and `opensslconf.h` are platform dependent
in the OpenSSL sources. They are replaced with `config/*.h.tmpl`
files to include the file in the `../../../config/` and referred to
each arch file that depends on asm and no-asm option.
each arch file that depends on asm and no-asm option. These headers are
generated by the make target `generate_headers`.

### Supported architectures for use of ASM

Expand Down
36 changes: 18 additions & 18 deletions deps/openssl/config/Makefile
Expand Up @@ -9,7 +9,7 @@ endif
PERL = perl

# Supported architecture list
ASM_ARCHS = aix-gcc aix64-gcc BSD-x86 BSD-x86_64 \
ASM_ARCHS = aix-gcc aix64-gcc-as BSD-x86 BSD-x86_64 \
darwin64-x86_64-cc darwin-i386-cc darwin64-arm64-cc linux-aarch64 \
linux-armv4 linux-elf linux-x32 linux-x86_64 linux-ppc \
linux-ppc64 linux-ppc64le linux32-s390x linux64-s390x linux64-mips64\
Expand All @@ -25,7 +25,7 @@ CONFIGURE = ./Configure
# no-shared: openssl-cli needs static link
# no-afalgeng: old Linux kernel < 4.0 does not support it
# enable-ssl-trace: cause the optional SSL_trace API to be built
COPTS = no-comp no-shared no-afalgeng enable-ssl-trace
COPTS = no-comp no-shared no-afalgeng enable-ssl-trace enable-fips

# disable platform check in Configure
NO_WARN_ENV = CONFIGURE_CHECKER_WARN=1
Expand All @@ -35,41 +35,41 @@ GENERATE = ./generate_gypi.pl
OPSSL_SRC = ../openssl

# Header files generated with Configure
CFG = opensslconf.h
SRC_CFG = $(OPSSL_SRC)/include/openssl/$(CFG)
INT_CFGS = bn_conf.h dso_conf.h
#INT_CFGS = bn_conf.h dso_conf.h
INT_CFG_DIR = $(OPSSL_SRC)/include/crypto
GEN_HEADERS = asn1 asn1t bio cmp cms configuration conf crmf crypto ct err \
ess fipskey lhash ocsp opensslv pkcs12 pkcs7 safestack srp ssl \
ui x509 x509v3 x509_vfy conf

PHONY = all clean replace
CRYPTO_GEN_HEADERS = bn_conf dso_conf

PHONY = all clean replace generate_headers
.PHONY: $(PHONY)

all: $(ASM_ARCHS) $(NO_ASM_ARCHS) replace
#all: $(ASM_ARCHS) $(NO_ASM_ARCHS) generate_headers replace
all: $(ASM_ARCHS) $(NO_ASM_ARCHS) generate_headers

# Configure and generate openssl asm files for each archs
$(ASM_ARCHS):
cd $(OPSSL_SRC); $(NO_WARN_ENV) CC=$(CC) $(PERL) $(CONFIGURE) $(COPTS) $@;
$(PERL) -w -I$(OPSSL_SRC) $(GENERATE) asm $@
$(PERL) -w -I$(OPSSL_SRC) $(GENERATE) asm $@ "${GEN_HEADERS}" "${CRYPTO_GEN_HEADERS}"
# Confgure asm_avx2 and generate upto avx2 support
cd $(OPSSL_SRC); $(NO_WARN_ENV) CC=$(FAKE_GCC) $(PERL) $(CONFIGURE) \
$(COPTS) $@;
$(PERL) -w -I$(OPSSL_SRC) $(GENERATE) asm_avx2 $@
$(PERL) -w -I$(OPSSL_SRC) $(GENERATE) asm_avx2 $@ "${GEN_HEADERS}" "${CRYTO_GEN_HEADERS}"
# Configure no-asm and generate no-asm sources
cd $(OPSSL_SRC); $(NO_WARN_ENV) $(PERL) $(CONFIGURE) $(COPTS) \
no-asm $@;
$(PERL) -w -I$(OPSSL_SRC) $(GENERATE) no-asm $@
$(PERL) -w -I$(OPSSL_SRC) $(GENERATE) no-asm $@ "${GEN_HEADERS}" "${CRYPTO_GEN_HEADERS}"

$(NO_ASM_ARCHS):
# Configure no-asm and generate no-asm sources
cd $(OPSSL_SRC); $(NO_WARN_ENV) $(PERL) $(CONFIGURE) $(COPTS) \
no-asm $@;
$(PERL) -w -I$(OPSSL_SRC) $(GENERATE) no-asm $@

# Replace and copy arch dependent headers
replace:
cp ./$(CFG).tmpl $(SRC_CFG)
@for c in $(INT_CFGS); do \
cp ./$$c.tmpl $(INT_CFG_DIR)/$$c; \
done
$(PERL) -w -I$(OPSSL_SRC) $(GENERATE) no-asm $@ "${GEN_HEADERS}" "${CRYPTO_GEN_HEADERS}"

generate_headers:
@$(PERL) -w -I$(OPSSL_SRC) ./generate_headers.pl "${GEN_HEADERS}" "${CRYPTO_GEN_HEADERS}"

clean:
find archs \( -name \*.S -o -name \*.s -o -name \*.asm -o \
Expand Down

0 comments on commit 66da32c

Please sign in to comment.