Merge pull request #298 from rdesktop/GnuTLS
Replace OpenSSL with GnuTLS Nettle, libtasn1
This commit is contained in:
commit
fcf3e923ba
10
.travis.yml
10
.travis.yml
@ -1,11 +1,11 @@
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
dist: trusty
|
||||
dist: xenial
|
||||
sudo: required
|
||||
compiler: gcc
|
||||
- os: linux
|
||||
dist: trusty
|
||||
dist: xenial
|
||||
sudo: required
|
||||
compiler: clang
|
||||
- os: osx
|
||||
@ -20,12 +20,12 @@ notifications:
|
||||
|
||||
before_install:
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install openssl ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install libtasn1 nettle gnutls; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get -qq update ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install -y libpcsclite-dev libxcursor-dev libao-dev libasound2-dev ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install -y libpcsclite-dev libxcursor-dev libao-dev libasound2-dev libtasn1-dev nettle-dev libgnutls-dev ; fi
|
||||
|
||||
script:
|
||||
- ./bootstrap
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then PKG_CONFIG_PATH=/opt/X11/lib/pkgconfig ./configure --with-openssl=/usr/local/opt/openssl ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then PKG_CONFIG_PATH=/opt/X11/lib/pkgconfig ./configure ; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./configure ; fi
|
||||
- make
|
||||
|
213
asn.c
213
asn.c
@ -2,6 +2,7 @@
|
||||
rdesktop: A Remote Desktop Protocol client.
|
||||
ASN.1 utility functions
|
||||
Copyright 2012-2017 Henrik Andersson <hean01@cendio.se> for Cendio AB
|
||||
Copyright 2017 Alexander Zakharov <uglym8@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -17,8 +18,20 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "rdesktop.h"
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <libtasn1.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "rdesktop.h"
|
||||
#include "asn.h"
|
||||
|
||||
// Generated by asn1Parser
|
||||
#include "pkix_asn1_tab.c"
|
||||
|
||||
static asn1_node *asn_defs = NULL;
|
||||
|
||||
#define MAX_ERROR_DESCRIPTION_SIZE 1024
|
||||
char errstr[MAX_ERROR_DESCRIPTION_SIZE];
|
||||
|
||||
/* Parse an ASN.1 BER header */
|
||||
RD_BOOL
|
||||
@ -118,3 +131,201 @@ ber_in_header(STREAM s, int *tagval, int *decoded_len)
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
int init_asn1_lib(void)
|
||||
{
|
||||
int asn1_rv;
|
||||
|
||||
if (asn_defs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
asn_defs = malloc(sizeof(*asn_defs));
|
||||
|
||||
if (!asn_defs) {
|
||||
logger(Core, Error, "%s:%s:%d Failed to allocate memory for ASN.1 parser\n",
|
||||
__FILE__, __func__, __LINE__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
*asn_defs = NULL;
|
||||
|
||||
if (ASN1_SUCCESS != (asn1_rv = asn1_array2tree(pkix_asn1_tab, asn_defs, errstr))) {
|
||||
logger(Core, Error, "%s:%s:%d Failed to init ASN.1 parser. Error = 0x%x (%s)\n",
|
||||
__FILE__, __func__, __LINE__, asn1_rv, asn1_strerror(asn1_rv));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Encode RSA public key into DER PKCS#1 */
|
||||
/* Returns; 0 - success, 1 - fatal error, 2 - insufficient space in buffer */
|
||||
int write_pkcs1_der_pubkey(const gnutls_datum_t *m, const gnutls_datum_t *e, uint8_t *out, int *out_len)
|
||||
{
|
||||
int asn1_rv;
|
||||
asn1_node asn_cert;
|
||||
|
||||
if (!asn_defs) {
|
||||
if (init_asn1_lib() != 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ASN1_SUCCESS != (asn1_rv = asn1_create_element(*asn_defs, "PKIX1Implicit88.RSAPublicKey", &asn_cert))) {
|
||||
logger(Core, Error, "%s:%s:%d Failed to create ASN.1 parser element for RSAPublicKey. Error = 0x%x (%s)\n",
|
||||
__FILE__, __func__, __LINE__, asn1_rv, asn1_strerror(asn1_rv));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ASN1_SUCCESS != (asn1_rv = asn1_write_value(asn_cert, "modulus", m->data, m->size))) {
|
||||
logger(Core, Error, "%s:%s:%d Failed to write modulus. Error = 0x%x (%s)\n",
|
||||
__FILE__, __func__, __LINE__, asn1_rv, asn1_strerror(asn1_rv));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ASN1_SUCCESS != (asn1_rv = asn1_write_value(asn_cert, "publicExponent", e->data, e->size))) {
|
||||
logger(Core, Error, "%s:%s:%d Failed to write publicExponent. Error = 0x%x (%s)\n",
|
||||
__FILE__, __func__, __LINE__, asn1_rv, asn1_strerror(asn1_rv));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ASN1_SUCCESS != (asn1_rv = asn1_der_coding(asn_cert, "", out, out_len, errstr))) {
|
||||
logger(Core, Error, "%s:%s:%d Failed to encode PKIX1Implicit88.RSAPublicKey. Error = 0x%x (%s)\n",
|
||||
__FILE__, __func__, __LINE__, asn1_rv, asn1_strerror(asn1_rv));
|
||||
|
||||
if (asn1_rv == ASN1_MEM_ERROR) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libtasn_read_cert_pk_oid(uint8_t *data, size_t len, char *oid, size_t *oid_size)
|
||||
{
|
||||
int asn1_rv;
|
||||
asn1_node asn_cert;
|
||||
|
||||
/* Parse DER encoded x.509 certificate */
|
||||
if (!asn_defs) {
|
||||
if (init_asn1_lib() != 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ASN1_SUCCESS != (asn1_rv = asn1_create_element(*asn_defs, "PKIX1Implicit88.Certificate", &asn_cert))) {
|
||||
logger(Core, Error, "%s:%s:%d Failed to create ASN.1 parser element. Error = 0x%x (%s)\n",
|
||||
__FILE__, __func__, __LINE__, asn1_rv, asn1_strerror(asn1_rv));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ASN1_SUCCESS != (asn1_rv = asn1_der_decoding(&asn_cert, data, len, errstr))) {
|
||||
logger(Core, Error, "%s:%s:%d Failed to decode certificate object. Error = 0x%x (%s)\n",
|
||||
__FILE__, __func__, __LINE__, asn1_rv, asn1_strerror(asn1_rv));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ASN1_SUCCESS != (asn1_rv = asn1_read_value(asn_cert, "tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm",
|
||||
oid, (int *)oid_size)))
|
||||
{
|
||||
logger(Core, Error, "%s:%s:%d Failed to get cert's public key algorithm. Error = 0x%x (%s)\n",
|
||||
__FILE__, __func__, __LINE__, asn1_rv, asn1_strerror(asn1_rv));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int libtasn_read_cert_pk_parameters(uint8_t *data, size_t len, gnutls_datum_t *m, gnutls_datum_t *e)
|
||||
{
|
||||
int asn1_rv;
|
||||
asn1_node asn_cert;
|
||||
|
||||
int buflen;
|
||||
uint8_t buf[16384];
|
||||
|
||||
asn1_node asn_key;
|
||||
int nblen;
|
||||
uint8_t newbuf[16384];
|
||||
|
||||
/* Parse DER encoded x.509 certificate */
|
||||
init_asn1_lib();
|
||||
|
||||
if (ASN1_SUCCESS != (asn1_rv = asn1_create_element(*asn_defs, "PKIX1Implicit88.Certificate", &asn_cert))) {
|
||||
logger(Core, Error, "%s:%s:%d Failed to create ASN.1 parser element. Error = 0x%x (%s)\n",
|
||||
__FILE__, __func__, __LINE__, asn1_rv, asn1_strerror(asn1_rv));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ASN1_SUCCESS != (asn1_rv = asn1_der_decoding(&asn_cert, data, len, errstr))) {
|
||||
logger(Core, Error, "%s:%s:%d Failed to decode certificate object. Error = 0x%x (%s)\n",
|
||||
__FILE__, __func__, __LINE__, asn1_rv, asn1_strerror(asn1_rv));
|
||||
return 1;
|
||||
}
|
||||
|
||||
buflen = sizeof(buf) - 1;
|
||||
if (ASN1_SUCCESS != (asn1_rv = asn1_read_value(asn_cert, "tbsCertificate.subjectPublicKeyInfo.subjectPublicKey", buf, &buflen))) {
|
||||
logger(Core, Error, "%s:%s:%d Failed to get cert's public key. Error = 0x%x (%s)\n",
|
||||
__FILE__, __func__, __LINE__, asn1_rv, asn1_strerror(asn1_rv));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ASN1_SUCCESS != (asn1_rv = asn1_create_element(*asn_defs, "PKIX1Implicit88.RSAPublicKey", &asn_key))) {
|
||||
logger(Core, Error, "%s:%s:%d Failed to create ASN.1 parser element. Error = 0x%x (%s)\n",
|
||||
__FILE__, __func__, __LINE__, asn1_rv, asn1_strerror(asn1_rv));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// As it' a BIT STRING the len constitutes the number of BITS, not BYTES
|
||||
if (ASN1_SUCCESS != (asn1_rv = asn1_der_decoding(&asn_key, buf, buflen / 8, errstr))) {
|
||||
logger(Core, Error, "%s:%s:%d Failed to decode public key object. Error = 0x%x (%s)\n",
|
||||
__FILE__, __func__, __LINE__, asn1_rv, asn1_strerror(asn1_rv));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get RSA public key's modulus and exponent */
|
||||
nblen = sizeof(newbuf);
|
||||
|
||||
if (ASN1_SUCCESS != (asn1_rv = asn1_read_value(asn_key, "modulus", newbuf, &nblen))) {
|
||||
logger(Core, Error, "%s:%s:%d Failed to get RSA public key's modulus. Error = 0x%x (%s)\n",
|
||||
__FILE__, __func__, __LINE__, asn1_rv, asn1_strerror(asn1_rv));
|
||||
return 1;
|
||||
}
|
||||
|
||||
m->size = nblen;
|
||||
|
||||
if (!(m->data = malloc(m->size))) {
|
||||
logger(Core, Error, "%s:%s:%d Failed to allocate memory for modulus.\n", __FILE__, __func__, __LINE__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
memcpy((void *)m->data, newbuf, m->size);
|
||||
|
||||
nblen = sizeof(newbuf);
|
||||
|
||||
if (ASN1_SUCCESS != (asn1_rv = asn1_read_value(asn_key, "publicExponent", newbuf, &nblen))) {
|
||||
logger(Core, Error, "%s:%s:%d Failed to get RSA public key's exponent. Error = 0x%x (%s)\n",
|
||||
__FILE__, __func__, __LINE__, asn1_rv, asn1_strerror(asn1_rv));
|
||||
return 1;
|
||||
}
|
||||
|
||||
e->size = nblen;
|
||||
|
||||
if (!(e->data = malloc(e->size))) {
|
||||
logger(Core, Error, "%s:%s:%d Failed to allocate memory for exponent.\n", __FILE__, __func__, __LINE__);
|
||||
if (m->data) {
|
||||
free(m->data);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
memcpy((void *)e->data, newbuf, m->size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
45
asn.h
Normal file
45
asn.h
Normal file
@ -0,0 +1,45 @@
|
||||
/* -*- c-basic-offset: 8 -*-
|
||||
rdesktop: A Remote Desktop Protocol client.
|
||||
ASN.1 utility functions header
|
||||
Copyright 2017 Alexander Zakharov <uglym8@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _RDASN_H
|
||||
#define _RDASN_H
|
||||
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <libtasn1.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define OID_SHA_WITH_RSA_SIGNATURE "1.3.14.3.2.15"
|
||||
#define OID_MD5_WITH_RSA_SIGNATURE "1.3.14.3.2.25"
|
||||
|
||||
int init_asn1_lib(void);
|
||||
int write_pkcs1_der_pubkey(const gnutls_datum_t *m, const gnutls_datum_t *e, uint8_t *out, int *out_len);
|
||||
|
||||
int libtasn_read_cert_pk_oid(uint8_t *data, size_t len, char *oid, size_t *oid_size);
|
||||
int libtasn_read_cert_pk_parameters(uint8_t *data, size_t len, gnutls_datum_t *m, gnutls_datum_t *e);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _RDASN_H */
|
127
configure.ac
127
configure.ac
@ -29,6 +29,9 @@ fi
|
||||
|
||||
AC_PATH_TOOL(PKG_CONFIG, pkg-config)
|
||||
|
||||
# no .pc for GMP
|
||||
AC_SEARCH_LIBS([__gmpz_init], [gmp])
|
||||
|
||||
AC_SEARCH_LIBS(socket, socket)
|
||||
AC_SEARCH_LIBS(inet_aton, resolv)
|
||||
|
||||
@ -61,74 +64,6 @@ AC_ARG_ENABLE([address-sanitizer], AS_HELP_STRING([--enable-address-sanitizer],
|
||||
[AC_MSG_ERROR([Address Sanitizer not available])])
|
||||
])
|
||||
|
||||
#
|
||||
# OpenSSL detection borrowed from stunnel
|
||||
#
|
||||
checkssldir() { :
|
||||
if test -f "$1/include/openssl/ssl.h"; then
|
||||
ssldir="$1"
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
AC_MSG_CHECKING([for OpenSSL directory])
|
||||
AC_ARG_WITH(openssl,
|
||||
[ --with-openssl=DIR look for OpenSSL at DIR/include, DIR/lib],
|
||||
[
|
||||
dnl Check the specified location only
|
||||
checkssldir "$withval"
|
||||
],
|
||||
[
|
||||
dnl Search default locations of OpenSSL library
|
||||
for maindir in /usr/local /usr/lib /usr/pkg /usr /var/ssl /opt; do
|
||||
for dir in $maindir $maindir/openssl $maindir/ssl; do
|
||||
checkssldir $dir && break 2
|
||||
done
|
||||
done
|
||||
]
|
||||
)
|
||||
if test -z "$ssldir"; then
|
||||
AC_MSG_RESULT([Not found])
|
||||
echo
|
||||
echo "ERROR: Could not find OpenSSL headers/libraries."
|
||||
if test -f /etc/debian_version; then
|
||||
echo "Probably you need to install the libssl-dev package."
|
||||
elif test -f /etc/redhat-release; then
|
||||
echo "Probably you need to install the openssl-devel package."
|
||||
fi
|
||||
echo "To specify a path manually, use the --with-openssl option."
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
AC_MSG_RESULT([$ssldir])
|
||||
AC_SUBST(ssldir)
|
||||
AC_DEFINE_UNQUOTED(ssldir, "$ssldir")
|
||||
|
||||
dnl Add OpenSSL includes and libraries
|
||||
CFLAGS="$CFLAGS -I$ssldir/include"
|
||||
AC_ARG_ENABLE(static-openssl,
|
||||
[ --enable-static-openssl link OpenSSL statically],
|
||||
[static_openssl=yes],
|
||||
[static_openssl=no])
|
||||
if test x"$static_openssl" = "xyes"; then
|
||||
# OpenSSL generally relies on libz
|
||||
AC_SEARCH_LIBS(deflate, z)
|
||||
LIBS="-L$ssldir/lib -L$ssldir/lib64 -Wl,-Bstatic -lssl -lcrypto -Wl,-Bdynamic -ldl $LIBS"
|
||||
else
|
||||
LIBS="-L$ssldir/lib -L$ssldir/lib64 -lssl -lcrypto -ldl $LIBS"
|
||||
|
||||
#
|
||||
# target-specific stuff
|
||||
#
|
||||
case "$host" in
|
||||
*-*-solaris*)
|
||||
LDFLAGS="$LDFLAGS -R$ssldir/lib"
|
||||
;;
|
||||
*-dec-osf*)
|
||||
LDFLAGS="$LDFLAGS -Wl,-rpath,$ssldir/lib"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
dnl CredSSP feature
|
||||
AC_ARG_ENABLE([credssp], AS_HELP_STRING([--disable-credssp], [disable support for CredSSP]))
|
||||
@ -201,6 +136,62 @@ else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# libtasn1
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
PKG_CHECK_MODULES(LIBTASN1, libtasn1, [HAVE_LIBTASN1=1], [HAVE_LIBTASN1=0])
|
||||
fi
|
||||
if test x"$HAVE_LIBTASN1" = "x1"; then
|
||||
CFLAGS="$CFLAGS $LIBTASN1_CFLAGS"
|
||||
LIBS="$LIBS $LIBTASN1_LIBS"
|
||||
else
|
||||
echo
|
||||
echo "rdesktop requires libtasn1. Please install the dependency"
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# nettle
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
PKG_CHECK_MODULES(NETTLE, nettle, [HAVE_NETTLE=1], [HAVE_NETTLE=0])
|
||||
fi
|
||||
if test x"$HAVE_NETTLE" = "x1"; then
|
||||
CFLAGS="$CFLAGS $NETTLE_CFLAGS"
|
||||
LIBS="$LIBS $NETTLE_LIBS"
|
||||
else
|
||||
echo
|
||||
echo "rdesktop requires Nettle. Please install the dependency"
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# hogweed
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
PKG_CHECK_MODULES(HOGWEED, hogweed, [HAVE_HOGWEED=1], [HAVE_HOGWEED=0])
|
||||
fi
|
||||
if test x"$HAVE_HOGWEED" = "x1"; then
|
||||
CFLAGS="$CFLAGS $HOGWEED_CFLAGS"
|
||||
LIBS="$LIBS $HOGWEED_LIBS"
|
||||
else
|
||||
echo
|
||||
echo "rdesktop requires hogweed. Please install the dependency"
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# GnuTLS
|
||||
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
PKG_CHECK_MODULES(GNUTLS, gnutls >= 3.2.0, [HAVE_GNUTLS=1], [HAVE_GNUTLS=0])
|
||||
fi
|
||||
if test x"$HAVE_GNUTLS" = "x1"; then
|
||||
CFLAGS="$CFLAGS $GNUTLS_CFLAGS"
|
||||
LIBS="$LIBS $GNUTLS_LIBS"
|
||||
else
|
||||
echo
|
||||
echo "rdesktop requires GnuTLS. Please install the dependency"
|
||||
echo
|
||||
exit 1
|
||||
fi
|
||||
|
||||
dnl Smartcard support
|
||||
AC_ARG_ENABLE(smartcard, AS_HELP_STRING([--disable-smartcard], [disable support for smartcard]))
|
||||
|
999
pkix.asn
Normal file
999
pkix.asn
Normal file
@ -0,0 +1,999 @@
|
||||
|
||||
PKIX1Implicit88 {iso(1) identified-organization(3) dod(6) internet(1)
|
||||
security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-implicit-88(2)}
|
||||
|
||||
DEFINITIONS IMPLICIT TAGS ::=
|
||||
|
||||
BEGIN
|
||||
|
||||
|
||||
-- ISO arc for standard certificate and CRL extensions
|
||||
|
||||
id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29}
|
||||
|
||||
|
||||
-- authority key identifier OID and syntax
|
||||
|
||||
id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 }
|
||||
|
||||
AuthorityKeyIdentifier ::= SEQUENCE {
|
||||
keyIdentifier [0] KeyIdentifier OPTIONAL,
|
||||
authorityCertIssuer [1] GeneralNames OPTIONAL,
|
||||
authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
|
||||
-- authorityCertIssuer and authorityCertSerialNumber shall both
|
||||
-- be present or both be absgent
|
||||
|
||||
KeyIdentifier ::= OCTET STRING
|
||||
|
||||
-- subject key identifier OID and syntax
|
||||
|
||||
id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 }
|
||||
|
||||
SubjectKeyIdentifier ::= KeyIdentifier
|
||||
|
||||
-- key usage extension OID and syntax
|
||||
|
||||
id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 }
|
||||
|
||||
KeyUsage ::= BIT STRING {
|
||||
digitalSignature (0),
|
||||
nonRepudiation (1),
|
||||
keyEncipherment (2),
|
||||
dataEncipherment (3),
|
||||
keyAgreement (4),
|
||||
keyCertSign (5),
|
||||
cRLSign (6),
|
||||
encipherOnly (7),
|
||||
decipherOnly (8) }
|
||||
|
||||
-- private key usage period extension OID and syntax
|
||||
|
||||
id-ce-privateKeyUsagePeriod OBJECT IDENTIFIER ::= { id-ce 16 }
|
||||
|
||||
PrivateKeyUsagePeriod ::= SEQUENCE {
|
||||
notBefore [0] GeneralizedTime OPTIONAL,
|
||||
notAfter [1] GeneralizedTime OPTIONAL }
|
||||
-- either notBefore or notAfter shall be present
|
||||
|
||||
-- certificate policies extension OID and syntax
|
||||
|
||||
id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
|
||||
|
||||
CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
|
||||
|
||||
PolicyInformation ::= SEQUENCE {
|
||||
policyIdentifier CertPolicyId,
|
||||
policyQualifiers SEQUENCE SIZE (1..MAX) OF
|
||||
PolicyQualifierInfo OPTIONAL }
|
||||
|
||||
CertPolicyId ::= OBJECT IDENTIFIER
|
||||
|
||||
PolicyQualifierInfo ::= SEQUENCE {
|
||||
policyQualifierId PolicyQualifierId,
|
||||
qualifier ANY DEFINED BY policyQualifierId }
|
||||
|
||||
-- Implementations that recognize additional policy qualifiers shall
|
||||
-- augment the following definition for PolicyQualifierId
|
||||
|
||||
PolicyQualifierId ::=
|
||||
OBJECT IDENTIFIER -- ( id-qt-cps | id-qt-unotice )
|
||||
|
||||
-- CPS pointer qualifier
|
||||
|
||||
CPSuri ::= IA5String
|
||||
|
||||
-- user notice qualifier
|
||||
|
||||
UserNotice ::= SEQUENCE {
|
||||
noticeRef NoticeReference OPTIONAL,
|
||||
explicitText DisplayText OPTIONAL}
|
||||
|
||||
NoticeReference ::= SEQUENCE {
|
||||
organization DisplayText,
|
||||
noticeNumbers SEQUENCE OF INTEGER }
|
||||
|
||||
DisplayText ::= CHOICE {
|
||||
visibleString VisibleString (SIZE (1..200)),
|
||||
bmpString BMPString (SIZE (1..200)),
|
||||
utf8String UTF8String (SIZE (1..200)) }
|
||||
|
||||
-- policy mapping extension OID and syntax
|
||||
|
||||
id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 }
|
||||
|
||||
PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
|
||||
issuerDomainPolicy CertPolicyId,
|
||||
subjectDomainPolicy CertPolicyId }
|
||||
|
||||
-- subject alternative name extension OID and syntax
|
||||
|
||||
id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 }
|
||||
|
||||
SubjectAltName ::= GeneralNames
|
||||
|
||||
GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
|
||||
|
||||
GeneralName ::= CHOICE {
|
||||
otherName [0] AnotherName,
|
||||
rfc822Name [1] IA5String,
|
||||
dNSName [2] IA5String,
|
||||
x400Address [3] ORAddress,
|
||||
directoryName [4] Name,
|
||||
ediPartyName [5] EDIPartyName,
|
||||
uniformResourceIdentifier [6] IA5String,
|
||||
iPAddress [7] OCTET STRING,
|
||||
registeredID [8] OBJECT IDENTIFIER }
|
||||
|
||||
-- AnotherName replaces OTHER-NAME ::= TYPE-IDENTIFIER, as
|
||||
-- TYPE-IDENTIFIER is not supported in the '88 ASN.1 syntax
|
||||
|
||||
AnotherName ::= SEQUENCE {
|
||||
type-id OBJECT IDENTIFIER,
|
||||
value [0] EXPLICIT ANY DEFINED BY type-id }
|
||||
|
||||
EDIPartyName ::= SEQUENCE {
|
||||
nameAssigner [0] DirectoryString OPTIONAL,
|
||||
partyName [1] DirectoryString }
|
||||
|
||||
-- issuer alternative name extension OID and syntax
|
||||
|
||||
id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 }
|
||||
|
||||
IssuerAltName ::= GeneralNames
|
||||
|
||||
id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 }
|
||||
|
||||
SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF Attribute
|
||||
|
||||
-- basic constraints extension OID and syntax
|
||||
|
||||
id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 }
|
||||
|
||||
BasicConstraints ::= SEQUENCE {
|
||||
cA BOOLEAN DEFAULT FALSE,
|
||||
pathLenConstraint INTEGER (0..MAX) OPTIONAL }
|
||||
|
||||
-- name constraints extension OID and syntax
|
||||
|
||||
id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 }
|
||||
|
||||
NameConstraints ::= SEQUENCE {
|
||||
permittedSubtrees [0] GeneralSubtrees OPTIONAL,
|
||||
excludedSubtrees [1] GeneralSubtrees OPTIONAL }
|
||||
|
||||
GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
|
||||
|
||||
GeneralSubtree ::= SEQUENCE {
|
||||
base GeneralName,
|
||||
minimum [0] BaseDistance DEFAULT 0,
|
||||
maximum [1] BaseDistance OPTIONAL }
|
||||
|
||||
BaseDistance ::= INTEGER (0..MAX)
|
||||
|
||||
-- policy constraints extension OID and syntax
|
||||
|
||||
id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 }
|
||||
|
||||
PolicyConstraints ::= SEQUENCE {
|
||||
requireExplicitPolicy [0] SkipCerts OPTIONAL,
|
||||
inhibitPolicyMapping [1] SkipCerts OPTIONAL }
|
||||
|
||||
SkipCerts ::= INTEGER (0..MAX)
|
||||
|
||||
-- CRL distribution points extension OID and syntax
|
||||
|
||||
id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= {id-ce 31}
|
||||
|
||||
CRLDistPointsSyntax ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
|
||||
|
||||
DistributionPoint ::= SEQUENCE {
|
||||
distributionPoint [0] DistributionPointName OPTIONAL,
|
||||
reasons [1] ReasonFlags OPTIONAL,
|
||||
cRLIssuer [2] GeneralNames OPTIONAL }
|
||||
|
||||
-- This was previously a CHOICE with two possible choices,
|
||||
-- corresponding to the same names and types. However, this
|
||||
-- rendered libtasn1 unable to interpret the certificate
|
||||
-- revocation lists on the test SITHS certificate that I've
|
||||
-- had. Turning it to a sequence with two optional members
|
||||
-- made it work though, so I truly hope that this doesn't break
|
||||
-- anything.
|
||||
|
||||
DistributionPointName ::= SEQUENCE {
|
||||
fullName [0] GeneralNames OPTIONAL,
|
||||
nameRelativeToCRLIssuer [1] RelativeDistinguishedName OPTIONAL }
|
||||
|
||||
|
||||
|
||||
ReasonFlags ::= BIT STRING {
|
||||
unused (0),
|
||||
keyCompromise (1),
|
||||
cACompromise (2),
|
||||
affiliationChanged (3),
|
||||
superseded (4),
|
||||
cessationOfOperation (5),
|
||||
certificateHold (6) }
|
||||
|
||||
-- extended key usage extension OID and syntax
|
||||
|
||||
id-ce-extKeyUsage OBJECT IDENTIFIER ::= {id-ce 37}
|
||||
|
||||
ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
|
||||
|
||||
KeyPurposeId ::= OBJECT IDENTIFIER
|
||||
|
||||
-- extended key purpose OIDs
|
||||
id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 }
|
||||
id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 }
|
||||
id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 }
|
||||
id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 }
|
||||
id-kp-ipsecEndSystem OBJECT IDENTIFIER ::= { id-kp 5 }
|
||||
id-kp-ipsecTunnel OBJECT IDENTIFIER ::= { id-kp 6 }
|
||||
id-kp-ipsecUser OBJECT IDENTIFIER ::= { id-kp 7 }
|
||||
id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 }
|
||||
|
||||
-- authority info access
|
||||
|
||||
id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
|
||||
|
||||
AuthorityInfoAccessSyntax ::=
|
||||
SEQUENCE SIZE (1..MAX) OF AccessDescription
|
||||
|
||||
AccessDescription ::= SEQUENCE {
|
||||
accessMethod OBJECT IDENTIFIER,
|
||||
accessLocation GeneralName }
|
||||
|
||||
-- CRL number extension OID and syntax
|
||||
|
||||
id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 }
|
||||
|
||||
CRLNumber ::= INTEGER (0..MAX)
|
||||
|
||||
-- issuing distribution point extension OID and syntax
|
||||
|
||||
id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-ce 28 }
|
||||
|
||||
IssuingDistributionPoint ::= SEQUENCE {
|
||||
distributionPoint [0] DistributionPointName OPTIONAL,
|
||||
onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE,
|
||||
onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE,
|
||||
onlySomeReasons [3] ReasonFlags OPTIONAL,
|
||||
indirectCRL [4] BOOLEAN DEFAULT FALSE }
|
||||
|
||||
|
||||
id-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= { id-ce 27 }
|
||||
|
||||
-- deltaCRLIndicator ::= BaseCRLNumber
|
||||
|
||||
BaseCRLNumber ::= CRLNumber
|
||||
|
||||
-- CRL reasons extension OID and syntax
|
||||
|
||||
id-ce-cRLReasons OBJECT IDENTIFIER ::= { id-ce 21 }
|
||||
|
||||
CRLReason ::= ENUMERATED {
|
||||
unspecified (0),
|
||||
keyCompromise (1),
|
||||
cACompromise (2),
|
||||
affiliationChanged (3),
|
||||
superseded (4),
|
||||
cessationOfOperation (5),
|
||||
certificateHold (6),
|
||||
removeFromCRL (8) }
|
||||
|
||||
-- certificate issuer CRL entry extension OID and syntax
|
||||
|
||||
id-ce-certificateIssuer OBJECT IDENTIFIER ::= { id-ce 29 }
|
||||
|
||||
CertificateIssuer ::= GeneralNames
|
||||
|
||||
-- hold instruction extension OID and syntax
|
||||
|
||||
id-ce-holdInstructionCode OBJECT IDENTIFIER ::= { id-ce 23 }
|
||||
|
||||
HoldInstructionCode ::= OBJECT IDENTIFIER
|
||||
|
||||
-- ANSI x9 holdinstructions
|
||||
|
||||
-- ANSI x9 arc holdinstruction arc
|
||||
holdInstruction OBJECT IDENTIFIER ::=
|
||||
{joint-iso-itu-t(2) member-body(2) us(840) x9cm(10040) 2}
|
||||
|
||||
-- ANSI X9 holdinstructions referenced by this standard
|
||||
id-holdinstruction-none OBJECT IDENTIFIER ::=
|
||||
{holdInstruction 1} -- deprecated
|
||||
id-holdinstruction-callissuer OBJECT IDENTIFIER ::=
|
||||
{holdInstruction 2}
|
||||
id-holdinstruction-reject OBJECT IDENTIFIER ::=
|
||||
{holdInstruction 3}
|
||||
|
||||
-- invalidity date CRL entry extension OID and syntax
|
||||
|
||||
id-ce-invalidityDate OBJECT IDENTIFIER ::= { id-ce 24 }
|
||||
|
||||
InvalidityDate ::= GeneralizedTime
|
||||
|
||||
-- Netscape certificate type extension
|
||||
|
||||
id-netscape OBJECT IDENTIFIER ::= {
|
||||
joint-iso-itu-t(2) country(16) us(840) organization(1) netscape(113730) }
|
||||
|
||||
id-netscape-certExtension OBJECT IDENTIFIER ::= { id-netscape 1 }
|
||||
|
||||
id-netscape-certType OBJECT IDENTIFIER ::= { id-netscape-certExtension 1 }
|
||||
|
||||
CertType ::= BIT STRING {
|
||||
sslClient (0),
|
||||
sslServer (1),
|
||||
smime (2),
|
||||
objectSigning (3),
|
||||
reserved (4),
|
||||
sslCA (5),
|
||||
smimeCA (6),
|
||||
objectSigningCA (7) }
|
||||
|
||||
|
||||
-- --------------------------------------
|
||||
-- EXPLICIT
|
||||
-- --------------------------------------
|
||||
|
||||
-- UNIVERSAL Types defined in '93 and '98 ASN.1
|
||||
-- but required by this specification
|
||||
|
||||
VisibleString ::= [UNIVERSAL 26] IMPLICIT OCTET STRING
|
||||
|
||||
NumericString ::= [UNIVERSAL 18] IMPLICIT OCTET STRING
|
||||
|
||||
IA5String ::= [UNIVERSAL 22] IMPLICIT OCTET STRING
|
||||
|
||||
TeletexString ::= [UNIVERSAL 20] IMPLICIT OCTET STRING
|
||||
|
||||
PrintableString ::= [UNIVERSAL 19] IMPLICIT OCTET STRING
|
||||
|
||||
UniversalString ::= [UNIVERSAL 28] IMPLICIT OCTET STRING
|
||||
-- UniversalString is defined in ASN.1:1993
|
||||
|
||||
BMPString ::= [UNIVERSAL 30] IMPLICIT OCTET STRING
|
||||
-- BMPString is the subtype of UniversalString and models
|
||||
-- the Basic Multilingual Plane of ISO/IEC/ITU 10646-1
|
||||
|
||||
UTF8String ::= [UNIVERSAL 12] IMPLICIT OCTET STRING
|
||||
-- The content of this type conforms to RFC 2279.
|
||||
|
||||
|
||||
-- PKIX specific OIDs
|
||||
|
||||
id-pkix OBJECT IDENTIFIER ::=
|
||||
{ iso(1) identified-organization(3) dod(6) internet(1)
|
||||
security(5) mechanisms(5) pkix(7) }
|
||||
|
||||
-- PKIX arcs
|
||||
|
||||
id-pe OBJECT IDENTIFIER ::= { id-pkix 1 }
|
||||
-- arc for private certificate extensions
|
||||
id-qt OBJECT IDENTIFIER ::= { id-pkix 2 }
|
||||
-- arc for policy qualifier types
|
||||
id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
|
||||
-- arc for extended key purpose OIDS
|
||||
id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }
|
||||
-- arc for access descriptors
|
||||
|
||||
-- policyQualifierIds for Internet policy qualifiers
|
||||
|
||||
id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 }
|
||||
-- OID for CPS qualifier
|
||||
id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 }
|
||||
-- OID for user notice qualifier
|
||||
|
||||
-- access descriptor definitions
|
||||
|
||||
id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 }
|
||||
id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 }
|
||||
|
||||
-- attribute data types --
|
||||
|
||||
Attribute ::= SEQUENCE {
|
||||
type AttributeType,
|
||||
values SET OF AttributeValue
|
||||
-- at least one value is required --
|
||||
}
|
||||
|
||||
AttributeType ::= OBJECT IDENTIFIER
|
||||
|
||||
AttributeValue ::= ANY
|
||||
|
||||
AttributeTypeAndValue ::= SEQUENCE {
|
||||
type AttributeType,
|
||||
value AttributeValue }
|
||||
|
||||
-- suggested naming attributes: Definition of the following
|
||||
-- information object set may be augmented to meet local
|
||||
-- requirements. Note that deleting members of the set may
|
||||
-- prevent interoperability with conforming implementations.
|
||||
-- presented in pairs: the AttributeType followed by the
|
||||
-- type definition for the corresponding AttributeValue
|
||||
|
||||
-- Arc for standard naming attributes
|
||||
id-at OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 4}
|
||||
|
||||
-- Attributes of type NameDirectoryString
|
||||
id-at-name AttributeType ::= {id-at 41}
|
||||
id-at-surname AttributeType ::= {id-at 4}
|
||||
id-at-givenName AttributeType ::= {id-at 42}
|
||||
id-at-initials AttributeType ::= {id-at 43}
|
||||
id-at-generationQualifier AttributeType ::= {id-at 44}
|
||||
|
||||
X520name ::= CHOICE {
|
||||
teletexString TeletexString (SIZE (1..ub-name)),
|
||||
printableString PrintableString (SIZE (1..ub-name)),
|
||||
universalString UniversalString (SIZE (1..ub-name)),
|
||||
utf8String UTF8String (SIZE (1..ub-name)),
|
||||
bmpString BMPString (SIZE(1..ub-name)) }
|
||||
|
||||
--
|
||||
|
||||
id-at-commonName AttributeType ::= {id-at 3}
|
||||
|
||||
X520CommonName ::= CHOICE {
|
||||
teletexString TeletexString (SIZE (1..ub-common-name)),
|
||||
printableString PrintableString (SIZE (1..ub-common-name)),
|
||||
universalString UniversalString (SIZE (1..ub-common-name)),
|
||||
utf8String UTF8String (SIZE (1..ub-common-name)),
|
||||
bmpString BMPString (SIZE(1..ub-common-name)) }
|
||||
|
||||
--
|
||||
|
||||
id-at-localityName AttributeType ::= {id-at 7}
|
||||
|
||||
X520LocalityName ::= CHOICE {
|
||||
teletexString TeletexString (SIZE (1..ub-locality-name)),
|
||||
printableString PrintableString (SIZE (1..ub-locality-name)),
|
||||
universalString UniversalString (SIZE (1..ub-locality-name)),
|
||||
utf8String UTF8String (SIZE (1..ub-locality-name)),
|
||||
bmpString BMPString (SIZE(1..ub-locality-name)) }
|
||||
|
||||
--
|
||||
|
||||
id-at-stateOrProvinceName AttributeType ::= {id-at 8}
|
||||
|
||||
X520StateOrProvinceName ::= CHOICE {
|
||||
teletexString TeletexString (SIZE (1..ub-state-name)),
|
||||
printableString PrintableString (SIZE (1..ub-state-name)),
|
||||
universalString UniversalString (SIZE (1..ub-state-name)),
|
||||
utf8String UTF8String (SIZE (1..ub-state-name)),
|
||||
bmpString BMPString (SIZE(1..ub-state-name)) }
|
||||
|
||||
--
|
||||
|
||||
id-at-organizationName AttributeType ::= {id-at 10}
|
||||
|
||||
X520OrganizationName ::= CHOICE {
|
||||
teletexString TeletexString (SIZE (1..ub-organization-name)),
|
||||
printableString PrintableString (SIZE (1..ub-organization-name)),
|
||||
universalString UniversalString (SIZE (1..ub-organization-name)),
|
||||
utf8String UTF8String (SIZE (1..ub-organization-name)),
|
||||
bmpString BMPString (SIZE(1..ub-organization-name)) }
|
||||
|
||||
--
|
||||
|
||||
id-at-organizationalUnitName AttributeType ::= {id-at 11}
|
||||
|
||||
X520OrganizationalUnitName ::= CHOICE {
|
||||
teletexString TeletexString (SIZE (1..ub-organizational-unit-name)),
|
||||
printableString PrintableString
|
||||
(SIZE (1..ub-organizational-unit-name)),
|
||||
universalString UniversalString
|
||||
(SIZE (1..ub-organizational-unit-name)),
|
||||
utf8String UTF8String (SIZE (1..ub-organizational-unit-name)),
|
||||
bmpString BMPString (SIZE(1..ub-organizational-unit-name)) }
|
||||
|
||||
--
|
||||
|
||||
id-at-title AttributeType ::= {id-at 12}
|
||||
|
||||
X520Title ::= CHOICE {
|
||||
teletexString TeletexString (SIZE (1..ub-title)),
|
||||
printableString PrintableString (SIZE (1..ub-title)),
|
||||
universalString UniversalString (SIZE (1..ub-title)),
|
||||
utf8String UTF8String (SIZE (1..ub-title)),
|
||||
bmpString BMPString (SIZE(1..ub-title)) }
|
||||
|
||||
--
|
||||
|
||||
id-at-dnQualifier AttributeType ::= {id-at 46}
|
||||
X520dnQualifier ::= PrintableString
|
||||
|
||||
id-at-countryName AttributeType ::= {id-at 6}
|
||||
X520countryName ::= PrintableString (SIZE (2)) -- IS 3166 codes
|
||||
|
||||
-- Legacy attributes
|
||||
|
||||
pkcs-9 OBJECT IDENTIFIER ::=
|
||||
{ iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 }
|
||||
|
||||
emailAddress AttributeType ::= { pkcs-9 1 }
|
||||
|
||||
Pkcs9email ::= IA5String (SIZE (1..ub-emailaddress-length))
|
||||
|
||||
-- naming data types --
|
||||
|
||||
Name ::= CHOICE { -- only one possibility for now --
|
||||
rdnSequence RDNSequence }
|
||||
|
||||
RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
|
||||
|
||||
DistinguishedName ::= RDNSequence
|
||||
|
||||
RelativeDistinguishedName ::=
|
||||
SET SIZE (1 .. MAX) OF AttributeTypeAndValue
|
||||
|
||||
-- Directory string type --
|
||||
|
||||
DirectoryString ::= CHOICE {
|
||||
teletexString TeletexString (SIZE (1..MAX)),
|
||||
printableString PrintableString (SIZE (1..MAX)),
|
||||
universalString UniversalString (SIZE (1..MAX)),
|
||||
utf8String UTF8String (SIZE (1..MAX)),
|
||||
bmpString BMPString (SIZE(1..MAX)) }
|
||||
|
||||
|
||||
-- --------------------------------------------------------
|
||||
-- certificate and CRL specific structures begin here
|
||||
-- --------------------------------------------------------
|
||||
|
||||
Certificate ::= SEQUENCE {
|
||||
tbsCertificate TBSCertificate,
|
||||
signatureAlgorithm AlgorithmIdentifier,
|
||||
signature BIT STRING }
|
||||
|
||||
TBSCertificate ::= SEQUENCE {
|
||||
version [0] EXPLICIT Version DEFAULT v1,
|
||||
serialNumber CertificateSerialNumber,
|
||||
signature AlgorithmIdentifier,
|
||||
issuer Name,
|
||||
validity Validity,
|
||||
subject Name,
|
||||
subjectPublicKeyInfo SubjectPublicKeyInfo,
|
||||
issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
|
||||
-- If present, version shall be v2 or v3
|
||||
subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
|
||||
-- If present, version shall be v2 or v3
|
||||
extensions [3] EXPLICIT Extensions OPTIONAL
|
||||
-- If present, version shall be v3 --
|
||||
}
|
||||
|
||||
Version ::= INTEGER { v1(0), v2(1), v3(2) }
|
||||
|
||||
CertificateSerialNumber ::= INTEGER
|
||||
|
||||
Validity ::= SEQUENCE {
|
||||
notBefore Time,
|
||||
notAfter Time }
|
||||
|
||||
Time ::= CHOICE {
|
||||
utcTime UTCTime,
|
||||
generalTime GeneralizedTime }
|
||||
|
||||
UniqueIdentifier ::= BIT STRING
|
||||
|
||||
SubjectPublicKeyInfo ::= SEQUENCE {
|
||||
algorithm AlgorithmIdentifier,
|
||||
subjectPublicKey BIT STRING }
|
||||
|
||||
Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
|
||||
|
||||
Extension ::= SEQUENCE {
|
||||
extnID OBJECT IDENTIFIER,
|
||||
critical BOOLEAN DEFAULT FALSE,
|
||||
extnValue OCTET STRING }
|
||||
|
||||
|
||||
-- ------------------------------------------
|
||||
-- CRL structures
|
||||
-- ------------------------------------------
|
||||
|
||||
CertificateList ::= SEQUENCE {
|
||||
tbsCertList TBSCertList,
|
||||
signatureAlgorithm AlgorithmIdentifier,
|
||||
signature BIT STRING }
|
||||
|
||||
TBSCertList ::= SEQUENCE {
|
||||
version Version OPTIONAL,
|
||||
-- if present, shall be v2
|
||||
signature AlgorithmIdentifier,
|
||||
issuer Name,
|
||||
thisUpdate Time,
|
||||
nextUpdate Time OPTIONAL,
|
||||
revokedCertificates SEQUENCE OF SEQUENCE {
|
||||
userCertificate CertificateSerialNumber,
|
||||
revocationDate Time,
|
||||
crlEntryExtensions Extensions OPTIONAL
|
||||
-- if present, shall be v2
|
||||
} OPTIONAL,
|
||||
crlExtensions [0] EXPLICIT Extensions OPTIONAL
|
||||
-- if present, shall be v2 --
|
||||
}
|
||||
|
||||
-- Version, Time, CertificateSerialNumber, and Extensions were
|
||||
-- defined earlier for use in the certificate structure
|
||||
|
||||
AlgorithmIdentifier ::= SEQUENCE {
|
||||
algorithm OBJECT IDENTIFIER,
|
||||
parameters ANY DEFINED BY algorithm OPTIONAL }
|
||||
-- contains a value of the type
|
||||
-- registered for use with the
|
||||
-- algorithm object identifier value
|
||||
|
||||
-- Algorithm OIDs and parameter structures
|
||||
|
||||
pkcs-1 OBJECT IDENTIFIER ::= {
|
||||
iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 }
|
||||
|
||||
rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 }
|
||||
|
||||
md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 }
|
||||
|
||||
md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 }
|
||||
|
||||
sha1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 }
|
||||
|
||||
-- Cendio additions:
|
||||
|
||||
sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 }
|
||||
|
||||
sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 }
|
||||
|
||||
sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 }
|
||||
|
||||
RSAPublicKey ::= SEQUENCE {
|
||||
modulus INTEGER, -- n
|
||||
publicExponent INTEGER -- e
|
||||
}
|
||||
|
||||
RSAPrivateKey ::= SEQUENCE {
|
||||
version Version,
|
||||
modulus INTEGER, -- n
|
||||
publicExponent INTEGER, -- e
|
||||
privateExponent INTEGER, -- d
|
||||
prime1 INTEGER, -- p
|
||||
prime2 INTEGER, -- q
|
||||
exponent1 INTEGER, -- d mod (p-1)
|
||||
exponent2 INTEGER, -- d mod (q-1)
|
||||
coefficient INTEGER -- (inverse of q) mod p
|
||||
}
|
||||
|
||||
|
||||
id-dsa-with-sha1 OBJECT IDENTIFIER ::= {
|
||||
iso(1) member-body(2) us(840) x9-57 (10040) x9algorithm(4) 3 }
|
||||
|
||||
Dss-Sig-Value ::= SEQUENCE {
|
||||
r INTEGER,
|
||||
s INTEGER }
|
||||
|
||||
dhpublicnumber OBJECT IDENTIFIER ::= {
|
||||
iso(1) member-body(2) us(840) ansi-x942(10046) number-type(2) 1 }
|
||||
|
||||
DomainParameters ::= SEQUENCE {
|
||||
p INTEGER, -- odd prime, p=jq +1
|
||||
g INTEGER, -- generator, g
|
||||
q INTEGER, -- factor of p-1
|
||||
j INTEGER OPTIONAL, -- subgroup factor, j>= 2
|
||||
validationParms ValidationParms OPTIONAL }
|
||||
|
||||
ValidationParms ::= SEQUENCE {
|
||||
seed BIT STRING,
|
||||
pgenCounter INTEGER }
|
||||
|
||||
id-dsa OBJECT IDENTIFIER ::= {
|
||||
iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) 1 }
|
||||
|
||||
Dss-Parms ::= SEQUENCE {
|
||||
p INTEGER,
|
||||
q INTEGER,
|
||||
g INTEGER }
|
||||
|
||||
-- x400 address syntax starts here
|
||||
-- OR Names
|
||||
|
||||
ORAddress ::= SEQUENCE {
|
||||
built-in-standard-attributes BuiltInStandardAttributes,
|
||||
built-in-domain-defined-attributes
|
||||
BuiltInDomainDefinedAttributes OPTIONAL,
|
||||
-- see also teletex-domain-defined-attributes
|
||||
extension-attributes ExtensionAttributes OPTIONAL }
|
||||
-- The OR-address is semantically absent from the OR-name if the
|
||||
-- built-in-standard-attribute sequence is empty and the
|
||||
-- built-in-domain-defined-attributes and extension-attributes are
|
||||
-- both omitted.
|
||||
|
||||
-- Built-in Standard Attributes
|
||||
|
||||
BuiltInStandardAttributes ::= SEQUENCE {
|
||||
country-name CountryName OPTIONAL,
|
||||
administration-domain-name AdministrationDomainName OPTIONAL,
|
||||
network-address [0] EXPLICIT NetworkAddress OPTIONAL,
|
||||
-- see also extended-network-address
|
||||
terminal-identifier [1] EXPLICIT TerminalIdentifier OPTIONAL,
|
||||
private-domain-name [2] EXPLICIT PrivateDomainName OPTIONAL,
|
||||
organization-name [3] EXPLICIT OrganizationName OPTIONAL,
|
||||
-- see also teletex-organization-name
|
||||
numeric-user-identifier [4] EXPLICIT NumericUserIdentifier OPTIONAL,
|
||||
personal-name [5] EXPLICIT PersonalName OPTIONAL,
|
||||
-- see also teletex-personal-name
|
||||
organizational-unit-names [6] EXPLICIT OrganizationalUnitNames OPTIONAL
|
||||
-- see also teletex-organizational-unit-names --
|
||||
}
|
||||
|
||||
CountryName ::= [APPLICATION 1] CHOICE {
|
||||
x121-dcc-code NumericString
|
||||
(SIZE (ub-country-name-numeric-length)),
|
||||
iso-3166-alpha2-code PrintableString
|
||||
(SIZE (ub-country-name-alpha-length)) }
|
||||
|
||||
AdministrationDomainName ::= [APPLICATION 2] EXPLICIT CHOICE {
|
||||
numeric NumericString (SIZE (0..ub-domain-name-length)),
|
||||
printable PrintableString (SIZE (0..ub-domain-name-length)) }
|
||||
|
||||
NetworkAddress ::= X121Address -- see also extended-network-address
|
||||
|
||||
X121Address ::= NumericString (SIZE (1..ub-x121-address-length))
|
||||
|
||||
TerminalIdentifier ::= PrintableString (SIZE (1..ub-terminal-id-length))
|
||||
|
||||
PrivateDomainName ::= CHOICE {
|
||||
numeric NumericString (SIZE (1..ub-domain-name-length)),
|
||||
printable PrintableString (SIZE (1..ub-domain-name-length)) }
|
||||
|
||||
OrganizationName ::= PrintableString
|
||||
(SIZE (1..ub-organization-name-length))
|
||||
-- see also teletex-organization-name
|
||||
|
||||
NumericUserIdentifier ::= NumericString
|
||||
(SIZE (1..ub-numeric-user-id-length))
|
||||
|
||||
PersonalName ::= SET {
|
||||
surname [0] PrintableString (SIZE (1..ub-surname-length)),
|
||||
given-name [1] PrintableString
|
||||
(SIZE (1..ub-given-name-length)) OPTIONAL,
|
||||
initials [2] PrintableString (SIZE (1..ub-initials-length)) OPTIONAL,
|
||||
generation-qualifier [3] PrintableString
|
||||
(SIZE (1..ub-generation-qualifier-length)) OPTIONAL }
|
||||
-- see also teletex-personal-name
|
||||
|
||||
OrganizationalUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units)
|
||||
OF OrganizationalUnitName
|
||||
-- see also teletex-organizational-unit-names
|
||||
|
||||
OrganizationalUnitName ::= PrintableString (SIZE
|
||||
(1..ub-organizational-unit-name-length))
|
||||
|
||||
-- Built-in Domain-defined Attributes
|
||||
|
||||
BuiltInDomainDefinedAttributes ::= SEQUENCE SIZE
|
||||
(1..ub-domain-defined-attributes) OF
|
||||
BuiltInDomainDefinedAttribute
|
||||
|
||||
BuiltInDomainDefinedAttribute ::= SEQUENCE {
|
||||
type PrintableString (SIZE
|
||||
(1..ub-domain-defined-attribute-type-length)),
|
||||
value PrintableString (SIZE
|
||||
(1..ub-domain-defined-attribute-value-length))}
|
||||
|
||||
-- Extension Attributes
|
||||
|
||||
ExtensionAttributes ::= SET SIZE (1..ub-extension-attributes) OF
|
||||
ExtensionAttribute
|
||||
|
||||
ExtensionAttribute ::= SEQUENCE {
|
||||
extension-attribute-type [0] EXPLICIT INTEGER (0..ub-extension-attributes),
|
||||
extension-attribute-value [1] EXPLICIT
|
||||
ANY DEFINED BY extension-attribute-type }
|
||||
|
||||
-- Extension types and attribute values
|
||||
--
|
||||
|
||||
common-name INTEGER ::= 1
|
||||
|
||||
CommonName ::= PrintableString (SIZE (1..ub-common-name-length))
|
||||
|
||||
teletex-common-name INTEGER ::= 2
|
||||
|
||||
TeletexCommonName ::= TeletexString (SIZE (1..ub-common-name-length))
|
||||
|
||||
teletex-organization-name INTEGER ::= 3
|
||||
|
||||
TeletexOrganizationName ::=
|
||||
TeletexString (SIZE (1..ub-organization-name-length))
|
||||
|
||||
teletex-personal-name INTEGER ::= 4
|
||||
|
||||
TeletexPersonalName ::= SET {
|
||||
surname [0] EXPLICIT TeletexString (SIZE (1..ub-surname-length)),
|
||||
given-name [1] EXPLICIT TeletexString
|
||||
(SIZE (1..ub-given-name-length)) OPTIONAL,
|
||||
initials [2] EXPLICIT TeletexString (SIZE (1..ub-initials-length)) OPTIONAL,
|
||||
generation-qualifier [3] EXPLICIT TeletexString (SIZE
|
||||
(1..ub-generation-qualifier-length)) OPTIONAL }
|
||||
|
||||
teletex-organizational-unit-names INTEGER ::= 5
|
||||
|
||||
TeletexOrganizationalUnitNames ::= SEQUENCE SIZE
|
||||
(1..ub-organizational-units) OF TeletexOrganizationalUnitName
|
||||
|
||||
TeletexOrganizationalUnitName ::= TeletexString
|
||||
(SIZE (1..ub-organizational-unit-name-length))
|
||||
|
||||
pds-name INTEGER ::= 7
|
||||
|
||||
PDSName ::= PrintableString (SIZE (1..ub-pds-name-length))
|
||||
|
||||
physical-delivery-country-name INTEGER ::= 8
|
||||
|
||||
PhysicalDeliveryCountryName ::= CHOICE {
|
||||
x121-dcc-code NumericString (SIZE (ub-country-name-numeric-length)),
|
||||
iso-3166-alpha2-code PrintableString
|
||||
(SIZE (ub-country-name-alpha-length)) }
|
||||
|
||||
postal-code INTEGER ::= 9
|
||||
|
||||
PostalCode ::= CHOICE {
|
||||
numeric-code NumericString (SIZE (1..ub-postal-code-length)),
|
||||
printable-code PrintableString (SIZE (1..ub-postal-code-length)) }
|
||||
|
||||
physical-delivery-office-name INTEGER ::= 10
|
||||
|
||||
PhysicalDeliveryOfficeName ::= PDSParameter
|
||||
|
||||
physical-delivery-office-number INTEGER ::= 11
|
||||
|
||||
PhysicalDeliveryOfficeNumber ::= PDSParameter
|
||||
|
||||
extension-OR-address-components INTEGER ::= 12
|
||||
|
||||
ExtensionORAddressComponents ::= PDSParameter
|
||||
|
||||
physical-delivery-personal-name INTEGER ::= 13
|
||||
|
||||
PhysicalDeliveryPersonalName ::= PDSParameter
|
||||
|
||||
physical-delivery-organization-name INTEGER ::= 14
|
||||
|
||||
PhysicalDeliveryOrganizationName ::= PDSParameter
|
||||
|
||||
extension-physical-delivery-address-components INTEGER ::= 15
|
||||
|
||||
ExtensionPhysicalDeliveryAddressComponents ::= PDSParameter
|
||||
|
||||
unformatted-postal-address INTEGER ::= 16
|
||||
|
||||
UnformattedPostalAddress ::= SET {
|
||||
printable-address SEQUENCE SIZE (1..ub-pds-physical-address-lines) OF
|
||||
PrintableString (SIZE (1..ub-pds-parameter-length)) OPTIONAL,
|
||||
teletex-string TeletexString
|
||||
(SIZE (1..ub-unformatted-address-length)) OPTIONAL }
|
||||
|
||||
street-address INTEGER ::= 17
|
||||
|
||||
StreetAddress ::= PDSParameter
|
||||
|
||||
post-office-box-address INTEGER ::= 18
|
||||
|
||||
PostOfficeBoxAddress ::= PDSParameter
|
||||
|
||||
poste-restante-address INTEGER ::= 19
|
||||
|
||||
PosteRestanteAddress ::= PDSParameter
|
||||
|
||||
unique-postal-name INTEGER ::= 20
|
||||
|
||||
UniquePostalName ::= PDSParameter
|
||||
|
||||
local-postal-attributes INTEGER ::= 21
|
||||
|
||||
LocalPostalAttributes ::= PDSParameter
|
||||
|
||||
PDSParameter ::= SET {
|
||||
printable-string PrintableString
|
||||
(SIZE(1..ub-pds-parameter-length)) OPTIONAL,
|
||||
teletex-string TeletexString
|
||||
(SIZE(1..ub-pds-parameter-length)) OPTIONAL }
|
||||
|
||||
extended-network-address INTEGER ::= 22
|
||||
|
||||
ExtendedNetworkAddress ::= CHOICE {
|
||||
e163-4-address SEQUENCE {
|
||||
number [0] EXPLICIT NumericString (SIZE (1..ub-e163-4-number-length)),
|
||||
sub-address [1] EXPLICIT NumericString
|
||||
(SIZE (1..ub-e163-4-sub-address-length)) OPTIONAL },
|
||||
psap-address [0] EXPLICIT PresentationAddress }
|
||||
|
||||
PresentationAddress ::= SEQUENCE {
|
||||
pSelector [0] EXPLICIT OCTET STRING OPTIONAL,
|
||||
sSelector [1] EXPLICIT OCTET STRING OPTIONAL,
|
||||
tSelector [2] EXPLICIT OCTET STRING OPTIONAL,
|
||||
nAddresses [3] EXPLICIT SET SIZE (1..MAX) OF OCTET STRING }
|
||||
|
||||
terminal-type INTEGER ::= 23
|
||||
|
||||
TerminalType ::= INTEGER {
|
||||
telex (3),
|
||||
teletex (4),
|
||||
g3-facsimile (5),
|
||||
g4-facsimile (6),
|
||||
ia5-terminal (7),
|
||||
videotex (8) } (0..ub-integer-options)
|
||||
|
||||
-- Extension Domain-defined Attributes
|
||||
|
||||
teletex-domain-defined-attributes INTEGER ::= 6
|
||||
|
||||
TeletexDomainDefinedAttributes ::= SEQUENCE SIZE
|
||||
(1..ub-domain-defined-attributes) OF TeletexDomainDefinedAttribute
|
||||
|
||||
TeletexDomainDefinedAttribute ::= SEQUENCE {
|
||||
type TeletexString
|
||||
(SIZE (1..ub-domain-defined-attribute-type-length)),
|
||||
value TeletexString
|
||||
(SIZE (1..ub-domain-defined-attribute-value-length)) }
|
||||
|
||||
-- specifications of Upper Bounds shall be regarded as mandatory
|
||||
-- from Annex B of ITU-T X.411 Reference Definition of MTS Parameter
|
||||
-- Upper Bounds
|
||||
|
||||
-- Upper Bounds
|
||||
ub-name INTEGER ::= 32768
|
||||
ub-common-name INTEGER ::= 64
|
||||
ub-locality-name INTEGER ::= 128
|
||||
ub-state-name INTEGER ::= 128
|
||||
ub-organization-name INTEGER ::= 64
|
||||
ub-organizational-unit-name INTEGER ::= 64
|
||||
ub-title INTEGER ::= 64
|
||||
ub-match INTEGER ::= 128
|
||||
|
||||
ub-emailaddress-length INTEGER ::= 128
|
||||
|
||||
ub-common-name-length INTEGER ::= 64
|
||||
ub-country-name-alpha-length INTEGER ::= 2
|
||||
ub-country-name-numeric-length INTEGER ::= 3
|
||||
ub-domain-defined-attributes INTEGER ::= 4
|
||||
ub-domain-defined-attribute-type-length INTEGER ::= 8
|
||||
ub-domain-defined-attribute-value-length INTEGER ::= 128
|
||||
ub-domain-name-length INTEGER ::= 16
|
||||
ub-extension-attributes INTEGER ::= 256
|
||||
ub-e163-4-number-length INTEGER ::= 15
|
||||
ub-e163-4-sub-address-length INTEGER ::= 40
|
||||
ub-generation-qualifier-length INTEGER ::= 3
|
||||
ub-given-name-length INTEGER ::= 16
|
||||
ub-initials-length INTEGER ::= 5
|
||||
ub-integer-options INTEGER ::= 256
|
||||
ub-numeric-user-id-length INTEGER ::= 32
|
||||
ub-organization-name-length INTEGER ::= 64
|
||||
ub-organizational-unit-name-length INTEGER ::= 32
|
||||
ub-organizational-units INTEGER ::= 4
|
||||
ub-pds-name-length INTEGER ::= 16
|
||||
ub-pds-parameter-length INTEGER ::= 30
|
||||
ub-pds-physical-address-lines INTEGER ::= 6
|
||||
ub-postal-code-length INTEGER ::= 16
|
||||
ub-surname-length INTEGER ::= 40
|
||||
ub-terminal-id-length INTEGER ::= 24
|
||||
ub-unformatted-address-length INTEGER ::= 180
|
||||
ub-x121-address-length INTEGER ::= 16
|
||||
|
||||
-- Note - upper bounds on string types, such as TeletexString, are
|
||||
-- measured in characters. Excepting PrintableString or IA5String, a
|
||||
-- significantly greater number of octets will be required to hold
|
||||
-- such a value. As a minimum, 16 octets, or twice the specified upper
|
||||
-- bound, whichever is the larger, should be allowed for TeletexString.
|
||||
-- For UTF8String or UniversalString at least four times the upper
|
||||
-- bound should be allowed.
|
||||
|
||||
END
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
920
pkix_asn1_tab.c
Normal file
920
pkix_asn1_tab.c
Normal file
@ -0,0 +1,920 @@
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include <libtasn1.h>
|
||||
|
||||
const asn1_static_node pkix_asn1_tab[] = {
|
||||
{ "PKIX1Implicit88", 536875024, NULL },
|
||||
{ NULL, 1610612748, NULL },
|
||||
{ "iso", 1073741825, "1"},
|
||||
{ "identified-organization", 1073741825, "3"},
|
||||
{ "dod", 1073741825, "6"},
|
||||
{ "internet", 1073741825, "1"},
|
||||
{ "security", 1073741825, "5"},
|
||||
{ "mechanisms", 1073741825, "5"},
|
||||
{ "pkix", 1073741825, "7"},
|
||||
{ "id-mod", 1073741825, "0"},
|
||||
{ "id-pkix1-implicit-88", 1, "2"},
|
||||
{ "id-ce", 1879048204, NULL },
|
||||
{ "joint-iso-ccitt", 1073741825, "2"},
|
||||
{ "ds", 1073741825, "5"},
|
||||
{ NULL, 1, "29"},
|
||||
{ "id-ce-authorityKeyIdentifier", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ce"},
|
||||
{ NULL, 1, "35"},
|
||||
{ "AuthorityKeyIdentifier", 1610612741, NULL },
|
||||
{ "keyIdentifier", 1610637314, "KeyIdentifier"},
|
||||
{ NULL, 4104, "0"},
|
||||
{ "authorityCertIssuer", 1610637314, "GeneralNames"},
|
||||
{ NULL, 4104, "1"},
|
||||
{ "authorityCertSerialNumber", 536895490, "CertificateSerialNumber"},
|
||||
{ NULL, 4104, "2"},
|
||||
{ "KeyIdentifier", 1073741831, NULL },
|
||||
{ "id-ce-subjectKeyIdentifier", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ce"},
|
||||
{ NULL, 1, "14"},
|
||||
{ "SubjectKeyIdentifier", 1073741826, "KeyIdentifier"},
|
||||
{ "id-ce-keyUsage", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ce"},
|
||||
{ NULL, 1, "15"},
|
||||
{ "KeyUsage", 1610874886, NULL },
|
||||
{ "digitalSignature", 1073741825, "0"},
|
||||
{ "nonRepudiation", 1073741825, "1"},
|
||||
{ "keyEncipherment", 1073741825, "2"},
|
||||
{ "dataEncipherment", 1073741825, "3"},
|
||||
{ "keyAgreement", 1073741825, "4"},
|
||||
{ "keyCertSign", 1073741825, "5"},
|
||||
{ "cRLSign", 1073741825, "6"},
|
||||
{ "encipherOnly", 1073741825, "7"},
|
||||
{ "decipherOnly", 1, "8"},
|
||||
{ "id-ce-privateKeyUsagePeriod", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ce"},
|
||||
{ NULL, 1, "16"},
|
||||
{ "PrivateKeyUsagePeriod", 1610612741, NULL },
|
||||
{ "notBefore", 1610637349, NULL },
|
||||
{ NULL, 4104, "0"},
|
||||
{ "notAfter", 536895525, NULL },
|
||||
{ NULL, 4104, "1"},
|
||||
{ "id-ce-certificatePolicies", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ce"},
|
||||
{ NULL, 1, "32"},
|
||||
{ "CertificatePolicies", 1612709899, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 2, "PolicyInformation"},
|
||||
{ "PolicyInformation", 1610612741, NULL },
|
||||
{ "policyIdentifier", 1073741826, "CertPolicyId"},
|
||||
{ "policyQualifiers", 538984459, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 2, "PolicyQualifierInfo"},
|
||||
{ "CertPolicyId", 1073741836, NULL },
|
||||
{ "PolicyQualifierInfo", 1610612741, NULL },
|
||||
{ "policyQualifierId", 1073741826, "PolicyQualifierId"},
|
||||
{ "qualifier", 541065229, NULL },
|
||||
{ "policyQualifierId", 1, NULL },
|
||||
{ "PolicyQualifierId", 1073741836, NULL },
|
||||
{ "CPSuri", 1073741853, NULL },
|
||||
{ "UserNotice", 1610612741, NULL },
|
||||
{ "noticeRef", 1073758210, "NoticeReference"},
|
||||
{ "explicitText", 16386, "DisplayText"},
|
||||
{ "NoticeReference", 1610612741, NULL },
|
||||
{ "organization", 1073741826, "DisplayText"},
|
||||
{ "noticeNumbers", 536870923, NULL },
|
||||
{ NULL, 3, NULL },
|
||||
{ "DisplayText", 1610612754, NULL },
|
||||
{ "visibleString", 1612709923, NULL },
|
||||
{ "200", 524298, "1"},
|
||||
{ "bmpString", 1612709921, NULL },
|
||||
{ "200", 524298, "1"},
|
||||
{ "utf8String", 538968098, NULL },
|
||||
{ "200", 524298, "1"},
|
||||
{ "id-ce-policyMappings", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ce"},
|
||||
{ NULL, 1, "33"},
|
||||
{ "PolicyMappings", 1612709899, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 536870917, NULL },
|
||||
{ "issuerDomainPolicy", 1073741826, "CertPolicyId"},
|
||||
{ "subjectDomainPolicy", 2, "CertPolicyId"},
|
||||
{ "id-ce-subjectAltName", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ce"},
|
||||
{ NULL, 1, "17"},
|
||||
{ "SubjectAltName", 1073741826, "GeneralNames"},
|
||||
{ "GeneralNames", 1612709899, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 2, "GeneralName"},
|
||||
{ "GeneralName", 1610612754, NULL },
|
||||
{ "otherName", 1610620930, "AnotherName"},
|
||||
{ NULL, 4104, "0"},
|
||||
{ "rfc822Name", 1610620957, NULL },
|
||||
{ NULL, 4104, "1"},
|
||||
{ "dNSName", 1610620957, NULL },
|
||||
{ NULL, 4104, "2"},
|
||||
{ "x400Address", 1610620930, "ORAddress"},
|
||||
{ NULL, 4104, "3"},
|
||||
{ "directoryName", 1610620930, "Name"},
|
||||
{ NULL, 4104, "4"},
|
||||
{ "ediPartyName", 1610620930, "EDIPartyName"},
|
||||
{ NULL, 4104, "5"},
|
||||
{ "uniformResourceIdentifier", 1610620957, NULL },
|
||||
{ NULL, 4104, "6"},
|
||||
{ "iPAddress", 1610620935, NULL },
|
||||
{ NULL, 4104, "7"},
|
||||
{ "registeredID", 536879116, NULL },
|
||||
{ NULL, 4104, "8"},
|
||||
{ "AnotherName", 1610612741, NULL },
|
||||
{ "type-id", 1073741836, NULL },
|
||||
{ "value", 541073421, NULL },
|
||||
{ NULL, 1073743880, "0"},
|
||||
{ "type-id", 1, NULL },
|
||||
{ "EDIPartyName", 1610612741, NULL },
|
||||
{ "nameAssigner", 1610637314, "DirectoryString"},
|
||||
{ NULL, 4104, "0"},
|
||||
{ "partyName", 536879106, "DirectoryString"},
|
||||
{ NULL, 4104, "1"},
|
||||
{ "id-ce-issuerAltName", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ce"},
|
||||
{ NULL, 1, "18"},
|
||||
{ "IssuerAltName", 1073741826, "GeneralNames"},
|
||||
{ "id-ce-subjectDirectoryAttributes", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ce"},
|
||||
{ NULL, 1, "9"},
|
||||
{ "SubjectDirectoryAttributes", 1612709899, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 2, "Attribute"},
|
||||
{ "id-ce-basicConstraints", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ce"},
|
||||
{ NULL, 1, "19"},
|
||||
{ "BasicConstraints", 1610612741, NULL },
|
||||
{ "cA", 1610645508, NULL },
|
||||
{ NULL, 131081, NULL },
|
||||
{ "pathLenConstraint", 537411587, NULL },
|
||||
{ "0", 10, "MAX"},
|
||||
{ "id-ce-nameConstraints", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ce"},
|
||||
{ NULL, 1, "30"},
|
||||
{ "NameConstraints", 1610612741, NULL },
|
||||
{ "permittedSubtrees", 1610637314, "GeneralSubtrees"},
|
||||
{ NULL, 4104, "0"},
|
||||
{ "excludedSubtrees", 536895490, "GeneralSubtrees"},
|
||||
{ NULL, 4104, "1"},
|
||||
{ "GeneralSubtrees", 1612709899, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 2, "GeneralSubtree"},
|
||||
{ "GeneralSubtree", 1610612741, NULL },
|
||||
{ "base", 1073741826, "GeneralName"},
|
||||
{ "minimum", 1610653698, "BaseDistance"},
|
||||
{ NULL, 1073741833, "0"},
|
||||
{ NULL, 4104, "0"},
|
||||
{ "maximum", 536895490, "BaseDistance"},
|
||||
{ NULL, 4104, "1"},
|
||||
{ "BaseDistance", 1611137027, NULL },
|
||||
{ "0", 10, "MAX"},
|
||||
{ "id-ce-policyConstraints", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ce"},
|
||||
{ NULL, 1, "36"},
|
||||
{ "PolicyConstraints", 1610612741, NULL },
|
||||
{ "requireExplicitPolicy", 1610637314, "SkipCerts"},
|
||||
{ NULL, 4104, "0"},
|
||||
{ "inhibitPolicyMapping", 536895490, "SkipCerts"},
|
||||
{ NULL, 4104, "1"},
|
||||
{ "SkipCerts", 1611137027, NULL },
|
||||
{ "0", 10, "MAX"},
|
||||
{ "id-ce-cRLDistributionPoints", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ce"},
|
||||
{ NULL, 1, "31"},
|
||||
{ "CRLDistPointsSyntax", 1612709899, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 2, "DistributionPoint"},
|
||||
{ "DistributionPoint", 1610612741, NULL },
|
||||
{ "distributionPoint", 1610637314, "DistributionPointName"},
|
||||
{ NULL, 4104, "0"},
|
||||
{ "reasons", 1610637314, "ReasonFlags"},
|
||||
{ NULL, 4104, "1"},
|
||||
{ "cRLIssuer", 536895490, "GeneralNames"},
|
||||
{ NULL, 4104, "2"},
|
||||
{ "DistributionPointName", 1610612741, NULL },
|
||||
{ "fullName", 1610637314, "GeneralNames"},
|
||||
{ NULL, 4104, "0"},
|
||||
{ "nameRelativeToCRLIssuer", 536895490, "RelativeDistinguishedName"},
|
||||
{ NULL, 4104, "1"},
|
||||
{ "ReasonFlags", 1610874886, NULL },
|
||||
{ "unused", 1073741825, "0"},
|
||||
{ "keyCompromise", 1073741825, "1"},
|
||||
{ "cACompromise", 1073741825, "2"},
|
||||
{ "affiliationChanged", 1073741825, "3"},
|
||||
{ "superseded", 1073741825, "4"},
|
||||
{ "cessationOfOperation", 1073741825, "5"},
|
||||
{ "certificateHold", 1, "6"},
|
||||
{ "id-ce-extKeyUsage", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ce"},
|
||||
{ NULL, 1, "37"},
|
||||
{ "ExtKeyUsageSyntax", 1612709899, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 2, "KeyPurposeId"},
|
||||
{ "KeyPurposeId", 1073741836, NULL },
|
||||
{ "id-kp-serverAuth", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-kp"},
|
||||
{ NULL, 1, "1"},
|
||||
{ "id-kp-clientAuth", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-kp"},
|
||||
{ NULL, 1, "2"},
|
||||
{ "id-kp-codeSigning", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-kp"},
|
||||
{ NULL, 1, "3"},
|
||||
{ "id-kp-emailProtection", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-kp"},
|
||||
{ NULL, 1, "4"},
|
||||
{ "id-kp-ipsecEndSystem", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-kp"},
|
||||
{ NULL, 1, "5"},
|
||||
{ "id-kp-ipsecTunnel", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-kp"},
|
||||
{ NULL, 1, "6"},
|
||||
{ "id-kp-ipsecUser", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-kp"},
|
||||
{ NULL, 1, "7"},
|
||||
{ "id-kp-timeStamping", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-kp"},
|
||||
{ NULL, 1, "8"},
|
||||
{ "id-pe-authorityInfoAccess", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-pe"},
|
||||
{ NULL, 1, "1"},
|
||||
{ "AuthorityInfoAccessSyntax", 1612709899, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 2, "AccessDescription"},
|
||||
{ "AccessDescription", 1610612741, NULL },
|
||||
{ "accessMethod", 1073741836, NULL },
|
||||
{ "accessLocation", 2, "GeneralName"},
|
||||
{ "id-ce-cRLNumber", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ce"},
|
||||
{ NULL, 1, "20"},
|
||||
{ "CRLNumber", 1611137027, NULL },
|
||||
{ "0", 10, "MAX"},
|
||||
{ "id-ce-issuingDistributionPoint", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ce"},
|
||||
{ NULL, 1, "28"},
|
||||
{ "IssuingDistributionPoint", 1610612741, NULL },
|
||||
{ "distributionPoint", 1610637314, "DistributionPointName"},
|
||||
{ NULL, 4104, "0"},
|
||||
{ "onlyContainsUserCerts", 1610653700, NULL },
|
||||
{ NULL, 1073872905, NULL },
|
||||
{ NULL, 4104, "1"},
|
||||
{ "onlyContainsCACerts", 1610653700, NULL },
|
||||
{ NULL, 1073872905, NULL },
|
||||
{ NULL, 4104, "2"},
|
||||
{ "onlySomeReasons", 1610637314, "ReasonFlags"},
|
||||
{ NULL, 4104, "3"},
|
||||
{ "indirectCRL", 536911876, NULL },
|
||||
{ NULL, 1073872905, NULL },
|
||||
{ NULL, 4104, "4"},
|
||||
{ "id-ce-deltaCRLIndicator", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ce"},
|
||||
{ NULL, 1, "27"},
|
||||
{ "BaseCRLNumber", 1073741826, "CRLNumber"},
|
||||
{ "id-ce-cRLReasons", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ce"},
|
||||
{ NULL, 1, "21"},
|
||||
{ "CRLReason", 1610874901, NULL },
|
||||
{ "unspecified", 1073741825, "0"},
|
||||
{ "keyCompromise", 1073741825, "1"},
|
||||
{ "cACompromise", 1073741825, "2"},
|
||||
{ "affiliationChanged", 1073741825, "3"},
|
||||
{ "superseded", 1073741825, "4"},
|
||||
{ "cessationOfOperation", 1073741825, "5"},
|
||||
{ "certificateHold", 1073741825, "6"},
|
||||
{ "removeFromCRL", 1, "8"},
|
||||
{ "id-ce-certificateIssuer", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ce"},
|
||||
{ NULL, 1, "29"},
|
||||
{ "CertificateIssuer", 1073741826, "GeneralNames"},
|
||||
{ "id-ce-holdInstructionCode", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ce"},
|
||||
{ NULL, 1, "23"},
|
||||
{ "HoldInstructionCode", 1073741836, NULL },
|
||||
{ "holdInstruction", 1879048204, NULL },
|
||||
{ "joint-iso-itu-t", 1073741825, "2"},
|
||||
{ "member-body", 1073741825, "2"},
|
||||
{ "us", 1073741825, "840"},
|
||||
{ "x9cm", 1073741825, "10040"},
|
||||
{ NULL, 1, "2"},
|
||||
{ "id-holdinstruction-none", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "holdInstruction"},
|
||||
{ NULL, 1, "1"},
|
||||
{ "id-holdinstruction-callissuer", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "holdInstruction"},
|
||||
{ NULL, 1, "2"},
|
||||
{ "id-holdinstruction-reject", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "holdInstruction"},
|
||||
{ NULL, 1, "3"},
|
||||
{ "id-ce-invalidityDate", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ce"},
|
||||
{ NULL, 1, "24"},
|
||||
{ "InvalidityDate", 1073741861, NULL },
|
||||
{ "id-netscape", 1879048204, NULL },
|
||||
{ "joint-iso-itu-t", 1073741825, "2"},
|
||||
{ "country", 1073741825, "16"},
|
||||
{ "us", 1073741825, "840"},
|
||||
{ "organization", 1073741825, "1"},
|
||||
{ "netscape", 1, "113730"},
|
||||
{ "id-netscape-certExtension", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-netscape"},
|
||||
{ NULL, 1, "1"},
|
||||
{ "id-netscape-certType", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-netscape-certExtension"},
|
||||
{ NULL, 1, "1"},
|
||||
{ "CertType", 1610874886, NULL },
|
||||
{ "sslClient", 1073741825, "0"},
|
||||
{ "sslServer", 1073741825, "1"},
|
||||
{ "smime", 1073741825, "2"},
|
||||
{ "objectSigning", 1073741825, "3"},
|
||||
{ "reserved", 1073741825, "4"},
|
||||
{ "sslCA", 1073741825, "5"},
|
||||
{ "smimeCA", 1073741825, "6"},
|
||||
{ "objectSigningCA", 1, "7"},
|
||||
{ "VisibleString", 1610620935, NULL },
|
||||
{ NULL, 4360, "26"},
|
||||
{ "NumericString", 1610620935, NULL },
|
||||
{ NULL, 4360, "18"},
|
||||
{ "IA5String", 1610620935, NULL },
|
||||
{ NULL, 4360, "22"},
|
||||
{ "TeletexString", 1610620935, NULL },
|
||||
{ NULL, 4360, "20"},
|
||||
{ "PrintableString", 1610620935, NULL },
|
||||
{ NULL, 4360, "19"},
|
||||
{ "UniversalString", 1610620935, NULL },
|
||||
{ NULL, 4360, "28"},
|
||||
{ "BMPString", 1610620935, NULL },
|
||||
{ NULL, 4360, "30"},
|
||||
{ "UTF8String", 1610620935, NULL },
|
||||
{ NULL, 4360, "12"},
|
||||
{ "id-pkix", 1879048204, NULL },
|
||||
{ "iso", 1073741825, "1"},
|
||||
{ "identified-organization", 1073741825, "3"},
|
||||
{ "dod", 1073741825, "6"},
|
||||
{ "internet", 1073741825, "1"},
|
||||
{ "security", 1073741825, "5"},
|
||||
{ "mechanisms", 1073741825, "5"},
|
||||
{ "pkix", 1, "7"},
|
||||
{ "id-pe", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-pkix"},
|
||||
{ NULL, 1, "1"},
|
||||
{ "id-qt", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-pkix"},
|
||||
{ NULL, 1, "2"},
|
||||
{ "id-kp", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-pkix"},
|
||||
{ NULL, 1, "3"},
|
||||
{ "id-ad", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-pkix"},
|
||||
{ NULL, 1, "48"},
|
||||
{ "id-qt-cps", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-qt"},
|
||||
{ NULL, 1, "1"},
|
||||
{ "id-qt-unotice", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-qt"},
|
||||
{ NULL, 1, "2"},
|
||||
{ "id-ad-ocsp", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ad"},
|
||||
{ NULL, 1, "1"},
|
||||
{ "id-ad-caIssuers", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "id-ad"},
|
||||
{ NULL, 1, "2"},
|
||||
{ "Attribute", 1610612741, NULL },
|
||||
{ "type", 1073741826, "AttributeType"},
|
||||
{ "values", 536870927, NULL },
|
||||
{ NULL, 2, "AttributeValue"},
|
||||
{ "AttributeType", 1073741836, NULL },
|
||||
{ "AttributeValue", 1073741837, NULL },
|
||||
{ "AttributeTypeAndValue", 1610612741, NULL },
|
||||
{ "type", 1073741826, "AttributeType"},
|
||||
{ "value", 2, "AttributeValue"},
|
||||
{ "id-at", 1879048204, NULL },
|
||||
{ "joint-iso-ccitt", 1073741825, "2"},
|
||||
{ "ds", 1073741825, "5"},
|
||||
{ NULL, 1, "4"},
|
||||
{ "id-at-name", 1880096780, "AttributeType"},
|
||||
{ NULL, 1073741825, "id-at"},
|
||||
{ NULL, 1, "41"},
|
||||
{ "id-at-surname", 1880096780, "AttributeType"},
|
||||
{ NULL, 1073741825, "id-at"},
|
||||
{ NULL, 1, "4"},
|
||||
{ "id-at-givenName", 1880096780, "AttributeType"},
|
||||
{ NULL, 1073741825, "id-at"},
|
||||
{ NULL, 1, "42"},
|
||||
{ "id-at-initials", 1880096780, "AttributeType"},
|
||||
{ NULL, 1073741825, "id-at"},
|
||||
{ NULL, 1, "43"},
|
||||
{ "id-at-generationQualifier", 1880096780, "AttributeType"},
|
||||
{ NULL, 1073741825, "id-at"},
|
||||
{ NULL, 1, "44"},
|
||||
{ "X520name", 1610612754, NULL },
|
||||
{ "teletexString", 1612709918, NULL },
|
||||
{ "ub-name", 524298, "1"},
|
||||
{ "printableString", 1612709919, NULL },
|
||||
{ "ub-name", 524298, "1"},
|
||||
{ "universalString", 1612709920, NULL },
|
||||
{ "ub-name", 524298, "1"},
|
||||
{ "utf8String", 1612709922, NULL },
|
||||
{ "ub-name", 524298, "1"},
|
||||
{ "bmpString", 538968097, NULL },
|
||||
{ "ub-name", 524298, "1"},
|
||||
{ "id-at-commonName", 1880096780, "AttributeType"},
|
||||
{ NULL, 1073741825, "id-at"},
|
||||
{ NULL, 1, "3"},
|
||||
{ "X520CommonName", 1610612754, NULL },
|
||||
{ "teletexString", 1612709918, NULL },
|
||||
{ "ub-common-name", 524298, "1"},
|
||||
{ "printableString", 1612709919, NULL },
|
||||
{ "ub-common-name", 524298, "1"},
|
||||
{ "universalString", 1612709920, NULL },
|
||||
{ "ub-common-name", 524298, "1"},
|
||||
{ "utf8String", 1612709922, NULL },
|
||||
{ "ub-common-name", 524298, "1"},
|
||||
{ "bmpString", 538968097, NULL },
|
||||
{ "ub-common-name", 524298, "1"},
|
||||
{ "id-at-localityName", 1880096780, "AttributeType"},
|
||||
{ NULL, 1073741825, "id-at"},
|
||||
{ NULL, 1, "7"},
|
||||
{ "X520LocalityName", 1610612754, NULL },
|
||||
{ "teletexString", 1612709918, NULL },
|
||||
{ "ub-locality-name", 524298, "1"},
|
||||
{ "printableString", 1612709919, NULL },
|
||||
{ "ub-locality-name", 524298, "1"},
|
||||
{ "universalString", 1612709920, NULL },
|
||||
{ "ub-locality-name", 524298, "1"},
|
||||
{ "utf8String", 1612709922, NULL },
|
||||
{ "ub-locality-name", 524298, "1"},
|
||||
{ "bmpString", 538968097, NULL },
|
||||
{ "ub-locality-name", 524298, "1"},
|
||||
{ "id-at-stateOrProvinceName", 1880096780, "AttributeType"},
|
||||
{ NULL, 1073741825, "id-at"},
|
||||
{ NULL, 1, "8"},
|
||||
{ "X520StateOrProvinceName", 1610612754, NULL },
|
||||
{ "teletexString", 1612709918, NULL },
|
||||
{ "ub-state-name", 524298, "1"},
|
||||
{ "printableString", 1612709919, NULL },
|
||||
{ "ub-state-name", 524298, "1"},
|
||||
{ "universalString", 1612709920, NULL },
|
||||
{ "ub-state-name", 524298, "1"},
|
||||
{ "utf8String", 1612709922, NULL },
|
||||
{ "ub-state-name", 524298, "1"},
|
||||
{ "bmpString", 538968097, NULL },
|
||||
{ "ub-state-name", 524298, "1"},
|
||||
{ "id-at-organizationName", 1880096780, "AttributeType"},
|
||||
{ NULL, 1073741825, "id-at"},
|
||||
{ NULL, 1, "10"},
|
||||
{ "X520OrganizationName", 1610612754, NULL },
|
||||
{ "teletexString", 1612709918, NULL },
|
||||
{ "ub-organization-name", 524298, "1"},
|
||||
{ "printableString", 1612709919, NULL },
|
||||
{ "ub-organization-name", 524298, "1"},
|
||||
{ "universalString", 1612709920, NULL },
|
||||
{ "ub-organization-name", 524298, "1"},
|
||||
{ "utf8String", 1612709922, NULL },
|
||||
{ "ub-organization-name", 524298, "1"},
|
||||
{ "bmpString", 538968097, NULL },
|
||||
{ "ub-organization-name", 524298, "1"},
|
||||
{ "id-at-organizationalUnitName", 1880096780, "AttributeType"},
|
||||
{ NULL, 1073741825, "id-at"},
|
||||
{ NULL, 1, "11"},
|
||||
{ "X520OrganizationalUnitName", 1610612754, NULL },
|
||||
{ "teletexString", 1612709918, NULL },
|
||||
{ "ub-organizational-unit-name", 524298, "1"},
|
||||
{ "printableString", 1612709919, NULL },
|
||||
{ "ub-organizational-unit-name", 524298, "1"},
|
||||
{ "universalString", 1612709920, NULL },
|
||||
{ "ub-organizational-unit-name", 524298, "1"},
|
||||
{ "utf8String", 1612709922, NULL },
|
||||
{ "ub-organizational-unit-name", 524298, "1"},
|
||||
{ "bmpString", 538968097, NULL },
|
||||
{ "ub-organizational-unit-name", 524298, "1"},
|
||||
{ "id-at-title", 1880096780, "AttributeType"},
|
||||
{ NULL, 1073741825, "id-at"},
|
||||
{ NULL, 1, "12"},
|
||||
{ "X520Title", 1610612754, NULL },
|
||||
{ "teletexString", 1612709918, NULL },
|
||||
{ "ub-title", 524298, "1"},
|
||||
{ "printableString", 1612709919, NULL },
|
||||
{ "ub-title", 524298, "1"},
|
||||
{ "universalString", 1612709920, NULL },
|
||||
{ "ub-title", 524298, "1"},
|
||||
{ "utf8String", 1612709922, NULL },
|
||||
{ "ub-title", 524298, "1"},
|
||||
{ "bmpString", 538968097, NULL },
|
||||
{ "ub-title", 524298, "1"},
|
||||
{ "id-at-dnQualifier", 1880096780, "AttributeType"},
|
||||
{ NULL, 1073741825, "id-at"},
|
||||
{ NULL, 1, "46"},
|
||||
{ "X520dnQualifier", 1073741855, NULL },
|
||||
{ "id-at-countryName", 1880096780, "AttributeType"},
|
||||
{ NULL, 1073741825, "id-at"},
|
||||
{ NULL, 1, "6"},
|
||||
{ "X520countryName", 1612709919, NULL },
|
||||
{ NULL, 1048586, "2"},
|
||||
{ "pkcs-9", 1879048204, NULL },
|
||||
{ "iso", 1073741825, "1"},
|
||||
{ "member-body", 1073741825, "2"},
|
||||
{ "us", 1073741825, "840"},
|
||||
{ "rsadsi", 1073741825, "113549"},
|
||||
{ "pkcs", 1073741825, "1"},
|
||||
{ NULL, 1, "9"},
|
||||
{ "emailAddress", 1880096780, "AttributeType"},
|
||||
{ NULL, 1073741825, "pkcs-9"},
|
||||
{ NULL, 1, "1"},
|
||||
{ "Pkcs9email", 1612709917, NULL },
|
||||
{ "ub-emailaddress-length", 524298, "1"},
|
||||
{ "Name", 1610612754, NULL },
|
||||
{ "rdnSequence", 2, "RDNSequence"},
|
||||
{ "RDNSequence", 1610612747, NULL },
|
||||
{ NULL, 2, "RelativeDistinguishedName"},
|
||||
{ "DistinguishedName", 1073741826, "RDNSequence"},
|
||||
{ "RelativeDistinguishedName", 1612709903, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 2, "AttributeTypeAndValue"},
|
||||
{ "DirectoryString", 1610612754, NULL },
|
||||
{ "teletexString", 1612709918, NULL },
|
||||
{ "MAX", 524298, "1"},
|
||||
{ "printableString", 1612709919, NULL },
|
||||
{ "MAX", 524298, "1"},
|
||||
{ "universalString", 1612709920, NULL },
|
||||
{ "MAX", 524298, "1"},
|
||||
{ "utf8String", 1612709922, NULL },
|
||||
{ "MAX", 524298, "1"},
|
||||
{ "bmpString", 538968097, NULL },
|
||||
{ "MAX", 524298, "1"},
|
||||
{ "Certificate", 1610612741, NULL },
|
||||
{ "tbsCertificate", 1073741826, "TBSCertificate"},
|
||||
{ "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "signature", 6, NULL },
|
||||
{ "TBSCertificate", 1610612741, NULL },
|
||||
{ "version", 1610653698, "Version"},
|
||||
{ NULL, 1073741833, "v1"},
|
||||
{ NULL, 2056, "0"},
|
||||
{ "serialNumber", 1073741826, "CertificateSerialNumber"},
|
||||
{ "signature", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "issuer", 1073741826, "Name"},
|
||||
{ "validity", 1073741826, "Validity"},
|
||||
{ "subject", 1073741826, "Name"},
|
||||
{ "subjectPublicKeyInfo", 1073741826, "SubjectPublicKeyInfo"},
|
||||
{ "issuerUniqueID", 1610637314, "UniqueIdentifier"},
|
||||
{ NULL, 4104, "1"},
|
||||
{ "subjectUniqueID", 1610637314, "UniqueIdentifier"},
|
||||
{ NULL, 4104, "2"},
|
||||
{ "extensions", 536895490, "Extensions"},
|
||||
{ NULL, 2056, "3"},
|
||||
{ "Version", 1610874883, NULL },
|
||||
{ "v1", 1073741825, "0"},
|
||||
{ "v2", 1073741825, "1"},
|
||||
{ "v3", 1, "2"},
|
||||
{ "CertificateSerialNumber", 1073741827, NULL },
|
||||
{ "Validity", 1610612741, NULL },
|
||||
{ "notBefore", 1073741826, "Time"},
|
||||
{ "notAfter", 2, "Time"},
|
||||
{ "Time", 1610612754, NULL },
|
||||
{ "utcTime", 1073741860, NULL },
|
||||
{ "generalTime", 37, NULL },
|
||||
{ "UniqueIdentifier", 1073741830, NULL },
|
||||
{ "SubjectPublicKeyInfo", 1610612741, NULL },
|
||||
{ "algorithm", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "subjectPublicKey", 6, NULL },
|
||||
{ "Extensions", 1612709899, NULL },
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 2, "Extension"},
|
||||
{ "Extension", 1610612741, NULL },
|
||||
{ "extnID", 1073741836, NULL },
|
||||
{ "critical", 1610645508, NULL },
|
||||
{ NULL, 131081, NULL },
|
||||
{ "extnValue", 7, NULL },
|
||||
{ "CertificateList", 1610612741, NULL },
|
||||
{ "tbsCertList", 1073741826, "TBSCertList"},
|
||||
{ "signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "signature", 6, NULL },
|
||||
{ "TBSCertList", 1610612741, NULL },
|
||||
{ "version", 1073758210, "Version"},
|
||||
{ "signature", 1073741826, "AlgorithmIdentifier"},
|
||||
{ "issuer", 1073741826, "Name"},
|
||||
{ "thisUpdate", 1073741826, "Time"},
|
||||
{ "nextUpdate", 1073758210, "Time"},
|
||||
{ "revokedCertificates", 1610629131, NULL },
|
||||
{ NULL, 536870917, NULL },
|
||||
{ "userCertificate", 1073741826, "CertificateSerialNumber"},
|
||||
{ "revocationDate", 1073741826, "Time"},
|
||||
{ "crlEntryExtensions", 16386, "Extensions"},
|
||||
{ "crlExtensions", 536895490, "Extensions"},
|
||||
{ NULL, 2056, "0"},
|
||||
{ "AlgorithmIdentifier", 1610612741, NULL },
|
||||
{ "algorithm", 1073741836, NULL },
|
||||
{ "parameters", 541081613, NULL },
|
||||
{ "algorithm", 1, NULL },
|
||||
{ "pkcs-1", 1879048204, NULL },
|
||||
{ "iso", 1073741825, "1"},
|
||||
{ "member-body", 1073741825, "2"},
|
||||
{ "us", 1073741825, "840"},
|
||||
{ "rsadsi", 1073741825, "113549"},
|
||||
{ "pkcs", 1073741825, "1"},
|
||||
{ NULL, 1, "1"},
|
||||
{ "rsaEncryption", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "pkcs-1"},
|
||||
{ NULL, 1, "1"},
|
||||
{ "md2WithRSAEncryption", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "pkcs-1"},
|
||||
{ NULL, 1, "2"},
|
||||
{ "md5WithRSAEncryption", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "pkcs-1"},
|
||||
{ NULL, 1, "4"},
|
||||
{ "sha1WithRSAEncryption", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "pkcs-1"},
|
||||
{ NULL, 1, "5"},
|
||||
{ "sha256WithRSAEncryption", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "pkcs-1"},
|
||||
{ NULL, 1, "11"},
|
||||
{ "sha384WithRSAEncryption", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "pkcs-1"},
|
||||
{ NULL, 1, "12"},
|
||||
{ "sha512WithRSAEncryption", 1879048204, NULL },
|
||||
{ NULL, 1073741825, "pkcs-1"},
|
||||
{ NULL, 1, "13"},
|
||||
{ "RSAPublicKey", 1610612741, NULL },
|
||||
{ "modulus", 1073741827, NULL },
|
||||
{ "publicExponent", 3, NULL },
|
||||
{ "RSAPrivateKey", 1610612741, NULL },
|
||||
{ "version", 1073741826, "Version"},
|
||||
{ "modulus", 1073741827, NULL },
|
||||
{ "publicExponent", 1073741827, NULL },
|
||||
{ "privateExponent", 1073741827, NULL },
|
||||
{ "prime1", 1073741827, NULL },
|
||||
{ "prime2", 1073741827, NULL },
|
||||
{ "exponent1", 1073741827, NULL },
|
||||
{ "exponent2", 1073741827, NULL },
|
||||
{ "coefficient", 3, NULL },
|
||||
{ "id-dsa-with-sha1", 1879048204, NULL },
|
||||
{ "iso", 1073741825, "1"},
|
||||
{ "member-body", 1073741825, "2"},
|
||||
{ "us", 1073741825, "840"},
|
||||
{ "x9-57", 1073741825, "10040"},
|
||||
{ "x9algorithm", 1073741825, "4"},
|
||||
{ NULL, 1, "3"},
|
||||
{ "Dss-Sig-Value", 1610612741, NULL },
|
||||
{ "r", 1073741827, NULL },
|
||||
{ "s", 3, NULL },
|
||||
{ "dhpublicnumber", 1879048204, NULL },
|
||||
{ "iso", 1073741825, "1"},
|
||||
{ "member-body", 1073741825, "2"},
|
||||
{ "us", 1073741825, "840"},
|
||||
{ "ansi-x942", 1073741825, "10046"},
|
||||
{ "number-type", 1073741825, "2"},
|
||||
{ NULL, 1, "1"},
|
||||
{ "DomainParameters", 1610612741, NULL },
|
||||
{ "p", 1073741827, NULL },
|
||||
{ "g", 1073741827, NULL },
|
||||
{ "q", 1073741827, NULL },
|
||||
{ "j", 1073758211, NULL },
|
||||
{ "validationParms", 16386, "ValidationParms"},
|
||||
{ "ValidationParms", 1610612741, NULL },
|
||||
{ "seed", 1073741830, NULL },
|
||||
{ "pgenCounter", 3, NULL },
|
||||
{ "id-dsa", 1879048204, NULL },
|
||||
{ "iso", 1073741825, "1"},
|
||||
{ "member-body", 1073741825, "2"},
|
||||
{ "us", 1073741825, "840"},
|
||||
{ "x9-57", 1073741825, "10040"},
|
||||
{ "x9algorithm", 1073741825, "4"},
|
||||
{ NULL, 1, "1"},
|
||||
{ "Dss-Parms", 1610612741, NULL },
|
||||
{ "p", 1073741827, NULL },
|
||||
{ "q", 1073741827, NULL },
|
||||
{ "g", 3, NULL },
|
||||
{ "ORAddress", 1610612741, NULL },
|
||||
{ "built-in-standard-attributes", 1073741826, "BuiltInStandardAttributes"},
|
||||
{ "built-in-domain-defined-attributes", 1073758210, "BuiltInDomainDefinedAttributes"},
|
||||
{ "extension-attributes", 16386, "ExtensionAttributes"},
|
||||
{ "BuiltInStandardAttributes", 1610612741, NULL },
|
||||
{ "country-name", 1073758210, "CountryName"},
|
||||
{ "administration-domain-name", 1073758210, "AdministrationDomainName"},
|
||||
{ "network-address", 1610637314, "NetworkAddress"},
|
||||
{ NULL, 2056, "0"},
|
||||
{ "terminal-identifier", 1610637314, "TerminalIdentifier"},
|
||||
{ NULL, 2056, "1"},
|
||||
{ "private-domain-name", 1610637314, "PrivateDomainName"},
|
||||
{ NULL, 2056, "2"},
|
||||
{ "organization-name", 1610637314, "OrganizationName"},
|
||||
{ NULL, 2056, "3"},
|
||||
{ "numeric-user-identifier", 1610637314, "NumericUserIdentifier"},
|
||||
{ NULL, 2056, "4"},
|
||||
{ "personal-name", 1610637314, "PersonalName"},
|
||||
{ NULL, 2056, "5"},
|
||||
{ "organizational-unit-names", 536895490, "OrganizationalUnitNames"},
|
||||
{ NULL, 2056, "6"},
|
||||
{ "CountryName", 1610620946, NULL },
|
||||
{ NULL, 1073746952, "1"},
|
||||
{ "x121-dcc-code", 1612709916, NULL },
|
||||
{ NULL, 1048586, "ub-country-name-numeric-length"},
|
||||
{ "iso-3166-alpha2-code", 538968095, NULL },
|
||||
{ NULL, 1048586, "ub-country-name-alpha-length"},
|
||||
{ "AdministrationDomainName", 1610620946, NULL },
|
||||
{ NULL, 1073744904, "2"},
|
||||
{ "numeric", 1612709916, NULL },
|
||||
{ "ub-domain-name-length", 524298, "0"},
|
||||
{ "printable", 538968095, NULL },
|
||||
{ "ub-domain-name-length", 524298, "0"},
|
||||
{ "NetworkAddress", 1073741826, "X121Address"},
|
||||
{ "X121Address", 1612709916, NULL },
|
||||
{ "ub-x121-address-length", 524298, "1"},
|
||||
{ "TerminalIdentifier", 1612709919, NULL },
|
||||
{ "ub-terminal-id-length", 524298, "1"},
|
||||
{ "PrivateDomainName", 1610612754, NULL },
|
||||
{ "numeric", 1612709916, NULL },
|
||||
{ "ub-domain-name-length", 524298, "1"},
|
||||
{ "printable", 538968095, NULL },
|
||||
{ "ub-domain-name-length", 524298, "1"},
|
||||
{ "OrganizationName", 1612709919, NULL },
|
||||
{ "ub-organization-name-length", 524298, "1"},
|
||||
{ "NumericUserIdentifier", 1612709916, NULL },
|
||||
{ "ub-numeric-user-id-length", 524298, "1"},
|
||||
{ "PersonalName", 1610612750, NULL },
|
||||
{ "surname", 1814044703, NULL },
|
||||
{ NULL, 1073745928, "0"},
|
||||
{ "ub-surname-length", 524298, "1"},
|
||||
{ "given-name", 1814061087, NULL },
|
||||
{ NULL, 1073745928, "1"},
|
||||
{ "ub-given-name-length", 524298, "1"},
|
||||
{ "initials", 1814061087, NULL },
|
||||
{ NULL, 1073745928, "2"},
|
||||
{ "ub-initials-length", 524298, "1"},
|
||||
{ "generation-qualifier", 740319263, NULL },
|
||||
{ NULL, 1073745928, "3"},
|
||||
{ "ub-generation-qualifier-length", 524298, "1"},
|
||||
{ "OrganizationalUnitNames", 1612709899, NULL },
|
||||
{ "ub-organizational-units", 1074266122, "1"},
|
||||
{ NULL, 2, "OrganizationalUnitName"},
|
||||
{ "OrganizationalUnitName", 1612709919, NULL },
|
||||
{ "ub-organizational-unit-name-length", 524298, "1"},
|
||||
{ "BuiltInDomainDefinedAttributes", 1612709899, NULL },
|
||||
{ "ub-domain-defined-attributes", 1074266122, "1"},
|
||||
{ NULL, 2, "BuiltInDomainDefinedAttribute"},
|
||||
{ "BuiltInDomainDefinedAttribute", 1610612741, NULL },
|
||||
{ "type", 1612709919, NULL },
|
||||
{ "ub-domain-defined-attribute-type-length", 524298, "1"},
|
||||
{ "value", 538968095, NULL },
|
||||
{ "ub-domain-defined-attribute-value-length", 524298, "1"},
|
||||
{ "ExtensionAttributes", 1612709903, NULL },
|
||||
{ "ub-extension-attributes", 1074266122, "1"},
|
||||
{ NULL, 2, "ExtensionAttribute"},
|
||||
{ "ExtensionAttribute", 1610612741, NULL },
|
||||
{ "extension-attribute-type", 1611145219, NULL },
|
||||
{ NULL, 1073743880, "0"},
|
||||
{ "0", 10, "ub-extension-attributes"},
|
||||
{ "extension-attribute-value", 541073421, NULL },
|
||||
{ NULL, 1073743880, "1"},
|
||||
{ "extension-attribute-type", 1, NULL },
|
||||
{ "common-name", 1342177283, "1"},
|
||||
{ "CommonName", 1612709919, NULL },
|
||||
{ "ub-common-name-length", 524298, "1"},
|
||||
{ "teletex-common-name", 1342177283, "2"},
|
||||
{ "TeletexCommonName", 1612709918, NULL },
|
||||
{ "ub-common-name-length", 524298, "1"},
|
||||
{ "teletex-organization-name", 1342177283, "3"},
|
||||
{ "TeletexOrganizationName", 1612709918, NULL },
|
||||
{ "ub-organization-name-length", 524298, "1"},
|
||||
{ "teletex-personal-name", 1342177283, "4"},
|
||||
{ "TeletexPersonalName", 1610612750, NULL },
|
||||
{ "surname", 1814044702, NULL },
|
||||
{ NULL, 1073743880, "0"},
|
||||
{ "ub-surname-length", 524298, "1"},
|
||||
{ "given-name", 1814061086, NULL },
|
||||
{ NULL, 1073743880, "1"},
|
||||
{ "ub-given-name-length", 524298, "1"},
|
||||
{ "initials", 1814061086, NULL },
|
||||
{ NULL, 1073743880, "2"},
|
||||
{ "ub-initials-length", 524298, "1"},
|
||||
{ "generation-qualifier", 740319262, NULL },
|
||||
{ NULL, 1073743880, "3"},
|
||||
{ "ub-generation-qualifier-length", 524298, "1"},
|
||||
{ "teletex-organizational-unit-names", 1342177283, "5"},
|
||||
{ "TeletexOrganizationalUnitNames", 1612709899, NULL },
|
||||
{ "ub-organizational-units", 1074266122, "1"},
|
||||
{ NULL, 2, "TeletexOrganizationalUnitName"},
|
||||
{ "TeletexOrganizationalUnitName", 1612709918, NULL },
|
||||
{ "ub-organizational-unit-name-length", 524298, "1"},
|
||||
{ "pds-name", 1342177283, "7"},
|
||||
{ "PDSName", 1612709919, NULL },
|
||||
{ "ub-pds-name-length", 524298, "1"},
|
||||
{ "physical-delivery-country-name", 1342177283, "8"},
|
||||
{ "PhysicalDeliveryCountryName", 1610612754, NULL },
|
||||
{ "x121-dcc-code", 1612709916, NULL },
|
||||
{ NULL, 1048586, "ub-country-name-numeric-length"},
|
||||
{ "iso-3166-alpha2-code", 538968095, NULL },
|
||||
{ NULL, 1048586, "ub-country-name-alpha-length"},
|
||||
{ "postal-code", 1342177283, "9"},
|
||||
{ "PostalCode", 1610612754, NULL },
|
||||
{ "numeric-code", 1612709916, NULL },
|
||||
{ "ub-postal-code-length", 524298, "1"},
|
||||
{ "printable-code", 538968095, NULL },
|
||||
{ "ub-postal-code-length", 524298, "1"},
|
||||
{ "physical-delivery-office-name", 1342177283, "10"},
|
||||
{ "PhysicalDeliveryOfficeName", 1073741826, "PDSParameter"},
|
||||
{ "physical-delivery-office-number", 1342177283, "11"},
|
||||
{ "PhysicalDeliveryOfficeNumber", 1073741826, "PDSParameter"},
|
||||
{ "extension-OR-address-components", 1342177283, "12"},
|
||||
{ "ExtensionORAddressComponents", 1073741826, "PDSParameter"},
|
||||
{ "physical-delivery-personal-name", 1342177283, "13"},
|
||||
{ "PhysicalDeliveryPersonalName", 1073741826, "PDSParameter"},
|
||||
{ "physical-delivery-organization-name", 1342177283, "14"},
|
||||
{ "PhysicalDeliveryOrganizationName", 1073741826, "PDSParameter"},
|
||||
{ "extension-physical-delivery-address-components", 1342177283, "15"},
|
||||
{ "ExtensionPhysicalDeliveryAddressComponents", 1073741826, "PDSParameter"},
|
||||
{ "unformatted-postal-address", 1342177283, "16"},
|
||||
{ "UnformattedPostalAddress", 1610612750, NULL },
|
||||
{ "printable-address", 1814052875, NULL },
|
||||
{ "ub-pds-physical-address-lines", 1074266122, "1"},
|
||||
{ NULL, 538968095, NULL },
|
||||
{ "ub-pds-parameter-length", 524298, "1"},
|
||||
{ "teletex-string", 740311070, NULL },
|
||||
{ "ub-unformatted-address-length", 524298, "1"},
|
||||
{ "street-address", 1342177283, "17"},
|
||||
{ "StreetAddress", 1073741826, "PDSParameter"},
|
||||
{ "post-office-box-address", 1342177283, "18"},
|
||||
{ "PostOfficeBoxAddress", 1073741826, "PDSParameter"},
|
||||
{ "poste-restante-address", 1342177283, "19"},
|
||||
{ "PosteRestanteAddress", 1073741826, "PDSParameter"},
|
||||
{ "unique-postal-name", 1342177283, "20"},
|
||||
{ "UniquePostalName", 1073741826, "PDSParameter"},
|
||||
{ "local-postal-attributes", 1342177283, "21"},
|
||||
{ "LocalPostalAttributes", 1073741826, "PDSParameter"},
|
||||
{ "PDSParameter", 1610612750, NULL },
|
||||
{ "printable-string", 1814052895, NULL },
|
||||
{ "ub-pds-parameter-length", 524298, "1"},
|
||||
{ "teletex-string", 740311070, NULL },
|
||||
{ "ub-pds-parameter-length", 524298, "1"},
|
||||
{ "extended-network-address", 1342177283, "22"},
|
||||
{ "ExtendedNetworkAddress", 1610612754, NULL },
|
||||
{ "e163-4-address", 1610612741, NULL },
|
||||
{ "number", 1612718108, NULL },
|
||||
{ NULL, 1073743880, "0"},
|
||||
{ "ub-e163-4-number-length", 524298, "1"},
|
||||
{ "sub-address", 538992668, NULL },
|
||||
{ NULL, 1073743880, "1"},
|
||||
{ "ub-e163-4-sub-address-length", 524298, "1"},
|
||||
{ "psap-address", 536879106, "PresentationAddress"},
|
||||
{ NULL, 2056, "0"},
|
||||
{ "PresentationAddress", 1610612741, NULL },
|
||||
{ "pSelector", 1610637319, NULL },
|
||||
{ NULL, 2056, "0"},
|
||||
{ "sSelector", 1610637319, NULL },
|
||||
{ NULL, 2056, "1"},
|
||||
{ "tSelector", 1610637319, NULL },
|
||||
{ NULL, 2056, "2"},
|
||||
{ "nAddresses", 538976271, NULL },
|
||||
{ NULL, 1073743880, "3"},
|
||||
{ "MAX", 1074266122, "1"},
|
||||
{ NULL, 7, NULL },
|
||||
{ "terminal-type", 1342177283, "23"},
|
||||
{ "TerminalType", 1611137027, NULL },
|
||||
{ "0", 10, "ub-integer-options"},
|
||||
{ "teletex-domain-defined-attributes", 1342177283, "6"},
|
||||
{ "TeletexDomainDefinedAttributes", 1612709899, NULL },
|
||||
{ "ub-domain-defined-attributes", 1074266122, "1"},
|
||||
{ NULL, 2, "TeletexDomainDefinedAttribute"},
|
||||
{ "TeletexDomainDefinedAttribute", 1610612741, NULL },
|
||||
{ "type", 1612709918, NULL },
|
||||
{ "ub-domain-defined-attribute-type-length", 524298, "1"},
|
||||
{ "value", 538968094, NULL },
|
||||
{ "ub-domain-defined-attribute-value-length", 524298, "1"},
|
||||
{ "ub-name", 1342177283, "32768"},
|
||||
{ "ub-common-name", 1342177283, "64"},
|
||||
{ "ub-locality-name", 1342177283, "128"},
|
||||
{ "ub-state-name", 1342177283, "128"},
|
||||
{ "ub-organization-name", 1342177283, "64"},
|
||||
{ "ub-organizational-unit-name", 1342177283, "64"},
|
||||
{ "ub-title", 1342177283, "64"},
|
||||
{ "ub-match", 1342177283, "128"},
|
||||
{ "ub-emailaddress-length", 1342177283, "128"},
|
||||
{ "ub-common-name-length", 1342177283, "64"},
|
||||
{ "ub-country-name-alpha-length", 1342177283, "2"},
|
||||
{ "ub-country-name-numeric-length", 1342177283, "3"},
|
||||
{ "ub-domain-defined-attributes", 1342177283, "4"},
|
||||
{ "ub-domain-defined-attribute-type-length", 1342177283, "8"},
|
||||
{ "ub-domain-defined-attribute-value-length", 1342177283, "128"},
|
||||
{ "ub-domain-name-length", 1342177283, "16"},
|
||||
{ "ub-extension-attributes", 1342177283, "256"},
|
||||
{ "ub-e163-4-number-length", 1342177283, "15"},
|
||||
{ "ub-e163-4-sub-address-length", 1342177283, "40"},
|
||||
{ "ub-generation-qualifier-length", 1342177283, "3"},
|
||||
{ "ub-given-name-length", 1342177283, "16"},
|
||||
{ "ub-initials-length", 1342177283, "5"},
|
||||
{ "ub-integer-options", 1342177283, "256"},
|
||||
{ "ub-numeric-user-id-length", 1342177283, "32"},
|
||||
{ "ub-organization-name-length", 1342177283, "64"},
|
||||
{ "ub-organizational-unit-name-length", 1342177283, "32"},
|
||||
{ "ub-organizational-units", 1342177283, "4"},
|
||||
{ "ub-pds-name-length", 1342177283, "16"},
|
||||
{ "ub-pds-parameter-length", 1342177283, "30"},
|
||||
{ "ub-pds-physical-address-lines", 1342177283, "6"},
|
||||
{ "ub-postal-code-length", 1342177283, "16"},
|
||||
{ "ub-surname-length", 1342177283, "40"},
|
||||
{ "ub-terminal-id-length", 1342177283, "24"},
|
||||
{ "ub-unformatted-address-length", 1342177283, "180"},
|
||||
{ "ub-x121-address-length", 268435459, "16"},
|
||||
{ NULL, 0, NULL }
|
||||
};
|
1
proto.h
1
proto.h
@ -138,6 +138,7 @@ int load_licence(unsigned char **data);
|
||||
void save_licence(unsigned char *data, int length);
|
||||
void rd_create_ui(void);
|
||||
RD_BOOL rd_pstcache_mkdir(void);
|
||||
RD_BOOL rd_certcache_mkdir(void);
|
||||
int rd_open_file(char *filename);
|
||||
void rd_close_file(int fd);
|
||||
int rd_read_file(int fd, void *ptr, int len);
|
||||
|
46
rdesktop.c
46
rdesktop.c
@ -2025,6 +2025,52 @@ rd_create_ui()
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: Replace with recursive mkdir */
|
||||
RD_BOOL rd_certcache_mkdir(void)
|
||||
{
|
||||
char *home;
|
||||
char certcache_dir[PATH_MAX];
|
||||
|
||||
home = getenv("HOME");
|
||||
|
||||
if (home == NULL)
|
||||
return False;
|
||||
|
||||
snprintf(certcache_dir, sizeof(certcache_dir) - 1, "%s/%s", home, ".local");
|
||||
|
||||
if ((mkdir(certcache_dir, S_IRWXU) == -1) && errno != EEXIST)
|
||||
{
|
||||
logger(Core, Error, "%s: mkdir() failed: %s", __func__, strerror(errno));
|
||||
return False;
|
||||
}
|
||||
|
||||
snprintf(certcache_dir, sizeof(certcache_dir) - 1, "%s/%s", home, ".local/share");
|
||||
|
||||
if ((mkdir(certcache_dir, S_IRWXU) == -1) && errno != EEXIST)
|
||||
{
|
||||
logger(Core, Error, "%s: mkdir() failed: %s", __func__, strerror(errno));
|
||||
return False;
|
||||
}
|
||||
|
||||
snprintf(certcache_dir, sizeof(certcache_dir) - 1, "%s/%s", home, ".local/share/rdesktop");
|
||||
|
||||
if ((mkdir(certcache_dir, S_IRWXU) == -1) && errno != EEXIST)
|
||||
{
|
||||
logger(Core, Error, "%s: mkdir() failed: %s", __func__, strerror(errno));
|
||||
return False;
|
||||
}
|
||||
|
||||
snprintf(certcache_dir, sizeof(certcache_dir) - 1, "%s/%s", home, ".local/share/rdesktop/certs");
|
||||
|
||||
if ((mkdir(certcache_dir, S_IRWXU) == -1) && errno != EEXIST)
|
||||
{
|
||||
logger(Core, Error, "%s: mkdir() failed: %s", __func__, strerror(errno));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/* Create the bitmap cache directory */
|
||||
RD_BOOL
|
||||
rd_pstcache_mkdir(void)
|
||||
|
312
ssl.c
312
ssl.c
@ -4,6 +4,7 @@
|
||||
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
|
||||
Copyright (C) Jay Sorg <j@american-data.com> 2006-2008
|
||||
Copyright 2016-2017 Henrik Andersson <hean01@cendio.se> for Cendio AB
|
||||
Copyright 2017 Alexander Zakharov <uglym8@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -21,71 +22,56 @@
|
||||
|
||||
#include "rdesktop.h"
|
||||
#include "ssl.h"
|
||||
#include "asn.h"
|
||||
|
||||
/* Helper function to log internal SSL errors using logger */
|
||||
void
|
||||
rdssl_log_ssl_errors(const char *prefix)
|
||||
{
|
||||
unsigned long err;
|
||||
while (1)
|
||||
{
|
||||
err = ERR_get_error();
|
||||
if (err == 0)
|
||||
break;
|
||||
|
||||
logger(Protocol, Error,
|
||||
"%s, 0x%.8x:%s:%s: %s",
|
||||
prefix, err, ERR_lib_error_string(err),
|
||||
ERR_func_error_string(err), ERR_reason_error_string(err));
|
||||
}
|
||||
}
|
||||
#include <gnutls/x509.h>
|
||||
|
||||
void
|
||||
rdssl_sha1_init(RDSSL_SHA1 * sha1)
|
||||
{
|
||||
SHA1_Init(sha1);
|
||||
sha1_init(sha1);
|
||||
}
|
||||
|
||||
void
|
||||
rdssl_sha1_update(RDSSL_SHA1 * sha1, uint8 * data, uint32 len)
|
||||
{
|
||||
SHA1_Update(sha1, data, len);
|
||||
sha1_update(sha1, len, data);
|
||||
}
|
||||
|
||||
void
|
||||
rdssl_sha1_final(RDSSL_SHA1 * sha1, uint8 * out_data)
|
||||
{
|
||||
SHA1_Final(out_data, sha1);
|
||||
sha1_digest(sha1, SHA1_DIGEST_SIZE, out_data);
|
||||
}
|
||||
|
||||
void
|
||||
rdssl_md5_init(RDSSL_MD5 * md5)
|
||||
{
|
||||
MD5_Init(md5);
|
||||
md5_init(md5);
|
||||
}
|
||||
|
||||
void
|
||||
rdssl_md5_update(RDSSL_MD5 * md5, uint8 * data, uint32 len)
|
||||
{
|
||||
MD5_Update(md5, data, len);
|
||||
md5_update(md5, len, data);
|
||||
}
|
||||
|
||||
void
|
||||
rdssl_md5_final(RDSSL_MD5 * md5, uint8 * out_data)
|
||||
{
|
||||
MD5_Final(out_data, md5);
|
||||
md5_digest(md5, MD5_DIGEST_SIZE, out_data);
|
||||
}
|
||||
|
||||
void
|
||||
rdssl_rc4_set_key(RDSSL_RC4 * rc4, uint8 * key, uint32 len)
|
||||
{
|
||||
RC4_set_key(rc4, len, key);
|
||||
arcfour_set_key(rc4, len, key);
|
||||
}
|
||||
|
||||
void
|
||||
rdssl_rc4_crypt(RDSSL_RC4 * rc4, uint8 * in_data, uint8 * out_data, uint32 len)
|
||||
{
|
||||
RC4(rc4, len, in_data, out_data);
|
||||
arcfour_crypt(rc4, len, out_data, in_data);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -106,145 +92,179 @@ void
|
||||
rdssl_rsa_encrypt(uint8 * out, uint8 * in, int len, uint32 modulus_size, uint8 * modulus,
|
||||
uint8 * exponent)
|
||||
{
|
||||
BN_CTX *ctx;
|
||||
BIGNUM *mod, *exp, *x, *y;
|
||||
uint8 inr[SEC_MAX_MODULUS_SIZE];
|
||||
int outlen;
|
||||
mpz_t exp, mod;
|
||||
|
||||
reverse(modulus, modulus_size);
|
||||
reverse(exponent, SEC_EXPONENT_SIZE);
|
||||
memcpy(inr, in, len);
|
||||
reverse(inr, len);
|
||||
mpz_t y;
|
||||
mpz_t x;
|
||||
|
||||
ctx = BN_CTX_new();
|
||||
mod = BN_new();
|
||||
exp = BN_new();
|
||||
x = BN_new();
|
||||
y = BN_new();
|
||||
size_t outlen;
|
||||
|
||||
mpz_init(y);
|
||||
mpz_init(x);
|
||||
mpz_init(exp);
|
||||
mpz_init(mod);
|
||||
|
||||
mpz_import(mod, modulus_size, 1, sizeof(modulus[0]), 0, 0, modulus);
|
||||
// TODO: Need exponent size
|
||||
mpz_import(exp, 3, 1, sizeof(exponent[0]), 0, 0, exponent);
|
||||
|
||||
mpz_import(x, len, -1, sizeof(in[0]), 0, 0, in);
|
||||
|
||||
mpz_powm(y, x, exp, mod);
|
||||
|
||||
mpz_export(out, &outlen, -1, sizeof(out[0]), 0, 0, y);
|
||||
|
||||
BN_bin2bn(modulus, modulus_size, mod);
|
||||
BN_bin2bn(exponent, SEC_EXPONENT_SIZE, exp);
|
||||
BN_bin2bn(inr, len, x);
|
||||
BN_mod_exp(y, x, exp, mod, ctx);
|
||||
outlen = BN_bn2bin(y, out);
|
||||
reverse(out, outlen);
|
||||
if (outlen < (int) modulus_size)
|
||||
memset(out + outlen, 0, modulus_size - outlen);
|
||||
|
||||
BN_free(y);
|
||||
BN_clear_free(x);
|
||||
BN_free(exp);
|
||||
BN_free(mod);
|
||||
BN_CTX_free(ctx);
|
||||
}
|
||||
|
||||
/* returns newly allocated RDSSL_CERT or NULL */
|
||||
RDSSL_CERT *
|
||||
rdssl_cert_read(uint8 * data, uint32 len)
|
||||
{
|
||||
/* this will move the data pointer but we don't care, we don't use it again */
|
||||
return d2i_X509(NULL, (D2I_X509_CONST unsigned char **) &data, len);
|
||||
int ret;
|
||||
gnutls_datum_t cert_data;
|
||||
gnutls_x509_crt_t *cert;
|
||||
|
||||
cert = malloc(sizeof(*cert));
|
||||
|
||||
if (!cert) {
|
||||
logger(Protocol, Error, "%s:%s:%d: Failed to allocate memory for certificate structure.\n",
|
||||
__FILE__, __func__, __LINE__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((ret = gnutls_x509_crt_init(cert)) != GNUTLS_E_SUCCESS) {
|
||||
logger(Protocol, Error, "%s:%s:%d: Failed to init certificate structure. GnuTLS error = 0x%02x (%s)\n",
|
||||
__FILE__, __func__, __LINE__, ret, gnutls_strerror(ret));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cert_data.size = len;
|
||||
cert_data.data = data;
|
||||
|
||||
if ((ret = gnutls_x509_crt_import(*cert, &cert_data, GNUTLS_X509_FMT_DER)) != GNUTLS_E_SUCCESS) {
|
||||
logger(Protocol, Error, "%s:%s:%d: Failed to import DER encoded certificate. GnuTLS error = 0x%02x (%s)\n",
|
||||
__FILE__, __func__, __LINE__, ret, gnutls_strerror(ret));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return cert;
|
||||
}
|
||||
|
||||
void
|
||||
rdssl_cert_free(RDSSL_CERT * cert)
|
||||
{
|
||||
X509_free(cert);
|
||||
gnutls_free(cert);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* AFAIK, there's no way to alter the decoded certificate using GnuTLS.
|
||||
*
|
||||
* Upon detecting "problem" (wrong public RSA key OID) certificate
|
||||
* we basically have two options:
|
||||
*
|
||||
* 1)) encode certificate back to DER, then parse it using libtasn1,
|
||||
* fix public key OID (set it to 1.2.840.113549.1.1.1), encode to DER again
|
||||
* and finally reparse using GnuTLS
|
||||
*
|
||||
* 2) encode cert back to DER, get RSA public key parameters using libtasn1
|
||||
*
|
||||
* Or can rewrite the whole certificate related stuff later.
|
||||
*/
|
||||
|
||||
/* returns newly allocated RDSSL_RKEY or NULL */
|
||||
RDSSL_RKEY *
|
||||
rdssl_cert_to_rkey(RDSSL_CERT * cert, uint32 * key_len)
|
||||
{
|
||||
EVP_PKEY *epk = NULL;
|
||||
RDSSL_RKEY *lkey;
|
||||
int nid;
|
||||
int ret;
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
const unsigned char *p;
|
||||
RSA *rsa = NULL;
|
||||
int pklen;
|
||||
#endif
|
||||
RDSSL_RKEY *pkey;
|
||||
gnutls_datum_t m, e;
|
||||
|
||||
unsigned int algo, bits;
|
||||
char oid[64];
|
||||
size_t oid_size = sizeof(oid);
|
||||
|
||||
uint8_t data[2048];
|
||||
size_t len;
|
||||
|
||||
algo = gnutls_x509_crt_get_pk_algorithm(*cert, &bits);
|
||||
|
||||
/* By some reason, Microsoft sets the OID of the Public RSA key to
|
||||
the oid for "MD5 with RSA Encryption" instead of "RSA Encryption"
|
||||
|
||||
Kudos to Richard Levitte for the following (. intuitive .)
|
||||
lines of code that resets the OID and let's us extract the key. */
|
||||
Kudos to Richard Levitte for the finding this and proposed the fix
|
||||
using OpenSSL. */
|
||||
|
||||
X509_PUBKEY *key = NULL;
|
||||
X509_ALGOR *algor = NULL;
|
||||
if (algo == GNUTLS_PK_RSA) {
|
||||
|
||||
key = X509_get_X509_PUBKEY(cert);
|
||||
if (key == NULL)
|
||||
if ((ret = gnutls_x509_crt_get_pk_rsa_raw(*cert, &m, &e)) != GNUTLS_E_SUCCESS) {
|
||||
logger(Protocol, Error, "%s:%s:%d: Failed to get RSA public key parameters from certificate. GnuTLS error = 0x%02x (%s)\n",
|
||||
__FILE__, __func__, __LINE__, ret, gnutls_strerror(ret));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} else if (algo == GNUTLS_E_UNIMPLEMENTED_FEATURE) {
|
||||
|
||||
len = sizeof(data);
|
||||
if ((ret = gnutls_x509_crt_export(*cert, GNUTLS_X509_FMT_DER, data, &len)) != GNUTLS_E_SUCCESS) {
|
||||
logger(Protocol, Error, "%s:%s:%d: Failed to encode X.509 certificate to DER. GnuTLS error = 0x%02x (%s)\n",
|
||||
__FILE__, __func__, __LINE__, ret, gnutls_strerror(ret));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Validate public key algorithm as OID_SHA_WITH_RSA_SIGNATURE
|
||||
or OID_MD5_WITH_RSA_SIGNATURE
|
||||
*/
|
||||
if ((ret = libtasn_read_cert_pk_oid(data, len, oid, &oid_size)) != 0) {
|
||||
logger(Protocol, Error, "%s:%s:%d: Failed to get OID of public key algorithm.\n",
|
||||
__FILE__, __func__, __LINE__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(strncmp(oid, OID_SHA_WITH_RSA_SIGNATURE, strlen(OID_SHA_WITH_RSA_SIGNATURE)) == 0
|
||||
|| strncmp(oid, OID_MD5_WITH_RSA_SIGNATURE, strlen(OID_MD5_WITH_RSA_SIGNATURE)) == 0))
|
||||
{
|
||||
logger(Protocol, Error,
|
||||
"rdssl_cert_to_key(), failed to get public key from certificate");
|
||||
rdssl_log_ssl_errors("rdssl_cert_to_key()");
|
||||
logger(Protocol, Error, "%s:%s:%d: Wrong public key algorithm algo = 0x%02x (%s)\n",
|
||||
__FILE__, __func__, __LINE__, algo, oid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get public key parameters */
|
||||
if ((ret = libtasn_read_cert_pk_parameters(data, len, &m, &e)) != 0) {
|
||||
logger(Protocol, Error, "%s:%s:%d: Failed to read RSA public key parameters\n",
|
||||
__FILE__, __func__, __LINE__);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = X509_PUBKEY_get0_param(NULL, NULL, 0, &algor, key);
|
||||
if (ret != 1)
|
||||
{
|
||||
logger(Protocol, Error,
|
||||
"rdssl_cert_to_key(), failed to get algorithm used for public key");
|
||||
rdssl_log_ssl_errors("rdssl_cert_to_key()");
|
||||
|
||||
} else {
|
||||
logger(Protocol, Error, "%s:%s:%d: Failed to get public key algorithm from certificate. algo = 0x%02x (%d)\n",
|
||||
__FILE__, __func__, __LINE__, algo, algo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nid = OBJ_obj2nid(algor->algorithm);
|
||||
|
||||
if ((nid == NID_md5WithRSAEncryption) || (nid == NID_shaWithRSAEncryption))
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
logger(Protocol, Debug,
|
||||
"rdssl_cert_to_key(), re-setting algorithm type to RSA in server certificate");
|
||||
X509_PUBKEY_set0_param(key, OBJ_nid2obj(NID_rsaEncryption), 0, NULL, NULL, 0);
|
||||
#else
|
||||
|
||||
if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, key))
|
||||
{
|
||||
logger(Protocol, Error,
|
||||
"rdssl_cert_to_key(), failed to get algorithm used for public key");
|
||||
rdssl_log_ssl_errors("rdssl_cert_to_key()");
|
||||
pkey = malloc(sizeof(*pkey));
|
||||
|
||||
if (!pkey) {
|
||||
logger(Protocol, Error, "%s:%s:%d: Failed to allocate memory for RSA public key\n",
|
||||
__FILE__, __func__, __LINE__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(rsa = d2i_RSAPublicKey(NULL, &p, pklen)))
|
||||
{
|
||||
logger(Protocol, Error,
|
||||
"rdssl_cert_to_key(), failed to extract public key from certificate");
|
||||
rdssl_log_ssl_errors("rdssl_cert_to_key()");
|
||||
rsa_public_key_init(pkey);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
mpz_import(pkey->n, m.size, 1, sizeof(m.data[0]), 0, 0, m.data);
|
||||
mpz_import(pkey->e, e.size, 1, sizeof(e.data[0]), 0, 0, e.data);
|
||||
|
||||
lkey = RSAPublicKey_dup(rsa);
|
||||
*key_len = RSA_size(lkey);
|
||||
return lkey;
|
||||
#endif
|
||||
rsa_public_key_prepare(pkey);
|
||||
|
||||
}
|
||||
*key_len = pkey->size;
|
||||
|
||||
epk = X509_get_pubkey(cert);
|
||||
if (NULL == epk)
|
||||
{
|
||||
logger(Protocol, Error,
|
||||
"rdssl_cert_to_key(), failed to extract public key from certificate");
|
||||
rdssl_log_ssl_errors("rdssl_cert_to_key()");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lkey = RSAPublicKey_dup(EVP_PKEY_get1_RSA(epk));
|
||||
EVP_PKEY_free(epk);
|
||||
*key_len = RSA_size(lkey);
|
||||
return lkey;
|
||||
return pkey;
|
||||
}
|
||||
|
||||
/* returns boolean */
|
||||
@ -268,40 +288,52 @@ rdssl_certs_ok(RDSSL_CERT * server_cert, RDSSL_CERT * cacert)
|
||||
int
|
||||
rdssl_cert_print_fp(FILE * fp, RDSSL_CERT * cert)
|
||||
{
|
||||
return X509_print_fp(fp, cert);
|
||||
int ret;
|
||||
gnutls_datum_t cinfo;
|
||||
|
||||
ret = gnutls_x509_crt_print(*cert, GNUTLS_CRT_PRINT_ONELINE, &cinfo);
|
||||
|
||||
if (ret == 0) {
|
||||
fprintf (fp, "\t%s\n", cinfo.data);
|
||||
gnutls_free(cinfo.data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
rdssl_rkey_free(RDSSL_RKEY * rkey)
|
||||
{
|
||||
RSA_free(rkey);
|
||||
rsa_public_key_clear(rkey);
|
||||
free(rkey);
|
||||
}
|
||||
|
||||
/* Actually we can get rid of this function and use rsa_public)_key in rdssl_rsa_encrypt */
|
||||
/* returns error */
|
||||
int
|
||||
rdssl_rkey_get_exp_mod(RDSSL_RKEY * rkey, uint8 * exponent, uint32 max_exp_len, uint8 * modulus,
|
||||
uint32 max_mod_len)
|
||||
{
|
||||
int len;
|
||||
size_t outlen;
|
||||
|
||||
BIGNUM *e = NULL;
|
||||
BIGNUM *n = NULL;
|
||||
// TODO: Check size before exporing
|
||||
mpz_export(modulus, &outlen, 1, sizeof(uint8), 0, 0, rkey->n);
|
||||
mpz_export(exponent, &outlen, 1, sizeof(uint8), 0, 0, rkey->e);
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
e = rkey->e;
|
||||
n = rkey->n;
|
||||
#else
|
||||
RSA_get0_key(rkey, &n, &e, NULL);
|
||||
#endif
|
||||
/*
|
||||
* Note that gnutls_x509_crt_get_pk_rsa_raw() exports modulus with additional
|
||||
* zero byte as signed bignum. We can easily import this value using mpz_import()
|
||||
* After we use mpz_export() on pkey.n (modulus) it will (according to GMP docs)
|
||||
* export data without sign byte.
|
||||
*
|
||||
* This is only important if you get modulus from certificate using GnuTLS,
|
||||
* save it somewhere, import it into mpz and then export it from the said mpz to some
|
||||
* buffer. If you then compare initiail (saved) modulus with newly exported one they
|
||||
* will be different.
|
||||
*
|
||||
* On the other hand if we use mpz_t all the way, there will be no such situation.
|
||||
*/
|
||||
|
||||
if ((BN_num_bytes(e) > (int) max_exp_len) || (BN_num_bytes(n) > (int) max_mod_len))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
len = BN_bn2bin(e, exponent);
|
||||
reverse(exponent, len);
|
||||
len = BN_bn2bin(n, modulus);
|
||||
reverse(modulus, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -327,5 +359,9 @@ void
|
||||
rdssl_hmac_md5(const void *key, int key_len, const unsigned char *msg, int msg_len,
|
||||
unsigned char *md)
|
||||
{
|
||||
HMAC(EVP_md5(), key, key_len, msg, msg_len, md, NULL);
|
||||
struct hmac_md5_ctx ctx;
|
||||
|
||||
hmac_md5_set_key(&ctx, key_len, key);
|
||||
hmac_md5_update(&ctx, msg_len, msg);
|
||||
hmac_md5_digest(&ctx, MD5_DIGEST_SIZE, md);
|
||||
}
|
||||
|
30
ssl.h
30
ssl.h
@ -4,6 +4,7 @@
|
||||
Copyright (C) Matthew Chapman 1999-2008
|
||||
Copyright (C) Jay Sorg 2006-2008
|
||||
Copyright 2017 Henrik Andersson <hean01@cendio.se> for Cendio AB
|
||||
Copyright 2017 Alexander Zakharov <uglym8@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -22,25 +23,19 @@
|
||||
#ifndef _RDSSL_H
|
||||
#define _RDSSL_H
|
||||
|
||||
#include <openssl/rc4.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <nettle/md5.h>
|
||||
#include <nettle/sha1.h>
|
||||
#include <nettle/arcfour.h>
|
||||
#include <nettle/hmac.h>
|
||||
#include <nettle/rsa.h>
|
||||
|
||||
#if defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x0090800f)
|
||||
#define D2I_X509_CONST const
|
||||
#else
|
||||
#define D2I_X509_CONST
|
||||
#endif
|
||||
#include <gnutls/x509.h>
|
||||
|
||||
#define RDSSL_RC4 RC4_KEY
|
||||
#define RDSSL_SHA1 SHA_CTX
|
||||
#define RDSSL_MD5 MD5_CTX
|
||||
#define RDSSL_CERT X509
|
||||
#define RDSSL_RKEY RSA
|
||||
#define RDSSL_RC4 struct arcfour_ctx
|
||||
#define RDSSL_SHA1 struct sha1_ctx
|
||||
#define RDSSL_MD5 struct md5_ctx
|
||||
#define RDSSL_CERT gnutls_x509_crt_t
|
||||
#define RDSSL_RKEY struct rsa_public_key
|
||||
|
||||
void rdssl_sha1_init(RDSSL_SHA1 * sha1);
|
||||
void rdssl_sha1_update(RDSSL_SHA1 * sha1, uint8 * data, uint32 len);
|
||||
@ -65,5 +60,4 @@ RD_BOOL rdssl_sig_ok(uint8 * exponent, uint32 exp_len, uint8 * modulus, uint32 m
|
||||
|
||||
void rdssl_hmac_md5(const void *key, int key_len,
|
||||
const unsigned char *msg, int msg_len, unsigned char *md);
|
||||
void rdssl_log_ssl_errors(const char *prefix);
|
||||
#endif
|
||||
|
365
tcp.c
365
tcp.c
@ -3,7 +3,8 @@
|
||||
Protocol services - TCP layer
|
||||
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
|
||||
Copyright 2005-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
|
||||
Copyright 2012-2017 Henrik Andersson <hean01@cendio.se> for Cendio AB
|
||||
Copyright 2012-2019 Henrik Andersson <hean01@cendio.se> for Cendio AB
|
||||
Copyright 2017 Alexander Zakharov <uglym8@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -23,19 +24,24 @@
|
||||
#include <unistd.h> /* select read write close */
|
||||
#include <sys/socket.h> /* socket connect setsockopt */
|
||||
#include <sys/time.h> /* timeval */
|
||||
#include <sys/stat.h>
|
||||
#include <netdb.h> /* gethostbyname */
|
||||
#include <netinet/in.h> /* sockaddr_in */
|
||||
#include <netinet/tcp.h> /* TCP_NODELAY */
|
||||
#include <arpa/inet.h> /* inet_addr */
|
||||
#include <errno.h> /* errno */
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/err.h>
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/x509.h>
|
||||
|
||||
#include "rdesktop.h"
|
||||
#include "ssl.h"
|
||||
#include "asn.h"
|
||||
|
||||
|
||||
#define CHECK(x) assert((x)>=0)
|
||||
|
||||
#ifdef _WIN32
|
||||
#define socklen_t int
|
||||
@ -66,8 +72,6 @@ struct sockaddr_in *g_server_address = NULL;
|
||||
|
||||
static char *g_last_server_name = NULL;
|
||||
static RD_BOOL g_ssl_initialized = False;
|
||||
static SSL *g_ssl = NULL;
|
||||
static SSL_CTX *g_ssl_ctx = NULL;
|
||||
static int g_sock;
|
||||
static RD_BOOL g_run_ui = False;
|
||||
static struct stream g_in;
|
||||
@ -79,6 +83,8 @@ extern RD_BOOL g_network_error;
|
||||
extern RD_BOOL g_reconnect_loop;
|
||||
extern char g_tls_version[];
|
||||
|
||||
static gnutls_session_t g_tls_session;
|
||||
|
||||
/* wait till socket is ready to write or timeout */
|
||||
static RD_BOOL
|
||||
tcp_can_send(int sck, int millis)
|
||||
@ -123,7 +129,6 @@ tcp_init(uint32 maxlen)
|
||||
void
|
||||
tcp_send(STREAM s)
|
||||
{
|
||||
int ssl_err;
|
||||
int length = s->end - s->data;
|
||||
int sent, total = 0;
|
||||
|
||||
@ -133,30 +138,22 @@ tcp_send(STREAM s)
|
||||
#ifdef WITH_SCARD
|
||||
scard_lock(SCARD_LOCK_TCP);
|
||||
#endif
|
||||
|
||||
while (total < length)
|
||||
{
|
||||
if (g_ssl)
|
||||
{
|
||||
sent = SSL_write(g_ssl, s->data + total, length - total);
|
||||
if (sent <= 0)
|
||||
{
|
||||
ssl_err = SSL_get_error(g_ssl, sent);
|
||||
if (sent < 0 && (ssl_err == SSL_ERROR_WANT_READ ||
|
||||
ssl_err == SSL_ERROR_WANT_WRITE))
|
||||
{
|
||||
tcp_can_send(g_sock, 100);
|
||||
sent = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_ssl_initialized) {
|
||||
sent = gnutls_record_send(g_tls_session, s->data + total, length - total);
|
||||
if (sent <= 0) {
|
||||
if (gnutls_error_is_fatal(sent)) {
|
||||
#ifdef WITH_SCARD
|
||||
scard_unlock(SCARD_LOCK_TCP);
|
||||
#endif
|
||||
logger(Core, Error,
|
||||
"tcp_send(), SSL_write() failed with %d: %s",
|
||||
ssl_err, TCP_STRERROR);
|
||||
logger(Core, Error, "tcp_send(), gnutls_record_send() failed with %d: %s\n", sent, gnutls_strerror(sent));
|
||||
g_network_error = True;
|
||||
return;
|
||||
} else {
|
||||
tcp_can_send(g_sock, 100);
|
||||
sent = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -194,7 +191,7 @@ STREAM
|
||||
tcp_recv(STREAM s, uint32 length)
|
||||
{
|
||||
uint32 new_length, end_offset, p_offset;
|
||||
int rcvd = 0, ssl_err;
|
||||
int rcvd = 0;
|
||||
|
||||
if (g_network_error == True)
|
||||
return NULL;
|
||||
@ -227,7 +224,8 @@ tcp_recv(STREAM s, uint32 length)
|
||||
|
||||
while (length > 0)
|
||||
{
|
||||
if ((!g_ssl || SSL_pending(g_ssl) <= 0) && g_run_ui)
|
||||
|
||||
if ((!g_ssl_initialized || (gnutls_record_check_pending(g_tls_session) <= 0)) && g_run_ui)
|
||||
{
|
||||
ui_select(g_sock);
|
||||
|
||||
@ -237,35 +235,17 @@ tcp_recv(STREAM s, uint32 length)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (g_ssl)
|
||||
{
|
||||
rcvd = SSL_read(g_ssl, s->end, length);
|
||||
ssl_err = SSL_get_error(g_ssl, rcvd);
|
||||
if (g_ssl_initialized) {
|
||||
rcvd = gnutls_record_recv(g_tls_session, s->end, length);
|
||||
|
||||
if (ssl_err == SSL_ERROR_SSL)
|
||||
{
|
||||
if (SSL_get_shutdown(g_ssl) & SSL_RECEIVED_SHUTDOWN)
|
||||
{
|
||||
logger(Core, Error,
|
||||
"tcp_recv(), remote peer initiated ssl shutdown");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rdssl_log_ssl_errors("tcp_recv()");
|
||||
if (rcvd < 0) {
|
||||
if (gnutls_error_is_fatal(rcvd)) {
|
||||
logger(Core, Error, "tcp_recv(), gnutls_record_recv() failed with %d: %s\n", rcvd, gnutls_strerror(rcvd));
|
||||
g_network_error = True;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE)
|
||||
{
|
||||
} else {
|
||||
rcvd = 0;
|
||||
}
|
||||
else if (ssl_err != SSL_ERROR_NONE)
|
||||
{
|
||||
logger(Core, Error, "tcp_recv(), SSL_read() failed with %d: %s",
|
||||
ssl_err, TCP_STRERROR);
|
||||
g_network_error = True;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
@ -300,96 +280,144 @@ tcp_recv(STREAM s, uint32 length)
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Establish a SSL/TLS 1.0-1-2 connection */
|
||||
/*
|
||||
* Callback during handshake to verify peer certificate
|
||||
*/
|
||||
static int
|
||||
cert_verify_callback(gnutls_session_t session)
|
||||
{
|
||||
int rv;
|
||||
int type;
|
||||
RD_BOOL hostname_mismatch = False;
|
||||
unsigned int status;
|
||||
gnutls_x509_crt_t cert;
|
||||
const gnutls_datum_t *cert_list;
|
||||
unsigned int cert_list_size;
|
||||
|
||||
/*
|
||||
* verify certificate against system trust store
|
||||
*/
|
||||
rv = gnutls_certificate_verify_peers2(session, &status);
|
||||
if (rv == GNUTLS_E_SUCCESS)
|
||||
{
|
||||
logger(Core, Debug, "%s(), certificate verify status flags: %x", __func__, status);
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
/* get list of certificates */
|
||||
cert_list = NULL;
|
||||
cert_list_size = 0;
|
||||
|
||||
type = gnutls_certificate_type_get(session);
|
||||
if (type == GNUTLS_CRT_X509) {
|
||||
cert_list = gnutls_certificate_get_peers(session, &cert_list_size);
|
||||
}
|
||||
|
||||
if (cert_list_size > 0)
|
||||
{
|
||||
/* validate hostname */
|
||||
gnutls_x509_crt_init(&cert);
|
||||
gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER);
|
||||
if (gnutls_x509_crt_check_hostname(cert, g_last_server_name) != 0)
|
||||
{
|
||||
logger(Core, Debug, "%s(), certificate is valid", __func__);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
logger(Core, Warning, "%s(), certificate hostname mismatch", __func__);
|
||||
hostname_mismatch = True;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger(Core, Error, "%s(), failed to get certificate list for peers", __func__);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Use local store as fallback
|
||||
*/
|
||||
return utils_cert_handle_exception(session, status, hostname_mismatch, g_last_server_name);
|
||||
}
|
||||
|
||||
/* Establish a SSL/TLS 1.0 connection */
|
||||
RD_BOOL
|
||||
tcp_tls_connect(void)
|
||||
{
|
||||
int err;
|
||||
long options;
|
||||
|
||||
int type;
|
||||
int status;
|
||||
gnutls_datum_t out;
|
||||
gnutls_certificate_credentials_t xcred;
|
||||
|
||||
/* Initialize TLS session */
|
||||
if (!g_ssl_initialized)
|
||||
{
|
||||
SSL_load_error_strings();
|
||||
SSL_library_init();
|
||||
gnutls_global_init();
|
||||
CHECK(gnutls_init(&g_tls_session, GNUTLS_CLIENT));
|
||||
g_ssl_initialized = True;
|
||||
}
|
||||
|
||||
/* create process context */
|
||||
if (g_ssl_ctx == NULL)
|
||||
{
|
||||
/* It is recommended to use the default priorities */
|
||||
//CHECK(gnutls_set_default_priority(g_tls_session));
|
||||
// Use compatible priority to overcome key validation error
|
||||
// THIS IS TEMPORARY
|
||||
CHECK(gnutls_priority_set_direct(g_tls_session, "NORMAL:%COMPAT", NULL));
|
||||
CHECK(gnutls_certificate_allocate_credentials(&xcred));
|
||||
CHECK(gnutls_credentials_set(g_tls_session, GNUTLS_CRD_CERTIFICATE, xcred));
|
||||
CHECK(gnutls_certificate_set_x509_system_trust(xcred));
|
||||
gnutls_certificate_set_verify_function(xcred, cert_verify_callback);
|
||||
gnutls_transport_set_int(g_tls_session, g_sock);
|
||||
gnutls_handshake_set_timeout(g_tls_session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT);
|
||||
|
||||
const SSL_METHOD *(*tlsmeth) (void) = NULL;
|
||||
if (g_tls_version[0] == 0)
|
||||
tlsmeth = TLSv1_method;
|
||||
else if (!strcmp(g_tls_version, "1.0"))
|
||||
tlsmeth = TLSv1_method;
|
||||
else if (!strcmp(g_tls_version, "1.1"))
|
||||
tlsmeth = TLSv1_1_method;
|
||||
else if (!strcmp(g_tls_version, "1.2"))
|
||||
tlsmeth = TLSv1_2_method;
|
||||
if (tlsmeth == NULL)
|
||||
/* Perform the TLS handshake */
|
||||
do {
|
||||
err = gnutls_handshake(g_tls_session);
|
||||
} while (err < 0 && gnutls_error_is_fatal(err) == 0);
|
||||
|
||||
|
||||
if (err < 0) {
|
||||
|
||||
if (err == GNUTLS_E_CERTIFICATE_ERROR)
|
||||
{
|
||||
logger(Core, Error,
|
||||
"tcp_tls_connect(), TLS method should be 1.0, 1.1, or 1.2\n");
|
||||
logger(Core, Error, "%s(): Certificate error during TLS handshake", __func__);
|
||||
|
||||
/* TODO: Lookup if exit(1) is just plain wrong, its used here to breakout of
|
||||
fallback code path for connection, eg. if TLS fails, a retry with plain
|
||||
RDP is made.
|
||||
*/
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Handshake failed with unknown error, lets log */
|
||||
logger(Core, Error, "%s(), TLS handshake failed. GnuTLS error: %s",
|
||||
__func__, gnutls_strerror(err));
|
||||
|
||||
goto fail;
|
||||
}
|
||||
|
||||
g_ssl_ctx = SSL_CTX_new(tlsmeth());
|
||||
if (g_ssl_ctx == NULL)
|
||||
{
|
||||
logger(Core, Error,
|
||||
"tcp_tls_connect(), SSL_CTX_new() failed to create TLS v1.x context\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
options = 0;
|
||||
#ifdef SSL_OP_NO_COMPRESSION
|
||||
options |= SSL_OP_NO_COMPRESSION;
|
||||
#endif // __SSL_OP_NO_COMPRESSION
|
||||
options |= SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
|
||||
SSL_CTX_set_options(g_ssl_ctx, options);
|
||||
}
|
||||
|
||||
/* free old connection */
|
||||
if (g_ssl)
|
||||
SSL_free(g_ssl);
|
||||
|
||||
/* create new ssl connection */
|
||||
g_ssl = SSL_new(g_ssl_ctx);
|
||||
if (g_ssl == NULL)
|
||||
{
|
||||
logger(Core, Error, "tcp_tls_connect(), SSL_new() failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (SSL_set_fd(g_ssl, g_sock) < 1)
|
||||
{
|
||||
logger(Core, Error, "tcp_tls_connect(), SSL_set_fd() failed");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
err = SSL_connect(g_ssl);
|
||||
}
|
||||
while (SSL_get_error(g_ssl, err) == SSL_ERROR_WANT_READ);
|
||||
|
||||
if (err < 0)
|
||||
{
|
||||
rdssl_log_ssl_errors("tcp_tls_connect()");
|
||||
goto fail;
|
||||
} else {
|
||||
char *desc;
|
||||
desc = gnutls_session_get_desc(g_tls_session);
|
||||
logger(Core, Verbose, "TLS Session info: %s\n", desc);
|
||||
gnutls_free(desc);
|
||||
}
|
||||
|
||||
return True;
|
||||
|
||||
fail:
|
||||
if (g_ssl)
|
||||
SSL_free(g_ssl);
|
||||
if (g_ssl_ctx)
|
||||
SSL_CTX_free(g_ssl_ctx);
|
||||
|
||||
g_ssl = NULL;
|
||||
g_ssl_ctx = NULL;
|
||||
if (g_ssl_initialized) {
|
||||
gnutls_deinit(g_tls_session);
|
||||
// Not needed since 3.3.0
|
||||
gnutls_global_deinit();
|
||||
|
||||
g_ssl_initialized = False;
|
||||
}
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
@ -397,47 +425,85 @@ tcp_tls_connect(void)
|
||||
RD_BOOL
|
||||
tcp_tls_get_server_pubkey(STREAM s)
|
||||
{
|
||||
X509 *cert = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
int ret;
|
||||
unsigned int list_size;
|
||||
const gnutls_datum_t *cert_list;
|
||||
gnutls_x509_crt_t cert;
|
||||
|
||||
unsigned int algo, bits;
|
||||
gnutls_datum_t m, e;
|
||||
|
||||
int pk_size;
|
||||
uint8_t pk_data[1024];
|
||||
|
||||
s->data = s->p = NULL;
|
||||
s->size = 0;
|
||||
|
||||
if (g_ssl == NULL)
|
||||
goto out;
|
||||
cert_list = gnutls_certificate_get_peers(g_tls_session, &list_size);
|
||||
|
||||
cert = SSL_get_peer_certificate(g_ssl);
|
||||
if (cert == NULL)
|
||||
{
|
||||
logger(Core, Error,
|
||||
"tcp_tls_get_server_pubkey(), SSL_get_peer_certificate() failed");
|
||||
if (!cert_list) {
|
||||
logger(Core, Error, "%s:%s:%d Failed to get peer's certs' list\n", __FILE__, __func__, __LINE__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
pkey = X509_get_pubkey(cert);
|
||||
if (pkey == NULL)
|
||||
{
|
||||
logger(Core, Error, "tcp_tls_get_server_pubkey(), X509_get_pubkey() failed");
|
||||
if ((ret = gnutls_x509_crt_init(&cert)) != GNUTLS_E_SUCCESS) {
|
||||
logger(Core, Error, "%s:%s:%d Failed to init certificate structure. GnuTLS error: %s\n",
|
||||
__FILE__, __func__, __LINE__, gnutls_strerror(ret));
|
||||
goto out;
|
||||
}
|
||||
|
||||
s->size = i2d_PublicKey(pkey, NULL);
|
||||
if (s->size < 1)
|
||||
{
|
||||
logger(Core, Error, "tcp_tls_get_server_pubkey(), i2d_PublicKey() failed");
|
||||
if ((ret = gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER)) != GNUTLS_E_SUCCESS) {
|
||||
logger(Core, Error, "%s:%s:%d Failed to import DER certificate. GnuTLS error:%s\n",
|
||||
__FILE__, __func__, __LINE__, gnutls_strerror(ret));
|
||||
goto out;
|
||||
}
|
||||
|
||||
algo = gnutls_x509_crt_get_pk_algorithm(cert, &bits);
|
||||
|
||||
if (algo == GNUTLS_PK_RSA) {
|
||||
if ((ret = gnutls_x509_crt_get_pk_rsa_raw(cert, &m, &e)) != GNUTLS_E_SUCCESS) {
|
||||
logger(Core, Error, "%s:%s:%d Failed to get RSA public key parameters from certificate. GnuTLS error:%s\n",
|
||||
__FILE__, __func__, __LINE__, gnutls_strerror(ret));
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
logger(Core, Error, "%s:%s:%d Peer's certificate public key algorithm is not RSA. GnuTLS error:%s\n",
|
||||
__FILE__, __func__, __LINE__, gnutls_strerror(algo));
|
||||
goto out;
|
||||
}
|
||||
|
||||
pk_size = sizeof(pk_data);
|
||||
|
||||
/*
|
||||
* This key will be used further in cssp_connect() for server's key comparison.
|
||||
*
|
||||
* Note that we need to encode this RSA public key into PKCS#1 DER
|
||||
* ATM there's no way to encode/export RSA public key to PKCS#1 using GnuTLS,
|
||||
* gnutls_pubkey_export() encodes into PKCS#8. So besides fixing GnuTLS
|
||||
* we can use libtasn1 for encoding.
|
||||
*/
|
||||
|
||||
if ((ret = write_pkcs1_der_pubkey(&m, &e, pk_data, &pk_size)) != 0) {
|
||||
logger(Core, Error, "%s:%s:%d Failed to encode RSA public key to PKCS#1 DER\n",
|
||||
__FILE__, __func__, __LINE__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
s->size = pk_size;
|
||||
s->data = s->p = xmalloc(s->size);
|
||||
i2d_PublicKey(pkey, &s->p);
|
||||
memcpy((void *)s->data, (void *)pk_data, pk_size);
|
||||
s->p = s->data;
|
||||
s->end = s->p + s->size;
|
||||
|
||||
out:
|
||||
if (cert)
|
||||
X509_free(cert);
|
||||
if (pkey)
|
||||
EVP_PKEY_free(pkey);
|
||||
if ((e.size != 0) && (e.data)) {
|
||||
free(e.data);
|
||||
}
|
||||
|
||||
if ((m.size != 0) && (m.data)) {
|
||||
free(m.data);
|
||||
}
|
||||
|
||||
return (s->size != 0);
|
||||
}
|
||||
|
||||
@ -634,14 +700,13 @@ tcp_disconnect(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (g_ssl)
|
||||
{
|
||||
if (!g_network_error)
|
||||
(void) SSL_shutdown(g_ssl);
|
||||
SSL_free(g_ssl);
|
||||
g_ssl = NULL;
|
||||
SSL_CTX_free(g_ssl_ctx);
|
||||
g_ssl_ctx = NULL;
|
||||
if (g_ssl_initialized) {
|
||||
(void)gnutls_bye(g_tls_session, GNUTLS_SHUT_WR);
|
||||
gnutls_deinit(g_tls_session);
|
||||
// Not needed since 3.3.0
|
||||
gnutls_global_deinit();
|
||||
|
||||
g_ssl_initialized = False;
|
||||
}
|
||||
|
||||
TCP_CLOSE(g_sock);
|
||||
|
594
utils.c
594
utils.c
@ -1,7 +1,7 @@
|
||||
/* -*- c-basic-offset: 8 -*-
|
||||
rdesktop: A Remote Desktop Protocol client.
|
||||
Generic utility functions
|
||||
Copyright 2013-2017 Henrik Andersson <hean01@cendio.se> for Cendio AB
|
||||
Copyright 2013-2019 Henrik Andersson <hean01@cendio.se> for Cendio AB
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -22,6 +22,8 @@
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <iconv.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "rdesktop.h"
|
||||
|
||||
@ -277,11 +279,67 @@ utils_apply_session_size_limitations(uint32 * width, uint32 * height)
|
||||
*height = 200;
|
||||
}
|
||||
|
||||
#define MAX_CHOICES 10
|
||||
const char *
|
||||
util_dialog_choice(const char *message, ...)
|
||||
{
|
||||
int i;
|
||||
va_list ap;
|
||||
char *p;
|
||||
const char *choice;
|
||||
char response[512];
|
||||
const char *choices[MAX_CHOICES] = {0};
|
||||
|
||||
/* gather choices into array */
|
||||
va_start(ap, message);
|
||||
for (i = 0; i < MAX_CHOICES; i++)
|
||||
{
|
||||
choices[i] = va_arg(ap, const char *);
|
||||
if (choices[i] == NULL)
|
||||
break;
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
choice = NULL;
|
||||
while (choice == NULL)
|
||||
{
|
||||
/* display message */
|
||||
fprintf(stderr,"\n%s", message);
|
||||
|
||||
/* read input */
|
||||
if (fgets(response, sizeof(response), stdin) != NULL)
|
||||
{
|
||||
/* strip final newline */
|
||||
p = strchr(response, '\n');
|
||||
if (p != NULL)
|
||||
*p = 0;
|
||||
|
||||
for (i = 0; i < MAX_CHOICES; i++)
|
||||
{
|
||||
if (choices[i] == NULL)
|
||||
break;
|
||||
|
||||
if (strcmp(response, choices[i]) == 0)
|
||||
{
|
||||
choice = choices[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
logger(Core, Error, "Failed to read response from stdin");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return choice;
|
||||
}
|
||||
|
||||
/*
|
||||
* component logging
|
||||
*
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
|
||||
static char *level[] = {
|
||||
"debug",
|
||||
@ -431,3 +489,535 @@ logger_set_subjects(char *subjects)
|
||||
|
||||
free(pcs);
|
||||
}
|
||||
|
||||
static size_t
|
||||
_utils_data_to_hex(uint8 *data, size_t len, char *out, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
char hex[4];
|
||||
|
||||
assert((len * 2) < size);
|
||||
|
||||
memset(out, 0, size);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
snprintf(hex, sizeof(hex), "%.2x", data[i]);
|
||||
strcat(out, hex);
|
||||
}
|
||||
|
||||
return (len*2);
|
||||
}
|
||||
|
||||
static size_t
|
||||
_utils_oid_to_string(const char *oid, char *out, size_t size)
|
||||
{
|
||||
memset(out, 0, size);
|
||||
if (strcmp(oid, "0.9.2342.19200300.100.1.25") == 0) {
|
||||
snprintf(out, size, "%s", "DC");
|
||||
}
|
||||
else if (strcmp(oid, "2.5.4.3") == 0) {
|
||||
snprintf(out, size, "%s", "CN");
|
||||
}
|
||||
else if (strcmp(oid, "1.2.840.113549.1.1.13") == 0)
|
||||
{
|
||||
snprintf(out, size, "%s", "sha512WithRSAEncryption");
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(out, size, "%s", oid);
|
||||
}
|
||||
|
||||
return strlen(out);
|
||||
}
|
||||
|
||||
static int
|
||||
_utils_dn_to_string(gnutls_x509_dn_t dn, RD_BOOL exclude_oid,
|
||||
char *out, size_t size)
|
||||
{
|
||||
int i, j;
|
||||
char buf[128] = {0};
|
||||
char name[64] = {0};
|
||||
char result[1024] = {0};
|
||||
size_t left;
|
||||
gnutls_x509_ava_st ava;
|
||||
|
||||
left = sizeof(result);
|
||||
|
||||
for (j = 0; j < 100; j++)
|
||||
{
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
if (gnutls_x509_dn_get_rdn_ava(dn, j, i, &ava) != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (exclude_oid)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "%.*s", ava.value.size, ava.value.data);
|
||||
strncat(result, buf, left);
|
||||
left -= strlen(buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
_utils_oid_to_string((char *)ava.oid.data, name, sizeof(name));
|
||||
snprintf(buf, sizeof(buf), "%s%s=%.*s",
|
||||
(j > 0)?", ":"", name, ava.value.size, ava.value.data);
|
||||
strncat(result, buf, left);
|
||||
left -= strlen(buf);
|
||||
}
|
||||
}
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(out, size, "%s", result);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_utils_cert_get_info(gnutls_x509_crt_t cert, char *out, size_t size)
|
||||
{
|
||||
char buf[128];
|
||||
size_t buf_size;
|
||||
char digest[128];
|
||||
gnutls_x509_dn_t dn;
|
||||
time_t expire_ts, activated_ts;
|
||||
|
||||
char subject[256];
|
||||
char issuer[256];
|
||||
char valid_from[256];
|
||||
char valid_to[256];
|
||||
char sha1[256];
|
||||
char sha256[256];
|
||||
|
||||
/* get subject */
|
||||
gnutls_x509_crt_get_subject(cert, &dn);
|
||||
if (_utils_dn_to_string(dn, False, buf, sizeof(buf)) == 0)
|
||||
{
|
||||
snprintf(subject, sizeof(subject), " Subject: %s", buf);
|
||||
}
|
||||
|
||||
/* get issuer */
|
||||
gnutls_x509_crt_get_issuer(cert, &dn);
|
||||
if (_utils_dn_to_string(dn, False, buf, sizeof(buf)) == 0)
|
||||
{
|
||||
snprintf(issuer, sizeof(issuer), " Issuer: %s", buf);
|
||||
}
|
||||
|
||||
/* get activation / expiration time */
|
||||
activated_ts = gnutls_x509_crt_get_activation_time(cert);
|
||||
snprintf(valid_from, sizeof(valid_from), " Valid From: %s", ctime(&activated_ts));
|
||||
|
||||
expire_ts = gnutls_x509_crt_get_expiration_time(cert);
|
||||
snprintf(valid_to, sizeof(valid_to), " To: %s", ctime(&expire_ts));
|
||||
|
||||
/* get sha1 / sha256 fingerprint */
|
||||
buf_size = sizeof(buf);
|
||||
gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA1, buf, &buf_size);
|
||||
_utils_data_to_hex((uint8 *)buf, buf_size, digest, sizeof(digest));
|
||||
snprintf(sha1, sizeof(sha1), " sha1: %s", digest);
|
||||
|
||||
buf_size = sizeof(buf);
|
||||
gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA256, buf, &buf_size);
|
||||
_utils_data_to_hex((uint8 *)buf, buf_size, digest, sizeof(digest));
|
||||
snprintf(sha256, sizeof(sha256), " sha256: %s", digest);
|
||||
|
||||
/* render cert info into out */
|
||||
snprintf(out, size,
|
||||
"%s\n"
|
||||
"%s\n"
|
||||
"%s"
|
||||
"%s"
|
||||
"\n"
|
||||
" Certificate fingerprints:\n\n"
|
||||
"%s\n"
|
||||
"%s\n", subject, issuer, valid_from, valid_to, sha1, sha256);
|
||||
}
|
||||
|
||||
static int
|
||||
_utils_cert_san_to_string(gnutls_x509_crt_t cert, char *out, size_t size)
|
||||
{
|
||||
int i, res;
|
||||
char entries[1024] = {0};
|
||||
char san[128] = {0};
|
||||
ssize_t left;
|
||||
size_t san_size;
|
||||
unsigned int san_type, critical;
|
||||
|
||||
left = sizeof(entries);
|
||||
|
||||
for(i = 0; i < 50; i++)
|
||||
{
|
||||
san_size = sizeof(san);
|
||||
res = gnutls_x509_crt_get_subject_alt_name2(cert, i, san, &san_size, &san_type, &critical);
|
||||
|
||||
/* break if there are no more SAN entries */
|
||||
if (res <= 0)
|
||||
break;
|
||||
|
||||
/* log if we cant handle more san entires in buffer */
|
||||
if (left <= 0)
|
||||
{
|
||||
logger(Core, Warning, "%s(), buffer is full, at least one SAN entry is missing from list", __func__);
|
||||
break;
|
||||
}
|
||||
|
||||
/* add SAN entry to list */
|
||||
switch(san_type)
|
||||
{
|
||||
case GNUTLS_SAN_IPADDRESS:
|
||||
case GNUTLS_SAN_DNSNAME:
|
||||
|
||||
if (left < (ssize_t)sizeof(entries))
|
||||
{
|
||||
strncat(entries, ", ", left);
|
||||
left -= 2;
|
||||
}
|
||||
|
||||
strncat(entries, san, left);
|
||||
left -= strlen(san);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (strlen(entries) == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
snprintf(out, size, "%s", entries);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_utils_cert_get_status_report(gnutls_x509_crt_t cert, unsigned int status,
|
||||
RD_BOOL hostname_mismatch, const char *hostname,
|
||||
char *out, size_t size)
|
||||
{
|
||||
int i;
|
||||
char buf[1024];
|
||||
char str[1024 + 64];
|
||||
|
||||
i = 1;
|
||||
|
||||
if (hostname_mismatch == True)
|
||||
{
|
||||
snprintf(buf, sizeof(buf),
|
||||
" %d. The hostname used for this connection does not match any of the names\n"
|
||||
" given in the certificate.\n\n"
|
||||
" Hostname: %s\n"
|
||||
, i++, hostname);
|
||||
strncat(out, buf, size - 1);
|
||||
size -= strlen(buf);
|
||||
|
||||
/* parse subject dn */
|
||||
gnutls_x509_dn_t dn;
|
||||
gnutls_x509_crt_get_subject(cert, &dn);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
if (_utils_dn_to_string(dn, True, buf, sizeof(buf)) == 0)
|
||||
{
|
||||
snprintf(str, sizeof(str), " Common Name: %s\n", buf);
|
||||
strncat(out, str, size);
|
||||
size -= strlen(str);
|
||||
}
|
||||
|
||||
/* get SAN entries */
|
||||
if (_utils_cert_san_to_string(cert, buf, sizeof(buf)) == 0)
|
||||
{
|
||||
snprintf(str, sizeof(str), " Alternate names: %s\n", buf);
|
||||
strncat(out, str, size);
|
||||
size -= strlen(str);
|
||||
}
|
||||
|
||||
strcat(out, "\n");
|
||||
size -= 1;
|
||||
}
|
||||
|
||||
if (status & GNUTLS_CERT_REVOKED) {
|
||||
snprintf(buf, sizeof(buf),
|
||||
" %d. Certificate is revoked by its authority\n\n", i++);
|
||||
strncat(out, buf, size);
|
||||
size -= strlen(buf);
|
||||
}
|
||||
|
||||
if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) {
|
||||
snprintf(buf, sizeof(buf),
|
||||
" %d. Certificate issuer is not trusted by this system.\n\n", i++);
|
||||
strncat(out, buf, size);
|
||||
size -= strlen(buf);
|
||||
|
||||
/* parse subject dn */
|
||||
gnutls_x509_dn_t dn;
|
||||
gnutls_x509_crt_get_issuer(cert, &dn);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
if (_utils_dn_to_string(dn, False, buf, sizeof(buf)) == 0)
|
||||
{
|
||||
snprintf(str, sizeof(str), " Issuer: %s\n", buf);
|
||||
strncat(out, str, size);
|
||||
size -= strlen(str);
|
||||
}
|
||||
}
|
||||
|
||||
if (status & GNUTLS_CERT_SIGNER_NOT_CA) {
|
||||
snprintf(buf, sizeof(buf),
|
||||
" %d. Certificate signer is not a CA.\n\n", i++);
|
||||
strncat(out, buf, size);
|
||||
size -= strlen(buf);
|
||||
}
|
||||
|
||||
if (status & GNUTLS_CERT_INSECURE_ALGORITHM) {
|
||||
snprintf(buf, sizeof(buf),
|
||||
" %d. Certificate was signed using an insecure algorithm.\n\n", i++);
|
||||
strncat(out, buf, size);
|
||||
size -= strlen(buf);
|
||||
/* TODO: print algorithm*/
|
||||
}
|
||||
|
||||
if (status & GNUTLS_CERT_NOT_ACTIVATED) {
|
||||
snprintf(buf, sizeof(buf),
|
||||
" %d. Certificate is not yet activated.\n\n", i++);
|
||||
strncat(out, buf, size);
|
||||
size -= strlen(buf);
|
||||
/* TODO: print activation date */
|
||||
}
|
||||
|
||||
if (status & GNUTLS_CERT_EXPIRED) {
|
||||
snprintf(buf, sizeof(buf),
|
||||
" %d. Certificate has expired.\n\n", i++);
|
||||
strncat(out, buf, size);
|
||||
size -= strlen(buf);
|
||||
/* TODO: print expiration date */
|
||||
}
|
||||
|
||||
if (status & GNUTLS_CERT_SIGNATURE_FAILURE) {
|
||||
snprintf(buf, sizeof(buf),
|
||||
" %d. Failed to verify the signature of the certificate.\n\n", i++);
|
||||
strncat(out, buf, size);
|
||||
size -= strlen(buf);
|
||||
}
|
||||
|
||||
if (status & GNUTLS_CERT_REVOCATION_DATA_SUPERSEDED) {
|
||||
snprintf(buf, sizeof(buf),
|
||||
" %d. Revocation data are old and have been superseded.\n\n", i++);
|
||||
strncat(out, buf, size);
|
||||
size -= strlen(buf);
|
||||
}
|
||||
|
||||
if (status & GNUTLS_CERT_UNEXPECTED_OWNER) {
|
||||
snprintf(buf, sizeof(buf),
|
||||
" %d. The owner is not the expected one.\n\n", i++);
|
||||
strncat(out, buf, size);
|
||||
size -= strlen(buf);
|
||||
}
|
||||
|
||||
if (status & GNUTLS_CERT_REVOCATION_DATA_ISSUED_IN_FUTURE) {
|
||||
snprintf(buf, sizeof(buf),
|
||||
" %d. The revocation data have a future issue date.\n\n", i++);
|
||||
strncat(out, buf, size);
|
||||
size -= strlen(buf);
|
||||
}
|
||||
|
||||
if (status & GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE) {
|
||||
snprintf(buf, sizeof(buf),
|
||||
" %d. The certificate's signer constraints were violated.\n\n", i++);
|
||||
strncat(out, buf, size);
|
||||
size -= strlen(buf);
|
||||
}
|
||||
|
||||
if (status & GNUTLS_CERT_MISMATCH) {
|
||||
snprintf(buf, sizeof(buf),
|
||||
" %d. The certificate presented isn't the expected one (TOFU)\n\n", i++);
|
||||
strncat(out, buf, size);
|
||||
size -= strlen(buf);
|
||||
}
|
||||
|
||||
if (status & GNUTLS_CERT_PURPOSE_MISMATCH) {
|
||||
snprintf(buf, sizeof(buf),
|
||||
" %d. The certificate or an intermediate does not match the\n"
|
||||
" intended purpose (extended key usage).\n\n", i++);
|
||||
strncat(out, buf, size);
|
||||
size -= strlen(buf);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_utils_cert_store_get_filename(char *out, size_t size)
|
||||
{
|
||||
int rv;
|
||||
char *home;
|
||||
char dir[PATH_MAX - 12];
|
||||
struct stat sb;
|
||||
|
||||
home = getenv("HOME");
|
||||
|
||||
if (home == NULL)
|
||||
return 1;
|
||||
|
||||
if (snprintf(dir, sizeof(dir) - 1, "%s/%s", home, ".local/share/rdesktop/certs/") > (int)sizeof(dir))
|
||||
{
|
||||
logger(Core, Error, "%s(), certificate store directory is truncated", __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((rv = stat(dir, &sb)) == -1)
|
||||
{
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
if (rd_certcache_mkdir() == False) {
|
||||
logger(Core, Error, "%s(), failed to create directory '%s'", dir);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((sb.st_mode & S_IFMT) != S_IFDIR)
|
||||
{
|
||||
logger(Core, Error, "%s(), %s exists but it's not a directory",
|
||||
__func__, dir);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (snprintf(out, size, "%s/known_certs", dir) > (int)size)
|
||||
{
|
||||
logger(Core, Error, "%s(), certificate store filename is truncated");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TRUST_CERT_PROMPT_TEXT "Do you trust this certificate (yes/no)? "
|
||||
#define REVIEW_CERT_TEXT \
|
||||
"Review the following certificate info before you trust it to be added as an exception.\n" \
|
||||
"If you do not trust the certificate the connection atempt will be aborted:"
|
||||
|
||||
int
|
||||
utils_cert_handle_exception(gnutls_session_t session, unsigned int status,
|
||||
RD_BOOL hostname_mismatch, const char *hostname)
|
||||
{
|
||||
int rv;
|
||||
int type;
|
||||
time_t exp_time;
|
||||
gnutls_x509_crt_t cert;
|
||||
const gnutls_datum_t *cert_list;
|
||||
unsigned int cert_list_size = 0;
|
||||
|
||||
char certcache_fn[PATH_MAX];
|
||||
char cert_info[2048] = {0};
|
||||
char cert_invalid_reasons[2048] = {0};
|
||||
char message[8192] = {0};
|
||||
const char *response;
|
||||
|
||||
/* get filename for certificate exception store */
|
||||
if (_utils_cert_store_get_filename(certcache_fn, sizeof(certcache_fn)) != 0)
|
||||
{
|
||||
logger(Core, Error, "%s(), Failed to get certificate store file, "
|
||||
"disabling exception handling.", __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
type = gnutls_certificate_type_get(session);
|
||||
if (type != GNUTLS_CRT_X509)
|
||||
{
|
||||
logger(Core, Error, "%s(), Certificate for session is not an x509 certificate, "
|
||||
"disabling exception handling.", __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
cert_list = gnutls_certificate_get_peers(session, &cert_list_size);
|
||||
if (cert_list_size == 0)
|
||||
{
|
||||
logger(Core, Error, "%s(), Failed to get certificate, "
|
||||
"disabling exception handling.", __func__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
rv = gnutls_verify_stored_pubkey(certcache_fn, NULL, hostname, "rdesktop", type, &cert_list[0], 0);
|
||||
if (rv == GNUTLS_E_SUCCESS)
|
||||
{
|
||||
/* Certificate found in store and matches server */
|
||||
logger(Core, Warning, "Certificate received from server is NOT trusted by this system, "
|
||||
"an exception has been added by the user to trust this specific certificate.");
|
||||
return 0;
|
||||
}
|
||||
else if (rv != GNUTLS_E_CERTIFICATE_KEY_MISMATCH && rv != GNUTLS_E_NO_CERTIFICATE_FOUND)
|
||||
{
|
||||
/* Unhandled errors */
|
||||
logger(Core, Error, "%s(), verification for host '%s' certificate failed. Error = 0x%x (%s)",
|
||||
__func__, hostname, rv, gnutls_strerror(rv));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Give user possibility to add / update certificate to store
|
||||
*/
|
||||
|
||||
gnutls_x509_crt_init(&cert);
|
||||
gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER);
|
||||
_utils_cert_get_info(cert, cert_info, sizeof(cert_info));
|
||||
|
||||
if (rv == GNUTLS_E_CERTIFICATE_KEY_MISMATCH)
|
||||
{
|
||||
/* Certificate from server mismatches the one in store */
|
||||
|
||||
snprintf(message, sizeof(message),
|
||||
"ATTENTION! Found a certificate stored for host '%s', but it does not match the certificate\n"
|
||||
"received from server.\n"
|
||||
REVIEW_CERT_TEXT
|
||||
"\n\n"
|
||||
"%s"
|
||||
"\n\n"
|
||||
TRUST_CERT_PROMPT_TEXT
|
||||
, hostname, cert_info);
|
||||
|
||||
|
||||
}
|
||||
else if (rv == GNUTLS_E_NO_CERTIFICATE_FOUND)
|
||||
{
|
||||
/* Certificate is not found in store, propose to add an exception */
|
||||
_utils_cert_get_status_report(cert, status, hostname_mismatch, hostname,
|
||||
cert_invalid_reasons, sizeof(cert_invalid_reasons));
|
||||
|
||||
snprintf(message, sizeof(message),
|
||||
"ATTENTION! The server uses and invalid security certificate which can not be trusted for\n"
|
||||
"the following identified reasons(s);\n\n"
|
||||
"%s"
|
||||
"\n"
|
||||
REVIEW_CERT_TEXT
|
||||
"\n\n"
|
||||
"%s"
|
||||
"\n\n"
|
||||
TRUST_CERT_PROMPT_TEXT,
|
||||
cert_invalid_reasons, cert_info);
|
||||
}
|
||||
|
||||
/* show dialog */
|
||||
response = util_dialog_choice(message, "no", "yes", NULL);
|
||||
if (strcmp(response, "no") == 0 || response == NULL)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* user responded with yes, lets add certificate to store */
|
||||
logger(Core, Debug, "%s(), adding a new certificate for the host '%s'", __func__, hostname);
|
||||
exp_time = gnutls_x509_crt_get_expiration_time(cert);
|
||||
rv = gnutls_store_pubkey(certcache_fn, NULL, hostname, "rdesktop", type, &cert_list[0], exp_time, 0);
|
||||
if (rv != GNUTLS_E_SUCCESS)
|
||||
{
|
||||
logger(Core, Error, "%s(), failed to store certificate. error = 0x%x (%s)", __func__, rv, gnutls_strerror(rv));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
9
utils.h
9
utils.h
@ -1,7 +1,7 @@
|
||||
/* -*- c-basic-offset: 8 -*-
|
||||
rdesktop: A Remote Desktop Protocol client.
|
||||
|
||||
Copyright 2017 Henrik Andersson <hean01@cendio.se> for Cendio AB
|
||||
Copyright 2017-2019 Henrik Andersson <hean01@cendio.se> for Cendio AB
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -20,6 +20,9 @@
|
||||
#ifndef _utils_h
|
||||
#define _utils_h
|
||||
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/x509.h>
|
||||
|
||||
#include "types.h"
|
||||
|
||||
uint32 utils_djb2_hash(const char *str);
|
||||
@ -33,6 +36,10 @@ void utils_calculate_dpi_scale_factors(uint32 width, uint32 height, uint32 dpi,
|
||||
uint32 * desktopscale, uint32 * devicescale);
|
||||
void utils_apply_session_size_limitations(uint32 * width, uint32 * height);
|
||||
|
||||
const char* util_dialog_choice(const char *message, ...);
|
||||
|
||||
int utils_cert_handle_exception(gnutls_session_t session, unsigned int status,
|
||||
RD_BOOL hostname_mismatch, const char *hostname);
|
||||
|
||||
typedef enum log_level_t
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user