diff --git a/src/common-ssh/ssh.c b/src/common-ssh/ssh.c index ba88c40b..5ceba57b 100644 --- a/src/common-ssh/ssh.c +++ b/src/common-ssh/ssh.c @@ -22,6 +22,7 @@ #include "common-ssh/user.h" #include +#include #include #ifdef LIBSSH2_USES_GCRYPT @@ -46,6 +47,17 @@ GCRY_THREAD_OPTION_PTHREAD_IMPL; #endif +/** + * A list of all key exchange algorithms that are both FIPS-compliant, and + * OpenSSL-supported. + */ +#define FIPS_COMPLIANT_KEX_ALGORITHMS "diffie-hellman-group-exchange-sha256" + +/** + * A list of ciphers that are both FIPS-compliant, and OpenSSL-supported. + */ +#define FIPS_COMPLIANT_CIPHERS "aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,aes192-cbc,aes256-cbc" + #ifdef OPENSSL_REQUIRES_THREADING_CALLBACKS /** * Array of mutexes, used by OpenSSL. @@ -486,6 +498,17 @@ guac_common_ssh_session* guac_common_ssh_create_session(guac_client* client, return NULL; } + /* + * If FIPS mode is enabled, prefer only FIPS-compatible algorithms and + * ciphers that are also supported by libssh2. For more info, see: + * https://csrc.nist.gov/CSRC/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp2906.pdf + */ + if (guac_fips_enabled()) { + libssh2_session_method_pref(session, LIBSSH2_METHOD_KEX, FIPS_COMPLIANT_KEX_ALGORITHMS); + libssh2_session_method_pref(session, LIBSSH2_METHOD_CRYPT_CS, FIPS_COMPLIANT_CIPHERS); + libssh2_session_method_pref(session, LIBSSH2_METHOD_CRYPT_SC, FIPS_COMPLIANT_CIPHERS); + } + /* Perform handshake */ if (libssh2_session_handshake(session, fd)) { guac_client_abort(client, GUAC_PROTOCOL_STATUS_UPSTREAM_ERROR, diff --git a/src/libguac/Makefile.am b/src/libguac/Makefile.am index 93b15321..6db0c96c 100644 --- a/src/libguac/Makefile.am +++ b/src/libguac/Makefile.am @@ -44,6 +44,7 @@ libguacinc_HEADERS = \ guacamole/client-types.h \ guacamole/error.h \ guacamole/error-types.h \ + guacamole/fips.h \ guacamole/hash.h \ guacamole/layer.h \ guacamole/layer-types.h \ @@ -93,6 +94,7 @@ libguac_la_SOURCES = \ encode-jpeg.c \ encode-png.c \ error.c \ + fips.c \ hash.c \ id.c \ palette.c \ @@ -100,7 +102,7 @@ libguac_la_SOURCES = \ pool.c \ protocol.c \ raw_encoder.c \ - recording.c \ + recording.c \ socket.c \ socket-broadcast.c \ socket-fd.c \ diff --git a/src/libguac/fips.c b/src/libguac/fips.c new file mode 100644 index 00000000..b087e11c --- /dev/null +++ b/src/libguac/fips.c @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#include "config.h" +#include "guacamole/fips.h" + +/* If OpenSSL is available, include header for version numbers */ +#ifdef ENABLE_SSL + #include + + /* OpenSSL versions prior to 0.9.7e did not have FIPS support */ + #if !defined(OPENSSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x00090705f) + #define GUAC_FIPS_ENABLED 0 + + /* OpenSSL 3+ uses EVP_default_properties_is_fips_enabled() */ + #elif defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) + #include + #define GUAC_FIPS_ENABLED EVP_default_properties_is_fips_enabled(NULL) + + /* For OpenSSL versions between 0.9.7e and 3.0, use FIPS_mode() */ + #else + #include + #define GUAC_FIPS_ENABLED FIPS_mode() + #endif + +/* FIPS support does not exist if OpenSSL is not available. */ +#else +#define GUAC_FIPS_ENABLED 0 +#endif + +int guac_fips_enabled() { + + return GUAC_FIPS_ENABLED; + +} diff --git a/src/libguac/guacamole/fips.h b/src/libguac/guacamole/fips.h new file mode 100644 index 00000000..014f7dcd --- /dev/null +++ b/src/libguac/guacamole/fips.h @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +#ifndef GUAC_FIPS_H +#define GUAC_FIPS_H + +/** + * Returns a non-zero value if FIPS mode is enabled, or zero if FIPS mode + * is not enabled. + * + * @return + * A non-zero value if FIPS mode is enabled, or zero if FIPS mode is + * not enabled. + */ +int guac_fips_enabled(); + +#endif \ No newline at end of file