aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlv-426 <oxcafebaby@yahoo.com>2008-06-22 18:20:35 +0000
committerlv-426 <oxcafebaby@yahoo.com>2008-06-22 18:20:35 +0000
commita0339d2458867dbe9485499265641ff205063445 (patch)
tree055b38828b3696520408a32edf81df5bb37400f0 /src
parent97c026da05495b83f1511906c2ca027e12ef6cf7 (diff)
downloadlibmicrohttpd-a0339d2458867dbe9485499265641ff205063445.tar.gz
libmicrohttpd-a0339d2458867dbe9485499265641ff205063445.zip
initial GNU TLS import - this should reduce in size considerable
Diffstat (limited to 'src')
-rw-r--r--src/daemon/Makefile.am42
-rw-r--r--src/daemon/https/Makefile.am34
-rw-r--r--src/daemon/https/errcodes131
-rw-r--r--src/daemon/https/errcodes.c65
-rw-r--r--src/daemon/https/https_common.c877
-rw-r--r--src/daemon/https/https_common.h40
-rw-r--r--src/daemon/https/includes/Makefile.am3
-rw-r--r--src/daemon/https/includes/compat.h98
-rw-r--r--src/daemon/https/includes/extra.h185
-rw-r--r--src/daemon/https/includes/gnutls.h1286
-rw-r--r--src/daemon/https/includes/gnutlsxx.h393
-rw-r--r--src/daemon/https/lgl/Makefile.am37
-rw-r--r--src/daemon/https/lgl/asnprintf.c35
-rw-r--r--src/daemon/https/lgl/asprintf.c39
-rw-r--r--src/daemon/https/lgl/des.c662
-rw-r--r--src/daemon/https/lgl/des.h121
-rw-r--r--src/daemon/https/lgl/float+.h148
-rw-r--r--src/daemon/https/lgl/gc-gnulib.c791
-rw-r--r--src/daemon/https/lgl/gc-libgcrypt.c627
-rw-r--r--src/daemon/https/lgl/gc-pbkdf2-sha1.c185
-rw-r--r--src/daemon/https/lgl/gc.h347
-rw-r--r--src/daemon/https/lgl/gettext.h270
-rw-r--r--src/daemon/https/lgl/hmac-md5.c81
-rw-r--r--src/daemon/https/lgl/hmac-sha1.c81
-rw-r--r--src/daemon/https/lgl/hmac.h41
-rw-r--r--src/daemon/https/lgl/md5.c451
-rw-r--r--src/daemon/https/lgl/md5.h124
-rw-r--r--src/daemon/https/lgl/memmem.c61
-rw-r--r--src/daemon/https/lgl/memmove.c26
-rw-r--r--src/daemon/https/lgl/memxor.c35
-rw-r--r--src/daemon/https/lgl/memxor.h31
-rw-r--r--src/daemon/https/lgl/printf-args.c185
-rw-r--r--src/daemon/https/lgl/printf-args.h154
-rw-r--r--src/daemon/https/lgl/printf-parse.c599
-rw-r--r--src/daemon/https/lgl/printf-parse.h178
-rw-r--r--src/daemon/https/lgl/read-file.c136
-rw-r--r--src/daemon/https/lgl/read-file.h34
-rw-r--r--src/daemon/https/lgl/realloc.c87
-rw-r--r--src/daemon/https/lgl/rijndael-alg-fst.c1083
-rw-r--r--src/daemon/https/lgl/rijndael-alg-fst.h67
-rw-r--r--src/daemon/https/lgl/rijndael-api-fst.c517
-rw-r--r--src/daemon/https/lgl/rijndael-api-fst.h207
-rw-r--r--src/daemon/https/lgl/sha1.c416
-rw-r--r--src/daemon/https/lgl/sha1.h87
-rw-r--r--src/daemon/https/lgl/snprintf.c77
-rw-r--r--src/daemon/https/lgl/strverscmp.c130
-rw-r--r--src/daemon/https/lgl/strverscmp.h24
-rw-r--r--src/daemon/https/lgl/time_r.c46
-rw-r--r--src/daemon/https/lgl/vasnprintf.c4825
-rw-r--r--src/daemon/https/lgl/vasnprintf.h81
-rw-r--r--src/daemon/https/lgl/vasprintf.c56
-rw-r--r--src/daemon/https/lgl/xsize.h109
-rw-r--r--src/daemon/https/list.h449
-rw-r--r--src/daemon/https/minitasn1/Makefile.am16
-rw-r--r--src/daemon/https/minitasn1/README3
-rw-r--r--src/daemon/https/minitasn1/coding.c1229
-rw-r--r--src/daemon/https/minitasn1/decoding.c2821
-rw-r--r--src/daemon/https/minitasn1/element.c1013
-rw-r--r--src/daemon/https/minitasn1/element.h13
-rw-r--r--src/daemon/https/minitasn1/errors.c135
-rw-r--r--src/daemon/https/minitasn1/errors.h30
-rw-r--r--src/daemon/https/minitasn1/gstr.c68
-rw-r--r--src/daemon/https/minitasn1/gstr.h5
-rw-r--r--src/daemon/https/minitasn1/int.h112
-rw-r--r--src/daemon/https/minitasn1/libtasn1.h246
-rw-r--r--src/daemon/https/minitasn1/mem.h27
-rw-r--r--src/daemon/https/minitasn1/parser_aux.c1072
-rw-r--r--src/daemon/https/minitasn1/parser_aux.h63
-rw-r--r--src/daemon/https/minitasn1/structure.c1221
-rw-r--r--src/daemon/https/minitasn1/structure.h23
-rw-r--r--src/daemon/https/opencdk/Makefile.am12
-rw-r--r--src/daemon/https/opencdk/README5
-rw-r--r--src/daemon/https/opencdk/armor.c763
-rw-r--r--src/daemon/https/opencdk/cipher.c528
-rw-r--r--src/daemon/https/opencdk/compress.c238
-rw-r--r--src/daemon/https/opencdk/context.h120
-rw-r--r--src/daemon/https/opencdk/dummy.c15
-rw-r--r--src/daemon/https/opencdk/filters.h95
-rw-r--r--src/daemon/https/opencdk/kbnode.c581
-rw-r--r--src/daemon/https/opencdk/keydb.c2303
-rw-r--r--src/daemon/https/opencdk/literal.c307
-rw-r--r--src/daemon/https/opencdk/main.c779
-rw-r--r--src/daemon/https/opencdk/main.h183
-rw-r--r--src/daemon/https/opencdk/misc.c571
-rw-r--r--src/daemon/https/opencdk/new-packet.c874
-rw-r--r--src/daemon/https/opencdk/opencdk.h1169
-rw-r--r--src/daemon/https/opencdk/packet.h40
-rw-r--r--src/daemon/https/opencdk/pubkey.c1380
-rw-r--r--src/daemon/https/opencdk/read-packet.c1179
-rw-r--r--src/daemon/https/opencdk/seskey.c717
-rw-r--r--src/daemon/https/opencdk/sig-check.c489
-rw-r--r--src/daemon/https/opencdk/stream.c1446
-rw-r--r--src/daemon/https/opencdk/stream.h88
-rw-r--r--src/daemon/https/opencdk/types.h44
-rw-r--r--src/daemon/https/opencdk/verify.c306
-rw-r--r--src/daemon/https/opencdk/write-packet.c947
-rw-r--r--src/daemon/https/openpgp/Makefile.am27
-rw-r--r--src/daemon/https/openpgp/compat.c252
-rw-r--r--src/daemon/https/openpgp/extras.c165
-rw-r--r--src/daemon/https/openpgp/gnutls_extra.c110
-rw-r--r--src/daemon/https/openpgp/gnutls_extra.h50
-rw-r--r--src/daemon/https/openpgp/gnutls_ia.c905
-rw-r--r--src/daemon/https/openpgp/gnutls_openpgp.c973
-rw-r--r--src/daemon/https/openpgp/gnutls_openpgp.h98
-rw-r--r--src/daemon/https/openpgp/openpgp.h182
-rw-r--r--src/daemon/https/openpgp/pgp.c534
-rw-r--r--src/daemon/https/openpgp/pgp_privkey.c134
-rw-r--r--src/daemon/https/openpgp/pgp_verify.c144
-rw-r--r--src/daemon/https/tests.c1160
-rw-r--r--src/daemon/https/tests.h42
-rw-r--r--src/daemon/https/tls/Makefile.am73
-rw-r--r--src/daemon/https/tls/auth_anon.c178
-rw-r--r--src/daemon/https/tls/auth_anon.h48
-rw-r--r--src/daemon/https/tls/auth_cert.c1781
-rw-r--r--src/daemon/https/tls/auth_cert.h158
-rw-r--r--src/daemon/https/tls/auth_dh_common.c369
-rw-r--r--src/daemon/https/tls/auth_dh_common.h48
-rw-r--r--src/daemon/https/tls/auth_dhe.c276
-rw-r--r--src/daemon/https/tls/auth_rsa.c408
-rw-r--r--src/daemon/https/tls/auth_rsa_export.c325
-rw-r--r--src/daemon/https/tls/debug.c128
-rw-r--r--src/daemon/https/tls/debug.h30
-rw-r--r--src/daemon/https/tls/defines.h64
-rw-r--r--src/daemon/https/tls/ext_cert_type.c243
-rw-r--r--src/daemon/https/tls/ext_cert_type.h31
-rw-r--r--src/daemon/https/tls/ext_inner_application.c147
-rw-r--r--src/daemon/https/tls/ext_inner_application.h29
-rw-r--r--src/daemon/https/tls/ext_max_record.c196
-rw-r--r--src/daemon/https/tls/ext_max_record.h33
-rw-r--r--src/daemon/https/tls/ext_oprfi.c253
-rw-r--r--src/daemon/https/tls/ext_oprfi.h33
-rw-r--r--src/daemon/https/tls/ext_server_name.c330
-rw-r--r--src/daemon/https/tls/ext_server_name.h28
-rw-r--r--src/daemon/https/tls/gnutls.asn93
-rw-r--r--src/daemon/https/tls/gnutls.pc23
-rw-r--r--src/daemon/https/tls/gnutls_alert.c304
-rw-r--r--src/daemon/https/tls/gnutls_algorithms.c2225
-rw-r--r--src/daemon/https/tls/gnutls_algorithms.h141
-rw-r--r--src/daemon/https/tls/gnutls_anon_cred.c137
-rw-r--r--src/daemon/https/tls/gnutls_asn1_tab.c63
-rw-r--r--src/daemon/https/tls/gnutls_auth.c413
-rw-r--r--src/daemon/https/tls/gnutls_auth.h50
-rw-r--r--src/daemon/https/tls/gnutls_auth_int.h32
-rw-r--r--src/daemon/https/tls/gnutls_buffer.h31
-rw-r--r--src/daemon/https/tls/gnutls_buffers.c1241
-rw-r--r--src/daemon/https/tls/gnutls_buffers.h67
-rw-r--r--src/daemon/https/tls/gnutls_cert.c918
-rw-r--r--src/daemon/https/tls/gnutls_cert.h132
-rw-r--r--src/daemon/https/tls/gnutls_cipher.c584
-rw-r--r--src/daemon/https/tls/gnutls_cipher.h41
-rw-r--r--src/daemon/https/tls/gnutls_cipher_int.c133
-rw-r--r--src/daemon/https/tls/gnutls_cipher_int.h46
-rw-r--r--src/daemon/https/tls/gnutls_compress.c80
-rw-r--r--src/daemon/https/tls/gnutls_compress.h30
-rw-r--r--src/daemon/https/tls/gnutls_compress_int.c300
-rw-r--r--src/daemon/https/tls/gnutls_compress_int.h49
-rw-r--r--src/daemon/https/tls/gnutls_constate.c1039
-rw-r--r--src/daemon/https/tls/gnutls_constate.h40
-rw-r--r--src/daemon/https/tls/gnutls_datum.c114
-rw-r--r--src/daemon/https/tls/gnutls_datum.h40
-rw-r--r--src/daemon/https/tls/gnutls_db.c386
-rw-r--r--src/daemon/https/tls/gnutls_db.h37
-rw-r--r--src/daemon/https/tls/gnutls_dh.c162
-rw-r--r--src/daemon/https/tls/gnutls_dh.h38
-rw-r--r--src/daemon/https/tls/gnutls_dh_primes.c626
-rw-r--r--src/daemon/https/tls/gnutls_errors.c422
-rw-r--r--src/daemon/https/tls/gnutls_errors.h73
-rw-r--r--src/daemon/https/tls/gnutls_extensions.c318
-rw-r--r--src/daemon/https/tls/gnutls_extensions.h45
-rw-r--r--src/daemon/https/tls/gnutls_extra_hooks.c78
-rw-r--r--src/daemon/https/tls/gnutls_extra_hooks.h106
-rw-r--r--src/daemon/https/tls/gnutls_global.c375
-rw-r--r--src/daemon/https/tls/gnutls_global.h42
-rw-r--r--src/daemon/https/tls/gnutls_handshake.c3029
-rw-r--r--src/daemon/https/tls/gnutls_handshake.h60
-rw-r--r--src/daemon/https/tls/gnutls_hash_int.c446
-rw-r--r--src/daemon/https/tls/gnutls_hash_int.h72
-rw-r--r--src/daemon/https/tls/gnutls_int.h679
-rw-r--r--src/daemon/https/tls/gnutls_kx.c773
-rw-r--r--src/daemon/https/tls/gnutls_kx.h39
-rw-r--r--src/daemon/https/tls/gnutls_mem.c134
-rw-r--r--src/daemon/https/tls/gnutls_mem.h70
-rw-r--r--src/daemon/https/tls/gnutls_mpi.c285
-rw-r--r--src/daemon/https/tls/gnutls_mpi.h78
-rw-r--r--src/daemon/https/tls/gnutls_num.c192
-rw-r--r--src/daemon/https/tls/gnutls_num.h49
-rw-r--r--src/daemon/https/tls/gnutls_pk.c915
-rw-r--r--src/daemon/https/tls/gnutls_pk.h46
-rw-r--r--src/daemon/https/tls/gnutls_priority.c497
-rw-r--r--src/daemon/https/tls/gnutls_record.c1204
-rw-r--r--src/daemon/https/tls/gnutls_record.h32
-rw-r--r--src/daemon/https/tls/gnutls_rsa_export.c361
-rw-r--r--src/daemon/https/tls/gnutls_rsa_export.h27
-rw-r--r--src/daemon/https/tls/gnutls_session.c199
-rw-r--r--src/daemon/https/tls/gnutls_session.h23
-rw-r--r--src/daemon/https/tls/gnutls_session_pack.c1204
-rw-r--r--src/daemon/https/tls/gnutls_session_pack.h28
-rw-r--r--src/daemon/https/tls/gnutls_sig.c473
-rw-r--r--src/daemon/https/tls/gnutls_sig.h51
-rw-r--r--src/daemon/https/tls/gnutls_state.c1219
-rw-r--r--src/daemon/https/tls/gnutls_state.h72
-rw-r--r--src/daemon/https/tls/gnutls_str.c312
-rw-r--r--src/daemon/https/tls/gnutls_str.h67
-rw-r--r--src/daemon/https/tls/gnutls_supplemental.c207
-rw-r--r--src/daemon/https/tls/gnutls_supplemental.h31
-rw-r--r--src/daemon/https/tls/gnutls_ui.c627
-rw-r--r--src/daemon/https/tls/gnutls_v2_compat.c259
-rw-r--r--src/daemon/https/tls/gnutls_v2_compat.h26
-rw-r--r--src/daemon/https/tls/gnutls_x509.c1991
-rw-r--r--src/daemon/https/tls/gnutls_x509.h49
-rw-r--r--src/daemon/https/tls/gnutlsxx.cpp907
-rw-r--r--src/daemon/https/tls/io_debug.h79
-rw-r--r--src/daemon/https/tls/libgnutls-config104
-rw-r--r--src/daemon/https/tls/libgnutls.m4160
-rw-r--r--src/daemon/https/tls/libgnutls.vers27
-rw-r--r--src/daemon/https/tls/libgnutlsxx.vers30
-rw-r--r--src/daemon/https/tls/pkix.asn1241
-rw-r--r--src/daemon/https/tls/pkix_asn1_tab.c1130
-rw-r--r--src/daemon/https/tls/x509_b64.c599
-rw-r--r--src/daemon/https/tls/x509_b64.h45
-rw-r--r--src/daemon/https/tls_test.c348
-rw-r--r--src/daemon/https/x509/Makefile.am36
-rw-r--r--src/daemon/https/x509/common.c1491
-rw-r--r--src/daemon/https/x509/common.h126
-rw-r--r--src/daemon/https/x509/crl.c705
-rw-r--r--src/daemon/https/x509/crl_write.c316
-rw-r--r--src/daemon/https/x509/crq.c887
-rw-r--r--src/daemon/https/x509/crq.h30
-rw-r--r--src/daemon/https/x509/dn.c1140
-rw-r--r--src/daemon/https/x509/dn.h58
-rw-r--r--src/daemon/https/x509/dsa.c142
-rw-r--r--src/daemon/https/x509/dsa.h25
-rw-r--r--src/daemon/https/x509/extensions.c1095
-rw-r--r--src/daemon/https/x509/extensions.h68
-rw-r--r--src/daemon/https/x509/mpi.c576
-rw-r--r--src/daemon/https/x509/mpi.h57
-rw-r--r--src/daemon/https/x509/output.c1360
-rw-r--r--src/daemon/https/x509/pkcs12.c1325
-rw-r--r--src/daemon/https/x509/pkcs12.h208
-rw-r--r--src/daemon/https/x509/pkcs12_bag.c770
-rw-r--r--src/daemon/https/x509/pkcs12_encr.c169
-rw-r--r--src/daemon/https/x509/pkcs7.c1023
-rw-r--r--src/daemon/https/x509/pkcs7.h30
-rw-r--r--src/daemon/https/x509/privkey.h31
-rw-r--r--src/daemon/https/x509/privkey_pkcs8.c2219
-rw-r--r--src/daemon/https/x509/rfc2818.h26
-rw-r--r--src/daemon/https/x509/rfc2818_hostname.c160
-rw-r--r--src/daemon/https/x509/sign.c346
-rw-r--r--src/daemon/https/x509/sign.h36
-rw-r--r--src/daemon/https/x509/verify.h34
-rw-r--r--src/daemon/https/x509/x509-api.texi2943
-rw-r--r--src/daemon/https/x509/x509.c2851
-rw-r--r--src/daemon/https/x509/x509.h928
-rw-r--r--src/daemon/https/x509/x509_privkey.c1509
-rw-r--r--src/daemon/https/x509/x509_verify.c1037
-rw-r--r--src/daemon/https/x509/x509_write.c1094
256 files changed, 106559 insertions, 17 deletions
diff --git a/src/daemon/Makefile.am b/src/daemon/Makefile.am
index 365c1cf1..302d6ece 100644
--- a/src/daemon/Makefile.am
+++ b/src/daemon/Makefile.am
@@ -1,6 +1,15 @@
1SUBDIRS = . 1SUBDIRS = https .
2 2
3INCLUDES = -I$(top_srcdir)/src/include 3AM_CPPFLAGS = -I$(top_srcdir)/src/include \
4-I$(top_srcdir)/src/daemon \
5-I$(top_srcdir)/src/daemon/https/lgl \
6-I$(top_srcdir)/src/daemon/https/x509 \
7-I$(top_srcdir)/src/daemon/https/openpgp \
8-I$(top_srcdir)/src/daemon/https/opencdk \
9-I$(top_srcdir)/src/daemon/https/tls \
10-I$(top_srcdir)/src/daemon/https/includes \
11-I$(top_srcdir)/src/daemon/https/cfg \
12-I$(GCRYPT_CPPFLAGS)
4 13
5if HAVE_GNU_LD 14if HAVE_GNU_LD
6 retaincommand=-Wl,--retain-symbols-file -Wl,$(srcdir)/SYMBOLS 15 retaincommand=-Wl,--retain-symbols-file -Wl,$(srcdir)/SYMBOLS
@@ -12,21 +21,21 @@ lib_LTLIBRARIES = \
12 libmicrohttpd.la 21 libmicrohttpd.la
13 22
14libmicrohttpd_la_SOURCES = \ 23libmicrohttpd_la_SOURCES = \
15 connection.c connection.h \ 24connection.c connection.h \
16 reason_phrase.c reason_phrase.h \ 25reason_phrase.c reason_phrase.h \
17 daemon.c \ 26daemon.c \
18 internal.c internal.h \ 27internal.c internal.h \
19 memorypool.c memorypool.h \ 28memorypool.c memorypool.h \
20 plibc.h \ 29plibc.h \
21 postprocessor.c \ 30postprocessor.c \
22 response.c response.h 31response.c response.h
23libmicrohttpd_la_LDFLAGS = \ 32libmicrohttpd_la_LDFLAGS = \
24 -export-dynamic -version-info 4:3:0 $(retaincommand) \ 33 -export-dynamic -version-info 4:3:0 $(retaincommand)
25 -L$(GNUTLS_LIB_PATH) \ 34libmicrohttpd_la_LIBADD = \
26 -lgnutls 35https/libhttps.la
27libmicrohttpd_la_CPPFLAGS = \ 36
28 $(GNUTLS_CPPFLAGS)
29 37
38
30check_PROGRAMS = \ 39check_PROGRAMS = \
31 postprocessor_test \ 40 postprocessor_test \
32 postprocessor_large_test \ 41 postprocessor_large_test \
@@ -44,7 +53,6 @@ postprocessor_test_SOURCES = \
44postprocessor_test_LDADD = \ 53postprocessor_test_LDADD = \
45 $(top_builddir)/src/daemon/libmicrohttpd.la 54 $(top_builddir)/src/daemon/libmicrohttpd.la
46 55
47
48postprocessor_large_test_SOURCES = \ 56postprocessor_large_test_SOURCES = \
49 postprocessor_large_test.c 57 postprocessor_large_test.c
50postprocessor_large_test_LDADD = \ 58postprocessor_large_test_LDADD = \
diff --git a/src/daemon/https/Makefile.am b/src/daemon/https/Makefile.am
new file mode 100644
index 00000000..33f46f1b
--- /dev/null
+++ b/src/daemon/https/Makefile.am
@@ -0,0 +1,34 @@
1SUBDIRS = minitasn1 opencdk openpgp lgl x509 tls .
2
3AM_CPPFLAGS = -I./includes \
4-I$(top_srcdir)/src/daemon/https/lgl \
5-I$(top_srcdir)/src/daemon/https/x509 \
6-I$(top_srcdir)/src/daemon/https/openpgp \
7-I$(top_srcdir)/src/daemon/https/opencdk \
8-I$(top_srcdir)/src/daemon/https/tls \
9-I$(top_srcdir)/src/daemon/https/cfg
10
11noinst_LTLIBRARIES = libhttps.la
12
13libhttps_la_SOURCES = \
14https_common.c \
15errcodes.c
16
17libhttps_la_LIBADD = \
18opencdk/libopencdk.la \
19openpgp/libopenpgp.la \
20x509/libx509.la \
21lgl/liblgl.la \
22tls/libtls.la \
23minitasn1/libasn1.la
24
25#noinst_PROGRAMS = errcodes
26#errcodes_SOURCES = errcodes.c
27#errcodes_LDADD = ../lib/libgnutls.la $(LIBGCRYPT_LIBS) $(LIBTASN1_LIBS)
28
29# gnutls_serv_SOURCES = serv.gaa serv-gaa.h serv-gaa.c list.h serv.c common.h common.c select.c
30# srptool_SOURCES = crypt.gaa crypt-gaa.h crypt-gaa.c crypt.c
31# gnutls_cli_debug_SOURCES = tls_test.gaa tls_test-gaa.h tls_test-gaa.c \
32# tls_test.c tests.h tests.c common.h common.c
33# certtool_SOURCES = certtool.gaa certtool-gaa.h certtool-cfg.h \
34# certtool-gaa.c certtool.c prime.c certtool-cfg.c
diff --git a/src/daemon/https/errcodes b/src/daemon/https/errcodes
new file mode 100644
index 00000000..65774f43
--- /dev/null
+++ b/src/daemon/https/errcodes
@@ -0,0 +1,131 @@
1#! /bin/sh
2
3# errcodes - temporary wrapper script for .libs/errcodes
4# Generated by ltmain.sh - GNU libtool 1.5.26 Debian 1.5.26-3 (1.1220.2.493 2008/02/01 16:58:18)
5#
6# The errcodes program cannot be directly executed until all the libtool
7# libraries that it depends on are installed.
8#
9# This wrapper script should never be moved out of the build directory.
10# If it is, it will not operate correctly.
11
12# Sed substitution that helps us do robust quoting. It backslashifies
13# metacharacters that are still active within double-quoted strings.
14Xsed='/bin/sed -e 1s/^X//'
15sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
16
17# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE).
18if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
19 emulate sh
20 NULLCMD=:
21 # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
22 # is contrary to our usage. Disable this feature.
23 alias -g '${1+"$@"}'='"$@"'
24 setopt NO_GLOB_SUBST
25else
26 case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
27fi
28BIN_SH=xpg4; export BIN_SH # for Tru64
29DUALCASE=1; export DUALCASE # for MKS sh
30
31# The HP-UX ksh and POSIX shell print the target directory to stdout
32# if CDPATH is set.
33(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
34
35relink_command="(cd /home/lama/workbench/programming/c/gnunet/gnutls-2.2.3/src; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=\"/usr/lib/distcc:/usr/local/bin:/usr/bin:/bin:/usr/games\"; export PATH; gcc -std=gnu99 -g -O2 -D_REENTRANT -D_THREAD_SAFE -pipe -g -O2 -D_REENTRANT -D_THREAD_SAFE -Wno-pointer-sign -o \$progdir/\$file errcodes.o ../lib/.libs/libgnutls.so /usr/lib/libgcrypt.so -L/usr/lib /usr/lib/libtasn1.so -Wl,--rpath -Wl,/home/lama/workbench/programming/c/gnunet/gnutls-2.2.3/lib/.libs -Wl,--rpath -Wl,/home/lama/workbench/programming/c/gnunet/gnutls-2.2.3/build/lib ) "
36
37# This environment variable determines our operation mode.
38if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then
39 # install mode needs the following variable:
40 notinst_deplibs=' ../lib/libgnutls.la'
41else
42 # When we are sourced in execute mode, $file and $echo are already set.
43 if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
44 echo="echo"
45 file="$0"
46 # Make sure echo works.
47 if test "X$1" = X--no-reexec; then
48 # Discard the --no-reexec flag, and continue.
49 shift
50 elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
51 # Yippee, $echo works!
52 :
53 else
54 # Restart under the correct shell, and then maybe $echo will work.
55 exec /bin/sh "$0" --no-reexec ${1+"$@"}
56 fi
57 fi
58
59 # Find the directory that this script lives in.
60 thisdir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
61 test "x$thisdir" = "x$file" && thisdir=.
62
63 # Follow symbolic links until we get to the real thisdir.
64 file=`ls -ld "$file" | /bin/sed -n 's/.*-> //p'`
65 while test -n "$file"; do
66 destdir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
67
68 # If there was a directory component, then change thisdir.
69 if test "x$destdir" != "x$file"; then
70 case "$destdir" in
71 [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;;
72 *) thisdir="$thisdir/$destdir" ;;
73 esac
74 fi
75
76 file=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
77 file=`ls -ld "$thisdir/$file" | /bin/sed -n 's/.*-> //p'`
78 done
79
80 # Try to get the absolute directory name.
81 absdir=`cd "$thisdir" && pwd`
82 test -n "$absdir" && thisdir="$absdir"
83
84 program=lt-'errcodes'
85 progdir="$thisdir/.libs"
86
87 if test ! -f "$progdir/$program" || \
88 { file=`ls -1dt "$progdir/$program" "$progdir/../$program" 2>/dev/null | /bin/sed 1q`; \
89 test "X$file" != "X$progdir/$program"; }; then
90
91 file="$$-$program"
92
93 if test ! -d "$progdir"; then
94 mkdir "$progdir"
95 else
96 rm -f "$progdir/$file"
97 fi
98
99 # relink executable if necessary
100 if test -n "$relink_command"; then
101 if relink_command_output=`eval $relink_command 2>&1`; then :
102 else
103 echo "$relink_command_output" >&2
104 rm -f "$progdir/$file"
105 exit 1
106 fi
107 fi
108
109 mv -f "$progdir/$file" "$progdir/$program" 2>/dev/null ||
110 { rm -f "$progdir/$program";
111 mv -f "$progdir/$file" "$progdir/$program"; }
112 rm -f "$progdir/$file"
113 fi
114
115 if test -f "$progdir/$program"; then
116 if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
117 # Run the actual program with our arguments.
118
119 exec "$progdir/$program" ${1+"$@"}
120
121 $echo "$0: cannot exec $program $*"
122 exit 1
123 fi
124 else
125 # The program doesn't exist.
126 $echo "$0: error: \`$progdir/$program' does not exist" 1>&2
127 $echo "This script is just a wrapper for $program." 1>&2
128 echo "See the libtool documentation for more information." 1>&2
129 exit 1
130 fi
131fi
diff --git a/src/daemon/https/errcodes.c b/src/daemon/https/errcodes.c
new file mode 100644
index 00000000..96d04240
--- /dev/null
+++ b/src/daemon/https/errcodes.c
@@ -0,0 +1,65 @@
1#if HAVE_CONFIG_H
2#include "config.h"
3#endif
4
5#include <stdio.h>
6#include <stdlib.h>
7#include <string.h>
8#include <gnutls.h>
9
10const char *_gnutls_strerror (int);
11
12typedef struct
13{
14 char name[128];
15 int error_index;
16} error_name;
17
18
19static int
20compar (const void *_n1, const void *_n2)
21{
22 const error_name *n1 = (const error_name *) _n1,
23 *n2 = (const error_name *) _n2;
24 return strcmp (n1->name, n2->name);
25}
26
27//int
28//main (int argc, char *argv[])
29//{
30// int i, j;
31// const char *desc;
32// const char *_name;
33// error_name names_to_sort[400]; /* up to 400 names */
34//
35// printf ("@table @code\n");
36//
37// memset (names_to_sort, 0, sizeof (names_to_sort));
38// j = 0;
39// for (i = 0; i > -400; i--)
40// {
41// _name = _gnutls_strerror (i);
42// if (_name == NULL)
43// continue;
44//
45// strcpy (names_to_sort[j].name, _name);
46// names_to_sort[j].error_index = i;
47// j++;
48// }
49//
50// qsort (names_to_sort, j, sizeof (error_name), compar);
51//
52// for (i = 0; i < j; i++)
53// {
54// _name = names_to_sort[i].name;
55// desc = gnutls_strerror (names_to_sort[i].error_index);
56// if (desc == NULL || _name == NULL)
57// continue;
58//
59// printf ("@item %s:\n%s\n\n", _name, desc);
60// }
61//
62// printf ("@end table\n");
63//
64// return 0;
65//}
diff --git a/src/daemon/https/https_common.c b/src/daemon/https/https_common.c
new file mode 100644
index 00000000..748bc5bc
--- /dev/null
+++ b/src/daemon/https/https_common.c
@@ -0,0 +1,877 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 * Author: Nikos Mavrogiannopoulos
4 *
5 * This file is part of GNUTLS.
6 *
7 * GNUTLS is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * GNUTLS is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <config.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <gnutls.h>
26#include <extra.h>
27//#include "openpgp.h"
28#include <time.h>
29#include "https_common.h"
30
31#define TEST_STRING
32#define SU(x) (x!=NULL?x:"Unknown")
33
34// TODO clean - originaly from tls_test extern int verbose;
35int print_cert;
36int verbose = 0;
37
38static char buffer[5 * 1024];
39
40#define PRINTX(x,y) if (y[0]!=0) printf(" # %s %s\n", x, y)
41#define PRINT_PGP_NAME(X) PRINTX( "NAME:", name)
42
43const char str_unknown[] = "(unknown)";
44
45/* Hex encodes the given data.
46 */
47const char *
48raw_to_string (const unsigned char *raw, size_t raw_size)
49{
50 static char buf[1024];
51 size_t i;
52 if (raw_size == 0)
53 return NULL;
54
55 if (raw_size * 3 + 1 >= sizeof (buf))
56 return NULL;
57
58 for (i = 0; i < raw_size; i++)
59 {
60 sprintf (&(buf[i * 3]), "%02X%s", raw[i], (i == raw_size - 1) ? ""
61 : ":");
62 }
63 buf[sizeof (buf) - 1] = '\0';
64
65 return buf;
66}
67
68static const char *
69my_ctime (const time_t * tv)
70{
71 static char buf[256];
72 struct tm *tp;
73
74 if (((tp = localtime (tv)) == NULL) || (!strftime (buf, sizeof buf,
75 "%a %b %e %H:%M:%S %Z %Y\n",
76 tp)))
77 strcpy (buf, str_unknown); /* make sure buf text isn't garbage */
78
79 return buf;
80
81}
82
83void
84print_x509_info (gnutls_session_t session, const char *hostname)
85{
86 gnutls_x509_crt_t crt;
87 const gnutls_datum_t *cert_list;
88 unsigned int cert_list_size = 0;
89 int ret;
90 char digest[20];
91 char serial[40];
92 char dn[256];
93 size_t dn_size;
94 size_t digest_size = sizeof (digest);
95 unsigned int j;
96 size_t serial_size = sizeof (serial);
97 const char *print;
98 const char *cstr;
99 unsigned int bits, algo;
100 time_t expiret, activet;
101
102 cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
103
104 if (cert_list_size == 0)
105 {
106 fprintf (stderr, "No certificates found!\n");
107 return;
108 }
109
110 printf (" - Got a certificate list of %d certificates.\n\n",
111 cert_list_size);
112
113 for (j = 0; j < (unsigned int) cert_list_size; j++)
114 {
115
116 gnutls_x509_crt_init (&crt);
117 ret = gnutls_x509_crt_import (crt, &cert_list[j], GNUTLS_X509_FMT_DER);
118 if (ret < 0)
119 {
120 fprintf (stderr, "Decoding error: %s\n", gnutls_strerror (ret));
121 return;
122 }
123
124 printf (" - Certificate[%d] info:\n", j);
125
126 if (print_cert)
127 {
128 size_t size;
129
130 size = sizeof (buffer);
131
132 ret =
133 gnutls_x509_crt_export (crt, GNUTLS_X509_FMT_PEM, buffer, &size);
134 if (ret < 0)
135 {
136 fprintf (stderr, "Encoding error: %s\n", gnutls_strerror (ret));
137 return;
138 }
139 fputs ("\n", stdout);
140 fputs (buffer, stdout);
141 fputs ("\n", stdout);
142 }
143
144 if (j == 0 && hostname != NULL)
145 { /* Check the hostname of the first certificate
146 * if it matches the name of the host we
147 * connected to.
148 */
149 if (gnutls_x509_crt_check_hostname (crt, hostname) == 0)
150 {
151 printf
152 (" # The hostname in the certificate does NOT match '%s'.\n",
153 hostname);
154 }
155 else
156 {
157 printf (" # The hostname in the certificate matches '%s'.\n",
158 hostname);
159 }
160 }
161
162 expiret = gnutls_x509_crt_get_expiration_time (crt);
163 activet = gnutls_x509_crt_get_activation_time (crt);
164
165 printf (" # valid since: %s", my_ctime (&activet));
166 printf (" # expires at: %s", my_ctime (&expiret));
167
168 /* Print the serial number of the certificate.
169 */
170 if (verbose
171 && gnutls_x509_crt_get_serial (crt, serial, &serial_size) >= 0)
172 {
173 print = raw_to_string (serial, serial_size);
174 if (print != NULL)
175 printf (" # serial number: %s\n", print);
176 }
177
178 /* Print the fingerprint of the certificate
179 */
180 digest_size = sizeof (digest);
181 if ((ret = gnutls_x509_crt_get_fingerprint (crt, GNUTLS_DIG_MD5, digest,
182 &digest_size)) < 0)
183 {
184 fprintf (stderr,
185 "Error in fingerprint calculation: %s\n",
186 gnutls_strerror (ret));
187 }
188 else
189 {
190 print = raw_to_string (digest, digest_size);
191 if (print != NULL)
192 printf (" # fingerprint: %s\n", print);
193 }
194
195 /* Print the version of the X.509
196 * certificate.
197 */
198 if (verbose)
199 {
200 printf (" # version: #%d\n", gnutls_x509_crt_get_version (crt));
201
202 bits = 0;
203 algo = gnutls_x509_crt_get_pk_algorithm (crt, &bits);
204 printf (" # public key algorithm: ");
205
206 cstr = SU (gnutls_pk_algorithm_get_name (algo));
207 printf ("%s (%d bits)\n", cstr, bits);
208
209#ifdef ENABLE_PKI
210 if (algo == GNUTLS_PK_RSA)
211 {
212 gnutls_datum_t e, m;
213
214 ret = gnutls_x509_crt_get_pk_rsa_raw (crt, &m, &e);
215 if (ret >= 0)
216 {
217 print = SU (raw_to_string (e.data, e.size));
218 printf (" # e [%d bits]: %s\n", e.size * 8, print);
219
220 print = SU (raw_to_string (m.data, m.size));
221 printf (" # m [%d bits]: %s\n", m.size * 8, print);
222
223 gnutls_free (e.data);
224 gnutls_free (m.data);
225 }
226 }
227#endif
228 }
229
230 dn_size = sizeof (dn);
231 ret = gnutls_x509_crt_get_dn (crt, dn, &dn_size);
232 if (ret >= 0)
233 printf (" # Subject's DN: %s\n", dn);
234
235 dn_size = sizeof (dn);
236 ret = gnutls_x509_crt_get_issuer_dn (crt, dn, &dn_size);
237 if (ret >= 0)
238 printf (" # Issuer's DN: %s\n", dn);
239
240 gnutls_x509_crt_deinit (crt);
241
242 printf ("\n");
243
244 }
245
246}
247
248#ifdef ENABLE_OPENPGP
249
250void
251print_openpgp_info (gnutls_session_t session, const char *hostname)
252{
253
254 char digest[20];
255 size_t digest_size = sizeof (digest);
256 int ret;
257 const char *print;
258 const char *cstr;
259 char name[256];
260 size_t name_len = sizeof (name);
261 gnutls_openpgp_crt_t crt;
262 const gnutls_datum_t *cert_list;
263 int cert_list_size = 0;
264 time_t expiret;
265 time_t activet;
266
267 cert_list = gnutls_certificate_get_peers (session, &cert_list_size);
268
269 if (cert_list_size > 0)
270 {
271 unsigned int algo, bits;
272
273 gnutls_openpgp_crt_init (&crt);
274 ret = gnutls_openpgp_crt_import (crt, &cert_list[0],
275 GNUTLS_OPENPGP_FMT_RAW);
276 if (ret < 0)
277 {
278 fprintf (stderr, "Decoding error: %s\n", gnutls_strerror (ret));
279 return;
280 }
281
282 if (print_cert)
283 {
284 size_t size;
285
286 size = sizeof (buffer);
287
288 ret = gnutls_openpgp_crt_export (crt, GNUTLS_OPENPGP_FMT_BASE64,
289 buffer, &size);
290 if (ret < 0)
291 {
292 fprintf (stderr, "Encoding error: %s\n", gnutls_strerror (ret));
293 return;
294 }
295 fputs ("\n", stdout);
296 fputs (buffer, stdout);
297 fputs ("\n", stdout);
298 }
299
300 if (hostname != NULL)
301 { /* Check the hostname of the first certificate
302 * if it matches the name of the host we
303 * connected to.
304 */
305 if (gnutls_openpgp_crt_check_hostname (crt, hostname) == 0)
306 {
307 printf (" # The hostname in the key does NOT match '%s'.\n",
308 hostname);
309 }
310 else
311 {
312 printf (" # The hostname in the key matches '%s'.\n", hostname);
313 }
314 }
315
316 activet = gnutls_openpgp_crt_get_creation_time (crt);
317 expiret = gnutls_openpgp_crt_get_expiration_time (crt);
318
319 printf (" # Key was created at: %s", my_ctime (&activet));
320 printf (" # Key expires: ");
321 if (expiret != 0)
322 printf ("%s", my_ctime (&expiret));
323 else
324 printf ("Never\n");
325
326 if (gnutls_openpgp_crt_get_fingerprint (crt, digest, &digest_size) >= 0)
327 {
328 print = raw_to_string (digest, digest_size);
329
330 printf (" # PGP Key version: %d\n",
331 gnutls_openpgp_crt_get_version (crt));
332
333 bits = 0;
334 algo = gnutls_openpgp_crt_get_pk_algorithm (crt, &bits);
335
336 printf (" # PGP Key public key algorithm: ");
337 cstr = SU (gnutls_pk_algorithm_get_name (algo));
338 printf ("%s (%d bits)\n", cstr, bits);
339
340 if (print != NULL)
341 printf (" # PGP Key fingerprint: %s\n", print);
342
343 name_len = sizeof (name);
344 if (gnutls_openpgp_crt_get_name (crt, 0, name, &name_len) < 0)
345 {
346 fprintf (stderr, "Could not extract name\n");
347 }
348 else
349 {
350 PRINT_PGP_NAME (name);
351 }
352
353 }
354
355 gnutls_openpgp_crt_deinit (crt);
356
357 }
358}
359
360#endif
361
362void
363print_cert_vrfy (gnutls_session_t session)
364{
365 int rc;
366 unsigned int status;
367
368 rc = gnutls_certificate_verify_peers2 (session, &status);
369 printf ("\n");
370
371 if (rc == GNUTLS_E_NO_CERTIFICATE_FOUND)
372 {
373 printf ("- Peer did not send any certificate.\n");
374 return;
375 }
376
377 if (rc < 0)
378 {
379 printf ("- Could not verify certificate (err: %s)\n",
380 gnutls_strerror (rc));
381 return;
382 }
383
384 if (gnutls_certificate_type_get (session) == GNUTLS_CRT_X509)
385 {
386 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
387 printf ("- Peer's certificate issuer is unknown\n");
388 if (status & GNUTLS_CERT_INVALID)
389 printf ("- Peer's certificate is NOT trusted\n");
390 else
391 printf ("- Peer's certificate is trusted\n");
392 }
393 else
394 {
395 if (status & GNUTLS_CERT_INVALID)
396 printf ("- Peer's key is invalid\n");
397 else
398 printf ("- Peer's key is valid\n");
399 if (status & GNUTLS_CERT_SIGNER_NOT_FOUND)
400 printf ("- Could not find a signer of the peer's key\n");
401 }
402}
403
404int
405print_info (gnutls_session_t session, const char *hostname)
406{
407 const char *tmp;
408 gnutls_credentials_type_t cred;
409 gnutls_kx_algorithm_t kx;
410
411 /* print the key exchange's algorithm name
412 */
413 kx = gnutls_kx_get (session);
414
415 cred = gnutls_auth_get_type (session);
416 switch (cred)
417 {
418#ifdef ENABLE_ANON
419 case GNUTLS_CRD_ANON:
420 printf ("- Anonymous DH using prime of %d bits, secret key "
421 "of %d bits, and peer's public key is %d bits.\n",
422 gnutls_dh_get_prime_bits (session),
423 gnutls_dh_get_secret_bits (session),
424 gnutls_dh_get_peers_public_bits (session));
425 break;
426#endif
427#ifdef ENABLE_SRP
428 case GNUTLS_CRD_SRP:
429 /* This should be only called in server
430 * side.
431 */
432 if (gnutls_srp_server_get_username (session) != NULL)
433 printf ("- SRP authentication. Connected as '%s'\n",
434 gnutls_srp_server_get_username (session));
435 break;
436#endif
437#ifdef ENABLE_PSK
438 case GNUTLS_CRD_PSK:
439 /* This should be only called in server
440 * side.
441 */
442 if (gnutls_psk_server_get_username (session) != NULL)
443 printf ("- PSK authentication. Connected as '%s'\n",
444 gnutls_psk_server_get_username (session));
445 if (kx == GNUTLS_KX_DHE_PSK)
446 {
447 printf ("- DH using prime of %d bits, secret key "
448 "of %d bits, and peer's public key is %d bits.\n",
449 gnutls_dh_get_prime_bits (session),
450 gnutls_dh_get_secret_bits (session),
451 gnutls_dh_get_peers_public_bits (session));
452 }
453 break;
454#endif
455 case GNUTLS_CRD_IA:
456 printf ("- TLS/IA authentication\n");
457 break;
458 case GNUTLS_CRD_CERTIFICATE:
459 {
460 char dns[256];
461 size_t dns_size = sizeof (dns);
462 unsigned int type;
463
464 /* This fails in client side */
465 if (gnutls_server_name_get (session, dns, &dns_size, &type, 0) == 0)
466 {
467 printf ("- Given server name[%d]: %s\n", type, dns);
468 }
469 }
470
471 if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS)
472 {
473 printf ("- Ephemeral DH using prime of %d bits, secret key "
474 "of %d bits, and peer's public key is %d bits.\n",
475 gnutls_dh_get_prime_bits (session),
476 gnutls_dh_get_secret_bits (session),
477 gnutls_dh_get_peers_public_bits (session));
478 }
479
480 print_cert_info (session, hostname);
481
482 print_cert_vrfy (session);
483
484 }
485
486 tmp = SU (gnutls_protocol_get_name (gnutls_protocol_get_version (session)));
487 printf ("- Version: %s\n", tmp);
488
489 tmp = SU (gnutls_kx_get_name (kx));
490 printf ("- Key Exchange: %s\n", tmp);
491
492 tmp = SU (gnutls_cipher_get_name (gnutls_cipher_get (session)));
493 printf ("- Cipher: %s\n", tmp);
494
495 tmp = SU (gnutls_mac_get_name (gnutls_mac_get (session)));
496 printf ("- MAC: %s\n", tmp);
497
498 tmp = SU (gnutls_compression_get_name (gnutls_compression_get (session)));
499 printf ("- Compression: %s\n", tmp);
500
501 if (verbose)
502 {
503 char id[32];
504 size_t id_size = sizeof (id);
505 gnutls_session_get_id (session, id, &id_size);
506 printf ("- Session ID: %s\n", raw_to_string (id, id_size));
507 }
508
509 fflush (stdout);
510
511 return 0;
512}
513
514void
515print_cert_info (gnutls_session_t session, const char *hostname)
516{
517
518 if (gnutls_certificate_client_get_request_status (session) != 0)
519 printf ("- Server has requested a certificate.\n");
520
521 printf ("- Certificate type: ");
522 switch (gnutls_certificate_type_get (session))
523 {
524 case GNUTLS_CRT_X509:
525 printf ("X.509\n");
526 print_x509_info (session, hostname);
527 break;
528#ifdef ENABLE_OPENPGP
529 case GNUTLS_CRT_OPENPGP:
530 printf ("OpenPGP\n");
531 print_openpgp_info (session, hostname);
532 break;
533#endif
534 }
535}
536
537void
538print_list (int verbose)
539{
540 {
541 size_t i;
542 const char *name;
543 char id[2];
544 gnutls_kx_algorithm_t kx;
545 gnutls_cipher_algorithm_t cipher;
546 gnutls_mac_algorithm_t mac;
547 gnutls_protocol_t version;
548
549 printf ("Cipher suites:\n");
550 for (i = 0; (name = gnutls_cipher_suite_info (i, id, &kx, &cipher, &mac,
551 &version)); i++)
552 {
553 printf ("%-50s\t0x%02x, 0x%02x\t%s\n", name, (unsigned char) id[0],
554 (unsigned char) id[1], gnutls_protocol_get_name (version));
555 if (verbose)
556 printf ("\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n",
557 gnutls_kx_get_name (kx), gnutls_cipher_get_name (cipher),
558 gnutls_mac_get_name (mac));
559 }
560 }
561
562 {
563 const gnutls_certificate_type_t *p = gnutls_certificate_type_list ();
564
565 printf ("Certificate types: ");
566 for (; *p; p++)
567 {
568 printf ("%s", gnutls_certificate_type_get_name (*p));
569 if (*(p + 1))
570 printf (", ");
571 else
572 printf ("\n");
573 }
574 }
575
576 {
577 const gnutls_protocol_t *p = gnutls_protocol_list ();
578
579 printf ("Protocols: ");
580 for (; *p; p++)
581 {
582 printf ("%s", gnutls_protocol_get_name (*p));
583 if (*(p + 1))
584 printf (", ");
585 else
586 printf ("\n");
587 }
588 }
589
590 {
591 const gnutls_cipher_algorithm_t *p = gnutls_cipher_list ();
592
593 printf ("Ciphers: ");
594 for (; *p; p++)
595 {
596 printf ("%s", gnutls_cipher_get_name (*p));
597 if (*(p + 1))
598 printf (", ");
599 else
600 printf ("\n");
601 }
602 }
603
604 {
605 const gnutls_mac_algorithm_t *p = gnutls_mac_list ();
606
607 printf ("MACs: ");
608 for (; *p; p++)
609 {
610 printf ("%s", gnutls_mac_get_name (*p));
611 if (*(p + 1))
612 printf (", ");
613 else
614 printf ("\n");
615 }
616 }
617
618 {
619 const gnutls_kx_algorithm_t *p = gnutls_kx_list ();
620
621 printf ("Key exchange algorithms: ");
622 for (; *p; p++)
623 {
624 printf ("%s", gnutls_kx_get_name (*p));
625 if (*(p + 1))
626 printf (", ");
627 else
628 printf ("\n");
629 }
630 }
631
632 {
633 const gnutls_compression_method_t *p = gnutls_compression_list ();
634
635 printf ("Compression: ");
636 for (; *p; p++)
637 {
638 printf ("%s", gnutls_compression_get_name (*p));
639 if (*(p + 1))
640 printf (", ");
641 else
642 printf ("\n");
643 }
644 }
645}
646
647void
648print_license (void)
649{
650 fputs ("\nCopyright (C) 2004,2005,2006,2007 Free Software Foundation\n"
651 "This program is free software; you can redistribute it and/or modify \n"
652 "it under the terms of the GNU General Public License as published by \n"
653 "the Free Software Foundation; either version 3 of the License, or \n"
654 "(at your option) any later version. \n" "\n"
655 "This program is distributed in the hope that it will be useful, \n"
656 "but WITHOUT ANY WARRANTY; without even the implied warranty of \n"
657 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the \n"
658 "GNU General Public License for more details. \n" "\n"
659 "You should have received a copy of the GNU General Public License \n"
660 "along with this program; if not, write to the Free Software \n"
661 "Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n",
662 stdout);
663}
664
665static int depr_printed = 0;
666#define DEPRECATED if (depr_printed==0) { \
667 fprintf(stderr, "This method of specifying algorithms is deprecated. Please use the --priority option.\n"); \
668 depr_printed = 1; \
669 }
670
671void
672parse_protocols (char **protocols, int protocols_size, int *protocol_priority)
673{
674 int i, j;
675
676 if (protocols != NULL && protocols_size > 0)
677 {
678 DEPRECATED;
679
680 for (j = i = 0; i < protocols_size; i++)
681 {
682 if (strncasecmp (protocols[i], "SSL", 3) == 0)
683 protocol_priority[j++] = GNUTLS_SSL3;
684 else if (strncasecmp (protocols[i], "TLS1.1", 6) == 0)
685 protocol_priority[j++] = GNUTLS_TLS1_1;
686 else if (strncasecmp (protocols[i], "TLS1.2", 6) == 0)
687 protocol_priority[j++] = GNUTLS_TLS1_2;
688 else if (strncasecmp (protocols[i], "TLS", 3) == 0)
689 protocol_priority[j++] = GNUTLS_TLS1_0;
690 else
691 fprintf (stderr, "Unknown protocol: '%s'\n", protocols[i]);
692 }
693 protocol_priority[j] = 0;
694 }
695}
696
697void
698parse_ciphers (char **ciphers, int nciphers, int *cipher_priority)
699{
700 int j, i;
701
702 if (ciphers != NULL && nciphers > 0)
703 {
704 DEPRECATED;
705 for (j = i = 0; i < nciphers; i++)
706 {
707 if (strncasecmp (ciphers[i], "AES-2", 5) == 0)
708 cipher_priority[j++] = GNUTLS_CIPHER_AES_256_CBC;
709 else if (strncasecmp (ciphers[i], "AES", 3) == 0)
710 cipher_priority[j++] = GNUTLS_CIPHER_AES_128_CBC;
711 else if (strncasecmp (ciphers[i], "3DE", 3) == 0)
712 cipher_priority[j++] = GNUTLS_CIPHER_3DES_CBC;
713 else if (strcasecmp (ciphers[i], "ARCFOUR-40") == 0)
714 cipher_priority[j++] = GNUTLS_CIPHER_ARCFOUR_40;
715 else if (strcasecmp (ciphers[i], "ARCFOUR") == 0)
716 cipher_priority[j++] = GNUTLS_CIPHER_ARCFOUR_128;
717#ifdef ENABLE_CAMELLIA
718 else if (strncasecmp (ciphers[i], "CAMELLIA-2", 10) == 0)
719 cipher_priority[j++] = GNUTLS_CIPHER_CAMELLIA_256_CBC;
720 else if (strncasecmp (ciphers[i], "CAM", 3) == 0)
721 cipher_priority[j++] = GNUTLS_CIPHER_CAMELLIA_128_CBC;
722#endif
723 else if (strncasecmp (ciphers[i], "NUL", 3) == 0)
724 cipher_priority[j++] = GNUTLS_CIPHER_NULL;
725 else
726 fprintf (stderr, "Unknown cipher: '%s'\n", ciphers[i]);
727 }
728 cipher_priority[j] = 0;
729 }
730}
731
732void
733parse_macs (char **macs, int nmacs, int *mac_priority)
734{
735 int i, j;
736
737 if (macs != NULL && nmacs > 0)
738 {
739 DEPRECATED;
740 for (j = i = 0; i < nmacs; i++)
741 {
742 if (strncasecmp (macs[i], "MD5", 3) == 0)
743 mac_priority[j++] = GNUTLS_MAC_MD5;
744 else if (strncasecmp (macs[i], "SHA256", 6) == 0)
745 mac_priority[j++] = GNUTLS_MAC_SHA256;
746 else if (strncasecmp (macs[i], "SHA", 3) == 0)
747 mac_priority[j++] = GNUTLS_MAC_SHA1;
748 else
749 fprintf (stderr, "Unknown MAC: '%s'\n", macs[i]);
750 }
751 mac_priority[j] = 0;
752 }
753}
754
755void
756parse_ctypes (char **ctype, int nctype, int *cert_type_priority)
757{
758 int i, j;
759
760 if (ctype != NULL && nctype > 0)
761 {
762 DEPRECATED;
763 for (j = i = 0; i < nctype; i++)
764 {
765 if (strncasecmp (ctype[i], "OPE", 3) == 0)
766 cert_type_priority[j++] = GNUTLS_CRT_OPENPGP;
767 else if (strncasecmp (ctype[i], "X", 1) == 0)
768 cert_type_priority[j++] = GNUTLS_CRT_X509;
769 else
770 fprintf (stderr, "Unknown certificate type: '%s'\n", ctype[i]);
771 }
772 cert_type_priority[j] = 0;
773 }
774}
775
776void
777parse_kx (char **kx, int nkx, int *kx_priority)
778{
779 int i, j;
780
781 if (kx != NULL && nkx > 0)
782 {
783 DEPRECATED;
784 for (j = i = 0; i < nkx; i++)
785 {
786 if (strcasecmp (kx[i], "SRP") == 0)
787 kx_priority[j++] = GNUTLS_KX_SRP;
788 else if (strcasecmp (kx[i], "SRP-RSA") == 0)
789 kx_priority[j++] = GNUTLS_KX_SRP_RSA;
790 else if (strcasecmp (kx[i], "SRP-DSS") == 0)
791 kx_priority[j++] = GNUTLS_KX_SRP_DSS;
792 else if (strcasecmp (kx[i], "RSA") == 0)
793 kx_priority[j++] = GNUTLS_KX_RSA;
794 else if (strcasecmp (kx[i], "PSK") == 0)
795 kx_priority[j++] = GNUTLS_KX_PSK;
796 else if (strcasecmp (kx[i], "DHE-PSK") == 0)
797 kx_priority[j++] = GNUTLS_KX_DHE_PSK;
798 else if (strcasecmp (kx[i], "RSA-EXPORT") == 0)
799 kx_priority[j++] = GNUTLS_KX_RSA_EXPORT;
800 else if (strncasecmp (kx[i], "DHE-RSA", 7) == 0)
801 kx_priority[j++] = GNUTLS_KX_DHE_RSA;
802 else if (strncasecmp (kx[i], "DHE-DSS", 7) == 0)
803 kx_priority[j++] = GNUTLS_KX_DHE_DSS;
804 else if (strncasecmp (kx[i], "ANON", 4) == 0)
805 kx_priority[j++] = GNUTLS_KX_ANON_DH;
806 else
807 fprintf (stderr, "Unknown key exchange: '%s'\n", kx[i]);
808 }
809 kx_priority[j] = 0;
810 }
811}
812
813void
814parse_comp (char **comp, int ncomp, int *comp_priority)
815{
816 int i, j;
817
818 if (comp != NULL && ncomp > 0)
819 {
820 DEPRECATED;
821 for (j = i = 0; i < ncomp; i++)
822 {
823 if (strncasecmp (comp[i], "NUL", 3) == 0)
824 comp_priority[j++] = GNUTLS_COMP_NULL;
825 else if (strncasecmp (comp[i], "ZLI", 3) == 0)
826 comp_priority[j++] = GNUTLS_COMP_DEFLATE;
827 else if (strncasecmp (comp[i], "DEF", 3) == 0)
828 comp_priority[j++] = GNUTLS_COMP_DEFLATE;
829 else if (strncasecmp (comp[i], "LZO", 3) == 0)
830 comp_priority[j++] = GNUTLS_COMP_LZO;
831 else
832 fprintf (stderr, "Unknown compression: '%s'\n", comp[i]);
833 }
834 comp_priority[j] = 0;
835 }
836}
837
838void
839sockets_init (void)
840{
841#ifdef _WIN32
842 WORD wVersionRequested;
843 WSADATA wsaData;
844
845 wVersionRequested = MAKEWORD (1, 1);
846 if (WSAStartup (wVersionRequested, &wsaData) != 0)
847 {
848 perror ("WSA_STARTUP_ERROR");
849 }
850#endif
851}
852
853/* converts a service name or a port (in string) to a
854 * port number. The protocol is assumed to be TCP.
855 *
856 * returns -1 on error;
857 */
858int
859service_to_port (const char *service)
860{
861 int port;
862 struct servent *server_port;
863
864 port = atoi (service);
865 if (port != 0)
866 return port;
867
868 server_port = getservbyname (service, "tcp");
869 if (server_port == NULL)
870 {
871 perror ("getservbyname()");
872 return (-1);
873 }
874
875 return ntohs (server_port->s_port);
876
877}
diff --git a/src/daemon/https/https_common.h b/src/daemon/https/https_common.h
new file mode 100644
index 00000000..3ccd2cb1
--- /dev/null
+++ b/src/daemon/https/https_common.h
@@ -0,0 +1,40 @@
1#define PORT 5556
2#define SERVER "127.0.0.1"
3
4#include <config.h>
5#include <gnutls.h>
6
7#include <sys/socket.h>
8#include <arpa/inet.h>
9#ifdef _WIN32
10# include <io.h>
11# include <winbase.h>
12# define close closesocket
13#else
14# include <netinet/in.h>
15# include <unistd.h>
16# include <netdb.h>
17# include <signal.h>
18#endif
19
20/* the number of elements in the priority structures.
21 */
22#define PRI_MAX 16
23
24extern const char str_unknown[];
25
26int print_info (gnutls_session_t state, const char *hostname);
27void print_cert_info (gnutls_session_t state, const char *hostname);
28void print_list (int verbose);
29
30void parse_comp (char **comp, int ncomp, int *comp_priority);
31void parse_kx (char **kx, int nkx, int *kx_priority);
32void parse_ctypes (char **ctype, int nctype, int *cert_type_priority);
33void parse_macs (char **macs, int nmacs, int *mac_priority);
34void parse_ciphers (char **ciphers, int nciphers, int *cipher_priority);
35void parse_protocols (char **protocols, int protocols_size,
36 int *protocol_priority);
37const char *raw_to_string (const unsigned char *raw, size_t raw_size);
38int service_to_port (const char *service);
39
40void sockets_init (void);
diff --git a/src/daemon/https/includes/Makefile.am b/src/daemon/https/includes/Makefile.am
new file mode 100644
index 00000000..b0c6ada1
--- /dev/null
+++ b/src/daemon/https/includes/Makefile.am
@@ -0,0 +1,3 @@
1AM_CPPFLAGS = -I$(top_srcdir)/src/https/includes
2
3lib_LTLIBRARIES = libmicrohttpd.la
diff --git a/src/daemon/https/includes/compat.h b/src/daemon/https/includes/compat.h
new file mode 100644
index 00000000..32f5d2bd
--- /dev/null
+++ b/src/daemon/https/includes/compat.h
@@ -0,0 +1,98 @@
1/* Typedefs to be fully compatible with the types of
2 * GnuTLS 1.0.x.
3 */
4
5#include "gnutls.h"
6
7#ifndef GCOMPAT_H
8# define GCOMPAT_H
9
10#ifdef __GNUC__
11
12#define _GNUTLS_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
13
14#if _GNUTLS_GCC_VERSION >= 30100
15#define _GNUTLS_GCC_ATTR_DEPRECATED __attribute__ ((__deprecated__))
16#endif
17
18#endif /* __GNUC__ */
19
20#ifndef _GNUTLS_GCC_ATTR_DEPRECATED
21#define _GNUTLS_GCC_ATTR_DEPRECATED
22#endif
23
24#define gnutls_cipher_algorithm gnutls_cipher_algorithm_t
25#define gnutls_kx_algorithm gnutls_kx_algorithm_t
26#define gnutls_paramsype gnutls_paramsype_t
27#define gnutls_mac_algorithm gnutls_mac_algorithm_t
28#define gnutls_digest_algorithm gnutls_digest_algorithm_t
29#define gnutls_compression_method gnutls_compression_method_t
30#define gnutls_connection_end gnutls_connection_end_t
31#define gnutls_credentialsype gnutls_credentialsype_t
32#define gnutls_certificateype gnutls_certificateype_t
33#define gnutls_x509_crt_fmt gnutls_x509_crt_fmt_t
34#define gnutls_openpgp_key_fmt gnutls_openpgp_key_fmt_t
35#define gnutls_pk_algorithm gnutls_pk_algorithm_t
36#define gnutls_sign_algorithm gnutls_sign_algorithm_t
37#define gnutls_server_name gnutls_server_nameype_t
38#define gnutls_protocol gnutls_protocol_version_t
39#define gnutls_close_request gnutls_close_request_t
40#define gnutls_openpgp_key_status gnutls_openpgp_key_status_t
41#define gnutls_certificate_request gnutls_certificate_request_t
42#define gnutls_certificate_status gnutls_certificate_status_t
43#define gnutls_session gnutls_session_t
44#define gnutls_alert_level gnutls_alert_level_t
45#define gnutls_alert_description gnutls_alert_description_t
46#define gnutls_x509_subject_alt_name gnutls_x509_subject_alt_name_t
47#define gnutls_openpgp_key gnutls_openpgp_key_t
48#define gnutls_openpgp_privkey gnutls_openpgp_privkey_t
49#define gnutls_openpgp_keyring gnutls_openpgp_keyring_t
50#define gnutls_x509_crt gnutls_x509_crt_t
51#define gnutls_x509_privkey gnutls_x509_privkey_t
52#define gnutls_x509_crl gnutls_x509_crl_t
53#define gnutls_pkcs7 gnutls_pkcs7_t
54#define gnutls_x509_crq gnutls_x509_crq_t
55#define gnutls_pkcs_encrypt_flags gnutls_pkcs_encrypt_flags_t
56#define gnutls_pkcs12_bag_type gnutls_pkcs12_bag_type_t
57#define gnutls_pkcs12_bag gnutls_pkcs12_bag_t
58#define gnutls_pkcs12 gnutls_pkcs12_t
59#define gnutls_certificate_credentials gnutls_certificate_credentials_t
60#define gnutls_anon_server_credentials gnutls_anon_server_credentials_t
61#define gnutls_anon_client_credentials gnutls_anon_client_credentials_t
62#define gnutls_srp_client_credentials gnutls_srp_client_credentials_t
63#define gnutls_srp_server_credentials gnutls_srp_server_credentials_t
64#define gnutls_dh_params gnutls_dh_params_t
65#define gnutls_rsa_params gnutls_rsa_params_t
66#define gnutls_params_type gnutls_params_type_t
67#define gnutls_credentials_type gnutls_credentials_type_t
68#define gnutls_certificate_type gnutls_certificate_type_t
69#define gnutls_datum gnutls_datum_t
70#define gnutls_transport_ptr gnutls_transport_ptr_t
71
72/* Old SRP alerts removed in 2.1.x because the TLS-SRP RFC was
73 modified to use the PSK alert. */
74#define GNUTLS_A_MISSING_SRP_USERNAME GNUTLS_A_UNKNOWN_PSK_IDENTITY
75#define GNUTLS_A_UNKNOWN_SRP_USERNAME GNUTLS_A_UNKNOWN_PSK_IDENTITY
76
77/* OpenPGP stuff renamed in 2.1.x. */
78#define gnutls_openpgp_key_fmt_t gnutls_openpgp_crt_fmt_t
79#define GNUTLS_OPENPGP_KEY GNUTLS_OPENPGP_CERT
80#define GNUTLS_OPENPGP_KEY_FINGERPRINT GNUTLS_OPENPGP_CERT_FINGERPRINT
81#define gnutls_openpgp_send_key gnutls_openpgp_send_cert
82#define gnutls_openpgp_key_status_t gnutls_openpgp_crt_status_t
83#define gnutls_openpgp_key_t gnutls_openpgp_crt_t
84#define gnutls_openpgp_key_init gnutls_openpgp_crt_init
85#define gnutls_openpgp_key_deinit gnutls_openpgp_crt_deinit
86#define gnutls_openpgp_key_import gnutls_openpgp_crt_import
87#define gnutls_openpgp_key_export gnutls_openpgp_crt_export
88#define gnutls_openpgp_key_get_key_usage gnutls_openpgp_crt_get_key_usage
89#define gnutls_openpgp_key_get_fingerprint gnutls_openpgp_crt_get_fingerprint
90#define gnutls_openpgp_key_get_pk_algorithm gnutls_openpgp_crt_get_pk_algorithm
91#define gnutls_openpgp_key_get_name gnutls_openpgp_crt_get_name
92#define gnutls_openpgp_key_get_version gnutls_openpgp_crt_get_version
93#define gnutls_openpgp_key_get_creation_time gnutls_openpgp_crt_get_creation_time
94#define gnutls_openpgp_key_get_expiration_time gnutls_openpgp_crt_get_expiration_time
95#define gnutls_openpgp_key_get_id gnutls_openpgp_crt_get_id
96#define gnutls_openpgp_key_check_hostname gnutls_openpgp_crt_check_hostname
97
98#endif /* GCOMPAT_H */
diff --git a/src/daemon/https/includes/extra.h b/src/daemon/https/includes/extra.h
new file mode 100644
index 00000000..ca0cb5b4
--- /dev/null
+++ b/src/daemon/https/includes/extra.h
@@ -0,0 +1,185 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS-EXTRA.
7 *
8 * GNUTLS-EXTRA is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 3 of the
11 * License, or (at your option) any later version.
12 *
13 * GNUTLS-EXTRA is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with GNUTLS-EXTRA; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 *
23 */
24
25/* Note the libgnutls-extra is not a standalone library. It requires
26 * to link also against libgnutls.
27 */
28
29#ifndef GNUTLS_EXTRA_H
30# define GNUTLS_EXTRA_H
31
32#include <gnutls.h>
33
34#ifdef __cplusplus
35extern "C"
36{
37#endif
38
39#define LIBGNUTLS_EXTRA_VERSION LIBGNUTLS_VERSION
40
41/* Openpgp certificate stuff
42 */
43
44 typedef enum gnutls_openpgp_crt_fmt
45 { GNUTLS_OPENPGP_FMT_RAW,
46 GNUTLS_OPENPGP_FMT_BASE64
47 } gnutls_openpgp_crt_fmt_t;
48
49/**
50 * gnutls_openpgp_recv_key_func - Callback prototype to get OpenPGP keys
51 * @session: a TLS session
52 * @keyfpr: key fingerprint
53 * @keyfpr_length: length of key fingerprint
54 * @key: output key.
55 *
56 * A callback of this type is used to retrieve OpenPGP keys. Only
57 * useful on the server, and will only be used if the peer send a key
58 * fingerprint instead of a full key. See also
59 * gnutls_openpgp_set_recv_key_function().
60 *
61 */
62 typedef int (*gnutls_openpgp_recv_key_func) (gnutls_session_t session,
63 const unsigned char *keyfpr,
64 unsigned int keyfpr_length,
65 gnutls_datum_t * key);
66
67 void gnutls_openpgp_set_recv_key_function (gnutls_session_t session,
68 gnutls_openpgp_recv_key_func
69 func);
70
71 int
72 gnutls_certificate_set_openpgp_key_file (gnutls_certificate_credentials_t
73 res, const char *CERTFILE,
74 const char *KEYFILE, gnutls_openpgp_crt_fmt_t);
75 int gnutls_certificate_set_openpgp_key_mem (gnutls_certificate_credentials_t
76 res,
77 const gnutls_datum_t * CERT,
78 const gnutls_datum_t * KEY, gnutls_openpgp_crt_fmt_t);
79
80 int
81 gnutls_certificate_set_openpgp_keyring_mem
82 (gnutls_certificate_credentials_t c, const unsigned char *data,
83 size_t dlen, gnutls_openpgp_crt_fmt_t);
84
85 int
86 gnutls_certificate_set_openpgp_keyring_file
87 (gnutls_certificate_credentials_t c, const char *file, gnutls_openpgp_crt_fmt_t);
88
89 /* TLS/IA stuff
90 */
91
92 typedef enum
93 {
94 GNUTLS_IA_APPLICATION_PAYLOAD = 0,
95 GNUTLS_IA_INTERMEDIATE_PHASE_FINISHED = 1,
96 GNUTLS_IA_FINAL_PHASE_FINISHED = 2
97 } gnutls_ia_apptype_t;
98
99 /* TLS/IA credential
100 */
101
102 typedef int (*gnutls_ia_avp_func) (gnutls_session_t session, void *ptr,
103 const char *last, size_t lastlen,
104 char **next, size_t * nextlen);
105
106 typedef struct gnutls_ia_server_credentials_st
107 *gnutls_ia_server_credentials_t;
108 typedef struct gnutls_ia_client_credentials_st
109 *gnutls_ia_client_credentials_t;
110
111 /* Allocate and free TLS/IA credentials. */
112 extern void
113 gnutls_ia_free_client_credentials (gnutls_ia_client_credentials_t sc);
114 extern int
115 gnutls_ia_allocate_client_credentials (gnutls_ia_client_credentials_t *
116 sc);
117
118 extern void
119 gnutls_ia_free_server_credentials (gnutls_ia_server_credentials_t sc);
120 extern int
121 gnutls_ia_allocate_server_credentials (gnutls_ia_server_credentials_t *
122 sc);
123
124 /* Client TLS/IA credential functions. */
125 extern void
126 gnutls_ia_set_client_avp_function (gnutls_ia_client_credentials_t cred,
127 gnutls_ia_avp_func avp_func);
128 extern void
129 gnutls_ia_set_client_avp_ptr (gnutls_ia_client_credentials_t cred,
130 void *ptr);
131 extern void *gnutls_ia_get_client_avp_ptr (gnutls_ia_client_credentials_t
132 cred);
133
134 /* Server TLS/IA credential functions. */
135 extern void
136 gnutls_ia_set_server_avp_function (gnutls_ia_server_credentials_t cred,
137 gnutls_ia_avp_func avp_func);
138 extern void
139 gnutls_ia_set_server_avp_ptr (gnutls_ia_server_credentials_t cred,
140 void *ptr);
141 extern void *gnutls_ia_get_server_avp_ptr (gnutls_ia_server_credentials_t
142 cred);
143
144 /* TLS/IA handshake. */
145 extern int gnutls_ia_handshake_p (gnutls_session_t session);
146
147 extern int gnutls_ia_handshake (gnutls_session_t session);
148
149 /* TLS/IA low level interface. */
150 extern int
151 gnutls_ia_permute_inner_secret (gnutls_session_t session,
152 size_t session_keys_size,
153 const char *session_keys);
154 extern int gnutls_ia_endphase_send (gnutls_session_t session,
155 int final_p);
156
157 extern int gnutls_ia_verify_endphase (gnutls_session_t session,
158 const char *checksum);
159
160 extern ssize_t gnutls_ia_send (gnutls_session_t session,
161 const char *data, size_t sizeofdata);
162 extern ssize_t gnutls_ia_recv (gnutls_session_t session,
163 char *data, size_t sizeofdata);
164
165 /* Utility stuff. */
166 extern int gnutls_ia_generate_challenge (gnutls_session_t session,
167 size_t buffer_size,
168 char *buffer);
169 extern void gnutls_ia_extract_inner_secret (gnutls_session_t session,
170 char *buffer);
171
172 /* Define whether inner phases are wanted. */
173 extern void gnutls_ia_enable (gnutls_session_t session,
174 int allow_skip_on_resume);
175
176 int gnutls_global_init_extra (void);
177
178/* returns libgnutls-extra version (call it with a NULL argument)
179 */
180 const char *gnutls_extra_check_version (const char *req_version);
181
182#ifdef __cplusplus
183}
184#endif
185#endif
diff --git a/src/daemon/https/includes/gnutls.h b/src/daemon/https/includes/gnutls.h
new file mode 100644
index 00000000..b5d168f7
--- /dev/null
+++ b/src/daemon/https/includes/gnutls.h
@@ -0,0 +1,1286 @@
1/* -*- c -*-
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavroyanopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 * USA
22 *
23 */
24
25/* This file contains the types and prototypes for all the
26 * high level functionality of gnutls main library. For the
27 * extra functionality (which is under the GNU GPL license) check
28 * the gnutls/extra.h header. The openssl compatibility layer is
29 * in gnutls/openssl.h.
30 *
31 * The low level cipher functionality is in libgcrypt. Check
32 * gcrypt.h
33 */
34
35
36#ifndef GNUTLS_H
37# define GNUTLS_H
38
39#ifdef __cplusplus
40extern "C"
41{
42#endif
43
44#define LIBGNUTLS_VERSION "2.2.3"
45
46#define LIBGNUTLS_VERSION_MAJOR 2
47#define LIBGNUTLS_VERSION_MINOR 2
48#define LIBGNUTLS_VERSION_PATCH 3
49
50#define LIBGNUTLS_VERSION_NUMBER 0x020203
51
52
53
54/* Get size_t. */
55#include <stddef.h>
56/* Get ssize_t. */
57#ifndef HAVE_SSIZE_T
58# define HAVE_SSIZE_T
59#include <sys/types.h>
60#endif
61/* Get time_t. */
62#include <time.h>
63#include <compat.h>
64
65#define GNUTLS_CIPHER_RIJNDAEL_128_CBC GNUTLS_CIPHER_AES_128_CBC
66#define GNUTLS_CIPHER_RIJNDAEL_256_CBC GNUTLS_CIPHER_AES_256_CBC
67#define GNUTLS_CIPHER_RIJNDAEL_CBC GNUTLS_CIPHER_AES_128_CBC
68#define GNUTLS_CIPHER_ARCFOUR GNUTLS_CIPHER_ARCFOUR_128
69
70 typedef enum gnutls_cipher_algorithm
71 {
72 GNUTLS_CIPHER_UNKNOWN = 0,
73 GNUTLS_CIPHER_NULL = 1,
74 GNUTLS_CIPHER_ARCFOUR_128,
75 GNUTLS_CIPHER_3DES_CBC,
76 GNUTLS_CIPHER_AES_128_CBC,
77 GNUTLS_CIPHER_AES_256_CBC,
78 GNUTLS_CIPHER_ARCFOUR_40,
79 GNUTLS_CIPHER_CAMELLIA_128_CBC,
80 GNUTLS_CIPHER_CAMELLIA_256_CBC,
81 GNUTLS_CIPHER_RC2_40_CBC = 90,
82 GNUTLS_CIPHER_DES_CBC
83 } gnutls_cipher_algorithm_t;
84
85 typedef enum
86 {
87 GNUTLS_KX_UNKNOWN = 0,
88 GNUTLS_KX_RSA = 1,
89 GNUTLS_KX_DHE_DSS,
90 GNUTLS_KX_DHE_RSA,
91 GNUTLS_KX_ANON_DH,
92 GNUTLS_KX_SRP,
93 GNUTLS_KX_RSA_EXPORT,
94 GNUTLS_KX_SRP_RSA,
95 GNUTLS_KX_SRP_DSS,
96 GNUTLS_KX_PSK,
97 GNUTLS_KX_DHE_PSK
98 } gnutls_kx_algorithm_t;
99
100 typedef enum
101 {
102 GNUTLS_PARAMS_RSA_EXPORT = 1,
103 GNUTLS_PARAMS_DH
104 } gnutls_params_type_t;
105
106 typedef enum
107 {
108 GNUTLS_CRD_CERTIFICATE = 1,
109 GNUTLS_CRD_ANON,
110 GNUTLS_CRD_SRP,
111 GNUTLS_CRD_PSK,
112 GNUTLS_CRD_IA
113 } gnutls_credentials_type_t;
114
115#define GNUTLS_MAC_SHA GNUTLS_MAC_SHA1
116#define GNUTLS_DIG_SHA GNUTLS_DIG_SHA1
117
118 typedef enum
119 {
120 GNUTLS_MAC_UNKNOWN = 0,
121 GNUTLS_MAC_NULL = 1,
122 GNUTLS_MAC_MD5,
123 GNUTLS_MAC_SHA1,
124 //GNUTLS_MAC_RMD160,
125 //GNUTLS_MAC_MD2,
126 GNUTLS_MAC_SHA256,
127 //GNUTLS_MAC_SHA384,
128 //GNUTLS_MAC_SHA512
129 } gnutls_mac_algorithm_t;
130
131 /* The enumerations here should have the same value with
132 gnutls_mac_algorithm_t.
133 */
134 typedef enum
135 {
136 GNUTLS_DIG_NULL = GNUTLS_MAC_NULL,
137 GNUTLS_DIG_MD5 = GNUTLS_MAC_MD5,
138 GNUTLS_DIG_SHA1 = GNUTLS_MAC_SHA1,
139 GNUTLS_DIG_SHA256 = GNUTLS_MAC_SHA256,
140 } gnutls_digest_algorithm_t;
141
142 /* exported for other gnutls headers. This is the maximum number of
143 * algorithms (ciphers, kx or macs).
144 */
145#define GNUTLS_MAX_ALGORITHM_NUM 16
146
147#define GNUTLS_COMP_ZLIB GNUTLS_COMP_DEFLATE
148 typedef enum
149 {
150 GNUTLS_COMP_UNKNOWN = 0,
151 GNUTLS_COMP_NULL = 1,
152 GNUTLS_COMP_DEFLATE,
153 GNUTLS_COMP_LZO /* only available if gnutls-extra has
154 been initialized
155 */
156 } gnutls_compression_method_t;
157
158 typedef enum
159 {
160 GNUTLS_SERVER = 1,
161 GNUTLS_CLIENT
162 } gnutls_connection_end_t;
163
164 typedef enum
165 {
166 GNUTLS_AL_WARNING = 1,
167 GNUTLS_AL_FATAL
168 } gnutls_alert_level_t;
169
170 typedef enum
171 {
172 GNUTLS_A_CLOSE_NOTIFY,
173 GNUTLS_A_UNEXPECTED_MESSAGE = 10,
174 GNUTLS_A_BAD_RECORD_MAC = 20,
175 GNUTLS_A_DECRYPTION_FAILED,
176 GNUTLS_A_RECORD_OVERFLOW,
177 GNUTLS_A_DECOMPRESSION_FAILURE = 30,
178 GNUTLS_A_HANDSHAKE_FAILURE = 40,
179 GNUTLS_A_SSL3_NO_CERTIFICATE = 41,
180 GNUTLS_A_BAD_CERTIFICATE = 42,
181 GNUTLS_A_UNSUPPORTED_CERTIFICATE,
182 GNUTLS_A_CERTIFICATE_REVOKED,
183 GNUTLS_A_CERTIFICATE_EXPIRED,
184 GNUTLS_A_CERTIFICATE_UNKNOWN,
185 GNUTLS_A_ILLEGAL_PARAMETER,
186 GNUTLS_A_UNKNOWN_CA,
187 GNUTLS_A_ACCESS_DENIED,
188 GNUTLS_A_DECODE_ERROR = 50,
189 GNUTLS_A_DECRYPT_ERROR,
190 GNUTLS_A_EXPORT_RESTRICTION = 60,
191 GNUTLS_A_PROTOCOL_VERSION = 70,
192 GNUTLS_A_INSUFFICIENT_SECURITY,
193 GNUTLS_A_INTERNAL_ERROR = 80,
194 GNUTLS_A_USER_CANCELED = 90,
195 GNUTLS_A_NO_RENEGOTIATION = 100,
196 GNUTLS_A_UNSUPPORTED_EXTENSION = 110,
197 GNUTLS_A_CERTIFICATE_UNOBTAINABLE = 111,
198 GNUTLS_A_UNRECOGNIZED_NAME = 112,
199 GNUTLS_A_UNKNOWN_PSK_IDENTITY = 115,
200 GNUTLS_A_INNER_APPLICATION_FAILURE = 208,
201 GNUTLS_A_INNER_APPLICATION_VERIFICATION = 209
202 } gnutls_alert_description_t;
203
204 typedef enum
205 { GNUTLS_HANDSHAKE_HELLO_REQUEST = 0,
206 GNUTLS_HANDSHAKE_CLIENT_HELLO = 1,
207 GNUTLS_HANDSHAKE_SERVER_HELLO = 2,
208 GNUTLS_HANDSHAKE_CERTIFICATE_PKT = 11,
209 GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE = 12,
210 GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST = 13,
211 GNUTLS_HANDSHAKE_SERVER_HELLO_DONE = 14,
212 GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY = 15,
213 GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE = 16,
214 GNUTLS_HANDSHAKE_FINISHED = 20,
215 GNUTLS_HANDSHAKE_SUPPLEMENTAL = 23
216 } gnutls_handshake_description_t;
217
218/* Note that the status bits have different meanings
219 * in openpgp keys and x.509 certificate verification.
220 */
221 typedef enum
222 {
223 GNUTLS_CERT_INVALID = 2, /* will be set if the certificate
224 * was not verified.
225 */
226 GNUTLS_CERT_REVOKED = 32, /* in X.509 this will be set only if CRLs are checked
227 */
228
229 /* Those are extra information about the verification
230 * process. Will be set only if the certificate was
231 * not verified.
232 */
233 GNUTLS_CERT_SIGNER_NOT_FOUND = 64,
234 GNUTLS_CERT_SIGNER_NOT_CA = 128,
235 GNUTLS_CERT_INSECURE_ALGORITHM = 256
236 } gnutls_certificate_status_t;
237
238 typedef enum
239 {
240 GNUTLS_CERT_IGNORE,
241 GNUTLS_CERT_REQUEST = 1,
242 GNUTLS_CERT_REQUIRE
243 } gnutls_certificate_request_t;
244
245 typedef enum
246 { GNUTLS_OPENPGP_CERT,
247 GNUTLS_OPENPGP_CERT_FINGERPRINT
248 } gnutls_openpgp_crt_status_t;
249
250 typedef enum
251 {
252 GNUTLS_SHUT_RDWR = 0,
253 GNUTLS_SHUT_WR = 1
254 } gnutls_close_request_t;
255
256#define GNUTLS_TLS1 GNUTLS_TLS1_0
257 typedef enum
258 {
259 GNUTLS_SSL3 = 1,
260 GNUTLS_TLS1_0,
261 GNUTLS_TLS1_1,
262 GNUTLS_TLS1_2,
263 GNUTLS_VERSION_UNKNOWN = 0xff
264 } gnutls_protocol_t;
265
266 typedef enum
267 {
268 GNUTLS_CRT_UNKNOWN = 0,
269 GNUTLS_CRT_X509 = 1,
270 GNUTLS_CRT_OPENPGP
271 } gnutls_certificate_type_t;
272
273 typedef enum
274 {
275 GNUTLS_X509_FMT_DER,
276 GNUTLS_X509_FMT_PEM
277 } gnutls_x509_crt_fmt_t;
278
279 typedef enum
280 {
281 GNUTLS_PK_UNKNOWN = 0,
282 GNUTLS_PK_RSA = 1,
283 //GNUTLS_PK_DSA
284 } gnutls_pk_algorithm_t;
285
286 const char *gnutls_pk_algorithm_get_name (gnutls_pk_algorithm_t algorithm);
287
288#define GNUTLS_SIGN_RSA_SHA GNUTLS_SIGN_RSA_SHA1
289#define GNUTLS_SIGN_DSA_SHA GNUTLS_SIGN_DSA_SHA1
290 typedef enum
291 {
292 GNUTLS_SIGN_UNKNOWN = 0,
293 GNUTLS_SIGN_RSA_SHA1 = 1,
294 GNUTLS_SIGN_DSA_SHA1,
295 GNUTLS_SIGN_RSA_MD5,
296 GNUTLS_SIGN_RSA_MD2,
297 GNUTLS_SIGN_RSA_RMD160,
298 GNUTLS_SIGN_RSA_SHA256,
299 GNUTLS_SIGN_RSA_SHA384,
300 GNUTLS_SIGN_RSA_SHA512
301 } gnutls_sign_algorithm_t;
302
303 const char *gnutls_sign_algorithm_get_name (gnutls_sign_algorithm_t
304 algorithm);
305
306/* If you want to change this, then also change the define in
307 * gnutls_int.h, and recompile.
308 */
309 typedef void * gnutls_transport_ptr_t;
310
311 struct gnutls_session_int;
312 typedef struct gnutls_session_int * gnutls_session_t;
313
314 struct gnutls_dh_params_int;
315 typedef struct gnutls_dh_params_int *gnutls_dh_params_t;
316
317 struct gnutls_x509_privkey_int; /* XXX ugly. */
318 typedef struct gnutls_x509_privkey_int *gnutls_rsa_params_t; /* XXX ugly. */
319
320 struct gnutls_priority_st;
321 typedef struct gnutls_priority_st *gnutls_priority_t;
322
323 typedef struct
324 {
325 unsigned char *data;
326 unsigned int size;
327 } gnutls_datum_t;
328
329
330 typedef struct gnutls_params_st
331 {
332 gnutls_params_type_t type;
333 union params
334 {
335 gnutls_dh_params_t dh;
336 gnutls_rsa_params_t rsa_export;
337 } params;
338 int deinit;
339 } gnutls_params_st;
340
341 typedef int gnutls_params_function (gnutls_session_t, gnutls_params_type_t,
342 gnutls_params_st *);
343
344/* internal functions */
345
346 int gnutls_init (gnutls_session_t * session,
347 gnutls_connection_end_t con_end);
348 void gnutls_deinit (gnutls_session_t session);
349#define _gnutls_deinit(x) gnutls_deinit(x)
350
351 int gnutls_bye (gnutls_session_t session, gnutls_close_request_t how);
352
353 int gnutls_handshake (gnutls_session_t session);
354 int gnutls_rehandshake (gnutls_session_t session);
355
356 gnutls_alert_description_t gnutls_alert_get (gnutls_session_t session);
357 int gnutls_alert_send (gnutls_session_t session,
358 gnutls_alert_level_t level,
359 gnutls_alert_description_t desc);
360 int gnutls_alert_send_appropriate (gnutls_session_t session, int err);
361 const char *gnutls_alert_get_name (gnutls_alert_description_t alert);
362
363/* get information on the current session */
364 gnutls_cipher_algorithm_t gnutls_cipher_get (gnutls_session_t session);
365 gnutls_kx_algorithm_t gnutls_kx_get (gnutls_session_t session);
366 gnutls_mac_algorithm_t gnutls_mac_get (gnutls_session_t session);
367 gnutls_compression_method_t gnutls_compression_get (gnutls_session_t
368 session);
369 gnutls_certificate_type_t gnutls_certificate_type_get (gnutls_session_t
370 session);
371
372 size_t gnutls_cipher_get_key_size (gnutls_cipher_algorithm_t algorithm);
373 size_t gnutls_mac_get_key_size (gnutls_mac_algorithm_t algorithm);
374
375/* the name of the specified algorithms */
376 const char *gnutls_cipher_get_name (gnutls_cipher_algorithm_t algorithm);
377 const char *gnutls_mac_get_name (gnutls_mac_algorithm_t algorithm);
378 const char *gnutls_compression_get_name (gnutls_compression_method_t
379 algorithm);
380 const char *gnutls_kx_get_name (gnutls_kx_algorithm_t algorithm);
381 const char *gnutls_certificate_type_get_name (gnutls_certificate_type_t
382 type);
383
384 gnutls_mac_algorithm_t gnutls_mac_get_id (const char* name);
385 gnutls_compression_method_t gnutls_compression_get_id (const char* name);
386 gnutls_cipher_algorithm_t gnutls_cipher_get_id (const char* name);
387 gnutls_kx_algorithm_t gnutls_kx_get_id (const char* name);
388 gnutls_protocol_t gnutls_protocol_get_id (const char* name);
389 gnutls_certificate_type_t gnutls_certificate_type_get_id (const char* name);
390
391
392 /* list supported algorithms */
393 const gnutls_cipher_algorithm_t *gnutls_cipher_list (void);
394 const gnutls_mac_algorithm_t *gnutls_mac_list (void);
395 const gnutls_compression_method_t *gnutls_compression_list (void);
396 const gnutls_protocol_t *gnutls_protocol_list (void);
397 const gnutls_certificate_type_t *gnutls_certificate_type_list (void);
398 const gnutls_kx_algorithm_t *gnutls_kx_list (void);
399 const char *gnutls_cipher_suite_info (size_t i,
400 char *id,
401 gnutls_kx_algorithm_t *kx,
402 gnutls_cipher_algorithm_t *cipher,
403 gnutls_mac_algorithm_t *mac,
404 gnutls_protocol_t *version);
405
406 /* error functions */
407 int gnutls_error_is_fatal (int error);
408 int gnutls_error_to_alert (int err, int *level);
409
410 void gnutls_perror (int error);
411 const char *gnutls_strerror (int error);
412
413/* Semi-internal functions.
414 */
415 void gnutls_handshake_set_private_extensions (gnutls_session_t session,
416 int allow);
417 gnutls_handshake_description_t
418 gnutls_handshake_get_last_out (gnutls_session_t session);
419 gnutls_handshake_description_t
420 gnutls_handshake_get_last_in (gnutls_session_t session);
421
422/* Record layer functions.
423 */
424 ssize_t gnutls_record_send (gnutls_session_t session, const void *data,
425 size_t sizeofdata);
426 ssize_t gnutls_record_recv (gnutls_session_t session, void *data,
427 size_t sizeofdata);
428#define gnutls_read gnutls_record_recv
429#define gnutls_write gnutls_record_send
430
431 void gnutls_session_enable_compatibility_mode (gnutls_session_t session);
432
433 void gnutls_record_disable_padding (gnutls_session_t session);
434
435 int gnutls_record_get_direction (gnutls_session_t session);
436
437 size_t gnutls_record_get_max_size (gnutls_session_t session);
438 ssize_t gnutls_record_set_max_size (gnutls_session_t session, size_t size);
439
440 size_t gnutls_record_check_pending (gnutls_session_t session);
441
442 int gnutls_prf (gnutls_session_t session,
443 size_t label_size, const char *label,
444 int server_random_first,
445 size_t extra_size, const char *extra,
446 size_t outsize, char *out);
447
448 int gnutls_prf_raw (gnutls_session_t session,
449 size_t label_size, const char *label,
450 size_t seed_size, const char *seed,
451 size_t outsize, char *out);
452
453/* TLS Extensions */
454
455 typedef enum
456 {
457 GNUTLS_NAME_DNS = 1
458 } gnutls_server_name_type_t;
459
460 int gnutls_server_name_set (gnutls_session_t session,
461 gnutls_server_name_type_t type,
462 const void *name, size_t name_length);
463
464 int gnutls_server_name_get (gnutls_session_t session,
465 void *data, size_t * data_length,
466 unsigned int *type, unsigned int indx);
467
468 /* Opaque PRF Input
469 * http://tools.ietf.org/id/draft-rescorla-tls-opaque-prf-input-00.txt
470 */
471
472 void
473 gnutls_oprfi_enable_client (gnutls_session_t session,
474 size_t len,
475 unsigned char *data);
476
477 typedef int (*gnutls_oprfi_callback_func) (gnutls_session_t session,
478 void *userdata,
479 size_t oprfi_len,
480 const unsigned char *in_oprfi,
481 unsigned char *out_oprfi);
482
483 void
484 gnutls_oprfi_enable_server (gnutls_session_t session,
485 gnutls_oprfi_callback_func cb,
486 void *userdata);
487
488 /* Supplemental data, RFC 4680. */
489 typedef enum
490 {
491 GNUTLS_SUPPLEMENTAL_USER_MAPPING_DATA = 0
492 } gnutls_supplemental_data_format_type_t;
493
494 const char *gnutls_supplemental_get_name
495 (gnutls_supplemental_data_format_type_t type);
496
497/* functions to set priority of cipher suites
498 */
499 int gnutls_cipher_set_priority (gnutls_session_t session, const int *list);
500 int gnutls_mac_set_priority (gnutls_session_t session, const int *list);
501 int gnutls_compression_set_priority (gnutls_session_t session,
502 const int *list);
503 int gnutls_kx_set_priority (gnutls_session_t session, const int *list);
504 int gnutls_protocol_set_priority (gnutls_session_t session,
505 const int *list);
506 int gnutls_certificate_type_set_priority (gnutls_session_t session,
507 const int *list);
508
509/* if you just want some defaults, use the following.
510 */
511 int gnutls_priority_init( gnutls_priority_t*, const char *priority, const char** err_pos);
512 void gnutls_priority_deinit( gnutls_priority_t);
513
514 int gnutls_priority_set(gnutls_session_t session, gnutls_priority_t);
515 int gnutls_priority_set_direct(gnutls_session_t session, const char *priority, const char** err_pos);
516
517 /* for compatibility
518 */
519 int gnutls_set_default_priority (gnutls_session_t session);
520 int gnutls_set_default_export_priority (gnutls_session_t session);
521
522/* Returns the name of a cipher suite */
523 const char *gnutls_cipher_suite_get_name (gnutls_kx_algorithm_t
524 kx_algorithm,
525 gnutls_cipher_algorithm_t
526 cipher_algorithm,
527 gnutls_mac_algorithm_t
528 mac_algorithm);
529
530/* get the currently used protocol version */
531 gnutls_protocol_t gnutls_protocol_get_version (gnutls_session_t session);
532
533 const char *gnutls_protocol_get_name (gnutls_protocol_t version);
534
535
536/* get/set session
537 */
538 int gnutls_session_set_data (gnutls_session_t session,
539 const void *session_data,
540 size_t session_data_size);
541 int gnutls_session_get_data (gnutls_session_t session, void *session_data,
542 size_t * session_data_size);
543 int gnutls_session_get_data2 (gnutls_session_t session,
544 gnutls_datum_t * data);
545
546/* returns the session ID */
547#define GNUTLS_MAX_SESSION_ID 32
548 int gnutls_session_get_id (gnutls_session_t session, void *session_id,
549 size_t * session_id_size);
550
551/* returns security values.
552 * Do not use them unless you know what you're doing.
553 */
554#define TLS_MASTER_SIZE 48
555#define TLS_RANDOM_SIZE 32
556 const void *gnutls_session_get_server_random (gnutls_session_t session);
557 const void *gnutls_session_get_client_random (gnutls_session_t session);
558 const void *gnutls_session_get_master_secret (gnutls_session_t session);
559
560/* checks if this session is a resumed one
561 */
562 int gnutls_session_is_resumed (gnutls_session_t session);
563
564 typedef int (*gnutls_db_store_func) (void *, gnutls_datum_t key,
565 gnutls_datum_t data);
566 typedef int (*gnutls_db_remove_func) (void *, gnutls_datum_t key);
567 typedef gnutls_datum_t (*gnutls_db_retr_func) (void *, gnutls_datum_t key);
568
569 void gnutls_db_set_cache_expiration (gnutls_session_t session, int seconds);
570
571 void gnutls_db_remove_session (gnutls_session_t session);
572 void gnutls_db_set_retrieve_function (gnutls_session_t session,
573 gnutls_db_retr_func retr_func);
574 void gnutls_db_set_remove_function (gnutls_session_t session,
575 gnutls_db_remove_func rem_func);
576 void gnutls_db_set_store_function (gnutls_session_t session,
577 gnutls_db_store_func store_func);
578 void gnutls_db_set_ptr (gnutls_session_t session, void *ptr);
579 void *gnutls_db_get_ptr (gnutls_session_t session);
580 int gnutls_db_check_entry (gnutls_session_t session,
581 gnutls_datum_t session_entry);
582
583 typedef int (*gnutls_handshake_post_client_hello_func)(gnutls_session_t);
584 void gnutls_handshake_set_post_client_hello_function(gnutls_session_t,
585 gnutls_handshake_post_client_hello_func);
586
587 void gnutls_handshake_set_max_packet_length (gnutls_session_t session,
588 size_t max);
589
590/* returns libgnutls version (call it with a NULL argument)
591 */
592 const char *gnutls_check_version (const char *req_version);
593
594/* Functions for setting/clearing credentials
595 */
596 void gnutls_credentials_clear (gnutls_session_t session);
597
598/* cred is a structure defined by the kx algorithm
599 */
600 int gnutls_credentials_set (gnutls_session_t session,
601 gnutls_credentials_type_t type, void *cred);
602#define gnutls_cred_set gnutls_credentials_set
603
604/* Credential structures - used in gnutls_credentials_set(); */
605
606 struct gnutls_certificate_credentials_st;
607 typedef struct gnutls_certificate_credentials_st
608 *gnutls_certificate_credentials_t;
609 typedef gnutls_certificate_credentials_t
610 gnutls_certificate_server_credentials;
611 typedef gnutls_certificate_credentials_t
612 gnutls_certificate_client_credentials;
613
614 typedef struct gnutls_anon_server_credentials_st
615 *gnutls_anon_server_credentials_t;
616 typedef struct gnutls_anon_client_credentials_st
617 *gnutls_anon_client_credentials_t;
618
619 void gnutls_anon_free_server_credentials (gnutls_anon_server_credentials_t sc);
620 int gnutls_anon_allocate_server_credentials (gnutls_anon_server_credentials_t * sc);
621
622 void gnutls_anon_set_server_dh_params (gnutls_anon_server_credentials_t res,
623 gnutls_dh_params_t dh_params);
624
625 void
626 gnutls_anon_set_server_params_function (gnutls_anon_server_credentials_t
627 res,
628 gnutls_params_function * func);
629
630 void gnutls_anon_free_client_credentials (gnutls_anon_client_credentials_t
631 sc);
632 int
633 gnutls_anon_allocate_client_credentials (gnutls_anon_client_credentials_t
634 * sc);
635
636/* CERTFILE is an x509 certificate in PEM form.
637 * KEYFILE is a pkcs-1 private key in PEM form (for RSA keys).
638 */
639 void gnutls_certificate_free_credentials (gnutls_certificate_credentials_t
640 sc);
641 int
642 gnutls_certificate_allocate_credentials (gnutls_certificate_credentials_t
643 * res);
644
645 void gnutls_certificate_free_keys (gnutls_certificate_credentials_t sc);
646 void gnutls_certificate_free_cas (gnutls_certificate_credentials_t sc);
647 void gnutls_certificate_free_ca_names (gnutls_certificate_credentials_t sc);
648 void gnutls_certificate_free_crls (gnutls_certificate_credentials_t sc);
649
650 void gnutls_certificate_set_dh_params (gnutls_certificate_credentials_t res,
651 gnutls_dh_params_t dh_params);
652 void
653 gnutls_certificate_set_rsa_export_params (gnutls_certificate_credentials_t
654 res,
655 gnutls_rsa_params_t rsa_params);
656 void gnutls_certificate_set_verify_flags (gnutls_certificate_credentials_t
657 res, unsigned int flags);
658 void gnutls_certificate_set_verify_limits (gnutls_certificate_credentials_t
659 res, unsigned int max_bits,
660 unsigned int max_depth);
661
662 int gnutls_certificate_set_x509_trust_file (gnutls_certificate_credentials_t
663 res, const char *CAFILE,
664 gnutls_x509_crt_fmt_t type);
665 int gnutls_certificate_set_x509_trust_mem (gnutls_certificate_credentials_t
666 res, const gnutls_datum_t * CA,
667 gnutls_x509_crt_fmt_t type);
668
669 int gnutls_certificate_set_x509_crl_file (gnutls_certificate_credentials_t
670 res, const char *crlfile,
671 gnutls_x509_crt_fmt_t type);
672 int gnutls_certificate_set_x509_crl_mem (gnutls_certificate_credentials_t
673 res, const gnutls_datum_t * CRL,
674 gnutls_x509_crt_fmt_t type);
675
676 int gnutls_certificate_set_x509_key_file (gnutls_certificate_credentials_t
677 res, const char *CERTFILE,
678 const char *KEYFILE,
679 gnutls_x509_crt_fmt_t type);
680 int gnutls_certificate_set_x509_key_mem (gnutls_certificate_credentials_t
681 res, const gnutls_datum_t * CERT,
682 const gnutls_datum_t * KEY,
683 gnutls_x509_crt_fmt_t type);
684
685 void gnutls_certificate_send_x509_rdn_sequence (gnutls_session_t session,
686 int status);
687
688
689 extern int
690 gnutls_certificate_set_x509_simple_pkcs12_file
691 (gnutls_certificate_credentials_t res, const char *pkcs12file,
692 gnutls_x509_crt_fmt_t type, const char *password);
693
694/* New functions to allow setting already parsed X.509 stuff.
695 */
696 struct gnutls_x509_privkey_int;
697 typedef struct gnutls_x509_privkey_int *gnutls_x509_privkey_t;
698
699 struct gnutls_x509_crl_int;
700 typedef struct gnutls_x509_crl_int *gnutls_x509_crl_t;
701
702 struct gnutls_x509_crt_int;
703 typedef struct gnutls_x509_crt_int * gnutls_x509_crt_t;
704
705 int gnutls_certificate_set_x509_key (gnutls_certificate_credentials_t res,
706 gnutls_x509_crt_t * cert_list,
707 int cert_list_size,
708 gnutls_x509_privkey_t key);
709 int gnutls_certificate_set_x509_trust (gnutls_certificate_credentials_t res,
710 gnutls_x509_crt_t * ca_list,
711 int ca_list_size);
712 int gnutls_certificate_set_x509_crl (gnutls_certificate_credentials_t res,
713 gnutls_x509_crl_t * crl_list,
714 int crl_list_size);
715
716/* global state functions
717 */
718 int gnutls_global_init (void);
719 void gnutls_global_deinit (void);
720
721 typedef void *(*gnutls_alloc_function) (size_t);
722 typedef void *(*gnutls_calloc_function) (size_t, size_t);
723 typedef int (*gnutls_is_secure_function) (const void *);
724 typedef void (*gnutls_free_function) (void *);
725 typedef void *(*gnutls_realloc_function) (void *, size_t);
726
727 extern void
728 gnutls_global_set_mem_functions (gnutls_alloc_function gt_alloc_func,
729 gnutls_alloc_function
730 gt_secure_alloc_func,
731 gnutls_is_secure_function
732 gt_is_secure_func,
733 gnutls_realloc_function gt_realloc_func,
734 gnutls_free_function gt_free_func);
735
736/* For use in callbacks */
737 extern gnutls_alloc_function gnutls_malloc;
738 extern gnutls_alloc_function gnutls_secure_malloc;
739 extern gnutls_realloc_function gnutls_realloc;
740 extern gnutls_calloc_function gnutls_calloc;
741 extern gnutls_free_function gnutls_free;
742
743 extern char *(*gnutls_strdup) (const char *);
744
745 typedef void (*gnutls_log_func) (int, const char *);
746 void gnutls_global_set_log_function (gnutls_log_func log_func);
747 void gnutls_global_set_log_level (int level);
748
749/* Diffie Hellman parameter handling.
750 */
751 int gnutls_dh_params_init (gnutls_dh_params_t * dh_params);
752 void gnutls_dh_params_deinit (gnutls_dh_params_t dh_params);
753 int gnutls_dh_params_import_raw (gnutls_dh_params_t dh_params,
754 const gnutls_datum_t * prime,
755 const gnutls_datum_t * generator);
756 int gnutls_dh_params_import_pkcs3 (gnutls_dh_params_t params,
757 const gnutls_datum_t * pkcs3_params,
758 gnutls_x509_crt_fmt_t format);
759 int gnutls_dh_params_generate2 (gnutls_dh_params_t params,
760 unsigned int bits);
761 int gnutls_dh_params_export_pkcs3 (gnutls_dh_params_t params,
762 gnutls_x509_crt_fmt_t format,
763 unsigned char *params_data,
764 size_t * params_data_size);
765 int gnutls_dh_params_export_raw (gnutls_dh_params_t params,
766 gnutls_datum_t * prime,
767 gnutls_datum_t * generator,
768 unsigned int *bits);
769 int gnutls_dh_params_cpy (gnutls_dh_params_t dst, gnutls_dh_params_t src);
770
771
772/* RSA params
773 */
774 int gnutls_rsa_params_init (gnutls_rsa_params_t * rsa_params);
775 void gnutls_rsa_params_deinit (gnutls_rsa_params_t rsa_params);
776 int gnutls_rsa_params_cpy (gnutls_rsa_params_t dst,
777 gnutls_rsa_params_t src);
778 int gnutls_rsa_params_import_raw (gnutls_rsa_params_t rsa_params,
779 const gnutls_datum_t * m,
780 const gnutls_datum_t * e,
781 const gnutls_datum_t * d,
782 const gnutls_datum_t * p,
783 const gnutls_datum_t * q,
784 const gnutls_datum_t * u);
785 int gnutls_rsa_params_generate2 (gnutls_rsa_params_t params,
786 unsigned int bits);
787 int gnutls_rsa_params_export_raw (gnutls_rsa_params_t params,
788 gnutls_datum_t * m, gnutls_datum_t * e,
789 gnutls_datum_t * d, gnutls_datum_t * p,
790 gnutls_datum_t * q, gnutls_datum_t * u,
791 unsigned int *bits);
792 int gnutls_rsa_params_export_pkcs1 (gnutls_rsa_params_t params,
793 gnutls_x509_crt_fmt_t format,
794 unsigned char *params_data,
795 size_t * params_data_size);
796 int gnutls_rsa_params_import_pkcs1 (gnutls_rsa_params_t params,
797 const gnutls_datum_t * pkcs1_params,
798 gnutls_x509_crt_fmt_t format);
799
800/* Session stuff
801 */
802 typedef ssize_t (*gnutls_pull_func) (gnutls_transport_ptr_t, void *,
803 size_t);
804 typedef ssize_t (*gnutls_push_func) (gnutls_transport_ptr_t, const void *,
805 size_t);
806 void gnutls_transport_set_ptr (gnutls_session_t session,
807 gnutls_transport_ptr_t ptr);
808 void gnutls_transport_set_ptr2 (gnutls_session_t session,
809 gnutls_transport_ptr_t recv_ptr,
810 gnutls_transport_ptr_t send_ptr);
811
812 gnutls_transport_ptr_t gnutls_transport_get_ptr (gnutls_session_t session);
813 void gnutls_transport_get_ptr2 (gnutls_session_t session,
814 gnutls_transport_ptr_t * recv_ptr,
815 gnutls_transport_ptr_t * send_ptr);
816
817 void gnutls_transport_set_lowat (gnutls_session_t session, int num);
818
819
820 void gnutls_transport_set_push_function (gnutls_session_t session,
821 gnutls_push_func push_func);
822 void gnutls_transport_set_pull_function (gnutls_session_t session,
823 gnutls_pull_func pull_func);
824
825 void gnutls_transport_set_errno (gnutls_session_t session, int err);
826 void gnutls_transport_set_global_errno (int err);
827
828/* session specific
829 */
830 void gnutls_session_set_ptr (gnutls_session_t session, void *ptr);
831 void *gnutls_session_get_ptr (gnutls_session_t session);
832
833 void gnutls_openpgp_send_cert (gnutls_session_t session,
834 gnutls_openpgp_crt_status_t status);
835
836/* fingerprint
837 * Actually this function returns the hash of the given data.
838 */
839 int gnutls_fingerprint (gnutls_digest_algorithm_t algo,
840 const gnutls_datum_t * data, void *result,
841 size_t * result_size);
842
843
844/* SRP
845 */
846
847 typedef struct gnutls_srp_server_credentials_st
848 *gnutls_srp_server_credentials_t;
849 typedef struct gnutls_srp_client_credentials_st
850 *gnutls_srp_client_credentials_t;
851
852 void gnutls_srp_free_client_credentials (gnutls_srp_client_credentials_t
853 sc);
854 int gnutls_srp_allocate_client_credentials (gnutls_srp_client_credentials_t
855 * sc);
856 int gnutls_srp_set_client_credentials (gnutls_srp_client_credentials_t res,
857 const char *username, const char *password);
858
859 void gnutls_srp_free_server_credentials (gnutls_srp_server_credentials_t
860 sc);
861 int gnutls_srp_allocate_server_credentials (gnutls_srp_server_credentials_t
862 * sc);
863 int gnutls_srp_set_server_credentials_file (gnutls_srp_server_credentials_t
864 res, const char *password_file,
865 const char *password_conf_file);
866
867 const char *gnutls_srp_server_get_username (gnutls_session_t session);
868
869 extern int gnutls_srp_verifier (const char *username,
870 const char *password,
871 const gnutls_datum_t * salt,
872 const gnutls_datum_t * generator,
873 const gnutls_datum_t * prime,
874 gnutls_datum_t * res);
875
876/* The static parameters defined in draft-ietf-tls-srp-05
877 * Those should be used as input to gnutls_srp_verifier().
878 */
879 extern const gnutls_datum_t gnutls_srp_2048_group_prime;
880 extern const gnutls_datum_t gnutls_srp_2048_group_generator;
881
882 extern const gnutls_datum_t gnutls_srp_1536_group_prime;
883 extern const gnutls_datum_t gnutls_srp_1536_group_generator;
884
885 extern const gnutls_datum_t gnutls_srp_1024_group_prime;
886 extern const gnutls_datum_t gnutls_srp_1024_group_generator;
887
888 typedef int gnutls_srp_server_credentials_function (gnutls_session_t,
889 const char *username,
890 gnutls_datum_t * salt,
891 gnutls_datum_t *
892 verifier,
893 gnutls_datum_t *
894 generator,
895 gnutls_datum_t * prime);
896 void
897 gnutls_srp_set_server_credentials_function
898 (gnutls_srp_server_credentials_t cred,
899 gnutls_srp_server_credentials_function * func);
900
901 typedef int gnutls_srp_client_credentials_function (gnutls_session_t,
902 char **, char **);
903 void
904 gnutls_srp_set_client_credentials_function
905 (gnutls_srp_client_credentials_t cred,
906 gnutls_srp_client_credentials_function * func);
907
908 int gnutls_srp_base64_encode (const gnutls_datum_t * data, char *result,
909 size_t * result_size);
910 int gnutls_srp_base64_encode_alloc (const gnutls_datum_t * data,
911 gnutls_datum_t * result);
912
913 int gnutls_srp_base64_decode (const gnutls_datum_t * b64_data, char *result,
914 size_t * result_size);
915 int gnutls_srp_base64_decode_alloc (const gnutls_datum_t * b64_data,
916 gnutls_datum_t * result);
917
918/* PSK stuff */
919 typedef struct gnutls_psk_server_credentials_st
920 *gnutls_psk_server_credentials_t;
921 typedef struct gnutls_psk_client_credentials_st
922 *gnutls_psk_client_credentials_t;
923
924 typedef enum gnutls_psk_key_flags
925 {
926 GNUTLS_PSK_KEY_RAW = 0,
927 GNUTLS_PSK_KEY_HEX
928 } gnutls_psk_key_flags;
929
930 void gnutls_psk_free_client_credentials (gnutls_psk_client_credentials_t
931 sc);
932 int gnutls_psk_allocate_client_credentials (gnutls_psk_client_credentials_t
933 * sc);
934 int gnutls_psk_set_client_credentials (gnutls_psk_client_credentials_t res,
935 const char *username,
936 const gnutls_datum_t * key,
937 gnutls_psk_key_flags format);
938
939 void gnutls_psk_free_server_credentials (gnutls_psk_server_credentials_t
940 sc);
941 int gnutls_psk_allocate_server_credentials (gnutls_psk_server_credentials_t
942 * sc);
943 int gnutls_psk_set_server_credentials_file (gnutls_psk_server_credentials_t
944 res, const char *password_file);
945
946 const char *gnutls_psk_server_get_username (gnutls_session_t session);
947
948 typedef int gnutls_psk_server_credentials_function (gnutls_session_t,
949 const char *username,
950 gnutls_datum_t * key);
951 void
952 gnutls_psk_set_server_credentials_function
953 (gnutls_psk_server_credentials_t cred,
954 gnutls_psk_server_credentials_function * func);
955
956 typedef int gnutls_psk_client_credentials_function (gnutls_session_t,
957 char **username,
958 gnutls_datum_t * key);
959 void
960 gnutls_psk_set_client_credentials_function
961 (gnutls_psk_client_credentials_t cred,
962 gnutls_psk_client_credentials_function * func);
963
964 int gnutls_hex_encode (const gnutls_datum_t * data, char *result,
965 size_t * result_size);
966 int gnutls_hex_decode (const gnutls_datum_t * hex_data, char *result,
967 size_t * result_size);
968
969 void gnutls_psk_set_server_dh_params (gnutls_psk_server_credentials_t res,
970 gnutls_dh_params_t dh_params);
971
972 void gnutls_psk_set_server_params_function (gnutls_psk_server_credentials_t
973 res,
974 gnutls_params_function * func);
975
976 typedef enum gnutls_x509_subject_alt_name_t
977 {
978 GNUTLS_SAN_DNSNAME = 1,
979 GNUTLS_SAN_RFC822NAME,
980 GNUTLS_SAN_URI,
981 GNUTLS_SAN_IPADDRESS,
982 GNUTLS_SAN_OTHERNAME,
983 GNUTLS_SAN_DN,
984 /* The following are "virtual" subject alternative name types, in
985 that they are represented by an otherName value and an OID.
986 Used by gnutls_x509_crt_get_subject_alt_othername_oid(). */
987 GNUTLS_SAN_OTHERNAME_XMPP = 1000
988 } gnutls_x509_subject_alt_name_t;
989
990 struct gnutls_openpgp_crt_int;
991 typedef struct gnutls_openpgp_crt_int *gnutls_openpgp_crt_t;
992
993 struct gnutls_openpgp_privkey_int;
994 typedef struct gnutls_openpgp_privkey_int *gnutls_openpgp_privkey_t;
995
996 typedef struct gnutls_retr_st
997 {
998 gnutls_certificate_type_t type;
999 union cert
1000 {
1001 gnutls_x509_crt_t *x509;
1002 gnutls_openpgp_crt_t pgp;
1003 } cert;
1004 unsigned int ncerts; /* one for pgp keys */
1005
1006 union key
1007 {
1008 gnutls_x509_privkey_t x509;
1009 gnutls_openpgp_privkey_t pgp;
1010 } key;
1011
1012 unsigned int deinit_all; /* if non zero all keys will be deinited */
1013 } gnutls_retr_st;
1014
1015 typedef int gnutls_certificate_client_retrieve_function (gnutls_session_t,
1016 const
1017 gnutls_datum_t *
1018 req_ca_rdn,
1019 int nreqs,
1020 const
1021 gnutls_pk_algorithm_t
1022 * pk_algos,
1023 int
1024 pk_algos_length,
1025 gnutls_retr_st *);
1026 typedef int gnutls_certificate_server_retrieve_function (gnutls_session_t,
1027 gnutls_retr_st *);
1028
1029
1030 /* Functions that allow auth_info_t structures handling
1031 */
1032
1033 gnutls_credentials_type_t gnutls_auth_get_type (gnutls_session_t session);
1034 gnutls_credentials_type_t
1035 gnutls_auth_server_get_type (gnutls_session_t session);
1036 gnutls_credentials_type_t
1037 gnutls_auth_client_get_type (gnutls_session_t session);
1038
1039 /* DH */
1040
1041 void gnutls_dh_set_prime_bits (gnutls_session_t session, unsigned int bits);
1042 int gnutls_dh_get_secret_bits (gnutls_session_t session);
1043 int gnutls_dh_get_peers_public_bits (gnutls_session_t session);
1044 int gnutls_dh_get_prime_bits (gnutls_session_t session);
1045
1046 int gnutls_dh_get_group (gnutls_session_t session, gnutls_datum_t * raw_gen,
1047 gnutls_datum_t * raw_prime);
1048 int gnutls_dh_get_pubkey (gnutls_session_t session,
1049 gnutls_datum_t * raw_key);
1050
1051 /* RSA */
1052 int gnutls_rsa_export_get_pubkey (gnutls_session_t session,
1053 gnutls_datum_t * exponent,
1054 gnutls_datum_t * modulus);
1055 int gnutls_rsa_export_get_modulus_bits (gnutls_session_t session);
1056
1057 /* X509PKI */
1058
1059 /* External signing callback. Experimental. */
1060 typedef int (*gnutls_sign_func) (gnutls_session_t session,
1061 void *userdata,
1062 gnutls_certificate_type_t cert_type,
1063 const gnutls_datum_t * cert,
1064 const gnutls_datum_t * hash,
1065 gnutls_datum_t * signature);
1066
1067 void gnutls_sign_callback_set (gnutls_session_t session,
1068 gnutls_sign_func sign_func,
1069 void *userdata);
1070 gnutls_sign_func
1071 gnutls_sign_callback_get (gnutls_session_t session,
1072 void **userdata);
1073
1074 /* These are set on the credentials structure.
1075 */
1076 void gnutls_certificate_client_set_retrieve_function
1077 (gnutls_certificate_credentials_t cred,
1078 gnutls_certificate_client_retrieve_function * func);
1079 void gnutls_certificate_server_set_retrieve_function
1080 (gnutls_certificate_credentials_t cred,
1081 gnutls_certificate_server_retrieve_function * func);
1082
1083 void gnutls_certificate_server_set_request (gnutls_session_t session,
1084 gnutls_certificate_request_t
1085 req);
1086
1087 /* get data from the session
1088 */
1089 const gnutls_datum_t *gnutls_certificate_get_peers (gnutls_session_t
1090 session,
1091 unsigned int
1092 *list_size);
1093 const gnutls_datum_t *gnutls_certificate_get_ours (gnutls_session_t
1094 session);
1095
1096 time_t gnutls_certificate_activation_time_peers (gnutls_session_t session);
1097 time_t gnutls_certificate_expiration_time_peers (gnutls_session_t session);
1098
1099 int gnutls_certificate_client_get_request_status (gnutls_session_t session);
1100 int gnutls_certificate_verify_peers2 (gnutls_session_t session,
1101 unsigned int *status);
1102
1103 /* this is obsolete (?). */
1104 int gnutls_certificate_verify_peers (gnutls_session_t session);
1105
1106 int gnutls_pem_base64_encode (const char *msg, const gnutls_datum_t * data,
1107 char *result, size_t * result_size);
1108 int gnutls_pem_base64_decode (const char *header,
1109 const gnutls_datum_t * b64_data,
1110 unsigned char *result, size_t * result_size);
1111
1112 int gnutls_pem_base64_encode_alloc (const char *msg,
1113 const gnutls_datum_t * data,
1114 gnutls_datum_t * result);
1115 int gnutls_pem_base64_decode_alloc (const char *header,
1116 const gnutls_datum_t * b64_data,
1117 gnutls_datum_t * result);
1118
1119 int gnutls_global_init (void);
1120
1121 /* key_usage will be an OR of the following values:
1122 */
1123
1124 /* when the key is to be used for signing: */
1125#define GNUTLS_KEY_DIGITAL_SIGNATURE 128
1126#define GNUTLS_KEY_NON_REPUDIATION 64
1127 /* when the key is to be used for encryption: */
1128#define GNUTLS_KEY_KEY_ENCIPHERMENT 32
1129#define GNUTLS_KEY_DATA_ENCIPHERMENT 16
1130#define GNUTLS_KEY_KEY_AGREEMENT 8
1131#define GNUTLS_KEY_KEY_CERT_SIGN 4
1132#define GNUTLS_KEY_CRL_SIGN 2
1133#define GNUTLS_KEY_ENCIPHER_ONLY 1
1134#define GNUTLS_KEY_DECIPHER_ONLY 32768
1135
1136 void
1137 gnutls_certificate_set_params_function (gnutls_certificate_credentials_t res,
1138 gnutls_params_function * func);
1139 void gnutls_anon_set_params_function (gnutls_anon_server_credentials_t res,
1140 gnutls_params_function * func);
1141 void gnutls_psk_set_params_function (gnutls_psk_server_credentials_t res,
1142 gnutls_params_function * func);
1143
1144 /* Gnutls error codes. The mapping to a TLS alert is also shown in
1145 * comments.
1146 */
1147
1148#define GNUTLS_E_SUCCESS 0
1149#define GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM -3
1150#define GNUTLS_E_UNKNOWN_CIPHER_TYPE -6
1151#define GNUTLS_E_LARGE_PACKET -7
1152#define GNUTLS_E_UNSUPPORTED_VERSION_PACKET -8 /* GNUTLS_A_PROTOCOL_VERSION */
1153#define GNUTLS_E_UNEXPECTED_PACKET_LENGTH -9 /* GNUTLS_A_RECORD_OVERFLOW */
1154#define GNUTLS_E_INVALID_SESSION -10
1155#define GNUTLS_E_FATAL_ALERT_RECEIVED -12
1156#define GNUTLS_E_UNEXPECTED_PACKET -15 /* GNUTLS_A_UNEXPECTED_MESSAGE */
1157#define GNUTLS_E_WARNING_ALERT_RECEIVED -16
1158#define GNUTLS_E_ERROR_IN_FINISHED_PACKET -18
1159#define GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET -19
1160#define GNUTLS_E_UNKNOWN_CIPHER_SUITE -21 /* GNUTLS_A_HANDSHAKE_FAILURE */
1161#define GNUTLS_E_UNWANTED_ALGORITHM -22
1162#define GNUTLS_E_MPI_SCAN_FAILED -23
1163#define GNUTLS_E_DECRYPTION_FAILED -24 /* GNUTLS_A_DECRYPTION_FAILED, GNUTLS_A_BAD_RECORD_MAC */
1164#define GNUTLS_E_MEMORY_ERROR -25
1165#define GNUTLS_E_DECOMPRESSION_FAILED -26 /* GNUTLS_A_DECOMPRESSION_FAILURE */
1166#define GNUTLS_E_COMPRESSION_FAILED -27
1167#define GNUTLS_E_AGAIN -28
1168#define GNUTLS_E_EXPIRED -29
1169#define GNUTLS_E_DB_ERROR -30
1170#define GNUTLS_E_SRP_PWD_ERROR -31
1171#define GNUTLS_E_INSUFFICIENT_CREDENTIALS -32
1172#define GNUTLS_E_INSUFICIENT_CREDENTIALS GNUTLS_E_INSUFFICIENT_CREDENTIALS /* for backwards compatibility only */
1173#define GNUTLS_E_INSUFFICIENT_CRED GNUTLS_E_INSUFFICIENT_CREDENTIALS
1174#define GNUTLS_E_INSUFICIENT_CRED GNUTLS_E_INSUFFICIENT_CREDENTIALS /* for backwards compatibility only */
1175
1176#define GNUTLS_E_HASH_FAILED -33
1177#define GNUTLS_E_BASE64_DECODING_ERROR -34
1178
1179#define GNUTLS_E_MPI_PRINT_FAILED -35
1180#define GNUTLS_E_REHANDSHAKE -37 /* GNUTLS_A_NO_RENEGOTIATION */
1181#define GNUTLS_E_GOT_APPLICATION_DATA -38
1182#define GNUTLS_E_RECORD_LIMIT_REACHED -39
1183#define GNUTLS_E_ENCRYPTION_FAILED -40
1184
1185#define GNUTLS_E_PK_ENCRYPTION_FAILED -44
1186#define GNUTLS_E_PK_DECRYPTION_FAILED -45
1187#define GNUTLS_E_PK_SIGN_FAILED -46
1188#define GNUTLS_E_X509_UNSUPPORTED_CRITICAL_EXTENSION -47
1189#define GNUTLS_E_KEY_USAGE_VIOLATION -48
1190#define GNUTLS_E_NO_CERTIFICATE_FOUND -49 /* GNUTLS_A_BAD_CERTIFICATE */
1191#define GNUTLS_E_INVALID_REQUEST -50
1192#define GNUTLS_E_SHORT_MEMORY_BUFFER -51
1193#define GNUTLS_E_INTERRUPTED -52
1194#define GNUTLS_E_PUSH_ERROR -53
1195#define GNUTLS_E_PULL_ERROR -54
1196#define GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER -55 /* GNUTLS_A_ILLEGAL_PARAMETER */
1197#define GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE -56
1198#define GNUTLS_E_PKCS1_WRONG_PAD -57
1199#define GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION -58
1200#define GNUTLS_E_INTERNAL_ERROR -59
1201#define GNUTLS_E_DH_PRIME_UNACCEPTABLE -63
1202#define GNUTLS_E_FILE_ERROR -64
1203#define GNUTLS_E_TOO_MANY_EMPTY_PACKETS -78
1204#define GNUTLS_E_UNKNOWN_PK_ALGORITHM -80
1205
1206
1207 /* returned if libextra functionality was requested but
1208 * gnutls_global_init_extra() was not called.
1209 */
1210#define GNUTLS_E_INIT_LIBEXTRA -82
1211#define GNUTLS_E_LIBRARY_VERSION_MISMATCH -83
1212
1213
1214 /* returned if you need to generate temporary RSA
1215 * parameters. These are needed for export cipher suites.
1216 */
1217#define GNUTLS_E_NO_TEMPORARY_RSA_PARAMS -84
1218
1219#define GNUTLS_E_LZO_INIT_FAILED -85
1220#define GNUTLS_E_NO_COMPRESSION_ALGORITHMS -86
1221#define GNUTLS_E_NO_CIPHER_SUITES -87
1222
1223#define GNUTLS_E_OPENPGP_GETKEY_FAILED -88
1224#define GNUTLS_E_PK_SIG_VERIFY_FAILED -89
1225
1226#define GNUTLS_E_ILLEGAL_SRP_USERNAME -90
1227#define GNUTLS_E_SRP_PWD_PARSING_ERROR -91
1228#define GNUTLS_E_NO_TEMPORARY_DH_PARAMS -93
1229
1230 /* For certificate and key stuff
1231 */
1232#define GNUTLS_E_ASN1_ELEMENT_NOT_FOUND -67
1233#define GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND -68
1234#define GNUTLS_E_ASN1_DER_ERROR -69
1235#define GNUTLS_E_ASN1_VALUE_NOT_FOUND -70
1236#define GNUTLS_E_ASN1_GENERIC_ERROR -71
1237#define GNUTLS_E_ASN1_VALUE_NOT_VALID -72
1238#define GNUTLS_E_ASN1_TAG_ERROR -73
1239#define GNUTLS_E_ASN1_TAG_IMPLICIT -74
1240#define GNUTLS_E_ASN1_TYPE_ANY_ERROR -75
1241#define GNUTLS_E_ASN1_SYNTAX_ERROR -76
1242#define GNUTLS_E_ASN1_DER_OVERFLOW -77
1243#define GNUTLS_E_OPENPGP_UID_REVOKED -79
1244#define GNUTLS_E_CERTIFICATE_ERROR -43
1245#define GNUTLS_E_X509_CERTIFICATE_ERROR GNUTLS_E_CERTIFICATE_ERROR
1246#define GNUTLS_E_CERTIFICATE_KEY_MISMATCH -60
1247#define GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE -61 /* GNUTLS_A_UNSUPPORTED_CERTIFICATE */
1248#define GNUTLS_E_X509_UNKNOWN_SAN -62
1249#define GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED -94
1250#define GNUTLS_E_X509_UNSUPPORTED_ATTRIBUTE -95
1251#define GNUTLS_E_UNKNOWN_HASH_ALGORITHM -96
1252#define GNUTLS_E_UNKNOWN_PKCS_CONTENT_TYPE -97
1253#define GNUTLS_E_UNKNOWN_PKCS_BAG_TYPE -98
1254#define GNUTLS_E_INVALID_PASSWORD -99
1255#define GNUTLS_E_MAC_VERIFY_FAILED -100 /* for PKCS #12 MAC */
1256#define GNUTLS_E_CONSTRAINT_ERROR -101
1257
1258#define GNUTLS_E_WARNING_IA_IPHF_RECEIVED -102
1259#define GNUTLS_E_WARNING_IA_FPHF_RECEIVED -103
1260
1261#define GNUTLS_E_IA_VERIFY_FAILED -104
1262
1263#define GNUTLS_E_UNKNOWN_ALGORITHM -105
1264
1265#define GNUTLS_E_BASE64_ENCODING_ERROR -201
1266#define GNUTLS_E_INCOMPATIBLE_GCRYPT_LIBRARY -202 /* obsolete */
1267#define GNUTLS_E_INCOMPATIBLE_CRYPTO_LIBRARY -202
1268#define GNUTLS_E_INCOMPATIBLE_LIBTASN1_LIBRARY -203
1269
1270#define GNUTLS_E_OPENPGP_KEYRING_ERROR -204
1271#define GNUTLS_E_X509_UNSUPPORTED_OID -205
1272
1273#define GNUTLS_E_RANDOM_FAILED -206
1274#define GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR -207
1275
1276
1277#define GNUTLS_E_UNIMPLEMENTED_FEATURE -1250
1278
1279#define GNUTLS_E_APPLICATION_ERROR_MAX -65000
1280#define GNUTLS_E_APPLICATION_ERROR_MIN -65500
1281
1282#ifdef __cplusplus
1283}
1284#endif
1285
1286#endif /* GNUTLS_H */
diff --git a/src/daemon/https/includes/gnutlsxx.h b/src/daemon/https/includes/gnutlsxx.h
new file mode 100644
index 00000000..3e98da12
--- /dev/null
+++ b/src/daemon/https/includes/gnutlsxx.h
@@ -0,0 +1,393 @@
1#ifndef GNUTLSXX_H
2# define GNUTLSXX_H
3
4#include <exception>
5#include <vector>
6#include <gnutls.h>
7
8namespace gnutls {
9
10class exception: public std::exception
11{
12 public:
13 exception( int x);
14 const char* what() const throw();
15 int get_code();
16 protected:
17 int retcode;
18};
19
20class dh_params
21{
22 public:
23 dh_params();
24 ~dh_params();
25 void import_raw( const gnutls_datum_t & prime,
26 const gnutls_datum_t & generator);
27 void import_pkcs3( const gnutls_datum_t & pkcs3_params,
28 gnutls_x509_crt_fmt_t format);
29 void generate( unsigned int bits);
30
31 void export_pkcs3( gnutls_x509_crt_fmt_t format, unsigned char *params_data, size_t * params_data_size);
32 void export_raw( gnutls_datum_t& prime, gnutls_datum_t &generator);
33
34 gnutls_dh_params_t get_params_t() const;
35 dh_params & operator=(const dh_params& src);
36 protected:
37 gnutls_dh_params_t params;
38};
39
40
41class rsa_params
42{
43 public:
44 rsa_params();
45 ~rsa_params();
46 void import_raw( const gnutls_datum_t & m,
47 const gnutls_datum_t & e,
48 const gnutls_datum_t & d,
49 const gnutls_datum_t & p,
50 const gnutls_datum_t & q,
51 const gnutls_datum_t & u);
52 void import_pkcs1( const gnutls_datum_t & pkcs1_params,
53 gnutls_x509_crt_fmt_t format);
54 void generate( unsigned int bits);
55
56 void export_pkcs1( gnutls_x509_crt_fmt_t format, unsigned char *params_data, size_t * params_data_size);
57 void export_raw( gnutls_datum_t & m, gnutls_datum_t & e,
58 gnutls_datum_t & d, gnutls_datum_t & p,
59 gnutls_datum_t & q, gnutls_datum_t & u);
60 gnutls_rsa_params_t get_params_t() const;
61 rsa_params & operator=(const rsa_params& src);
62
63 protected:
64 gnutls_rsa_params_t params;
65};
66
67class session
68{
69 protected:
70 gnutls_session_t s;
71 public:
72 session( gnutls_connection_end_t);
73 session( session& s);
74 virtual ~session();
75
76 int bye( gnutls_close_request_t how);
77 int handshake ();
78
79 gnutls_alert_description_t get_alert() const;
80
81 int send_alert ( gnutls_alert_level_t level,
82 gnutls_alert_description_t desc);
83 int send_appropriate_alert (int err);
84
85 gnutls_cipher_algorithm_t get_cipher() const;
86 gnutls_kx_algorithm_t get_kx () const;
87 gnutls_mac_algorithm_t get_mac () const;
88 gnutls_compression_method_t get_compression () const;
89 gnutls_certificate_type_t get_certificate_type() const;
90
91 // for the handshake
92 void set_private_extensions ( bool allow);
93
94 gnutls_handshake_description_t get_handshake_last_out() const;
95 gnutls_handshake_description_t get_handshake_last_in() const;
96
97 ssize_t send (const void *data, size_t sizeofdata);
98 ssize_t recv (void *data, size_t sizeofdata);
99
100 bool get_record_direction() const;
101
102 // maximum packet size
103 size_t get_max_size() const;
104 void set_max_size(size_t size);
105
106 size_t check_pending() const;
107
108 void prf (size_t label_size, const char *label,
109 int server_random_first,
110 size_t extra_size, const char *extra,
111 size_t outsize, char *out);
112
113 void prf_raw ( size_t label_size, const char *label,
114 size_t seed_size, const char *seed,
115 size_t outsize, char *out);
116
117 void set_cipher_priority (const int *list);
118 void set_mac_priority (const int *list);
119 void set_compression_priority (const int *list);
120 void set_kx_priority (const int *list);
121 void set_protocol_priority (const int *list);
122 void set_certificate_type_priority (const int *list);
123
124/* if you just want some defaults, use the following.
125 */
126 void set_priority (const char* prio, const char** err_pos);
127 void set_priority (gnutls_priority_t p);
128
129 gnutls_protocol_t get_protocol_version() const;
130
131 // for resuming sessions
132 void set_data ( const void *session_data,
133 size_t session_data_size);
134 void get_data (void *session_data,
135 size_t * session_data_size) const;
136 void get_data(gnutls_session_t session,
137 gnutls_datum_t & data) const;
138 void get_id ( void *session_id,
139 size_t * session_id_size) const;
140
141 bool is_resumed () const;
142
143 void set_max_handshake_packet_length ( size_t max);
144
145 void clear_credentials();
146 void set_credentials( class credentials & cred);
147
148 void set_transport_ptr( gnutls_transport_ptr_t ptr);
149 void set_transport_ptr( gnutls_transport_ptr_t recv_ptr, gnutls_transport_ptr_t send_ptr);
150 gnutls_transport_ptr_t get_transport_ptr() const;
151 void get_transport_ptr(gnutls_transport_ptr_t & recv_ptr,
152 gnutls_transport_ptr_t & send_ptr) const;
153
154 void set_transport_lowat (size_t num);
155 void set_transport_push_function( gnutls_push_func push_func);
156 void set_transport_pull_function( gnutls_pull_func pull_func);
157
158 void set_user_ptr( void* ptr);
159 void *get_user_ptr() const;
160
161 void send_openpgp_cert( gnutls_openpgp_crt_status_t status);
162
163 gnutls_credentials_type_t get_auth_type() const;
164 gnutls_credentials_type_t get_server_auth_type() const;
165 gnutls_credentials_type_t get_client_auth_type() const;
166
167 // informational stuff
168 void set_dh_prime_bits( unsigned int bits);
169 unsigned int get_dh_secret_bits() const;
170 unsigned int get_dh_peers_public_bits() const;
171 unsigned int get_dh_prime_bits() const;
172 void get_dh_group( gnutls_datum_t & gen, gnutls_datum_t & prime) const;
173 void get_dh_pubkey( gnutls_datum_t & raw_key) const;
174 void get_rsa_export_pubkey( gnutls_datum_t& exponent, gnutls_datum_t& modulus) const;
175 unsigned int get_rsa_export_modulus_bits() const;
176
177 void get_our_certificate(gnutls_datum_t & cert) const;
178 bool get_peers_certificate(std::vector<gnutls_datum_t> &out_certs) const;
179 bool get_peers_certificate(const gnutls_datum_t** certs, unsigned int *certs_size) const;
180
181 time_t get_peers_certificate_activation_time() const;
182 time_t get_peers_certificate_expiration_time() const;
183 void verify_peers_certificate( unsigned int& status) const;
184
185};
186
187// interface for databases
188class DB
189{
190 public:
191 virtual ~DB()=0;
192 virtual bool store( const gnutls_datum_t& key, const gnutls_datum_t& data)=0;
193 virtual bool retrieve( const gnutls_datum_t& key, gnutls_datum_t& data)=0;
194 virtual bool remove( const gnutls_datum_t& key)=0;
195};
196
197class server_session: public session
198{
199 public:
200 server_session();
201 void db_remove() const;
202
203 void set_db_cache_expiration (unsigned int seconds);
204 void set_db( const DB& db);
205
206 // returns true if session is expired
207 bool db_check_entry ( gnutls_datum_t &session_data) const;
208
209 // server side only
210 const char *get_srp_username() const;
211 const char *get_psk_username() const;
212
213 void get_server_name (void *data, size_t * data_length,
214 unsigned int *type, unsigned int indx) const;
215
216 int rehandshake();
217 void set_certificate_request( gnutls_certificate_request_t);
218};
219
220class client_session: public session
221{
222 public:
223 client_session();
224 void set_server_name (gnutls_server_name_type_t type,
225 const void *name, size_t name_length);
226
227 bool get_request_status();
228};
229
230
231class credentials
232{
233 public:
234 credentials(gnutls_credentials_type_t t);
235#if defined(__APPLE__) || defined(__MACOS__)
236 /* FIXME: This #if is due to a compile bug in Mac OS X. Give
237 it some time and then remove this cruft. See also
238 lib/gnutlsxx.cpp. */
239 credentials( credentials& c) {
240 type = c.type;
241 set_ptr( c.ptr());
242 }
243#else
244 credentials( credentials& c);
245#endif
246 virtual ~credentials() { }
247 gnutls_credentials_type_t get_type() const;
248 protected:
249 friend class session;
250 virtual void* ptr() const=0;
251 virtual void set_ptr(void* ptr)=0;
252 gnutls_credentials_type_t type;
253};
254
255class certificate_credentials: public credentials
256{
257 public:
258 ~certificate_credentials();
259 certificate_credentials();
260
261 void free_keys ();
262 void free_cas ();
263 void free_ca_names ();
264 void free_crls ();
265
266 void set_dh_params ( const dh_params &params);
267 void set_rsa_export_params ( const rsa_params& params);
268 void set_verify_flags ( unsigned int flags);
269 void set_verify_limits ( unsigned int max_bits, unsigned int max_depth);
270
271 void set_x509_trust_file(const char *cafile, gnutls_x509_crt_fmt_t type);
272 void set_x509_trust(const gnutls_datum_t & CA, gnutls_x509_crt_fmt_t type);
273 // FIXME: use classes instead of gnutls_x509_crt_t
274 void set_x509_trust ( gnutls_x509_crt_t * ca_list, int ca_list_size);
275
276 void set_x509_crl_file( const char *crlfile, gnutls_x509_crt_fmt_t type);
277 void set_x509_crl(const gnutls_datum_t & CRL, gnutls_x509_crt_fmt_t type);
278 void set_x509_crl ( gnutls_x509_crl_t * crl_list, int crl_list_size);
279
280 void set_x509_key_file(const char *certfile, const char *KEYFILE, gnutls_x509_crt_fmt_t type);
281 void set_x509_key(const gnutls_datum_t & CERT, const gnutls_datum_t & KEY, gnutls_x509_crt_fmt_t type);
282 // FIXME: use classes
283 void set_x509_key ( gnutls_x509_crt_t * cert_list, int cert_list_size,
284 gnutls_x509_privkey_t key);
285
286
287 void set_simple_pkcs12_file( const char *pkcs12file,
288 gnutls_x509_crt_fmt_t type, const char *password);
289
290 protected:
291 void* ptr() const;
292 void set_ptr(void* p);
293 gnutls_certificate_credentials_t cred;
294};
295
296class certificate_server_credentials: public certificate_credentials
297{
298 certificate_server_credentials() { }
299 public:
300 void set_retrieve_function( gnutls_certificate_server_retrieve_function* func);
301 void set_params_function( gnutls_params_function* func);
302};
303
304class certificate_client_credentials: public certificate_credentials
305{
306 public:
307 certificate_client_credentials() { }
308 void set_retrieve_function( gnutls_certificate_client_retrieve_function* func);
309};
310
311
312
313
314class anon_server_credentials: public credentials
315{
316 public:
317 anon_server_credentials();
318 ~anon_server_credentials();
319 void set_dh_params ( const dh_params &params);
320 void set_params_function ( gnutls_params_function * func);
321 protected:
322 gnutls_anon_server_credentials_t cred;
323};
324
325class anon_client_credentials: public credentials
326{
327 public:
328 anon_client_credentials();
329 ~anon_client_credentials();
330 protected:
331 gnutls_anon_client_credentials_t cred;
332};
333
334
335class srp_server_credentials: public credentials
336{
337 public:
338 srp_server_credentials();
339 ~srp_server_credentials();
340 void set_credentials_file (const char *password_file, const char *password_conf_file);
341 void set_credentials_function( gnutls_srp_server_credentials_function *func);
342 protected:
343 void* ptr() const;
344 void set_ptr(void* p);
345 gnutls_srp_server_credentials_t cred;
346};
347
348class srp_client_credentials: public credentials
349{
350 public:
351 srp_client_credentials();
352 ~srp_client_credentials();
353 void set_credentials (const char *username, const char *password);
354 void set_credentials_function( gnutls_srp_client_credentials_function* func);
355 protected:
356 void* ptr() const;
357 void set_ptr(void* p);
358 gnutls_srp_client_credentials_t cred;
359};
360
361
362class psk_server_credentials: public credentials
363{
364 public:
365 psk_server_credentials();
366 ~psk_server_credentials();
367 void set_credentials_file(const char* password_file);
368 void set_credentials_function( gnutls_psk_server_credentials_function* func);
369 void set_dh_params ( const dh_params &params);
370 void set_params_function (gnutls_params_function * func);
371 protected:
372 void* ptr() const;
373 void set_ptr(void* p);
374 gnutls_psk_server_credentials_t cred;
375};
376
377class psk_client_credentials: public credentials
378{
379 public:
380 psk_client_credentials();
381 ~psk_client_credentials();
382 void set_credentials (const char *username, const gnutls_datum_t& key, gnutls_psk_key_flags flags);
383 void set_credentials_function( gnutls_psk_client_credentials_function* func);
384 protected:
385 void* ptr() const;
386 void set_ptr(void* p);
387 gnutls_psk_client_credentials_t cred;
388};
389
390
391}; /* namespace */
392
393#endif /* GNUTLSXX_H */
diff --git a/src/daemon/https/lgl/Makefile.am b/src/daemon/https/lgl/Makefile.am
new file mode 100644
index 00000000..1edb75ae
--- /dev/null
+++ b/src/daemon/https/lgl/Makefile.am
@@ -0,0 +1,37 @@
1SUBDIRS = .
2
3AM_CPPFLAGS = -std=c99 \
4-I$(GCRYPT_CPPFLAGS)
5
6# gc-gnulib.c
7
8noinst_LTLIBRARIES = liblgl.la
9
10liblgl_la_LDFLAGS = -lgcrypt
11# liblgl_la_LIBADD = ./gc-libgcrypt.lo
12
13liblgl_la_SOURCES = \
14asnprintf.c \
15sha1.c \
16gc-libgcrypt.c \
17time_r.c \
18rijndael-api-fst.c \
19gc-pbkdf2-sha1.c \
20read-file.c \
21rijndael-alg-fst.c \
22hmac-md5.c \
23hmac-sha1.c \
24realloc.c \
25memmem.c \
26memmove.c \
27memxor.c \
28printf-args.c \
29strverscmp.c \
30snprintf.c \
31asprintf.c \
32vasprintf.c \
33vasnprintf.c \
34md5.c \
35printf-parse.c \
36des.c
37 \ No newline at end of file
diff --git a/src/daemon/https/lgl/asnprintf.c b/src/daemon/https/lgl/asnprintf.c
new file mode 100644
index 00000000..a9114977
--- /dev/null
+++ b/src/daemon/https/lgl/asnprintf.c
@@ -0,0 +1,35 @@
1/* Formatted output to strings.
2 Copyright (C) 1999, 2002, 2006 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License along
15 with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18#include <config.h>
19
20/* Specification. */
21#include "vasnprintf.h"
22
23#include <stdarg.h>
24
25char *
26asnprintf (char *resultbuf, size_t * lengthp, const char *format, ...)
27{
28 va_list args;
29 char *result;
30
31 va_start (args, format);
32 result = vasnprintf (resultbuf, lengthp, format, args);
33 va_end (args);
34 return result;
35}
diff --git a/src/daemon/https/lgl/asprintf.c b/src/daemon/https/lgl/asprintf.c
new file mode 100644
index 00000000..2df1d4b0
--- /dev/null
+++ b/src/daemon/https/lgl/asprintf.c
@@ -0,0 +1,39 @@
1/* Formatted output to strings.
2 Copyright (C) 1999, 2002, 2006-2007 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License along
15 with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18#include <config.h>
19
20/* Specification. */
21#ifdef IN_LIBASPRINTF
22# include "vasprintf.h"
23#else
24# include <stdio.h>
25#endif
26
27#include <stdarg.h>
28
29int
30asprintf (char **resultp, const char *format, ...)
31{
32 va_list args;
33 int result;
34
35 va_start (args, format);
36 result = vasprintf (resultp, format, args);
37 va_end (args);
38 return result;
39}
diff --git a/src/daemon/https/lgl/des.c b/src/daemon/https/lgl/des.c
new file mode 100644
index 00000000..fd70bc7e
--- /dev/null
+++ b/src/daemon/https/lgl/des.c
@@ -0,0 +1,662 @@
1/* des.c --- DES and Triple-DES encryption/decryption Algorithm
2 * Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007
3 * Free Software Foundation, Inc.
4 *
5 * This file is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published
7 * by the Free Software Foundation; either version 2.1, or (at your
8 * option) any later version.
9 *
10 * This file is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this file; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301, USA.
19 *
20 */
21
22/* Adapted for gnulib by Simon Josefsson, based on Libgcrypt. */
23
24/*
25 * For a description of triple encryption, see:
26 * Bruce Schneier: Applied Cryptography. Second Edition.
27 * John Wiley & Sons, 1996. ISBN 0-471-12845-7. Pages 358 ff.
28 * This implementation is according to the definition of DES in FIPS
29 * PUB 46-2 from December 1993.
30 *
31 * Written by Michael Roth <mroth@nessie.de>, September 1998
32 */
33
34/*
35 * U S A G E
36 * ===========
37 *
38 * For DES or Triple-DES encryption/decryption you must initialize a proper
39 * encryption context with a key.
40 *
41 * A DES key is 64bit wide but only 56bits of the key are used. The remaining
42 * bits are parity bits and they will _not_ checked in this implementation, but
43 * simply ignored.
44 *
45 * For Triple-DES you could use either two 64bit keys or three 64bit keys.
46 * The parity bits will _not_ checked, too.
47 *
48 * After initializing a context with a key you could use this context to
49 * encrypt or decrypt data in 64bit blocks in Electronic Codebook Mode.
50 *
51 * DES Example
52 * -----------
53 * unsigned char key[8];
54 * unsigned char plaintext[8];
55 * unsigned char ciphertext[8];
56 * unsigned char recoverd[8];
57 * gl_des_ctx context;
58 *
59 * // Fill 'key' and 'plaintext' with some data
60 * ....
61 *
62 * // Set up the DES encryption context
63 * gl_des_setkey(&context, key);
64 *
65 * // Encrypt the plaintext
66 * des_ecb_encrypt(&context, plaintext, ciphertext);
67 *
68 * // To recover the orginal plaintext from ciphertext use:
69 * des_ecb_decrypt(&context, ciphertext, recoverd);
70 *
71 *
72 * Triple-DES Example
73 * ------------------
74 * unsigned char key1[8];
75 * unsigned char key2[8];
76 * unsigned char key3[8];
77 * unsigned char plaintext[8];
78 * unsigned char ciphertext[8];
79 * unsigned char recoverd[8];
80 * gl_3des_ctx context;
81 *
82 * // If you would like to use two 64bit keys, fill 'key1' and'key2'
83 * // then setup the encryption context:
84 * gl_3des_set2keys(&context, key1, key2);
85 *
86 * // To use three 64bit keys with Triple-DES use:
87 * gl_3des_set3keys(&context, key1, key2, key3);
88 *
89 * // Encrypting plaintext with Triple-DES
90 * gl_3des_ecb_encrypt(&context, plaintext, ciphertext);
91 *
92 * // Decrypting ciphertext to recover the plaintext with Triple-DES
93 * gl_3des_ecb_decrypt(&context, ciphertext, recoverd);
94 */
95
96
97#include <config.h>
98
99#include "des.h"
100
101#include <stdio.h>
102#include <string.h> /* memcpy, memcmp */
103
104/*
105 * The s-box values are permuted according to the 'primitive function P'
106 * and are rotated one bit to the left.
107 */
108static const uint32_t sbox1[64] = {
109 0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404,
110 0x00000004, 0x00010000, 0x00000400, 0x01010400, 0x01010404, 0x00000400,
111 0x01000404, 0x01010004, 0x01000000, 0x00000004, 0x00000404, 0x01000400,
112 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404,
113 0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404,
114 0x00010404, 0x01000000, 0x00010000, 0x01010404, 0x00000004, 0x01010000,
115 0x01010400, 0x01000000, 0x01000000, 0x00000400, 0x01010004, 0x00010000,
116 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404,
117 0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404,
118 0x00010404, 0x01010400, 0x00000404, 0x01000400, 0x01000400, 0x00000000,
119 0x00010004, 0x00010400, 0x00000000, 0x01010004
120};
121
122static const uint32_t sbox2[64] = {
123 0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020,
124 0x80100020, 0x80008020, 0x80000020, 0x80108020, 0x80108000, 0x80000000,
125 0x80008000, 0x00100000, 0x00000020, 0x80100020, 0x00108000, 0x00100020,
126 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000,
127 0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000,
128 0x80100000, 0x00008020, 0x00000000, 0x00108020, 0x80100020, 0x00100000,
129 0x80008020, 0x80100000, 0x80108000, 0x00008000, 0x80100000, 0x80008000,
130 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000,
131 0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020,
132 0x80000020, 0x00100020, 0x00108000, 0x00000000, 0x80008000, 0x00008020,
133 0x80000000, 0x80100020, 0x80108020, 0x00108000
134};
135
136static const uint32_t sbox3[64] = {
137 0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000,
138 0x00020208, 0x08000200, 0x00020008, 0x08000008, 0x08000008, 0x00020000,
139 0x08020208, 0x00020008, 0x08020000, 0x00000208, 0x08000000, 0x00000008,
140 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208,
141 0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208,
142 0x00000200, 0x08000000, 0x08020200, 0x08000000, 0x00020008, 0x00000208,
143 0x00020000, 0x08020200, 0x08000200, 0x00000000, 0x00000200, 0x00020008,
144 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008,
145 0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208,
146 0x00020200, 0x08000008, 0x08020000, 0x08000208, 0x00000208, 0x08020000,
147 0x00020208, 0x00000008, 0x08020008, 0x00020200
148};
149
150static const uint32_t sbox4[64] = {
151 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081,
152 0x00800001, 0x00002001, 0x00000000, 0x00802000, 0x00802000, 0x00802081,
153 0x00000081, 0x00000000, 0x00800080, 0x00800001, 0x00000001, 0x00002000,
154 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080,
155 0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080,
156 0x00802081, 0x00000081, 0x00800080, 0x00800001, 0x00802000, 0x00802081,
157 0x00000081, 0x00000000, 0x00000000, 0x00802000, 0x00002080, 0x00800080,
158 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080,
159 0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001,
160 0x00802080, 0x00800081, 0x00002001, 0x00002080, 0x00800000, 0x00802001,
161 0x00000080, 0x00800000, 0x00002000, 0x00802080
162};
163
164static const uint32_t sbox5[64] = {
165 0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100,
166 0x40000000, 0x02080000, 0x40080100, 0x00080000, 0x02000100, 0x40080100,
167 0x42000100, 0x42080000, 0x00080100, 0x40000000, 0x02000000, 0x40080000,
168 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100,
169 0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000,
170 0x42000000, 0x00080100, 0x00080000, 0x42000100, 0x00000100, 0x02000000,
171 0x40000000, 0x02080000, 0x42000100, 0x40080100, 0x02000100, 0x40000000,
172 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000,
173 0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000,
174 0x40080000, 0x42000000, 0x00080100, 0x02000100, 0x40000100, 0x00080000,
175 0x00000000, 0x40080000, 0x02080100, 0x40000100
176};
177
178static const uint32_t sbox6[64] = {
179 0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010,
180 0x20404010, 0x00400000, 0x20004000, 0x00404010, 0x00400000, 0x20000010,
181 0x00400010, 0x20004000, 0x20000000, 0x00004010, 0x00000000, 0x00400010,
182 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010,
183 0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000,
184 0x20404000, 0x20000000, 0x20004000, 0x00000010, 0x20400010, 0x00404000,
185 0x20404010, 0x00400000, 0x00004010, 0x20000010, 0x00400000, 0x20004000,
186 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000,
187 0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000,
188 0x20400000, 0x00404010, 0x00004000, 0x00400010, 0x20004010, 0x00000000,
189 0x20404000, 0x20000000, 0x00400010, 0x20004010
190};
191
192static const uint32_t sbox7[64] = {
193 0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802,
194 0x00200802, 0x04200800, 0x04200802, 0x00200000, 0x00000000, 0x04000002,
195 0x00000002, 0x04000000, 0x04200002, 0x00000802, 0x04000800, 0x00200802,
196 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002,
197 0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002,
198 0x04000000, 0x00200800, 0x04000000, 0x00200800, 0x00200000, 0x04000802,
199 0x04000802, 0x04200002, 0x04200002, 0x00000002, 0x00200002, 0x04000000,
200 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800,
201 0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000,
202 0x00000002, 0x04200802, 0x00000000, 0x00200802, 0x04200000, 0x00000800,
203 0x04000002, 0x04000800, 0x00000800, 0x00200002
204};
205
206static const uint32_t sbox8[64] = {
207 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040,
208 0x00000040, 0x10000000, 0x00040040, 0x10040000, 0x10041040, 0x00041000,
209 0x10041000, 0x00041040, 0x00001000, 0x00000040, 0x10040000, 0x10000040,
210 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000,
211 0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000,
212 0x00041040, 0x00040000, 0x00041040, 0x00040000, 0x10041000, 0x00001000,
213 0x00000040, 0x10040040, 0x00001000, 0x00041040, 0x10001000, 0x00000040,
214 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040,
215 0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000,
216 0x10001040, 0x00000000, 0x10041040, 0x00041000, 0x00041000, 0x00001040,
217 0x00001040, 0x00040040, 0x10000000, 0x10041000
218};
219
220/*
221 * These two tables are part of the 'permuted choice 1' function.
222 * In this implementation several speed improvements are done.
223 */
224static const uint32_t leftkey_swap[16] = {
225 0x00000000, 0x00000001, 0x00000100, 0x00000101,
226 0x00010000, 0x00010001, 0x00010100, 0x00010101,
227 0x01000000, 0x01000001, 0x01000100, 0x01000101,
228 0x01010000, 0x01010001, 0x01010100, 0x01010101
229};
230
231static const uint32_t rightkey_swap[16] = {
232 0x00000000, 0x01000000, 0x00010000, 0x01010000,
233 0x00000100, 0x01000100, 0x00010100, 0x01010100,
234 0x00000001, 0x01000001, 0x00010001, 0x01010001,
235 0x00000101, 0x01000101, 0x00010101, 0x01010101,
236};
237
238/*
239 * Numbers of left shifts per round for encryption subkeys. To
240 * calculate the decryption subkeys we just reverse the ordering of
241 * the calculated encryption subkeys, so there is no need for a
242 * decryption rotate tab.
243 */
244static const unsigned char encrypt_rotate_tab[16] = {
245 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
246};
247
248/*
249 * Table with weak DES keys sorted in ascending order. In DES there
250 * are 64 known keys which are weak. They are weak because they
251 * produce only one, two or four different subkeys in the subkey
252 * scheduling process. The keys in this table have all their parity
253 * bits cleared.
254 */
255static const unsigned char weak_keys[64][8] = {
256 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*w */
257 {0x00, 0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e},
258 {0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0},
259 {0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe},
260 {0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e}, /*sw */
261 {0x00, 0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00},
262 {0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe},
263 {0x00, 0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0},
264 {0x00, 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0}, /*sw */
265 {0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe},
266 {0x00, 0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00},
267 {0x00, 0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e},
268 {0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe}, /*sw */
269 {0x00, 0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0},
270 {0x00, 0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e},
271 {0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00},
272 {0x1e, 0x00, 0x00, 0x1e, 0x0e, 0x00, 0x00, 0x0e},
273 {0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00}, /*sw */
274 {0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0, 0xfe},
275 {0x1e, 0x00, 0xfe, 0xe0, 0x0e, 0x00, 0xfe, 0xf0},
276 {0x1e, 0x1e, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00},
277 {0x1e, 0x1e, 0x1e, 0x1e, 0x0e, 0x0e, 0x0e, 0x0e}, /*w */
278 {0x1e, 0x1e, 0xe0, 0xe0, 0x0e, 0x0e, 0xf0, 0xf0},
279 {0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe, 0xfe},
280 {0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00, 0xfe},
281 {0x1e, 0xe0, 0x1e, 0xe0, 0x0e, 0xf0, 0x0e, 0xf0}, /*sw */
282 {0x1e, 0xe0, 0xe0, 0x1e, 0x0e, 0xf0, 0xf0, 0x0e},
283 {0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0, 0xfe, 0x00},
284 {0x1e, 0xfe, 0x00, 0xe0, 0x0e, 0xfe, 0x00, 0xf0},
285 {0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe}, /*sw */
286 {0x1e, 0xfe, 0xe0, 0x00, 0x0e, 0xfe, 0xf0, 0x00},
287 {0x1e, 0xfe, 0xfe, 0x1e, 0x0e, 0xfe, 0xfe, 0x0e},
288 {0xe0, 0x00, 0x00, 0xe0, 0xf0, 0x00, 0x00, 0xf0},
289 {0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e, 0xfe},
290 {0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00}, /*sw */
291 {0xe0, 0x00, 0xfe, 0x1e, 0xf0, 0x00, 0xfe, 0x0e},
292 {0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00, 0xfe},
293 {0xe0, 0x1e, 0x1e, 0xe0, 0xf0, 0x0e, 0x0e, 0xf0},
294 {0xe0, 0x1e, 0xe0, 0x1e, 0xf0, 0x0e, 0xf0, 0x0e}, /*sw */
295 {0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e, 0xfe, 0x00},
296 {0xe0, 0xe0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00},
297 {0xe0, 0xe0, 0x1e, 0x1e, 0xf0, 0xf0, 0x0e, 0x0e},
298 {0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0}, /*w */
299 {0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe, 0xfe},
300 {0xe0, 0xfe, 0x00, 0x1e, 0xf0, 0xfe, 0x00, 0x0e},
301 {0xe0, 0xfe, 0x1e, 0x00, 0xf0, 0xfe, 0x0e, 0x00},
302 {0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0, 0xfe}, /*sw */
303 {0xe0, 0xfe, 0xfe, 0xe0, 0xf0, 0xfe, 0xfe, 0xf0},
304 {0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe},
305 {0xfe, 0x00, 0x1e, 0xe0, 0xfe, 0x00, 0x0e, 0xf0},
306 {0xfe, 0x00, 0xe0, 0x1e, 0xfe, 0x00, 0xf0, 0x0e},
307 {0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xfe, 0x00}, /*sw */
308 {0xfe, 0x1e, 0x00, 0xe0, 0xfe, 0x0e, 0x00, 0xf0},
309 {0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e, 0xfe},
310 {0xfe, 0x1e, 0xe0, 0x00, 0xfe, 0x0e, 0xf0, 0x00},
311 {0xfe, 0x1e, 0xfe, 0x1e, 0xfe, 0x0e, 0xfe, 0x0e}, /*sw */
312 {0xfe, 0xe0, 0x00, 0x1e, 0xfe, 0xf0, 0x00, 0x0e},
313 {0xfe, 0xe0, 0x1e, 0x00, 0xfe, 0xf0, 0x0e, 0x00},
314 {0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0, 0xfe},
315 {0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf0, 0xfe, 0xf0}, /*sw */
316 {0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00},
317 {0xfe, 0xfe, 0x1e, 0x1e, 0xfe, 0xfe, 0x0e, 0x0e},
318 {0xfe, 0xfe, 0xe0, 0xe0, 0xfe, 0xfe, 0xf0, 0xf0},
319 {0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe} /*w */
320};
321
322bool
323gl_des_is_weak_key (const char *key)
324{
325 char work[8];
326 int i, left, right, middle, cmp_result;
327
328 /* clear parity bits */
329 for (i = 0; i < 8; ++i)
330 work[i] = ((unsigned char) key[i]) & 0xfe;
331
332 /* binary search in the weak key table */
333 left = 0;
334 right = 63;
335 while (left <= right)
336 {
337 middle = (left + right) / 2;
338
339 if (!(cmp_result = memcmp (work, weak_keys[middle], 8)))
340 return -1;
341
342 if (cmp_result > 0)
343 left = middle + 1;
344 else
345 right = middle - 1;
346 }
347
348 return 0;
349}
350
351/*
352 * Macro to swap bits across two words.
353 */
354#define DO_PERMUTATION(a, temp, b, offset, mask) \
355 temp = ((a>>offset) ^ b) & mask; \
356 b ^= temp; \
357 a ^= temp<<offset;
358
359
360/*
361 * This performs the 'initial permutation' of the data to be encrypted
362 * or decrypted. Additionally the resulting two words are rotated one bit
363 * to the left.
364 */
365#define INITIAL_PERMUTATION(left, temp, right) \
366 DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f) \
367 DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \
368 DO_PERMUTATION(right, temp, left, 2, 0x33333333) \
369 DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \
370 right = (right << 1) | (right >> 31); \
371 temp = (left ^ right) & 0xaaaaaaaa; \
372 right ^= temp; \
373 left ^= temp; \
374 left = (left << 1) | (left >> 31);
375
376/*
377 * The 'inverse initial permutation'.
378 */
379#define FINAL_PERMUTATION(left, temp, right) \
380 left = (left << 31) | (left >> 1); \
381 temp = (left ^ right) & 0xaaaaaaaa; \
382 left ^= temp; \
383 right ^= temp; \
384 right = (right << 31) | (right >> 1); \
385 DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \
386 DO_PERMUTATION(right, temp, left, 2, 0x33333333) \
387 DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \
388 DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f)
389
390
391/*
392 * A full DES round including 'expansion function', 'sbox substitution'
393 * and 'primitive function P' but without swapping the left and right word.
394 * Please note: The data in 'from' and 'to' is already rotated one bit to
395 * the left, done in the initial permutation.
396 */
397#define DES_ROUND(from, to, work, subkey) \
398 work = from ^ *subkey++; \
399 to ^= sbox8[ work & 0x3f ]; \
400 to ^= sbox6[ (work>>8) & 0x3f ]; \
401 to ^= sbox4[ (work>>16) & 0x3f ]; \
402 to ^= sbox2[ (work>>24) & 0x3f ]; \
403 work = ((from << 28) | (from >> 4)) ^ *subkey++; \
404 to ^= sbox7[ work & 0x3f ]; \
405 to ^= sbox5[ (work>>8) & 0x3f ]; \
406 to ^= sbox3[ (work>>16) & 0x3f ]; \
407 to ^= sbox1[ (work>>24) & 0x3f ];
408
409/*
410 * Macros to convert 8 bytes from/to 32bit words.
411 */
412#define READ_64BIT_DATA(data, left, right) \
413 left = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; \
414 right = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7];
415
416#define WRITE_64BIT_DATA(data, left, right) \
417 data[0] = (left >> 24) &0xff; data[1] = (left >> 16) &0xff; \
418 data[2] = (left >> 8) &0xff; data[3] = left &0xff; \
419 data[4] = (right >> 24) &0xff; data[5] = (right >> 16) &0xff; \
420 data[6] = (right >> 8) &0xff; data[7] = right &0xff;
421
422/*
423 * des_key_schedule(): Calculate 16 subkeys pairs (even/odd) for
424 * 16 encryption rounds.
425 * To calculate subkeys for decryption the caller
426 * have to reorder the generated subkeys.
427 *
428 * rawkey: 8 Bytes of key data
429 * subkey: Array of at least 32 uint32_ts. Will be filled
430 * with calculated subkeys.
431 *
432 */
433static void
434des_key_schedule (const char *_rawkey, uint32_t * subkey)
435{
436 const unsigned char *rawkey = (const unsigned char *) _rawkey;
437 uint32_t left, right, work;
438 int round;
439
440 READ_64BIT_DATA (rawkey, left, right)
441 DO_PERMUTATION (right, work, left, 4, 0x0f0f0f0f)
442 DO_PERMUTATION (right, work, left, 0, 0x10101010)
443 left = ((leftkey_swap[(left >> 0) & 0xf] << 3)
444 | (leftkey_swap[(left >> 8) & 0xf] << 2)
445 | (leftkey_swap[(left >> 16) & 0xf] << 1)
446 | (leftkey_swap[(left >> 24) & 0xf])
447 | (leftkey_swap[(left >> 5) & 0xf] << 7)
448 | (leftkey_swap[(left >> 13) & 0xf] << 6)
449 | (leftkey_swap[(left >> 21) & 0xf] << 5)
450 | (leftkey_swap[(left >> 29) & 0xf] << 4));
451
452 left &= 0x0fffffff;
453
454 right = ((rightkey_swap[(right >> 1) & 0xf] << 3)
455 | (rightkey_swap[(right >> 9) & 0xf] << 2)
456 | (rightkey_swap[(right >> 17) & 0xf] << 1)
457 | (rightkey_swap[(right >> 25) & 0xf])
458 | (rightkey_swap[(right >> 4) & 0xf] << 7)
459 | (rightkey_swap[(right >> 12) & 0xf] << 6)
460 | (rightkey_swap[(right >> 20) & 0xf] << 5)
461 | (rightkey_swap[(right >> 28) & 0xf] << 4));
462
463 right &= 0x0fffffff;
464
465 for (round = 0; round < 16; ++round)
466 {
467 left = ((left << encrypt_rotate_tab[round])
468 | (left >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
469 right = ((right << encrypt_rotate_tab[round])
470 | (right >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
471
472 *subkey++ = (((left << 4) & 0x24000000)
473 | ((left << 28) & 0x10000000)
474 | ((left << 14) & 0x08000000)
475 | ((left << 18) & 0x02080000)
476 | ((left << 6) & 0x01000000)
477 | ((left << 9) & 0x00200000)
478 | ((left >> 1) & 0x00100000)
479 | ((left << 10) & 0x00040000)
480 | ((left << 2) & 0x00020000)
481 | ((left >> 10) & 0x00010000)
482 | ((right >> 13) & 0x00002000)
483 | ((right >> 4) & 0x00001000)
484 | ((right << 6) & 0x00000800)
485 | ((right >> 1) & 0x00000400)
486 | ((right >> 14) & 0x00000200)
487 | (right & 0x00000100)
488 | ((right >> 5) & 0x00000020)
489 | ((right >> 10) & 0x00000010)
490 | ((right >> 3) & 0x00000008)
491 | ((right >> 18) & 0x00000004)
492 | ((right >> 26) & 0x00000002)
493 | ((right >> 24) & 0x00000001));
494
495 *subkey++ = (((left << 15) & 0x20000000)
496 | ((left << 17) & 0x10000000)
497 | ((left << 10) & 0x08000000)
498 | ((left << 22) & 0x04000000)
499 | ((left >> 2) & 0x02000000)
500 | ((left << 1) & 0x01000000)
501 | ((left << 16) & 0x00200000)
502 | ((left << 11) & 0x00100000)
503 | ((left << 3) & 0x00080000)
504 | ((left >> 6) & 0x00040000)
505 | ((left << 15) & 0x00020000)
506 | ((left >> 4) & 0x00010000)
507 | ((right >> 2) & 0x00002000)
508 | ((right << 8) & 0x00001000)
509 | ((right >> 14) & 0x00000808)
510 | ((right >> 9) & 0x00000400)
511 | ((right) & 0x00000200)
512 | ((right << 7) & 0x00000100)
513 | ((right >> 7) & 0x00000020)
514 | ((right >> 3) & 0x00000011)
515 | ((right << 2) & 0x00000004)
516 | ((right >> 21) & 0x00000002));
517 }
518}
519
520void
521gl_des_setkey (gl_des_ctx * ctx, const char *key)
522{
523 int i;
524
525 des_key_schedule (key, ctx->encrypt_subkeys);
526
527 for (i = 0; i < 32; i += 2)
528 {
529 ctx->decrypt_subkeys[i] = ctx->encrypt_subkeys[30 - i];
530 ctx->decrypt_subkeys[i + 1] = ctx->encrypt_subkeys[31 - i];
531 }
532}
533
534bool
535gl_des_makekey (gl_des_ctx * ctx, const char *key, size_t keylen)
536{
537 if (keylen != 8)
538 return false;
539
540 gl_des_setkey (ctx, key);
541
542 return !gl_des_is_weak_key (key);
543}
544
545void
546gl_des_ecb_crypt (gl_des_ctx * ctx, const char *_from, char *_to, int mode)
547{
548 const unsigned char *from = (const unsigned char *) _from;
549 unsigned char *to = (unsigned char *) _to;
550 uint32_t left, right, work;
551 uint32_t *keys;
552
553 keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys;
554
555READ_64BIT_DATA (from, left, right)
556 INITIAL_PERMUTATION (left, work, right)
557 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
558 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
559 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
560 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
561 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
562 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
563 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
564 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
565 FINAL_PERMUTATION (right, work, left) WRITE_64BIT_DATA (to, right, left)}
566
567void
568gl_3des_set2keys (gl_3des_ctx * ctx, const char *key1, const char *key2)
569{
570 int i;
571
572 des_key_schedule (key1, ctx->encrypt_subkeys);
573 des_key_schedule (key2, &(ctx->decrypt_subkeys[32]));
574
575 for (i = 0; i < 32; i += 2)
576 {
577 ctx->decrypt_subkeys[i] = ctx->encrypt_subkeys[30 - i];
578 ctx->decrypt_subkeys[i + 1] = ctx->encrypt_subkeys[31 - i];
579
580 ctx->encrypt_subkeys[i + 32] = ctx->decrypt_subkeys[62 - i];
581 ctx->encrypt_subkeys[i + 33] = ctx->decrypt_subkeys[63 - i];
582
583 ctx->encrypt_subkeys[i + 64] = ctx->encrypt_subkeys[i];
584 ctx->encrypt_subkeys[i + 65] = ctx->encrypt_subkeys[i + 1];
585
586 ctx->decrypt_subkeys[i + 64] = ctx->decrypt_subkeys[i];
587 ctx->decrypt_subkeys[i + 65] = ctx->decrypt_subkeys[i + 1];
588 }
589}
590
591void
592gl_3des_set3keys (gl_3des_ctx * ctx, const char *key1,
593 const char *key2, const char *key3)
594{
595 int i;
596
597 des_key_schedule (key1, ctx->encrypt_subkeys);
598 des_key_schedule (key2, &(ctx->decrypt_subkeys[32]));
599 des_key_schedule (key3, &(ctx->encrypt_subkeys[64]));
600
601 for (i = 0; i < 32; i += 2)
602 {
603 ctx->decrypt_subkeys[i] = ctx->encrypt_subkeys[94 - i];
604 ctx->decrypt_subkeys[i + 1] = ctx->encrypt_subkeys[95 - i];
605
606 ctx->encrypt_subkeys[i + 32] = ctx->decrypt_subkeys[62 - i];
607 ctx->encrypt_subkeys[i + 33] = ctx->decrypt_subkeys[63 - i];
608
609 ctx->decrypt_subkeys[i + 64] = ctx->encrypt_subkeys[30 - i];
610 ctx->decrypt_subkeys[i + 65] = ctx->encrypt_subkeys[31 - i];
611 }
612}
613
614void
615gl_3des_ecb_crypt (gl_3des_ctx * ctx, const char *_from, char *_to, int mode)
616{
617 const unsigned char *from = (const unsigned char *) _from;
618 unsigned char *to = (unsigned char *) _to;
619 uint32_t left, right, work;
620 uint32_t *keys;
621
622 keys = mode ? ctx->decrypt_subkeys : ctx->encrypt_subkeys;
623
624READ_64BIT_DATA (from, left, right)
625 INITIAL_PERMUTATION (left, work, right)
626 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
627 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
628 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
629 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
630 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
631 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
632 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
633 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
634 DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
635 DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
636 DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
637 DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
638 DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
639 DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
640 DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
641 DES_ROUND (left, right, work, keys) DES_ROUND (right, left, work, keys)
642 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
643 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
644 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
645 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
646 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
647 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
648 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
649 DES_ROUND (right, left, work, keys) DES_ROUND (left, right, work, keys)
650 FINAL_PERMUTATION (right, work, left) WRITE_64BIT_DATA (to, right, left)}
651
652bool
653gl_3des_makekey (gl_3des_ctx * ctx, const char *key, size_t keylen)
654{
655 if (keylen != 24)
656 return false;
657
658 gl_3des_set3keys (ctx, key, key + 8, key + 16);
659
660 return !(gl_des_is_weak_key (key)
661 || gl_des_is_weak_key (key + 8) || gl_des_is_weak_key (key + 16));
662}
diff --git a/src/daemon/https/lgl/des.h b/src/daemon/https/lgl/des.h
new file mode 100644
index 00000000..fdc8686f
--- /dev/null
+++ b/src/daemon/https/lgl/des.h
@@ -0,0 +1,121 @@
1/* des.h --- DES cipher implementation.
2 * Copyright (C) 2005, 2007 Free Software Foundation, Inc.
3 *
4 * This file is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; either version 2.1, or (at your
7 * option) any later version.
8 *
9 * This file is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this file; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 */
20
21/* Adapted for gnulib by Simon Josefsson, based on Libgcrypt. */
22
23#ifndef DES_H
24# define DES_H
25
26#include <stddef.h>
27#include <stdint.h>
28#include <stdbool.h>
29
30/*
31 * Encryption/Decryption context of DES
32 */
33typedef struct
34{
35 uint32_t encrypt_subkeys[32];
36 uint32_t decrypt_subkeys[32];
37} gl_des_ctx;
38
39/*
40 * Encryption/Decryption context of Triple-DES
41 */
42typedef struct
43{
44 uint32_t encrypt_subkeys[96];
45 uint32_t decrypt_subkeys[96];
46} gl_3des_ctx;
47
48/* Check whether the 8 byte key is weak. Does not check the parity
49 * bits of the key but simple ignore them. */
50extern bool
51gl_des_is_weak_key (const char * key);
52
53/*
54 * DES
55 * ---
56 */
57
58/* Fill a DES context CTX with subkeys calculated from 64bit KEY.
59 * Does not check parity bits, but simply ignore them. Does not check
60 * for weak keys. */
61extern void
62gl_des_setkey (gl_des_ctx *ctx, const char * key);
63
64/* Fill a DES context CTX with subkeys calculated from 64bit KEY, with
65 * weak key checking. Does not check parity bits, but simply ignore
66 * them. */
67extern bool
68gl_des_makekey (gl_des_ctx *ctx, const char * key, size_t keylen);
69
70/* Electronic Codebook Mode DES encryption/decryption of data
71 * according to 'mode'. */
72extern void
73gl_des_ecb_crypt (gl_des_ctx *ctx, const char * from, char * to, int mode);
74
75#define gl_des_ecb_encrypt(ctx, from, to) gl_des_ecb_crypt(ctx, from, to, 0)
76#define gl_des_ecb_decrypt(ctx, from, to) gl_des_ecb_crypt(ctx, from, to, 1)
77
78/* Triple-DES
79 * ----------
80 */
81
82/* Fill a Triple-DES context CTX with subkeys calculated from two
83 * 64bit keys in KEY1 and KEY2. Does not check the parity bits of the
84 * keys, but simply ignore them. Does not check for weak keys. */
85extern void
86gl_3des_set2keys (gl_3des_ctx *ctx,
87 const char * key1,
88 const char * key2);
89
90/*
91 * Fill a Triple-DES context CTX with subkeys calculated from three
92 * 64bit keys in KEY1, KEY2 and KEY3. Does not check the parity bits
93 * of the keys, but simply ignore them. Does not check for weak
94 * keys. */
95extern void
96gl_3des_set3keys (gl_3des_ctx *ctx,
97 const char * key1,
98 const char * key2,
99 const char * key3);
100
101/* Fill a Triple-DES context CTX with subkeys calculated from three
102 * concatenated 64bit keys in KEY, with weak key checking. Does not
103 * check the parity bits of the keys, but simply ignore them. */
104extern bool
105gl_3des_makekey (gl_3des_ctx *ctx,
106 const char * key,
107 size_t keylen);
108
109/* Electronic Codebook Mode Triple-DES encryption/decryption of data
110 * according to 'mode'. Sometimes this mode is named 'EDE' mode
111 * (Encryption-Decryption-Encryption). */
112extern void
113gl_3des_ecb_crypt (gl_3des_ctx *ctx,
114 const char * from,
115 char * to,
116 int mode);
117
118#define gl_3des_ecb_encrypt(ctx, from, to) gl_3des_ecb_crypt(ctx,from,to,0)
119#define gl_3des_ecb_decrypt(ctx, from, to) gl_3des_ecb_crypt(ctx,from,to,1)
120
121#endif /* DES_H */
diff --git a/src/daemon/https/lgl/float+.h b/src/daemon/https/lgl/float+.h
new file mode 100644
index 00000000..f0c0c189
--- /dev/null
+++ b/src/daemon/https/lgl/float+.h
@@ -0,0 +1,148 @@
1/* Supplemental information about the floating-point formats.
2 Copyright (C) 2007 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2007.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
18
19#ifndef _FLOATPLUS_H
20#define _FLOATPLUS_H
21
22#include <float.h>
23#include <limits.h>
24
25/* Number of bits in the mantissa of a floating-point number, including the
26 "hidden bit". */
27#if FLT_RADIX == 2
28# define FLT_MANT_BIT FLT_MANT_DIG
29# define DBL_MANT_BIT DBL_MANT_DIG
30# define LDBL_MANT_BIT LDBL_MANT_DIG
31#elif FLT_RADIX == 4
32# define FLT_MANT_BIT (FLT_MANT_DIG * 2)
33# define DBL_MANT_BIT (DBL_MANT_DIG * 2)
34# define LDBL_MANT_BIT (LDBL_MANT_DIG * 2)
35#elif FLT_RADIX == 16
36# define FLT_MANT_BIT (FLT_MANT_DIG * 4)
37# define DBL_MANT_BIT (DBL_MANT_DIG * 4)
38# define LDBL_MANT_BIT (LDBL_MANT_DIG * 4)
39#endif
40
41/* Bit mask that can be used to mask the exponent, as an unsigned number. */
42#define FLT_EXP_MASK ((FLT_MAX_EXP - FLT_MIN_EXP) | 7)
43#define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7)
44#define LDBL_EXP_MASK ((LDBL_MAX_EXP - LDBL_MIN_EXP) | 7)
45
46/* Number of bits used for the exponent of a floating-point number, including
47 the exponent's sign. */
48#define FLT_EXP_BIT \
49 (FLT_EXP_MASK < 0x100 ? 8 : \
50 FLT_EXP_MASK < 0x200 ? 9 : \
51 FLT_EXP_MASK < 0x400 ? 10 : \
52 FLT_EXP_MASK < 0x800 ? 11 : \
53 FLT_EXP_MASK < 0x1000 ? 12 : \
54 FLT_EXP_MASK < 0x2000 ? 13 : \
55 FLT_EXP_MASK < 0x4000 ? 14 : \
56 FLT_EXP_MASK < 0x8000 ? 15 : \
57 FLT_EXP_MASK < 0x10000 ? 16 : \
58 FLT_EXP_MASK < 0x20000 ? 17 : \
59 FLT_EXP_MASK < 0x40000 ? 18 : \
60 FLT_EXP_MASK < 0x80000 ? 19 : \
61 FLT_EXP_MASK < 0x100000 ? 20 : \
62 FLT_EXP_MASK < 0x200000 ? 21 : \
63 FLT_EXP_MASK < 0x400000 ? 22 : \
64 FLT_EXP_MASK < 0x800000 ? 23 : \
65 FLT_EXP_MASK < 0x1000000 ? 24 : \
66 FLT_EXP_MASK < 0x2000000 ? 25 : \
67 FLT_EXP_MASK < 0x4000000 ? 26 : \
68 FLT_EXP_MASK < 0x8000000 ? 27 : \
69 FLT_EXP_MASK < 0x10000000 ? 28 : \
70 FLT_EXP_MASK < 0x20000000 ? 29 : \
71 FLT_EXP_MASK < 0x40000000 ? 30 : \
72 FLT_EXP_MASK <= 0x7fffffff ? 31 : \
73 32)
74#define DBL_EXP_BIT \
75 (DBL_EXP_MASK < 0x100 ? 8 : \
76 DBL_EXP_MASK < 0x200 ? 9 : \
77 DBL_EXP_MASK < 0x400 ? 10 : \
78 DBL_EXP_MASK < 0x800 ? 11 : \
79 DBL_EXP_MASK < 0x1000 ? 12 : \
80 DBL_EXP_MASK < 0x2000 ? 13 : \
81 DBL_EXP_MASK < 0x4000 ? 14 : \
82 DBL_EXP_MASK < 0x8000 ? 15 : \
83 DBL_EXP_MASK < 0x10000 ? 16 : \
84 DBL_EXP_MASK < 0x20000 ? 17 : \
85 DBL_EXP_MASK < 0x40000 ? 18 : \
86 DBL_EXP_MASK < 0x80000 ? 19 : \
87 DBL_EXP_MASK < 0x100000 ? 20 : \
88 DBL_EXP_MASK < 0x200000 ? 21 : \
89 DBL_EXP_MASK < 0x400000 ? 22 : \
90 DBL_EXP_MASK < 0x800000 ? 23 : \
91 DBL_EXP_MASK < 0x1000000 ? 24 : \
92 DBL_EXP_MASK < 0x2000000 ? 25 : \
93 DBL_EXP_MASK < 0x4000000 ? 26 : \
94 DBL_EXP_MASK < 0x8000000 ? 27 : \
95 DBL_EXP_MASK < 0x10000000 ? 28 : \
96 DBL_EXP_MASK < 0x20000000 ? 29 : \
97 DBL_EXP_MASK < 0x40000000 ? 30 : \
98 DBL_EXP_MASK <= 0x7fffffff ? 31 : \
99 32)
100#define LDBL_EXP_BIT \
101 (LDBL_EXP_MASK < 0x100 ? 8 : \
102 LDBL_EXP_MASK < 0x200 ? 9 : \
103 LDBL_EXP_MASK < 0x400 ? 10 : \
104 LDBL_EXP_MASK < 0x800 ? 11 : \
105 LDBL_EXP_MASK < 0x1000 ? 12 : \
106 LDBL_EXP_MASK < 0x2000 ? 13 : \
107 LDBL_EXP_MASK < 0x4000 ? 14 : \
108 LDBL_EXP_MASK < 0x8000 ? 15 : \
109 LDBL_EXP_MASK < 0x10000 ? 16 : \
110 LDBL_EXP_MASK < 0x20000 ? 17 : \
111 LDBL_EXP_MASK < 0x40000 ? 18 : \
112 LDBL_EXP_MASK < 0x80000 ? 19 : \
113 LDBL_EXP_MASK < 0x100000 ? 20 : \
114 LDBL_EXP_MASK < 0x200000 ? 21 : \
115 LDBL_EXP_MASK < 0x400000 ? 22 : \
116 LDBL_EXP_MASK < 0x800000 ? 23 : \
117 LDBL_EXP_MASK < 0x1000000 ? 24 : \
118 LDBL_EXP_MASK < 0x2000000 ? 25 : \
119 LDBL_EXP_MASK < 0x4000000 ? 26 : \
120 LDBL_EXP_MASK < 0x8000000 ? 27 : \
121 LDBL_EXP_MASK < 0x10000000 ? 28 : \
122 LDBL_EXP_MASK < 0x20000000 ? 29 : \
123 LDBL_EXP_MASK < 0x40000000 ? 30 : \
124 LDBL_EXP_MASK <= 0x7fffffff ? 31 : \
125 32)
126
127/* Number of bits used for a floating-point number: the mantissa (not
128 counting the "hidden bit", since it may or may not be explicit), the
129 exponent, and the sign. */
130#define FLT_TOTAL_BIT ((FLT_MANT_BIT - 1) + FLT_EXP_BIT + 1)
131#define DBL_TOTAL_BIT ((DBL_MANT_BIT - 1) + DBL_EXP_BIT + 1)
132#define LDBL_TOTAL_BIT ((LDBL_MANT_BIT - 1) + LDBL_EXP_BIT + 1)
133
134/* Number of bytes used for a floating-point number.
135 This can be smaller than the 'sizeof'. For example, on i386 systems,
136 'long double' most often have LDBL_MANT_BIT = 64, LDBL_EXP_BIT = 16, hence
137 LDBL_TOTAL_BIT = 80 bits, i.e. 10 bytes of consecutive memory, but
138 sizeof (long double) = 12 or = 16. */
139#define SIZEOF_FLT ((FLT_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT)
140#define SIZEOF_DBL ((DBL_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT)
141#define SIZEOF_LDBL ((LDBL_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT)
142
143/* Verify that SIZEOF_FLT <= sizeof (float) etc. */
144typedef int verify_sizeof_flt[2 * (SIZEOF_FLT <= sizeof (float)) - 1];
145typedef int verify_sizeof_dbl[2 * (SIZEOF_DBL <= sizeof (double)) - 1];
146typedef int verify_sizeof_ldbl[2 * (SIZEOF_LDBL <= sizeof (long double)) - 1];
147
148#endif /* _FLOATPLUS_H */
diff --git a/src/daemon/https/lgl/gc-gnulib.c b/src/daemon/https/lgl/gc-gnulib.c
new file mode 100644
index 00000000..05b12781
--- /dev/null
+++ b/src/daemon/https/lgl/gc-gnulib.c
@@ -0,0 +1,791 @@
1/* gc-gnulib.c --- Common gnulib internal crypto interface functions
2 * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Simon Josefsson
3 *
4 * This file is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; either version 2.1, or (at your
7 * option) any later version.
8 *
9 * This file is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this file; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 */
20
21/* Note: This file is only built if GC uses internal functions. */
22
23#include <config.h>
24
25/* Get prototype. */
26#include "gc.h"
27
28#include <stdlib.h>
29#include <string.h>
30
31/* For randomize. */
32#ifdef GNULIB_GC_RANDOM
33# include <unistd.h>
34# include <sys/types.h>
35# include <sys/stat.h>
36# include <fcntl.h>
37# include <errno.h>
38#endif
39
40/* Hashes. */
41#ifdef GNULIB_GC_MD5
42# include "md5.h"
43#endif
44#ifdef GNULIB_GC_SHA1
45# include "sha1.h"
46#endif
47#if defined(GNULIB_GC_HMAC_MD5) || defined(GNULIB_GC_HMAC_SHA1)
48# include "hmac.h"
49#endif
50
51/* Ciphers. */
52#ifdef GNULIB_GC_ARCFOUR
53# include "arcfour.h"
54#endif
55#ifdef GNULIB_GC_ARCTWO
56# include "arctwo.h"
57#endif
58#ifdef GNULIB_GC_DES
59# include "des.h"
60#endif
61#ifdef GNULIB_GC_RIJNDAEL
62# include "rijndael-api-fst.h"
63#endif
64
65/* The results of open() in this file are not used with fchdir,
66 therefore save some unnecessary work in fchdir.c. */
67#undef open
68#undef close
69
70Gc_rc gc_init(void)
71{
72 return GC_OK;
73}
74
75void gc_done(void)
76{
77 return;
78}
79
80#ifdef GNULIB_GC_RANDOM
81
82/* Randomness. */
83
84static Gc_rc
85randomize (int level, char *data, size_t datalen)
86 {
87 int fd;
88 const char *device;
89 size_t len = 0;
90 int rc;
91
92 switch (level)
93 {
94 case 0:
95 device = NAME_OF_NONCE_DEVICE;
96 break;
97
98 case 1:
99 device = NAME_OF_PSEUDO_RANDOM_DEVICE;
100 break;
101
102 default:
103 device = NAME_OF_RANDOM_DEVICE;
104 break;
105 }
106
107 if (strcmp (device, "no") == 0)
108 return GC_RANDOM_ERROR;
109
110 fd = open (device, O_RDONLY);
111 if (fd < 0)
112 return GC_RANDOM_ERROR;
113
114 do
115 {
116 ssize_t tmp;
117
118 tmp = read (fd, data, datalen);
119
120 if (tmp < 0)
121 {
122 int save_errno = errno;
123 close (fd);
124 errno = save_errno;
125 return GC_RANDOM_ERROR;
126 }
127
128 len += tmp;
129 }
130 while (len < datalen);
131
132 rc = close (fd);
133 if (rc < 0)
134 return GC_RANDOM_ERROR;
135
136 return GC_OK;
137 }
138
139Gc_rc
140gc_nonce (char *data, size_t datalen)
141 {
142 return randomize (0, data, datalen);
143 }
144
145Gc_rc
146gc_pseudo_random (char *data, size_t datalen)
147 {
148 return randomize (1, data, datalen);
149 }
150
151Gc_rc
152gc_random (char *data, size_t datalen)
153 {
154 return randomize (2, data, datalen);
155 }
156
157#endif
158
159/* Memory allocation. */
160void gc_set_allocators(gc_malloc_t func_malloc,
161 gc_malloc_t secure_malloc,
162 gc_secure_check_t secure_check,
163 gc_realloc_t func_realloc,
164 gc_free_t func_free)
165{
166 return;
167}
168
169/* Ciphers. */
170
171typedef struct _gc_cipher_ctx
172 {
173 Gc_cipher alg;
174 Gc_cipher_mode mode;
175#ifdef GNULIB_GC_ARCTWO
176 arctwo_context arctwoContext;
177 char arctwoIV[ARCTWO_BLOCK_SIZE];
178#endif
179#ifdef GNULIB_GC_ARCFOUR
180 arcfour_context arcfourContext;
181#endif
182#ifdef GNULIB_GC_DES
183 gl_des_ctx desContext;
184#endif
185#ifdef GNULIB_GC_RIJNDAEL
186 rijndaelKeyInstance aesEncKey;
187 rijndaelKeyInstance aesDecKey;
188 rijndaelCipherInstance aesContext;
189#endif
190 } _gc_cipher_ctx;
191
192Gc_rc gc_cipher_open(Gc_cipher alg,
193 Gc_cipher_mode mode,
194 gc_cipher_handle * outhandle)
195{
196 _gc_cipher_ctx *ctx;
197 Gc_rc rc = GC_OK;
198
199 ctx = calloc(sizeof (*ctx), 1);
200 if (!ctx)
201 return GC_MALLOC_ERROR;
202
203 ctx->alg = alg;
204 ctx->mode = mode;
205
206 switch (alg)
207 {
208#ifdef GNULIB_GC_ARCTWO
209 case GC_ARCTWO40:
210 switch (mode)
211 {
212 case GC_ECB:
213 case GC_CBC:
214 break;
215
216 default:
217 rc = GC_INVALID_CIPHER;
218 }
219 break;
220#endif
221
222#ifdef GNULIB_GC_ARCFOUR
223 case GC_ARCFOUR128:
224 case GC_ARCFOUR40:
225 switch (mode)
226 {
227 case GC_STREAM:
228 break;
229
230 default:
231 rc = GC_INVALID_CIPHER;
232 }
233 break;
234#endif
235
236#ifdef GNULIB_GC_DES
237 case GC_DES:
238 switch (mode)
239 {
240 case GC_ECB:
241 break;
242
243 default:
244 rc = GC_INVALID_CIPHER;
245 }
246 break;
247#endif
248
249#ifdef GNULIB_GC_RIJNDAEL
250 case GC_AES128:
251 case GC_AES192:
252 case GC_AES256:
253 switch (mode)
254 {
255 case GC_ECB:
256 case GC_CBC:
257 break;
258
259 default:
260 rc = GC_INVALID_CIPHER;
261 }
262 break;
263#endif
264
265 default:
266 rc = GC_INVALID_CIPHER;
267 }
268
269 if (rc == GC_OK)
270 *outhandle = ctx;
271 else
272 free(ctx);
273
274 return rc;
275}
276
277Gc_rc gc_cipher_setkey(gc_cipher_handle handle,
278 size_t keylen,
279 const char *key)
280{
281 _gc_cipher_ctx *ctx = handle;
282
283 switch (ctx->alg)
284 {
285#ifdef GNULIB_GC_ARCTWO
286 case GC_ARCTWO40:
287 arctwo_setkey (&ctx->arctwoContext, keylen, key);
288 break;
289#endif
290
291#ifdef GNULIB_GC_ARCFOUR
292 case GC_ARCFOUR128:
293 case GC_ARCFOUR40:
294 arcfour_setkey (&ctx->arcfourContext, key, keylen);
295 break;
296#endif
297
298#ifdef GNULIB_GC_DES
299 case GC_DES:
300 if (keylen != 8)
301 return GC_INVALID_CIPHER;
302 gl_des_setkey (&ctx->desContext, key);
303 break;
304#endif
305
306#ifdef GNULIB_GC_RIJNDAEL
307 case GC_AES128:
308 case GC_AES192:
309 case GC_AES256:
310 {
311 rijndael_rc rc;
312 size_t i;
313 char keyMaterial[RIJNDAEL_MAX_KEY_SIZE + 1];
314
315 for (i = 0; i < keylen; i++)
316 sprintf (&keyMaterial[2 * i], "%02x", key[i] & 0xFF);
317
318 rc = rijndaelMakeKey (&ctx->aesEncKey, RIJNDAEL_DIR_ENCRYPT,
319 keylen * 8, keyMaterial);
320 if (rc < 0)
321 return GC_INVALID_CIPHER;
322
323 rc = rijndaelMakeKey (&ctx->aesDecKey, RIJNDAEL_DIR_DECRYPT,
324 keylen * 8, keyMaterial);
325 if (rc < 0)
326 return GC_INVALID_CIPHER;
327
328 rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_ECB, NULL);
329 if (rc < 0)
330 return GC_INVALID_CIPHER;
331 }
332 break;
333#endif
334
335 default:
336 return GC_INVALID_CIPHER;
337 }
338
339 return GC_OK;
340}
341
342Gc_rc gc_cipher_setiv(gc_cipher_handle handle,
343 size_t ivlen,
344 const char *iv)
345{
346 _gc_cipher_ctx *ctx = handle;
347
348 switch (ctx->alg)
349 {
350#ifdef GNULIB_GC_ARCTWO
351 case GC_ARCTWO40:
352 if (ivlen != ARCTWO_BLOCK_SIZE)
353 return GC_INVALID_CIPHER;
354 memcpy (ctx->arctwoIV, iv, ivlen);
355 break;
356#endif
357
358#ifdef GNULIB_GC_RIJNDAEL
359 case GC_AES128:
360 case GC_AES192:
361 case GC_AES256:
362 switch (ctx->mode)
363 {
364 case GC_ECB:
365 /* Doesn't use IV. */
366 break;
367
368 case GC_CBC:
369 {
370 rijndael_rc rc;
371 size_t i;
372 char ivMaterial[2 * RIJNDAEL_MAX_IV_SIZE + 1];
373
374 for (i = 0; i < ivlen; i++)
375 sprintf (&ivMaterial[2 * i], "%02x", iv[i] & 0xFF);
376
377 rc = rijndaelCipherInit (&ctx->aesContext, RIJNDAEL_MODE_CBC,
378 ivMaterial);
379 if (rc < 0)
380 return GC_INVALID_CIPHER;
381 }
382 break;
383
384 default:
385 return GC_INVALID_CIPHER;
386 }
387 break;
388#endif
389
390 default:
391 return GC_INVALID_CIPHER;
392 }
393
394 return GC_OK;
395}
396
397Gc_rc gc_cipher_encrypt_inline(gc_cipher_handle handle,
398 size_t len,
399 char *data)
400{
401 _gc_cipher_ctx *ctx = handle;
402
403 switch (ctx->alg)
404 {
405#ifdef GNULIB_GC_ARCTWO
406 case GC_ARCTWO40:
407 switch (ctx->mode)
408 {
409 case GC_ECB:
410 arctwo_encrypt (&ctx->arctwoContext, data, data, len);
411 break;
412
413 case GC_CBC:
414 for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE,
415 data += ARCTWO_BLOCK_SIZE)
416 {
417 size_t i;
418 for (i = 0; i < ARCTWO_BLOCK_SIZE; i++)
419 data[i] ^= ctx->arctwoIV[i];
420 arctwo_encrypt (&ctx->arctwoContext, data, data,
421 ARCTWO_BLOCK_SIZE);
422 memcpy (ctx->arctwoIV, data, ARCTWO_BLOCK_SIZE);
423 }
424 break;
425
426 default:
427 return GC_INVALID_CIPHER;
428 }
429 break;
430#endif
431
432#ifdef GNULIB_GC_ARCFOUR
433 case GC_ARCFOUR128:
434 case GC_ARCFOUR40:
435 arcfour_stream (&ctx->arcfourContext, data, data, len);
436 break;
437#endif
438
439#ifdef GNULIB_GC_DES
440 case GC_DES:
441 for (; len >= 8; len -= 8, data += 8)
442 gl_des_ecb_encrypt (&ctx->desContext, data, data);
443 break;
444#endif
445
446#ifdef GNULIB_GC_RIJNDAEL
447 case GC_AES128:
448 case GC_AES192:
449 case GC_AES256:
450 {
451 int nblocks;
452
453 nblocks = rijndaelBlockEncrypt (&ctx->aesContext, &ctx->aesEncKey,
454 data, 8 * len, data);
455 if (nblocks < 0)
456 return GC_INVALID_CIPHER;
457 }
458 break;
459#endif
460
461 default:
462 return GC_INVALID_CIPHER;
463 }
464
465 return GC_OK;
466}
467
468Gc_rc gc_cipher_decrypt_inline(gc_cipher_handle handle,
469 size_t len,
470 char *data)
471{
472 _gc_cipher_ctx *ctx = handle;
473
474 switch (ctx->alg)
475 {
476#ifdef GNULIB_GC_ARCTWO
477 case GC_ARCTWO40:
478 switch (ctx->mode)
479 {
480 case GC_ECB:
481 arctwo_decrypt (&ctx->arctwoContext, data, data, len);
482 break;
483
484 case GC_CBC:
485 for (; len >= ARCTWO_BLOCK_SIZE; len -= ARCTWO_BLOCK_SIZE,
486 data += ARCTWO_BLOCK_SIZE)
487 {
488 char tmpIV[ARCTWO_BLOCK_SIZE];
489 size_t i;
490 memcpy (tmpIV, data, ARCTWO_BLOCK_SIZE);
491 arctwo_decrypt (&ctx->arctwoContext, data, data,
492 ARCTWO_BLOCK_SIZE);
493 for (i = 0; i < ARCTWO_BLOCK_SIZE; i++)
494 data[i] ^= ctx->arctwoIV[i];
495 memcpy (ctx->arctwoIV, tmpIV, ARCTWO_BLOCK_SIZE);
496 }
497 break;
498
499 default:
500 return GC_INVALID_CIPHER;
501 }
502 break;
503#endif
504
505#ifdef GNULIB_GC_ARCFOUR
506 case GC_ARCFOUR128:
507 case GC_ARCFOUR40:
508 arcfour_stream (&ctx->arcfourContext, data, data, len);
509 break;
510#endif
511
512#ifdef GNULIB_GC_DES
513 case GC_DES:
514 for (; len >= 8; len -= 8, data += 8)
515 gl_des_ecb_decrypt (&ctx->desContext, data, data);
516 break;
517#endif
518
519#ifdef GNULIB_GC_RIJNDAEL
520 case GC_AES128:
521 case GC_AES192:
522 case GC_AES256:
523 {
524 int nblocks;
525
526 nblocks = rijndaelBlockDecrypt (&ctx->aesContext, &ctx->aesDecKey,
527 data, 8 * len, data);
528 if (nblocks < 0)
529 return GC_INVALID_CIPHER;
530 }
531 break;
532#endif
533
534 default:
535 return GC_INVALID_CIPHER;
536 }
537
538 return GC_OK;
539}
540
541Gc_rc gc_cipher_close(gc_cipher_handle handle)
542{
543 _gc_cipher_ctx *ctx = handle;
544
545 if (ctx)
546 free(ctx);
547
548 return GC_OK;
549}
550
551/* Hashes. */
552
553#define MAX_DIGEST_SIZE 20
554
555typedef struct _gc_hash_ctx
556 {
557 Gc_hash alg;
558 Gc_hash_mode mode;
559 char hash[MAX_DIGEST_SIZE];
560#ifdef GNULIB_GC_MD5
561 struct md5_ctx md5Context;
562#endif
563#ifdef GNULIB_GC_SHA1
564 struct sha1_ctx sha1Context;
565#endif
566 } _gc_hash_ctx;
567
568Gc_rc gc_hash_open(Gc_hash hash,
569 Gc_hash_mode mode,
570 gc_hash_handle * outhandle)
571{
572 _gc_hash_ctx *ctx;
573 Gc_rc rc = GC_OK;
574
575 ctx = calloc(sizeof (*ctx), 1);
576 if (!ctx)
577 return GC_MALLOC_ERROR;
578
579 ctx->alg = hash;
580 ctx->mode = mode;
581
582 switch (hash)
583 {
584#ifdef GNULIB_GC_MD5
585 case GC_MD5:
586 md5_init_ctx (&ctx->md5Context);
587 break;
588#endif
589
590#ifdef GNULIB_GC_SHA1
591 case GC_SHA1:
592 sha1_init_ctx (&ctx->sha1Context);
593 break;
594#endif
595
596 default:
597 rc = GC_INVALID_HASH;
598 break;
599 }
600
601 switch (mode)
602 {
603 case 0:
604 break;
605
606 default:
607 rc = GC_INVALID_HASH;
608 break;
609 }
610
611 if (rc == GC_OK)
612 *outhandle = ctx;
613 else
614 free(ctx);
615
616 return rc;
617}
618
619Gc_rc gc_hash_clone(gc_hash_handle handle,
620 gc_hash_handle * outhandle)
621{
622 _gc_hash_ctx *in = handle;
623 _gc_hash_ctx *out;
624
625 *outhandle = out = calloc(sizeof (*out), 1);
626 if (!out)
627 return GC_MALLOC_ERROR;
628
629 memcpy(out, in, sizeof (*out));
630
631 return GC_OK;
632}
633
634size_t gc_hash_digest_length(Gc_hash hash)
635{
636 size_t len;
637
638 switch (hash)
639 {
640 case GC_MD2:
641 len = GC_MD2_DIGEST_SIZE;
642 break;
643
644 case GC_MD4:
645 len = GC_MD4_DIGEST_SIZE;
646 break;
647
648 case GC_MD5:
649 len = GC_MD5_DIGEST_SIZE;
650 break;
651
652 case GC_RMD160:
653 len = GC_RMD160_DIGEST_SIZE;
654 break;
655
656 case GC_SHA1:
657 len = GC_SHA1_DIGEST_SIZE;
658 break;
659
660 default:
661 return 0;
662 }
663
664 return len;
665}
666
667void gc_hash_write(gc_hash_handle handle,
668 size_t len,
669 const char *data)
670{
671 _gc_hash_ctx *ctx = handle;
672
673 switch (ctx->alg)
674 {
675#ifdef GNULIB_GC_MD5
676 case GC_MD5:
677 md5_process_bytes (data, len, &ctx->md5Context);
678 break;
679#endif
680
681#ifdef GNULIB_GC_SHA1
682 case GC_SHA1:
683 sha1_process_bytes (data, len, &ctx->sha1Context);
684 break;
685#endif
686
687 default:
688 break;
689 }
690}
691
692const char * gc_hash_read(gc_hash_handle handle)
693{
694 _gc_hash_ctx *ctx = handle;
695 const char *ret= NULL;
696
697 switch (ctx->alg)
698 {
699#ifdef GNULIB_GC_MD5
700 case GC_MD5:
701 md5_finish_ctx (&ctx->md5Context, ctx->hash);
702 ret = ctx->hash;
703 break;
704#endif
705
706#ifdef GNULIB_GC_SHA1
707 case GC_SHA1:
708 sha1_finish_ctx (&ctx->sha1Context, ctx->hash);
709 ret = ctx->hash;
710 break;
711#endif
712
713 default:
714 return NULL;
715 }
716
717 return ret;
718}
719
720void gc_hash_close(gc_hash_handle handle)
721{
722 _gc_hash_ctx *ctx = handle;
723
724 free(ctx);
725}
726
727Gc_rc gc_hash_buffer(Gc_hash hash,
728 const void *in,
729 size_t inlen,
730 char *resbuf)
731{
732 switch (hash)
733 {
734#ifdef GNULIB_GC_MD5
735 case GC_MD5:
736 md5_buffer (in, inlen, resbuf);
737 break;
738#endif
739
740#ifdef GNULIB_GC_SHA1
741 case GC_SHA1:
742 sha1_buffer (in, inlen, resbuf);
743 break;
744#endif
745
746 default:
747 return GC_INVALID_HASH;
748 }
749
750 return GC_OK;
751}
752
753#ifdef GNULIB_GC_MD5
754Gc_rc
755gc_md5 (const void *in, size_t inlen, void *resbuf)
756 {
757 md5_buffer (in, inlen, resbuf);
758 return GC_OK;
759 }
760#endif
761
762#ifdef GNULIB_GC_SHA1
763Gc_rc
764gc_sha1 (const void *in, size_t inlen, void *resbuf)
765 {
766 sha1_buffer (in, inlen, resbuf);
767 return GC_OK;
768 }
769#endif
770
771#ifdef GNULIB_GC_HMAC_MD5
772Gc_rc
773gc_hmac_md5 (const void *key, size_t keylen,
774 const void *in, size_t inlen, char *resbuf)
775 {
776 hmac_md5 (key, keylen, in, inlen, resbuf);
777 return GC_OK;
778 }
779#endif
780
781#ifdef GNULIB_GC_HMAC_SHA1
782Gc_rc gc_hmac_sha1(const void *key,
783 size_t keylen,
784 const void *in,
785 size_t inlen,
786 char *resbuf)
787{
788 hmac_sha1(key, keylen, in, inlen, resbuf);
789 return GC_OK;
790}
791#endif
diff --git a/src/daemon/https/lgl/gc-libgcrypt.c b/src/daemon/https/lgl/gc-libgcrypt.c
new file mode 100644
index 00000000..da9c5e16
--- /dev/null
+++ b/src/daemon/https/lgl/gc-libgcrypt.c
@@ -0,0 +1,627 @@
1/* gc-libgcrypt.c --- Crypto wrappers around Libgcrypt for GC.
2 * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Simon Josefsson
3 *
4 * This file is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; either version 2.1, or (at your
7 * option) any later version.
8 *
9 * This file is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this file; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 */
20
21/* Note: This file is only built if GC uses Libgcrypt. */
22
23#include "config.h"
24
25/* Get prototype. */
26#include "gc.h"
27
28#include <stdlib.h>
29#include <string.h>
30
31/* Get libgcrypt API. */
32#include <gcrypt.h>
33
34#include <assert.h>
35
36/* Initialization. */
37
38Gc_rc gc_init(void)
39{
40 gcry_error_t err;
41
42 err = gcry_control(GCRYCTL_ANY_INITIALIZATION_P);
43 if (err == GPG_ERR_NO_ERROR)
44 {
45 if (gcry_check_version(GCRYPT_VERSION) == NULL)
46 return GC_INIT_ERROR;
47
48 err = gcry_control(GCRYCTL_INITIALIZATION_FINISHED, NULL, 0);
49 if (err != GPG_ERR_NO_ERROR)
50 return GC_INIT_ERROR;
51 }
52 return GC_OK;
53}
54
55void gc_done(void)
56{
57 return;
58}
59
60#ifdef GNULIB_GC_RANDOM
61
62/* Randomness. */
63
64Gc_rc
65gc_nonce (char *data, size_t datalen)
66 {
67 gcry_create_nonce ((unsigned char *) data, datalen);
68 return GC_OK;
69 }
70
71Gc_rc
72gc_pseudo_random (char *data, size_t datalen)
73 {
74 gcry_randomize ((unsigned char *) data, datalen, GCRY_STRONG_RANDOM);
75 return GC_OK;
76 }
77
78Gc_rc
79gc_random (char *data, size_t datalen)
80 {
81 gcry_randomize ((unsigned char *) data, datalen, GCRY_VERY_STRONG_RANDOM);
82 return GC_OK;
83 }
84
85#endif
86
87/* Memory allocation. */
88
89void gc_set_allocators(gc_malloc_t func_malloc,
90 gc_malloc_t secure_malloc,
91 gc_secure_check_t secure_check,
92 gc_realloc_t func_realloc,
93 gc_free_t func_free)
94{
95 gcry_set_allocation_handler(func_malloc, secure_malloc, secure_check,
96 func_realloc, func_free);
97}
98
99/* Ciphers. */
100
101Gc_rc gc_cipher_open(Gc_cipher alg,
102 Gc_cipher_mode mode,
103 gc_cipher_handle * outhandle)
104{
105 int gcryalg, gcrymode;
106 gcry_error_t err;
107
108 switch (alg)
109 {
110 case GC_AES128:
111 gcryalg = GCRY_CIPHER_RIJNDAEL;
112 break;
113
114 case GC_AES192:
115 gcryalg = GCRY_CIPHER_RIJNDAEL;
116 break;
117
118 case GC_AES256:
119 gcryalg = GCRY_CIPHER_RIJNDAEL256;
120 break;
121
122 case GC_3DES:
123 gcryalg = GCRY_CIPHER_3DES;
124 break;
125
126 case GC_DES:
127 gcryalg = GCRY_CIPHER_DES;
128 break;
129
130 case GC_ARCFOUR128:
131 case GC_ARCFOUR40:
132 gcryalg = GCRY_CIPHER_ARCFOUR;
133 break;
134
135 case GC_ARCTWO40:
136 gcryalg = GCRY_CIPHER_RFC2268_40;
137 break;
138
139#ifdef ENABLE_CAMELLIA
140 case GC_CAMELLIA128:
141 gcryalg = GCRY_CIPHER_CAMELLIA128;
142 break;
143
144 case GC_CAMELLIA256:
145 gcryalg = GCRY_CIPHER_CAMELLIA256;
146 break;
147#endif
148
149 default:
150 return GC_INVALID_CIPHER;
151 }
152
153 switch (mode)
154 {
155 case GC_ECB:
156 gcrymode = GCRY_CIPHER_MODE_ECB;
157 break;
158
159 case GC_CBC:
160 gcrymode = GCRY_CIPHER_MODE_CBC;
161 break;
162
163 case GC_STREAM:
164 gcrymode = GCRY_CIPHER_MODE_STREAM;
165 break;
166
167 default:
168 return GC_INVALID_CIPHER;
169 }
170
171 err = gcry_cipher_open((gcry_cipher_hd_t *) outhandle, gcryalg, gcrymode, 0);
172 if (gcry_err_code(err))
173 return GC_INVALID_CIPHER;
174
175 return GC_OK;
176}
177
178Gc_rc gc_cipher_setkey(gc_cipher_handle handle,
179 size_t keylen,
180 const char *key)
181{
182 gcry_error_t err;
183
184 err = gcry_cipher_setkey ((gcry_cipher_hd_t) handle, key, keylen);
185 if (gcry_err_code(err))
186 return GC_INVALID_CIPHER;
187
188 return GC_OK;
189}
190
191Gc_rc gc_cipher_setiv(gc_cipher_handle handle,
192 size_t ivlen,
193 const char *iv)
194{
195 gcry_error_t err;
196
197 err = gcry_cipher_setiv ((gcry_cipher_hd_t) handle, iv, ivlen);
198 if (gcry_err_code(err))
199 return GC_INVALID_CIPHER;
200
201 return GC_OK;
202}
203
204Gc_rc gc_cipher_encrypt_inline(gc_cipher_handle handle,
205 size_t len,
206 char *data)
207{
208 if (gcry_cipher_encrypt((gcry_cipher_hd_t) handle, data, len, NULL, len) != 0)
209 return GC_INVALID_CIPHER;
210
211 return GC_OK;
212}
213
214Gc_rc gc_cipher_decrypt_inline(gc_cipher_handle handle,
215 size_t len,
216 char *data)
217{
218 if (gcry_cipher_decrypt((gcry_cipher_hd_t) handle, data, len, NULL, len) != 0)
219 return GC_INVALID_CIPHER;
220
221 return GC_OK;
222}
223
224Gc_rc gc_cipher_close(gc_cipher_handle handle)
225{
226 gcry_cipher_close(handle);
227
228 return GC_OK;
229}
230
231/* Hashes. */
232
233typedef struct _gc_hash_ctx
234 {
235 Gc_hash alg;
236 Gc_hash_mode mode;
237 gcry_md_hd_t gch;
238 } _gc_hash_ctx;
239
240Gc_rc gc_hash_open(Gc_hash hash,
241 Gc_hash_mode mode,
242 gc_hash_handle * outhandle)
243{
244 _gc_hash_ctx *ctx;
245 int gcryalg = 0, gcrymode = 0;
246 gcry_error_t err;
247 Gc_rc rc = GC_OK;
248
249 ctx = calloc(sizeof (*ctx), 1);
250 if (!ctx)
251 return GC_MALLOC_ERROR;
252
253 ctx->alg = hash;
254 ctx->mode = mode;
255
256 switch (hash)
257 {
258 case GC_MD2:
259 gcryalg = GCRY_MD_NONE;
260 break;
261
262 case GC_MD4:
263 gcryalg = GCRY_MD_MD4;
264 break;
265
266 case GC_MD5:
267 gcryalg = GCRY_MD_MD5;
268 break;
269
270 case GC_SHA1:
271 gcryalg = GCRY_MD_SHA1;
272 break;
273
274 case GC_SHA256:
275 gcryalg = GCRY_MD_SHA256;
276 break;
277
278 case GC_SHA384:
279 gcryalg = GCRY_MD_SHA384;
280 break;
281
282 case GC_SHA512:
283 gcryalg = GCRY_MD_SHA512;
284 break;
285
286 case GC_RMD160:
287 gcryalg = GCRY_MD_RMD160;
288 break;
289
290 default:
291 rc = GC_INVALID_HASH;
292 }
293
294 switch (mode)
295 {
296 case 0:
297 gcrymode = 0;
298 break;
299
300 case GC_HMAC:
301 gcrymode = GCRY_MD_FLAG_HMAC;
302 break;
303
304 default:
305 rc = GC_INVALID_HASH;
306 }
307
308 if (rc == GC_OK && gcryalg != GCRY_MD_NONE)
309 {
310 err = gcry_md_open(&ctx->gch, gcryalg, gcrymode);
311 if (gcry_err_code(err))
312 rc = GC_INVALID_HASH;
313 }
314
315 if (rc == GC_OK)
316 *outhandle = ctx;
317 else
318 free(ctx);
319
320 return rc;
321}
322
323Gc_rc gc_hash_clone(gc_hash_handle handle,
324 gc_hash_handle * outhandle)
325{
326 _gc_hash_ctx *in = handle;
327 _gc_hash_ctx *out;
328 int err;
329
330 *outhandle = out = calloc(sizeof (*out), 1);
331 if (!out)
332 return GC_MALLOC_ERROR;
333
334 memcpy(out, in, sizeof (*out));
335
336 err = gcry_md_copy(&out->gch, in->gch);
337 if (err)
338 {
339 free(out);
340 return GC_INVALID_HASH;
341 }
342
343 return GC_OK;
344}
345
346size_t gc_hash_digest_length(Gc_hash hash)
347{
348 size_t len;
349
350 switch (hash)
351 {
352 case GC_MD2:
353 len = GC_MD2_DIGEST_SIZE;
354 break;
355
356 case GC_MD4:
357 len = GC_MD4_DIGEST_SIZE;
358 break;
359
360 case GC_MD5:
361 len = GC_MD5_DIGEST_SIZE;
362 break;
363
364 case GC_RMD160:
365 len = GC_RMD160_DIGEST_SIZE;
366 break;
367
368 case GC_SHA1:
369 len = GC_SHA1_DIGEST_SIZE;
370 break;
371
372 case GC_SHA256:
373 len = GC_SHA256_DIGEST_SIZE;
374 break;
375
376 case GC_SHA384:
377 len = GC_SHA384_DIGEST_SIZE;
378 break;
379
380 case GC_SHA512:
381 len = GC_SHA512_DIGEST_SIZE;
382 break;
383
384 default:
385 return 0;
386 }
387
388 return len;
389}
390
391void gc_hash_hmac_setkey(gc_hash_handle handle,
392 size_t len,
393 const char *key)
394{
395 _gc_hash_ctx *ctx = handle;
396 gcry_md_setkey(ctx->gch, key, len);
397}
398
399void gc_hash_write(gc_hash_handle handle,
400 size_t len,
401 const char *data)
402{
403 _gc_hash_ctx *ctx = handle;
404 gcry_md_write(ctx->gch, data, len);
405}
406
407const char * gc_hash_read(gc_hash_handle handle)
408{
409 _gc_hash_ctx *ctx = handle;
410 const char *digest;
411 {
412 gcry_md_final (ctx->gch);
413 digest = gcry_md_read(ctx->gch, 0);
414 }
415
416 return digest;
417}
418
419void gc_hash_close(gc_hash_handle handle)
420{
421 _gc_hash_ctx *ctx = handle;
422
423 gcry_md_close(ctx->gch);
424
425 free(ctx);
426}
427
428Gc_rc gc_hash_buffer(Gc_hash hash,
429 const void *in,
430 size_t inlen,
431 char *resbuf)
432{
433 int gcryalg;
434
435 switch (hash)
436 {
437#ifdef GNULIB_GC_MD5
438 case GC_MD5:
439 gcryalg = GCRY_MD_MD5;
440 break;
441#endif
442
443#ifdef GNULIB_GC_SHA1
444 case GC_SHA1:
445 gcryalg = GCRY_MD_SHA1;
446 break;
447#endif
448
449#ifdef GNULIB_GC_SHA256
450 case GC_SHA256:
451 gcryalg = GCRY_MD_SHA256;
452 break;
453#endif
454
455#ifdef GNULIB_GC_SHA384
456 case GC_SHA384:
457 gcryalg = GCRY_MD_SHA384;
458 break;
459#endif
460
461#ifdef GNULIB_GC_SHA512
462 case GC_SHA512:
463 gcryalg = GCRY_MD_SHA512;
464 break;
465#endif
466
467#ifdef GNULIB_GC_RMD160
468 case GC_RMD160:
469 gcryalg = GCRY_MD_RMD160;
470 break;
471#endif
472
473 default:
474 return GC_INVALID_HASH;
475 }
476
477 gcry_md_hash_buffer(gcryalg, resbuf, in, inlen);
478
479 return GC_OK;
480}
481
482/* One-call interface. */
483#ifdef GNULIB_GC_MD5
484Gc_rc
485gc_md5 (const void *in, size_t inlen, void *resbuf)
486 {
487 size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_MD5);
488 gcry_md_hd_t hd;
489 gpg_error_t err;
490 unsigned char *p;
491
492 assert (outlen == GC_MD5_DIGEST_SIZE);
493
494 err = gcry_md_open (&hd, GCRY_MD_MD5, 0);
495 if (err != GPG_ERR_NO_ERROR)
496 return GC_INVALID_HASH;
497
498 gcry_md_write (hd, in, inlen);
499
500 p = gcry_md_read (hd, GCRY_MD_MD5);
501 if (p == NULL)
502 {
503 gcry_md_close (hd);
504 return GC_INVALID_HASH;
505 }
506
507 memcpy (resbuf, p, outlen);
508
509 gcry_md_close (hd);
510
511 return GC_OK;
512 }
513#endif
514
515#ifdef GNULIB_GC_SHA1
516Gc_rc
517gc_sha1 (const void *in, size_t inlen, void *resbuf)
518 {
519 size_t outlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
520 gcry_md_hd_t hd;
521 gpg_error_t err;
522 unsigned char *p;
523
524 assert (outlen == GC_SHA1_DIGEST_SIZE);
525
526 err = gcry_md_open (&hd, GCRY_MD_SHA1, 0);
527 if (err != GPG_ERR_NO_ERROR)
528 return GC_INVALID_HASH;
529
530 gcry_md_write (hd, in, inlen);
531
532 p = gcry_md_read (hd, GCRY_MD_SHA1);
533 if (p == NULL)
534 {
535 gcry_md_close (hd);
536 return GC_INVALID_HASH;
537 }
538
539 memcpy (resbuf, p, outlen);
540
541 gcry_md_close (hd);
542
543 return GC_OK;
544 }
545#endif
546
547#ifdef GNULIB_GC_HMAC_MD5
548Gc_rc
549gc_hmac_md5 (const void *key, size_t keylen,
550 const void *in, size_t inlen, char *resbuf)
551 {
552 size_t hlen = gcry_md_get_algo_dlen (GCRY_MD_MD5);
553 gcry_md_hd_t mdh;
554 unsigned char *hash;
555 gpg_error_t err;
556
557 assert (hlen == 16);
558
559 err = gcry_md_open (&mdh, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC);
560 if (err != GPG_ERR_NO_ERROR)
561 return GC_INVALID_HASH;
562
563 err = gcry_md_setkey (mdh, key, keylen);
564 if (err != GPG_ERR_NO_ERROR)
565 {
566 gcry_md_close (mdh);
567 return GC_INVALID_HASH;
568 }
569
570 gcry_md_write (mdh, in, inlen);
571
572 hash = gcry_md_read (mdh, GCRY_MD_MD5);
573 if (hash == NULL)
574 {
575 gcry_md_close (mdh);
576 return GC_INVALID_HASH;
577 }
578
579 memcpy (resbuf, hash, hlen);
580
581 gcry_md_close (mdh);
582
583 return GC_OK;
584 }
585#endif
586
587#ifdef GNULIB_GC_HMAC_SHA1
588Gc_rc gc_hmac_sha1(const void *key,
589 size_t keylen,
590 const void *in,
591 size_t inlen,
592 char *resbuf)
593{
594 size_t hlen = gcry_md_get_algo_dlen(GCRY_MD_SHA1);
595 gcry_md_hd_t mdh;
596 unsigned char *hash;
597 gpg_error_t err;
598
599 assert (hlen == GC_SHA1_DIGEST_SIZE);
600
601 err = gcry_md_open(&mdh, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC);
602 if (err != GPG_ERR_NO_ERROR)
603 return GC_INVALID_HASH;
604
605 err = gcry_md_setkey(mdh, key, keylen);
606 if (err != GPG_ERR_NO_ERROR)
607 {
608 gcry_md_close(mdh);
609 return GC_INVALID_HASH;
610 }
611
612 gcry_md_write(mdh, in, inlen);
613
614 hash = gcry_md_read(mdh, GCRY_MD_SHA1);
615 if (hash == NULL)
616 {
617 gcry_md_close(mdh);
618 return GC_INVALID_HASH;
619 }
620
621 memcpy(resbuf, hash, hlen);
622
623 gcry_md_close(mdh);
624
625 return GC_OK;
626}
627#endif
diff --git a/src/daemon/https/lgl/gc-pbkdf2-sha1.c b/src/daemon/https/lgl/gc-pbkdf2-sha1.c
new file mode 100644
index 00000000..f5daf7b7
--- /dev/null
+++ b/src/daemon/https/lgl/gc-pbkdf2-sha1.c
@@ -0,0 +1,185 @@
1/* gc-pbkdf2-sha1.c --- Password-Based Key Derivation Function a'la PKCS#5
2 Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18/* Written by Simon Josefsson. The comments in this file are taken
19 from RFC 2898. */
20
21#include <config.h>
22
23#include "gc.h"
24
25#include <stdlib.h>
26#include <string.h>
27
28/*
29 * 5.2 PBKDF2
30 *
31 * PBKDF2 applies a pseudorandom function (see Appendix B.1 for an
32 * example) to derive keys. The length of the derived key is essentially
33 * unbounded. (However, the maximum effective search space for the
34 * derived key may be limited by the structure of the underlying
35 * pseudorandom function. See Appendix B.1 for further discussion.)
36 * PBKDF2 is recommended for new applications.
37 *
38 * PBKDF2 (P, S, c, dkLen)
39 *
40 * Options: PRF underlying pseudorandom function (hLen
41 * denotes the length in octets of the
42 * pseudorandom function output)
43 *
44 * Input: P password, an octet string (ASCII or UTF-8)
45 * S salt, an octet string
46 * c iteration count, a positive integer
47 * dkLen intended length in octets of the derived
48 * key, a positive integer, at most
49 * (2^32 - 1) * hLen
50 *
51 * Output: DK derived key, a dkLen-octet string
52 */
53
54Gc_rc
55gc_pbkdf2_sha1 (const char *P, size_t Plen,
56 const char *S, size_t Slen,
57 unsigned int c, char *DK, size_t dkLen)
58{
59 unsigned int hLen = 20;
60 char U[20];
61 char T[20];
62 unsigned int u;
63 unsigned int l;
64 unsigned int r;
65 unsigned int i;
66 unsigned int k;
67 int rc;
68 char *tmp;
69 size_t tmplen = Slen + 4;
70
71 if (c == 0)
72 return GC_PKCS5_INVALID_ITERATION_COUNT;
73
74 if (dkLen == 0)
75 return GC_PKCS5_INVALID_DERIVED_KEY_LENGTH;
76
77 /*
78 *
79 * Steps:
80 *
81 * 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and
82 * stop.
83 */
84
85 if (dkLen > 4294967295U)
86 return GC_PKCS5_DERIVED_KEY_TOO_LONG;
87
88 /*
89 * 2. Let l be the number of hLen-octet blocks in the derived key,
90 * rounding up, and let r be the number of octets in the last
91 * block:
92 *
93 * l = CEIL (dkLen / hLen) ,
94 * r = dkLen - (l - 1) * hLen .
95 *
96 * Here, CEIL (x) is the "ceiling" function, i.e. the smallest
97 * integer greater than, or equal to, x.
98 */
99
100 l = ((dkLen - 1) / hLen) + 1;
101 r = dkLen - (l - 1) * hLen;
102
103 /*
104 * 3. For each block of the derived key apply the function F defined
105 * below to the password P, the salt S, the iteration count c, and
106 * the block index to compute the block:
107 *
108 * T_1 = F (P, S, c, 1) ,
109 * T_2 = F (P, S, c, 2) ,
110 * ...
111 * T_l = F (P, S, c, l) ,
112 *
113 * where the function F is defined as the exclusive-or sum of the
114 * first c iterates of the underlying pseudorandom function PRF
115 * applied to the password P and the concatenation of the salt S
116 * and the block index i:
117 *
118 * F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c
119 *
120 * where
121 *
122 * U_1 = PRF (P, S || INT (i)) ,
123 * U_2 = PRF (P, U_1) ,
124 * ...
125 * U_c = PRF (P, U_{c-1}) .
126 *
127 * Here, INT (i) is a four-octet encoding of the integer i, most
128 * significant octet first.
129 *
130 * 4. Concatenate the blocks and extract the first dkLen octets to
131 * produce a derived key DK:
132 *
133 * DK = T_1 || T_2 || ... || T_l<0..r-1>
134 *
135 * 5. Output the derived key DK.
136 *
137 * Note. The construction of the function F follows a "belt-and-
138 * suspenders" approach. The iterates U_i are computed recursively to
139 * remove a degree of parallelism from an opponent; they are exclusive-
140 * ored together to reduce concerns about the recursion degenerating
141 * into a small set of values.
142 *
143 */
144
145 tmp = malloc (tmplen);
146 if (tmp == NULL)
147 return GC_MALLOC_ERROR;
148
149 memcpy (tmp, S, Slen);
150
151 for (i = 1; i <= l; i++)
152 {
153 memset (T, 0, hLen);
154
155 for (u = 1; u <= c; u++)
156 {
157 if (u == 1)
158 {
159 tmp[Slen + 0] = (i & 0xff000000) >> 24;
160 tmp[Slen + 1] = (i & 0x00ff0000) >> 16;
161 tmp[Slen + 2] = (i & 0x0000ff00) >> 8;
162 tmp[Slen + 3] = (i & 0x000000ff) >> 0;
163
164 rc = gc_hmac_sha1 (P, Plen, tmp, tmplen, U);
165 }
166 else
167 rc = gc_hmac_sha1 (P, Plen, U, hLen, U);
168
169 if (rc != GC_OK)
170 {
171 free (tmp);
172 return rc;
173 }
174
175 for (k = 0; k < hLen; k++)
176 T[k] ^= U[k];
177 }
178
179 memcpy (DK + (i - 1) * hLen, T, i == l ? r : hLen);
180 }
181
182 free (tmp);
183
184 return GC_OK;
185}
diff --git a/src/daemon/https/lgl/gc.h b/src/daemon/https/lgl/gc.h
new file mode 100644
index 00000000..688e624a
--- /dev/null
+++ b/src/daemon/https/lgl/gc.h
@@ -0,0 +1,347 @@
1/* gc.h --- Header file for implementation agnostic crypto wrapper API.
2 * Copyright (C) 2002, 2003, 2004, 2005, 2007 Simon Josefsson
3 *
4 * This file is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; either version 2.1, or (at your
7 * option) any later version.
8 *
9 * This file is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this file; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 */
20
21#ifndef GC_H
22#define GC_H
23
24/* Get size_t. */
25# include <stddef.h>
26
27enum Gc_rc
28 {
29 GC_OK = 0,
30 GC_MALLOC_ERROR,
31 GC_INIT_ERROR,
32 GC_RANDOM_ERROR,
33 GC_INVALID_CIPHER,
34 GC_INVALID_HASH,
35 GC_PKCS5_INVALID_ITERATION_COUNT,
36 GC_PKCS5_INVALID_DERIVED_KEY_LENGTH,
37 GC_PKCS5_DERIVED_KEY_TOO_LONG
38 };
39typedef enum Gc_rc Gc_rc;
40
41/* Hash types. */
42enum Gc_hash
43 {
44 GC_MD4,
45 GC_MD5,
46 GC_SHA1,
47 GC_MD2,
48 GC_RMD160,
49 GC_SHA256,
50 GC_SHA384,
51 GC_SHA512
52 };
53typedef enum Gc_hash Gc_hash;
54
55enum Gc_hash_mode
56 {
57 GC_HMAC = 1
58 };
59typedef enum Gc_hash_mode Gc_hash_mode;
60
61typedef void *gc_hash_handle;
62
63#define GC_MD2_DIGEST_SIZE 16
64#define GC_MD4_DIGEST_SIZE 16
65#define GC_MD5_DIGEST_SIZE 16
66#define GC_RMD160_DIGEST_SIZE 20
67#define GC_SHA1_DIGEST_SIZE 20
68#define GC_SHA256_DIGEST_SIZE 32
69#define GC_SHA384_DIGEST_SIZE 48
70#define GC_SHA512_DIGEST_SIZE 64
71
72/* Cipher types. */
73enum Gc_cipher
74 {
75 GC_AES128,
76 GC_AES192,
77 GC_AES256,
78 GC_3DES,
79 GC_DES,
80 GC_ARCFOUR128,
81 GC_ARCFOUR40,
82 GC_ARCTWO40,
83 GC_CAMELLIA128,
84 GC_CAMELLIA256
85 };
86typedef enum Gc_cipher Gc_cipher;
87
88enum Gc_cipher_mode
89 {
90 GC_ECB,
91 GC_CBC,
92 GC_STREAM
93 };
94typedef enum Gc_cipher_mode Gc_cipher_mode;
95
96typedef void * gc_cipher_handle;
97
98/* Call before respectively after any other functions. */
99Gc_rc gc_init(void);
100void gc_done(void);
101
102/* Memory allocation (avoid). */
103typedef void *(*gc_malloc_t)(size_t n);
104typedef int (*gc_secure_check_t)(const void *);
105typedef void *(*gc_realloc_t)(void *p,
106 size_t n);
107typedef void (*gc_free_t)(void *);
108void gc_set_allocators(gc_malloc_t func_malloc,
109 gc_malloc_t secure_malloc,
110 gc_secure_check_t secure_check,
111 gc_realloc_t func_realloc,
112 gc_free_t func_free);
113
114/* Randomness. */
115Gc_rc gc_nonce(char *data,
116 size_t datalen);
117Gc_rc gc_pseudo_random(char *data,
118 size_t datalen);
119Gc_rc gc_random(char *data,
120 size_t datalen);
121
122/* Ciphers. */
123Gc_rc gc_cipher_open(Gc_cipher cipher,
124 Gc_cipher_mode mode,
125 gc_cipher_handle *outhandle);
126Gc_rc gc_cipher_setkey(gc_cipher_handle handle,
127 size_t keylen,
128 const char *key);
129Gc_rc gc_cipher_setiv(gc_cipher_handle handle,
130 size_t ivlen,
131 const char *iv);
132Gc_rc gc_cipher_encrypt_inline(gc_cipher_handle handle,
133 size_t len,
134 char *data);
135Gc_rc gc_cipher_decrypt_inline(gc_cipher_handle handle,
136 size_t len,
137 char *data);
138Gc_rc gc_cipher_close(gc_cipher_handle handle);
139
140/* Hashes. */
141
142Gc_rc gc_hash_open(Gc_hash hash,
143 Gc_hash_mode mode,
144 gc_hash_handle *outhandle);
145Gc_rc gc_hash_clone(gc_hash_handle handle,
146 gc_hash_handle *outhandle);
147size_t gc_hash_digest_length(Gc_hash hash);
148void gc_hash_hmac_setkey(gc_hash_handle handle,
149 size_t len,
150 const char *key);
151void gc_hash_write(gc_hash_handle handle,
152 size_t len,
153 const char *data);
154const char *gc_hash_read(gc_hash_handle handle);
155void gc_hash_close(gc_hash_handle handle);
156
157/* Compute a hash value over buffer IN of INLEN bytes size using the
158 algorithm HASH, placing the result in the pre-allocated buffer OUT.
159 The required size of OUT depends on HASH, and is generally
160 GC_<HASH>_DIGEST_SIZE. For example, for GC_MD5 the output buffer
161 must be 16 bytes. The return value is 0 (GC_OK) on success, or
162 another Gc_rc error code. */
163Gc_rc gc_hash_buffer(Gc_hash hash,
164 const void *in,
165 size_t inlen,
166 char *out);
167
168/* One-call interface. */
169Gc_rc gc_md2(const void *in,
170 size_t inlen,
171 void *resbuf);
172Gc_rc gc_md4(const void *in,
173 size_t inlen,
174 void *resbuf);
175Gc_rc gc_md5(const void *in,
176 size_t inlen,
177 void *resbuf);
178Gc_rc gc_sha1(const void *in,
179 size_t inlen,
180 void *resbuf);
181Gc_rc gc_hmac_md5(const void *key,
182 size_t keylen,
183 const void *in,
184 size_t inlen,
185 char *resbuf);
186Gc_rc gc_hmac_sha1(const void *key,
187 size_t keylen,
188 const void *in,
189 size_t inlen,
190 char *resbuf);
191
192/* Derive cryptographic keys from a password P of length PLEN, with
193 salt S of length SLEN, placing the result in pre-allocated buffer
194 DK of length DKLEN. An iteration count is specified in C, where a
195 larger value means this function take more time (typical iteration
196 counts are 1000-20000). This function "stretches" the key to be
197 exactly dkLen bytes long. GC_OK is returned on success, otherwise
198 an Gc_rc error code is returned. */
199Gc_rc gc_pbkdf2_sha1(const char *P,
200 size_t Plen,
201 const char *S,
202 size_t Slen,
203 unsigned int c,
204 char *DK,
205 size_t dkLen);
206
207/*
208 TODO:
209
210 From: Simon Josefsson <jas@extundo.com>
211 Subject: Re: generic crypto
212 Newsgroups: gmane.comp.lib.gnulib.bugs
213 Cc: bug-gnulib@gnu.org
214 Date: Fri, 07 Oct 2005 12:50:57 +0200
215 Mail-Copies-To: nobody
216
217 Paul Eggert <eggert@CS.UCLA.EDU> writes:
218
219 > Simon Josefsson <jas@extundo.com> writes:
220 >
221 >> * Perhaps the /dev/?random reading should be separated into a separate
222 >> module? It might be useful outside of the gc layer too.
223 >
224 > Absolutely. I've been meaning to do that for months (for a "shuffle"
225 > program I want to add to coreutils), but hadn't gotten around to it.
226 > It would have to be generalized a bit. I'd like to have the file
227 > descriptor cached, for example.
228
229 I'll write a separate module for that part.
230
231 I think we should even add a good PRNG that is re-seeded from
232 /dev/?random frequently. GnuTLS can need a lot of random data on a
233 big server, more than /dev/random can supply. And /dev/urandom might
234 not be strong enough. Further, the security of /dev/?random can also
235 be questionable.
236
237 >> I'm also not sure about the names of those functions, they suggest
238 >> a more higher-level API than what is really offered (i.e., the
239 >> names "nonce" and "pseudo_random" and "random" imply certain
240 >> cryptographic properties).
241 >
242 > Could you expand a bit more on that? What is the relationship between
243 > nonce/pseudorandom/random and the /dev/ values you are using?
244
245 There is none, that is the problem.
246
247 Applications generally need different kind of "random" numbers.
248 Sometimes they just need some random data and doesn't care whether it
249 is possible for an attacker to compute the string (aka a "nonce").
250 Sometimes they need data that is very difficult to compute (i.e.,
251 computing it require inverting SHA1 or similar). Sometimes they need
252 data that is not possible to compute, i.e., it wants real entropy
253 collected over time on the system. Collecting the last kind of random
254 data is very expensive, so it must not be used too often. The second
255 kind of random data ("pseudo random") is typically generated by
256 seeding a good PRNG with a couple of hundred bytes of real entropy
257 from the "real random" data pool. The "nonce" is usually computed
258 using the PRNG as well, because PRNGs are usually fast.
259
260 Pseudo-random data is typically used for session keys. Strong random
261 data is often used to generate long-term keys (e.g., private RSA
262 keys).
263
264 Of course, there are many subtleties. There are several different
265 kind of nonce:s. Sometimes a nonce is just an ever-increasing
266 integer, starting from 0. Sometimes it is assumed to be unlikely to
267 be the same as previous nonces, but without a requirement that the
268 nonce is possible to guess. MD5(system clock) would thus suffice, if
269 it isn't called too often. You can guess what the next value will be,
270 but it will always be different.
271
272 The problem is that /dev/?random doesn't offer any kind of semantic
273 guarantees. But applications need an API that make that promise.
274
275 I think we should do this in several steps:
276
277 1) Write a module that can read from /dev/?random.
278
279 2) Add a module for a known-good PRNG suitable for random number
280 generation, that can be continuously re-seeded.
281
282 3) Add a high-level module that provide various different randomness
283 functions. One for nonces, perhaps even different kind of nonces,
284 one for pseudo random data, and one for strong random data. It is
285 not clear whether we can hope to achieve the last one in a portable
286 way.
287
288 Further, it would be useful to allow users to provide their own
289 entropy source as a file, used to seed the PRNG or initialize the
290 strong randomness pool. This is used on embedded platforms that
291 doesn't have enough interrupts to hope to generate good random data.
292
293 > For example, why not use OpenBSD's /dev/arandom?
294
295 I don't trust ARC4. For example, recent cryptographic efforts
296 indicate that you must throw away the first 512 bytes generated from
297 the PRNG for it to be secure. I don't know whether OpenBSD do this.
298 Further, I recall some eprint paper on RC4 security that didn't
299 inspire confidence.
300
301 While I trust the random devices in OpenBSD more than
302 Solaris/AIX/HPUX/etc, I think that since we need something better on
303 Solaris/AIX/HPUX we'd might as well use it on OpenBSD or even Linux
304 too.
305
306 > Here is one thought. The user could specify a desired quality level
307 > range, and the implementation then would supply random data that is at
308 > least as good as the lower bound of the range. I.e., ihe
309 > implementation refuses to produce any random data if it can't generate
310 > data that is at least as good as the lower end of the range. The
311 > upper bound of the range is advice from the user not to be any more
312 > expensive than that, but the implementation can ignore the advice if
313 > it doesn't have anything cheaper.
314
315 I'm not sure this is a good idea. Users can't really be expected to
316 understand this. Further, applications need many different kind of
317 random data. Selecting the randomness level for each by the user will
318 be too complicated.
319
320 I think it is better if the application decide, from its cryptographic
321 requirement, what entropy quality it require, and call the proper API.
322 Meeting the implied semantic properties should be the job for gnulib.
323
324 >> Perhaps gc_dev_random and gc_dev_urandom?
325 >
326 > To some extent. I'd rather insulate the user from the details of
327 > where the random numbers come from. On the other hand we need to
328 > provide a way for applications to specify a file that contains
329 > random bits, so that people can override the defaults.
330
331 Agreed.
332
333 This may require some thinking before it is finalized. Is it ok to
334 install the GC module as-is meanwhile? Then I can continue to add the
335 stuff that GnuTLS need, and then come back to re-working the
336 randomness module. That way, we have two different projects that use
337 the code. GnuTLS includes the same randomness code that was in GNU
338 SASL and that is in the current gc module. I feel much more
339 comfortable working in small steps at a time, rather then working on
340 this for a long time in gnulib and only later integrate the stuff in
341 GnuTLS.
342
343 Thanks,
344 Simon
345 */
346
347#endif /* GC_H */
diff --git a/src/daemon/https/lgl/gettext.h b/src/daemon/https/lgl/gettext.h
new file mode 100644
index 00000000..bd214d5c
--- /dev/null
+++ b/src/daemon/https/lgl/gettext.h
@@ -0,0 +1,270 @@
1/* Convenience header for conditional use of GNU <libintl.h>.
2 Copyright (C) 1995-1998, 2000-2002, 2004-2006 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License along
15 with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18#ifndef _LIBGETTEXT_H
19#define _LIBGETTEXT_H 1
20
21/* NLS can be disabled through the configure --disable-nls option. */
22#if ENABLE_NLS
23
24/* Get declarations of GNU message catalog functions. */
25# include <libintl.h>
26
27/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by
28 the gettext() and ngettext() macros. This is an alternative to calling
29 textdomain(), and is useful for libraries. */
30# ifdef DEFAULT_TEXT_DOMAIN
31# undef gettext
32# define gettext(Msgid) \
33 dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
34# undef ngettext
35# define ngettext(Msgid1, Msgid2, N) \
36 dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
37# endif
38
39#else
40
41/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
42 chokes if dcgettext is defined as a macro. So include it now, to make
43 later inclusions of <locale.h> a NOP. We don't include <libintl.h>
44 as well because people using "gettext.h" will not include <libintl.h>,
45 and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
46 is OK. */
47#if defined(__sun)
48# include <locale.h>
49#endif
50
51/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
52 <libintl.h>, which chokes if dcgettext is defined as a macro. So include
53 it now, to make later inclusions of <libintl.h> a NOP. */
54#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
55# include <cstdlib>
56# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
57# include <libintl.h>
58# endif
59#endif
60
61/* Disabled NLS.
62 The casts to 'const char *' serve the purpose of producing warnings
63 for invalid uses of the value returned from these functions.
64 On pre-ANSI systems without 'const', the config.h file is supposed to
65 contain "#define const". */
66# define gettext(Msgid) ((const char *) (Msgid))
67# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
68# define dcgettext(Domainname, Msgid, Category) \
69 ((void) (Category), dgettext (Domainname, Msgid))
70# define ngettext(Msgid1, Msgid2, N) \
71 ((N) == 1 \
72 ? ((void) (Msgid2), (const char *) (Msgid1)) \
73 : ((void) (Msgid1), (const char *) (Msgid2)))
74# define dngettext(Domainname, Msgid1, Msgid2, N) \
75 ((void) (Domainname), ngettext (Msgid1, Msgid2, N))
76# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
77 ((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N))
78# define textdomain(Domainname) ((const char *) (Domainname))
79# define bindtextdomain(Domainname, Dirname) \
80 ((void) (Domainname), (const char *) (Dirname))
81# define bind_textdomain_codeset(Domainname, Codeset) \
82 ((void) (Domainname), (const char *) (Codeset))
83
84#endif
85
86/* A pseudo function call that serves as a marker for the automated
87 extraction of messages, but does not call gettext(). The run-time
88 translation is done at a different place in the code.
89 The argument, String, should be a literal string. Concatenated strings
90 and other string expressions won't work.
91 The macro's expansion is not parenthesized, so that it is suitable as
92 initializer for static 'char[]' or 'const char[]' variables. */
93#define gettext_noop(String) String
94
95/* The separator between msgctxt and msgid in a .mo file. */
96#define GETTEXT_CONTEXT_GLUE "\004"
97
98/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
99 MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be
100 short and rarely need to change.
101 The letter 'p' stands for 'particular' or 'special'. */
102#ifdef DEFAULT_TEXT_DOMAIN
103# define pgettext(Msgctxt, Msgid) \
104 pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
105#else
106# define pgettext(Msgctxt, Msgid) \
107 pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
108#endif
109#define dpgettext(Domainname, Msgctxt, Msgid) \
110 pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
111#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
112 pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
113#ifdef DEFAULT_TEXT_DOMAIN
114# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
115 npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
116#else
117# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
118 npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
119#endif
120#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
121 npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
122#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
123 npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
124
125#ifdef __GNUC__
126__inline
127#else
128#ifdef __cplusplus
129inline
130#endif
131#endif
132static const char *
133pgettext_aux (const char *domain,
134 const char *msg_ctxt_id, const char *msgid,
135 int category)
136{
137 const char *translation = dcgettext (domain, msg_ctxt_id, category);
138 if (translation == msg_ctxt_id)
139 return msgid;
140 else
141 return translation;
142}
143
144#ifdef __GNUC__
145__inline
146#else
147#ifdef __cplusplus
148inline
149#endif
150#endif
151static const char *
152npgettext_aux (const char *domain,
153 const char *msg_ctxt_id, const char *msgid,
154 const char *msgid_plural, unsigned long int n,
155 int category)
156{
157 const char *translation =
158 dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
159 if (translation == msg_ctxt_id || translation == msgid_plural)
160 return (n == 1 ? msgid : msgid_plural);
161 else
162 return translation;
163}
164
165/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID
166 can be arbitrary expressions. But for string literals these macros are
167 less efficient than those above. */
168
169#include <string.h>
170
171#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
172 (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
173 /* || __STDC_VERSION__ >= 199901L */ )
174
175#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
176#include <stdlib.h>
177#endif
178
179#define pgettext_expr(Msgctxt, Msgid) \
180 dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
181#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
182 dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
183
184#ifdef __GNUC__
185__inline
186#else
187#ifdef __cplusplus
188inline
189#endif
190#endif
191static const char *
192dcpgettext_expr (const char *domain,
193 const char *msgctxt, const char *msgid,
194 int category)
195{
196 size_t msgctxt_len = strlen (msgctxt) + 1;
197 size_t msgid_len = strlen (msgid) + 1;
198 const char *translation;
199#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
200 char msg_ctxt_id[msgctxt_len + msgid_len];
201#else
202 char buf[1024];
203 char *msg_ctxt_id =
204 (msgctxt_len + msgid_len <= sizeof (buf)
205 ? buf
206 : (char *) malloc (msgctxt_len + msgid_len));
207 if (msg_ctxt_id != NULL)
208#endif
209 {
210 memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
211 msg_ctxt_id[msgctxt_len - 1] = '\004';
212 memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
213 translation = dcgettext (domain, msg_ctxt_id, category);
214#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
215 if (msg_ctxt_id != buf)
216 free (msg_ctxt_id);
217#endif
218 if (translation != msg_ctxt_id)
219 return translation;
220 }
221 return msgid;
222}
223
224#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
225 dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
226#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
227 dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
228
229#ifdef __GNUC__
230__inline
231#else
232#ifdef __cplusplus
233inline
234#endif
235#endif
236static const char *
237dcnpgettext_expr (const char *domain,
238 const char *msgctxt, const char *msgid,
239 const char *msgid_plural, unsigned long int n,
240 int category)
241{
242 size_t msgctxt_len = strlen (msgctxt) + 1;
243 size_t msgid_len = strlen (msgid) + 1;
244 const char *translation;
245#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
246 char msg_ctxt_id[msgctxt_len + msgid_len];
247#else
248 char buf[1024];
249 char *msg_ctxt_id =
250 (msgctxt_len + msgid_len <= sizeof (buf)
251 ? buf
252 : (char *) malloc (msgctxt_len + msgid_len));
253 if (msg_ctxt_id != NULL)
254#endif
255 {
256 memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
257 msg_ctxt_id[msgctxt_len - 1] = '\004';
258 memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
259 translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
260#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
261 if (msg_ctxt_id != buf)
262 free (msg_ctxt_id);
263#endif
264 if (!(translation == msg_ctxt_id || translation == msgid_plural))
265 return translation;
266 }
267 return (n == 1 ? msgid : msgid_plural);
268}
269
270#endif /* _LIBGETTEXT_H */
diff --git a/src/daemon/https/lgl/hmac-md5.c b/src/daemon/https/lgl/hmac-md5.c
new file mode 100644
index 00000000..53cf2b10
--- /dev/null
+++ b/src/daemon/https/lgl/hmac-md5.c
@@ -0,0 +1,81 @@
1/* hmac-md5.c -- hashed message authentication codes
2 Copyright (C) 2005, 2006 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18/* Written by Simon Josefsson. */
19
20#include <config.h>
21
22#include "hmac.h"
23
24#include "memxor.h"
25#include "md5.h"
26
27#include <string.h>
28
29#define IPAD 0x36
30#define OPAD 0x5c
31
32int
33hmac_md5 (const void *key, size_t keylen,
34 const void *in, size_t inlen, void *resbuf)
35{
36 struct md5_ctx inner;
37 struct md5_ctx outer;
38 char optkeybuf[16];
39 char block[64];
40 char innerhash[16];
41
42 /* Reduce the key's size, so that it becomes <= 64 bytes large. */
43
44 if (keylen > 64)
45 {
46 struct md5_ctx keyhash;
47
48 md5_init_ctx (&keyhash);
49 md5_process_bytes (key, keylen, &keyhash);
50 md5_finish_ctx (&keyhash, optkeybuf);
51
52 key = optkeybuf;
53 keylen = 16;
54 }
55
56 /* Compute INNERHASH from KEY and IN. */
57
58 md5_init_ctx (&inner);
59
60 memset (block, IPAD, sizeof (block));
61 memxor (block, key, keylen);
62
63 md5_process_block (block, 64, &inner);
64 md5_process_bytes (in, inlen, &inner);
65
66 md5_finish_ctx (&inner, innerhash);
67
68 /* Compute result from KEY and INNERHASH. */
69
70 md5_init_ctx (&outer);
71
72 memset (block, OPAD, sizeof (block));
73 memxor (block, key, keylen);
74
75 md5_process_block (block, 64, &outer);
76 md5_process_bytes (innerhash, 16, &outer);
77
78 md5_finish_ctx (&outer, resbuf);
79
80 return 0;
81}
diff --git a/src/daemon/https/lgl/hmac-sha1.c b/src/daemon/https/lgl/hmac-sha1.c
new file mode 100644
index 00000000..a9cf18cd
--- /dev/null
+++ b/src/daemon/https/lgl/hmac-sha1.c
@@ -0,0 +1,81 @@
1/* hmac-sha1.c -- hashed message authentication codes
2 Copyright (C) 2005, 2006 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18/* Written by Simon Josefsson. */
19
20#include <config.h>
21
22#include "hmac.h"
23
24#include "memxor.h"
25#include "sha1.h"
26
27#include <string.h>
28
29#define IPAD 0x36
30#define OPAD 0x5c
31
32int
33hmac_sha1 (const void *key, size_t keylen,
34 const void *in, size_t inlen, void *resbuf)
35{
36 struct sha1_ctx inner;
37 struct sha1_ctx outer;
38 char optkeybuf[20];
39 char block[64];
40 char innerhash[20];
41
42 /* Reduce the key's size, so that it becomes <= 64 bytes large. */
43
44 if (keylen > 64)
45 {
46 struct sha1_ctx keyhash;
47
48 sha1_init_ctx (&keyhash);
49 sha1_process_bytes (key, keylen, &keyhash);
50 sha1_finish_ctx (&keyhash, optkeybuf);
51
52 key = optkeybuf;
53 keylen = 20;
54 }
55
56 /* Compute INNERHASH from KEY and IN. */
57
58 sha1_init_ctx (&inner);
59
60 memset (block, IPAD, sizeof (block));
61 memxor (block, key, keylen);
62
63 sha1_process_block (block, 64, &inner);
64 sha1_process_bytes (in, inlen, &inner);
65
66 sha1_finish_ctx (&inner, innerhash);
67
68 /* Compute result from KEY and INNERHASH. */
69
70 sha1_init_ctx (&outer);
71
72 memset (block, OPAD, sizeof (block));
73 memxor (block, key, keylen);
74
75 sha1_process_block (block, 64, &outer);
76 sha1_process_bytes (innerhash, 20, &outer);
77
78 sha1_finish_ctx (&outer, resbuf);
79
80 return 0;
81}
diff --git a/src/daemon/https/lgl/hmac.h b/src/daemon/https/lgl/hmac.h
new file mode 100644
index 00000000..5965b603
--- /dev/null
+++ b/src/daemon/https/lgl/hmac.h
@@ -0,0 +1,41 @@
1/* hmac.h -- hashed message authentication codes
2 Copyright (C) 2005 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18/* Written by Simon Josefsson. */
19
20#ifndef HMAC_H
21# define HMAC_H 1
22
23#include <stddef.h>
24
25/* Compute Hashed Message Authentication Code with MD5, as described
26 in RFC 2104, over BUFFER data of BUFLEN bytes using the KEY of
27 KEYLEN bytes, writing the output to pre-allocated 16 byte minimum
28 RESBUF buffer. Return 0 on success. */
29int
30hmac_md5 (const void *key, size_t keylen,
31 const void *buffer, size_t buflen, void *resbuf);
32
33/* Compute Hashed Message Authentication Code with SHA-1, over BUFFER
34 data of BUFLEN bytes using the KEY of KEYLEN bytes, writing the
35 output to pre-allocated 20 byte minimum RESBUF buffer. Return 0 on
36 success. */
37int
38hmac_sha1 (const void *key, size_t keylen,
39 const void *in, size_t inlen, void *resbuf);
40
41#endif /* HMAC_H */
diff --git a/src/daemon/https/lgl/md5.c b/src/daemon/https/lgl/md5.c
new file mode 100644
index 00000000..9b3bfbe8
--- /dev/null
+++ b/src/daemon/https/lgl/md5.c
@@ -0,0 +1,451 @@
1/* Functions to compute MD5 message digest of files or memory blocks.
2 according to the definition of MD5 in RFC 1321 from April 1992.
3 Copyright (C) 1995,1996,1997,1999,2000,2001,2005,2006
4 Free Software Foundation, Inc.
5 This file is part of the GNU C Library.
6
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by the
9 Free Software Foundation; either version 2.1, or (at your option) any
10 later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
20
21/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */
22
23#include <config.h>
24
25#include "md5.h"
26
27#include <stddef.h>
28#include <stdlib.h>
29#include <string.h>
30#include <sys/types.h>
31
32#if USE_UNLOCKED_IO
33# include "unlocked-io.h"
34#endif
35
36#ifdef _LIBC
37# include <endian.h>
38# if __BYTE_ORDER == __BIG_ENDIAN
39# define WORDS_BIGENDIAN 1
40# endif
41/* We need to keep the namespace clean so define the MD5 function
42 protected using leading __ . */
43# define md5_init_ctx __md5_init_ctx
44# define md5_process_block __md5_process_block
45# define md5_process_bytes __md5_process_bytes
46# define md5_finish_ctx __md5_finish_ctx
47# define md5_read_ctx __md5_read_ctx
48# define md5_stream __md5_stream
49# define md5_buffer __md5_buffer
50#endif
51
52#ifdef WORDS_BIGENDIAN
53# define SWAP(n) \
54 (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
55#else
56# define SWAP(n) (n)
57#endif
58
59#define BLOCKSIZE 4096
60#if BLOCKSIZE % 64 != 0
61# error "invalid BLOCKSIZE"
62#endif
63
64/* This array contains the bytes used to pad the buffer to the next
65 64-byte boundary. (RFC 1321, 3.1: Step 1) */
66static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
67
68
69/* Initialize structure containing state of computation.
70 (RFC 1321, 3.3: Step 3) */
71void
72md5_init_ctx (struct md5_ctx *ctx)
73{
74 ctx->A = 0x67452301;
75 ctx->B = 0xefcdab89;
76 ctx->C = 0x98badcfe;
77 ctx->D = 0x10325476;
78
79 ctx->total[0] = ctx->total[1] = 0;
80 ctx->buflen = 0;
81}
82
83/* Put result from CTX in first 16 bytes following RESBUF. The result
84 must be in little endian byte order.
85
86 IMPORTANT: On some systems it is required that RESBUF is correctly
87 aligned for a 32-bit value. */
88void *
89md5_read_ctx (const struct md5_ctx *ctx, void *resbuf)
90{
91 ((uint32_t *) resbuf)[0] = SWAP (ctx->A);
92 ((uint32_t *) resbuf)[1] = SWAP (ctx->B);
93 ((uint32_t *) resbuf)[2] = SWAP (ctx->C);
94 ((uint32_t *) resbuf)[3] = SWAP (ctx->D);
95
96 return resbuf;
97}
98
99/* Process the remaining bytes in the internal buffer and the usual
100 prolog according to the standard and write the result to RESBUF.
101
102 IMPORTANT: On some systems it is required that RESBUF is correctly
103 aligned for a 32-bit value. */
104void *
105md5_finish_ctx (struct md5_ctx *ctx, void *resbuf)
106{
107 /* Take yet unprocessed bytes into account. */
108 uint32_t bytes = ctx->buflen;
109 size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4;
110
111 /* Now count remaining bytes. */
112 ctx->total[0] += bytes;
113 if (ctx->total[0] < bytes)
114 ++ctx->total[1];
115
116 /* Put the 64-bit file length in *bits* at the end of the buffer. */
117 ctx->buffer[size - 2] = SWAP (ctx->total[0] << 3);
118 ctx->buffer[size - 1] = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29));
119
120 memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes);
121
122 /* Process last bytes. */
123 md5_process_block (ctx->buffer, size * 4, ctx);
124
125 return md5_read_ctx (ctx, resbuf);
126}
127
128/* Compute MD5 message digest for bytes read from STREAM. The
129 resulting message digest number will be written into the 16 bytes
130 beginning at RESBLOCK. */
131int
132md5_stream (FILE * stream, void *resblock)
133{
134 struct md5_ctx ctx;
135 char buffer[BLOCKSIZE + 72];
136 size_t sum;
137
138 /* Initialize the computation context. */
139 md5_init_ctx (&ctx);
140
141 /* Iterate over full file contents. */
142 while (1)
143 {
144 /* We read the file in blocks of BLOCKSIZE bytes. One call of the
145 computation function processes the whole buffer so that with the
146 next round of the loop another block can be read. */
147 size_t n;
148 sum = 0;
149
150 /* Read block. Take care for partial reads. */
151 while (1)
152 {
153 n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
154
155 sum += n;
156
157 if (sum == BLOCKSIZE)
158 break;
159
160 if (n == 0)
161 {
162 /* Check for the error flag IFF N == 0, so that we don't
163 exit the loop after a partial read due to e.g., EAGAIN
164 or EWOULDBLOCK. */
165 if (ferror (stream))
166 return 1;
167 goto process_partial_block;
168 }
169
170 /* We've read at least one byte, so ignore errors. But always
171 check for EOF, since feof may be true even though N > 0.
172 Otherwise, we could end up calling fread after EOF. */
173 if (feof (stream))
174 goto process_partial_block;
175 }
176
177 /* Process buffer with BLOCKSIZE bytes. Note that
178 BLOCKSIZE % 64 == 0
179 */
180 md5_process_block (buffer, BLOCKSIZE, &ctx);
181 }
182
183process_partial_block:
184
185 /* Process any remaining bytes. */
186 if (sum > 0)
187 md5_process_bytes (buffer, sum, &ctx);
188
189 /* Construct result in desired memory. */
190 md5_finish_ctx (&ctx, resblock);
191 return 0;
192}
193
194/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
195 result is always in little endian byte order, so that a byte-wise
196 output yields to the wanted ASCII representation of the message
197 digest. */
198void *
199md5_buffer (const char *buffer, size_t len, void *resblock)
200{
201 struct md5_ctx ctx;
202
203 /* Initialize the computation context. */
204 md5_init_ctx (&ctx);
205
206 /* Process whole buffer but last len % 64 bytes. */
207 md5_process_bytes (buffer, len, &ctx);
208
209 /* Put result in desired memory area. */
210 return md5_finish_ctx (&ctx, resblock);
211}
212
213
214void
215md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx)
216{
217 /* When we already have some bits in our internal buffer concatenate
218 both inputs first. */
219 if (ctx->buflen != 0)
220 {
221 size_t left_over = ctx->buflen;
222 size_t add = 128 - left_over > len ? len : 128 - left_over;
223
224 memcpy (&((char *) ctx->buffer)[left_over], buffer, add);
225 ctx->buflen += add;
226
227 if (ctx->buflen > 64)
228 {
229 md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
230
231 ctx->buflen &= 63;
232 /* The regions in the following copy operation cannot overlap. */
233 memcpy (ctx->buffer,
234 &((char *) ctx->buffer)[(left_over + add) & ~63],
235 ctx->buflen);
236 }
237
238 buffer = (const char *) buffer + add;
239 len -= add;
240 }
241
242 /* Process available complete blocks. */
243 if (len >= 64)
244 {
245#if !_STRING_ARCH_unaligned
246# define alignof(type) offsetof (struct { char c; type x; }, x)
247# define UNALIGNED_P(p) (((size_t) p) % alignof (uint32_t) != 0)
248 if (UNALIGNED_P (buffer))
249 while (len > 64)
250 {
251 md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
252 buffer = (const char *) buffer + 64;
253 len -= 64;
254 }
255 else
256#endif
257 {
258 md5_process_block (buffer, len & ~63, ctx);
259 buffer = (const char *) buffer + (len & ~63);
260 len &= 63;
261 }
262 }
263
264 /* Move remaining bytes in internal buffer. */
265 if (len > 0)
266 {
267 size_t left_over = ctx->buflen;
268
269 memcpy (&((char *) ctx->buffer)[left_over], buffer, len);
270 left_over += len;
271 if (left_over >= 64)
272 {
273 md5_process_block (ctx->buffer, 64, ctx);
274 left_over -= 64;
275 memcpy (ctx->buffer, &ctx->buffer[16], left_over);
276 }
277 ctx->buflen = left_over;
278 }
279}
280
281
282/* These are the four functions used in the four steps of the MD5 algorithm
283 and defined in the RFC 1321. The first function is a little bit optimized
284 (as found in Colin Plumbs public domain implementation). */
285/* #define FF(b, c, d) ((b & c) | (~b & d)) */
286#define FF(b, c, d) (d ^ (b & (c ^ d)))
287#define FG(b, c, d) FF (d, b, c)
288#define FH(b, c, d) (b ^ c ^ d)
289#define FI(b, c, d) (c ^ (b | ~d))
290
291/* Process LEN bytes of BUFFER, accumulating context into CTX.
292 It is assumed that LEN % 64 == 0. */
293
294void
295md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx)
296{
297 uint32_t correct_words[16];
298 const uint32_t *words = buffer;
299 size_t nwords = len / sizeof (uint32_t);
300 const uint32_t *endp = words + nwords;
301 uint32_t A = ctx->A;
302 uint32_t B = ctx->B;
303 uint32_t C = ctx->C;
304 uint32_t D = ctx->D;
305
306 /* First increment the byte count. RFC 1321 specifies the possible
307 length of the file up to 2^64 bits. Here we only compute the
308 number of bytes. Do a double word increment. */
309 ctx->total[0] += len;
310 if (ctx->total[0] < len)
311 ++ctx->total[1];
312
313 /* Process all bytes in the buffer with 64 bytes in each round of
314 the loop. */
315 while (words < endp)
316 {
317 uint32_t *cwp = correct_words;
318 uint32_t A_save = A;
319 uint32_t B_save = B;
320 uint32_t C_save = C;
321 uint32_t D_save = D;
322
323 /* First round: using the given function, the context and a constant
324 the next context is computed. Because the algorithms processing
325 unit is a 32-bit word and it is determined to work on words in
326 little endian byte order we perhaps have to change the byte order
327 before the computation. To reduce the work for the next steps
328 we store the swapped words in the array CORRECT_WORDS. */
329
330#define OP(a, b, c, d, s, T) \
331 do \
332 { \
333 a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \
334 ++words; \
335 CYCLIC (a, s); \
336 a += b; \
337 } \
338 while (0)
339
340 /* It is unfortunate that C does not provide an operator for
341 cyclic rotation. Hope the C compiler is smart enough. */
342#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
343
344 /* Before we start, one word to the strange constants.
345 They are defined in RFC 1321 as
346
347 T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
348
349 Here is an equivalent invocation using Perl:
350
351 perl -e 'foreach(1..64){printf "0x%08x\n", int (4294967296 * abs (sin $_))}'
352 */
353
354 /* Round 1. */
355 OP (A, B, C, D, 7, 0xd76aa478);
356 OP (D, A, B, C, 12, 0xe8c7b756);
357 OP (C, D, A, B, 17, 0x242070db);
358 OP (B, C, D, A, 22, 0xc1bdceee);
359 OP (A, B, C, D, 7, 0xf57c0faf);
360 OP (D, A, B, C, 12, 0x4787c62a);
361 OP (C, D, A, B, 17, 0xa8304613);
362 OP (B, C, D, A, 22, 0xfd469501);
363 OP (A, B, C, D, 7, 0x698098d8);
364 OP (D, A, B, C, 12, 0x8b44f7af);
365 OP (C, D, A, B, 17, 0xffff5bb1);
366 OP (B, C, D, A, 22, 0x895cd7be);
367 OP (A, B, C, D, 7, 0x6b901122);
368 OP (D, A, B, C, 12, 0xfd987193);
369 OP (C, D, A, B, 17, 0xa679438e);
370 OP (B, C, D, A, 22, 0x49b40821);
371
372 /* For the second to fourth round we have the possibly swapped words
373 in CORRECT_WORDS. Redefine the macro to take an additional first
374 argument specifying the function to use. */
375#undef OP
376#define OP(f, a, b, c, d, k, s, T) \
377 do \
378 { \
379 a += f (b, c, d) + correct_words[k] + T; \
380 CYCLIC (a, s); \
381 a += b; \
382 } \
383 while (0)
384
385 /* Round 2. */
386 OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
387 OP (FG, D, A, B, C, 6, 9, 0xc040b340);
388 OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
389 OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
390 OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
391 OP (FG, D, A, B, C, 10, 9, 0x02441453);
392 OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
393 OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
394 OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
395 OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
396 OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
397 OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
398 OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
399 OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
400 OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
401 OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
402
403 /* Round 3. */
404 OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
405 OP (FH, D, A, B, C, 8, 11, 0x8771f681);
406 OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
407 OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
408 OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
409 OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
410 OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
411 OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
412 OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
413 OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
414 OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
415 OP (FH, B, C, D, A, 6, 23, 0x04881d05);
416 OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
417 OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
418 OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
419 OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
420
421 /* Round 4. */
422 OP (FI, A, B, C, D, 0, 6, 0xf4292244);
423 OP (FI, D, A, B, C, 7, 10, 0x432aff97);
424 OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
425 OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
426 OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
427 OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
428 OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
429 OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
430 OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
431 OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
432 OP (FI, C, D, A, B, 6, 15, 0xa3014314);
433 OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
434 OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
435 OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
436 OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
437 OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
438
439 /* Add the starting values of the context. */
440 A += A_save;
441 B += B_save;
442 C += C_save;
443 D += D_save;
444 }
445
446 /* Put checksum in context given as argument. */
447 ctx->A = A;
448 ctx->B = B;
449 ctx->C = C;
450 ctx->D = D;
451}
diff --git a/src/daemon/https/lgl/md5.h b/src/daemon/https/lgl/md5.h
new file mode 100644
index 00000000..6018a6f6
--- /dev/null
+++ b/src/daemon/https/lgl/md5.h
@@ -0,0 +1,124 @@
1/* Declaration of functions and data types used for MD5 sum computing
2 library functions.
3 Copyright (C) 1995-1997,1999,2000,2001,2004,2005,2006
4 Free Software Foundation, Inc.
5 This file is part of the GNU C Library.
6
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by the
9 Free Software Foundation; either version 2.1, or (at your option) any
10 later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
20
21#ifndef _MD5_H
22#define _MD5_H 1
23
24#include <stdio.h>
25#include <stdint.h>
26
27#define MD5_DIGEST_SIZE 16
28#define MD5_BLOCK_SIZE 64
29
30#ifndef __GNUC_PREREQ
31# if defined __GNUC__ && defined __GNUC_MINOR__
32# define __GNUC_PREREQ(maj, min) \
33 ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
34# else
35# define __GNUC_PREREQ(maj, min) 0
36# endif
37#endif
38
39#ifndef __THROW
40# if defined __cplusplus && __GNUC_PREREQ (2,8)
41# define __THROW throw ()
42# else
43# define __THROW
44# endif
45#endif
46
47#ifndef _LIBC
48# define __md5_buffer md5_buffer
49# define __md5_finish_ctx md5_finish_ctx
50# define __md5_init_ctx md5_init_ctx
51# define __md5_process_block md5_process_block
52# define __md5_process_bytes md5_process_bytes
53# define __md5_read_ctx md5_read_ctx
54# define __md5_stream md5_stream
55#endif
56
57/* Structure to save state of computation between the single steps. */
58struct md5_ctx
59{
60 uint32_t A;
61 uint32_t B;
62 uint32_t C;
63 uint32_t D;
64
65 uint32_t total[2];
66 uint32_t buflen;
67 uint32_t buffer[32];
68};
69
70/*
71 * The following three functions are build up the low level used in
72 * the functions `md5_stream' and `md5_buffer'.
73 */
74
75/* Initialize structure containing state of computation.
76 (RFC 1321, 3.3: Step 3) */
77extern void __md5_init_ctx (struct md5_ctx *ctx) __THROW;
78
79/* Starting with the result of former calls of this function (or the
80 initialization function update the context for the next LEN bytes
81 starting at BUFFER.
82 It is necessary that LEN is a multiple of 64!!! */
83extern void __md5_process_block (const void *buffer, size_t len,
84 struct md5_ctx *ctx) __THROW;
85
86/* Starting with the result of former calls of this function (or the
87 initialization function update the context for the next LEN bytes
88 starting at BUFFER.
89 It is NOT required that LEN is a multiple of 64. */
90extern void __md5_process_bytes (const void *buffer, size_t len,
91 struct md5_ctx *ctx) __THROW;
92
93/* Process the remaining bytes in the buffer and put result from CTX
94 in first 16 bytes following RESBUF. The result is always in little
95 endian byte order, so that a byte-wise output yields to the wanted
96 ASCII representation of the message digest.
97
98 IMPORTANT: On some systems, RESBUF must be aligned to a 32-bit
99 boundary. */
100extern void *__md5_finish_ctx (struct md5_ctx *ctx, void *resbuf) __THROW;
101
102
103/* Put result from CTX in first 16 bytes following RESBUF. The result is
104 always in little endian byte order, so that a byte-wise output yields
105 to the wanted ASCII representation of the message digest.
106
107 IMPORTANT: On some systems, RESBUF must be aligned to a 32-bit
108 boundary. */
109extern void *__md5_read_ctx (const struct md5_ctx *ctx, void *resbuf) __THROW;
110
111
112/* Compute MD5 message digest for bytes read from STREAM. The
113 resulting message digest number will be written into the 16 bytes
114 beginning at RESBLOCK. */
115extern int __md5_stream (FILE *stream, void *resblock) __THROW;
116
117/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The
118 result is always in little endian byte order, so that a byte-wise
119 output yields to the wanted ASCII representation of the message
120 digest. */
121extern void *__md5_buffer (const char *buffer, size_t len,
122 void *resblock) __THROW;
123
124#endif /* md5.h */
diff --git a/src/daemon/https/lgl/memmem.c b/src/daemon/https/lgl/memmem.c
new file mode 100644
index 00000000..1b66ed56
--- /dev/null
+++ b/src/daemon/https/lgl/memmem.c
@@ -0,0 +1,61 @@
1/* Copyright (C) 1991,92,93,94,96,97,98,2000,2004,2007 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License along
15 with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18#ifndef _LIBC
19# include <config.h>
20#endif
21
22#include <stddef.h>
23#include <string.h>
24
25#ifndef _LIBC
26# define __builtin_expect(expr, val) (expr)
27#endif
28
29#undef memmem
30
31/* Return the first occurrence of NEEDLE in HAYSTACK. */
32void *
33memmem (haystack, haystack_len, needle, needle_len)
34 const void *haystack;
35 size_t haystack_len;
36 const void *needle;
37 size_t needle_len;
38{
39 const char *begin;
40 const char *const last_possible = (const char *) haystack + haystack_len
41 - needle_len;
42
43 if (needle_len == 0)
44 /* The first occurrence of the empty string is deemed to occur at
45 the beginning of the string. */
46 return (void *) haystack;
47
48 /* Sanity check, otherwise the loop might search through the whole
49 memory. */
50 if (__builtin_expect (haystack_len < needle_len, 0))
51 return NULL;
52
53 for (begin = (const char *) haystack; begin <= last_possible; ++begin)
54 if (begin[0] == ((const char *) needle)[0]
55 && !memcmp ((const void *) &begin[1],
56 (const void *) ((const char *) needle + 1),
57 needle_len - 1))
58 return (void *) begin;
59
60 return NULL;
61}
diff --git a/src/daemon/https/lgl/memmove.c b/src/daemon/https/lgl/memmove.c
new file mode 100644
index 00000000..0f040540
--- /dev/null
+++ b/src/daemon/https/lgl/memmove.c
@@ -0,0 +1,26 @@
1/* memmove.c -- copy memory.
2 Copy LENGTH bytes from SOURCE to DEST. Does not null-terminate.
3 In the public domain.
4 By David MacKenzie <djm@gnu.ai.mit.edu>. */
5
6#include <config.h>
7
8#include <stddef.h>
9
10void *
11memmove (void *dest0, void const *source0, size_t length)
12{
13 char *dest = dest0;
14 char const *source = source0;
15 if (source < dest)
16 /* Moving from low mem to hi mem; start at end. */
17 for (source += length, dest += length; length; --length)
18 *--dest = *--source;
19 else if (source != dest)
20 {
21 /* Moving from hi mem to low mem; start at beginning. */
22 for (; length; --length)
23 *dest++ = *source++;
24 }
25 return dest0;
26}
diff --git a/src/daemon/https/lgl/memxor.c b/src/daemon/https/lgl/memxor.c
new file mode 100644
index 00000000..7b0b6ae9
--- /dev/null
+++ b/src/daemon/https/lgl/memxor.c
@@ -0,0 +1,35 @@
1/* memxor.c -- perform binary exclusive OR operation of two memory blocks.
2 Copyright (C) 2005, 2006 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18/* Written by Simon Josefsson. The interface was inspired by memxor
19 in Niels Möller's Nettle. */
20
21#include <config.h>
22
23#include "memxor.h"
24
25void *
26memxor (void *restrict dest, const void *restrict src, size_t n)
27{
28 char const *s = src;
29 char *d = dest;
30
31 for (; n > 0; n--)
32 *d++ ^= *s++;
33
34 return dest;
35}
diff --git a/src/daemon/https/lgl/memxor.h b/src/daemon/https/lgl/memxor.h
new file mode 100644
index 00000000..4f85f2d7
--- /dev/null
+++ b/src/daemon/https/lgl/memxor.h
@@ -0,0 +1,31 @@
1/* memxor.h -- perform binary exclusive OR operation on memory blocks.
2 Copyright (C) 2005 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18/* Written by Simon Josefsson. The interface was inspired by memxor
19 in Niels Möller's Nettle. */
20
21#ifndef MEMXOR_H
22# define MEMXOR_H
23
24#include <stddef.h>
25
26/* Compute binary exclusive OR of memory areas DEST and SRC, putting
27 the result in DEST, of length N bytes. Returns a pointer to
28 DEST. */
29void *memxor (void *restrict dest, const void *restrict src, size_t n);
30
31#endif /* MEMXOR_H */
diff --git a/src/daemon/https/lgl/printf-args.c b/src/daemon/https/lgl/printf-args.c
new file mode 100644
index 00000000..55a5c439
--- /dev/null
+++ b/src/daemon/https/lgl/printf-args.c
@@ -0,0 +1,185 @@
1/* Decomposed printf argument list.
2 Copyright (C) 1999, 2002-2003, 2005-2007 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License along
15 with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18/* This file can be parametrized with the following macros:
19 ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions.
20 PRINTF_FETCHARGS Name of the function to be defined.
21 STATIC Set to 'static' to declare the function static. */
22
23#ifndef PRINTF_FETCHARGS
24# include <config.h>
25#endif
26
27/* Specification. */
28#ifndef PRINTF_FETCHARGS
29# include "printf-args.h"
30#endif
31
32#ifdef STATIC
33STATIC
34#endif
35 int
36PRINTF_FETCHARGS (va_list args, arguments * a)
37{
38 size_t i;
39 argument *ap;
40
41 for (i = 0, ap = &a->arg[0]; i < a->count; i++, ap++)
42 switch (ap->type)
43 {
44 case TYPE_SCHAR:
45 ap->a.a_schar = va_arg (args, /*signed char */ int);
46 break;
47 case TYPE_UCHAR:
48 ap->a.a_uchar = va_arg (args, /*unsigned char */ int);
49 break;
50 case TYPE_SHORT:
51 ap->a.a_short = va_arg (args, /*short */ int);
52 break;
53 case TYPE_USHORT:
54 ap->a.a_ushort = va_arg (args, /*unsigned short */ int);
55 break;
56 case TYPE_INT:
57 ap->a.a_int = va_arg (args, int);
58 break;
59 case TYPE_UINT:
60 ap->a.a_uint = va_arg (args, unsigned int);
61 break;
62 case TYPE_LONGINT:
63 ap->a.a_longint = va_arg (args, long int);
64 break;
65 case TYPE_ULONGINT:
66 ap->a.a_ulongint = va_arg (args, unsigned long int);
67 break;
68#if HAVE_LONG_LONG_INT
69 case TYPE_LONGLONGINT:
70 ap->a.a_longlongint = va_arg (args, long long int);
71 break;
72 case TYPE_ULONGLONGINT:
73 ap->a.a_ulonglongint = va_arg (args, unsigned long long int);
74 break;
75#endif
76 case TYPE_DOUBLE:
77 ap->a.a_double = va_arg (args, double);
78 break;
79 case TYPE_LONGDOUBLE:
80 ap->a.a_longdouble = va_arg (args, long double);
81 break;
82 case TYPE_CHAR:
83 ap->a.a_char = va_arg (args, int);
84 break;
85#if HAVE_WINT_T
86 case TYPE_WIDE_CHAR:
87 /* Although ISO C 99 7.24.1.(2) says that wint_t is "unchanged by
88 default argument promotions", this is not the case in mingw32,
89 where wint_t is 'unsigned short'. */
90 ap->a.a_wide_char =
91 (sizeof (wint_t) < sizeof (int)
92 ? va_arg (args, int) : va_arg (args, wint_t));
93 break;
94#endif
95 case TYPE_STRING:
96 ap->a.a_string = va_arg (args, const char *);
97 /* A null pointer is an invalid argument for "%s", but in practice
98 it occurs quite frequently in printf statements that produce
99 debug output. Use a fallback in this case. */
100 if (ap->a.a_string == NULL)
101 ap->a.a_string = "(NULL)";
102 break;
103#if HAVE_WCHAR_T
104 case TYPE_WIDE_STRING:
105 ap->a.a_wide_string = va_arg (args, const wchar_t *);
106 /* A null pointer is an invalid argument for "%ls", but in practice
107 it occurs quite frequently in printf statements that produce
108 debug output. Use a fallback in this case. */
109 if (ap->a.a_wide_string == NULL)
110 {
111 static const wchar_t wide_null_string[] = {
112 (wchar_t) '(',
113 (wchar_t) 'N', (wchar_t) 'U', (wchar_t) 'L', (wchar_t) 'L',
114 (wchar_t) ')',
115 (wchar_t) 0
116 };
117 ap->a.a_wide_string = wide_null_string;
118 }
119 break;
120#endif
121 case TYPE_POINTER:
122 ap->a.a_pointer = va_arg (args, void *);
123 break;
124 case TYPE_COUNT_SCHAR_POINTER:
125 ap->a.a_count_schar_pointer = va_arg (args, signed char *);
126 break;
127 case TYPE_COUNT_SHORT_POINTER:
128 ap->a.a_count_short_pointer = va_arg (args, short *);
129 break;
130 case TYPE_COUNT_INT_POINTER:
131 ap->a.a_count_int_pointer = va_arg (args, int *);
132 break;
133 case TYPE_COUNT_LONGINT_POINTER:
134 ap->a.a_count_longint_pointer = va_arg (args, long int *);
135 break;
136#if HAVE_LONG_LONG_INT
137 case TYPE_COUNT_LONGLONGINT_POINTER:
138 ap->a.a_count_longlongint_pointer = va_arg (args, long long int *);
139 break;
140#endif
141#if ENABLE_UNISTDIO
142 /* The unistdio extensions. */
143 case TYPE_U8_STRING:
144 ap->a.a_u8_string = va_arg (args, const uint8_t *);
145 /* A null pointer is an invalid argument for "%U", but in practice
146 it occurs quite frequently in printf statements that produce
147 debug output. Use a fallback in this case. */
148 if (ap->a.a_u8_string == NULL)
149 {
150 static const uint8_t u8_null_string[] =
151 { '(', 'N', 'U', 'L', 'L', ')', 0 };
152 ap->a.a_u8_string = u8_null_string;
153 }
154 break;
155 case TYPE_U16_STRING:
156 ap->a.a_u16_string = va_arg (args, const uint16_t *);
157 /* A null pointer is an invalid argument for "%lU", but in practice
158 it occurs quite frequently in printf statements that produce
159 debug output. Use a fallback in this case. */
160 if (ap->a.a_u16_string == NULL)
161 {
162 static const uint16_t u16_null_string[] =
163 { '(', 'N', 'U', 'L', 'L', ')', 0 };
164 ap->a.a_u16_string = u16_null_string;
165 }
166 break;
167 case TYPE_U32_STRING:
168 ap->a.a_u32_string = va_arg (args, const uint32_t *);
169 /* A null pointer is an invalid argument for "%llU", but in practice
170 it occurs quite frequently in printf statements that produce
171 debug output. Use a fallback in this case. */
172 if (ap->a.a_u32_string == NULL)
173 {
174 static const uint32_t u32_null_string[] =
175 { '(', 'N', 'U', 'L', 'L', ')', 0 };
176 ap->a.a_u32_string = u32_null_string;
177 }
178 break;
179#endif
180 default:
181 /* Unknown type. */
182 return -1;
183 }
184 return 0;
185}
diff --git a/src/daemon/https/lgl/printf-args.h b/src/daemon/https/lgl/printf-args.h
new file mode 100644
index 00000000..b663a63b
--- /dev/null
+++ b/src/daemon/https/lgl/printf-args.h
@@ -0,0 +1,154 @@
1/* Decomposed printf argument list.
2 Copyright (C) 1999, 2002-2003, 2006-2007 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License along
15 with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18#ifndef _PRINTF_ARGS_H
19#define _PRINTF_ARGS_H
20
21/* This file can be parametrized with the following macros:
22 ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions.
23 PRINTF_FETCHARGS Name of the function to be declared.
24 STATIC Set to 'static' to declare the function static. */
25
26/* Default parameters. */
27#ifndef PRINTF_FETCHARGS
28# define PRINTF_FETCHARGS printf_fetchargs
29#endif
30
31/* Get size_t. */
32#include <stddef.h>
33
34/* Get wchar_t. */
35#if HAVE_WCHAR_T
36# include <stddef.h>
37#endif
38
39/* Get wint_t. */
40#if HAVE_WINT_T
41# include <wchar.h>
42#endif
43
44/* Get va_list. */
45#include <stdarg.h>
46
47
48/* Argument types */
49typedef enum
50{
51 TYPE_NONE,
52 TYPE_SCHAR,
53 TYPE_UCHAR,
54 TYPE_SHORT,
55 TYPE_USHORT,
56 TYPE_INT,
57 TYPE_UINT,
58 TYPE_LONGINT,
59 TYPE_ULONGINT,
60#if HAVE_LONG_LONG_INT
61 TYPE_LONGLONGINT,
62 TYPE_ULONGLONGINT,
63#endif
64 TYPE_DOUBLE,
65 TYPE_LONGDOUBLE,
66 TYPE_CHAR,
67#if HAVE_WINT_T
68 TYPE_WIDE_CHAR,
69#endif
70 TYPE_STRING,
71#if HAVE_WCHAR_T
72 TYPE_WIDE_STRING,
73#endif
74 TYPE_POINTER,
75 TYPE_COUNT_SCHAR_POINTER,
76 TYPE_COUNT_SHORT_POINTER,
77 TYPE_COUNT_INT_POINTER,
78 TYPE_COUNT_LONGINT_POINTER
79#if HAVE_LONG_LONG_INT
80, TYPE_COUNT_LONGLONGINT_POINTER
81#endif
82#if ENABLE_UNISTDIO
83 /* The unistdio extensions. */
84, TYPE_U8_STRING
85, TYPE_U16_STRING
86, TYPE_U32_STRING
87#endif
88} arg_type;
89
90/* Polymorphic argument */
91typedef struct
92{
93 arg_type type;
94 union
95 {
96 signed char a_schar;
97 unsigned char a_uchar;
98 short a_short;
99 unsigned short a_ushort;
100 int a_int;
101 unsigned int a_uint;
102 long int a_longint;
103 unsigned long int a_ulongint;
104#if HAVE_LONG_LONG_INT
105 long long int a_longlongint;
106 unsigned long long int a_ulonglongint;
107#endif
108 float a_float;
109 double a_double;
110 long double a_longdouble;
111 int a_char;
112#if HAVE_WINT_T
113 wint_t a_wide_char;
114#endif
115 const char* a_string;
116#if HAVE_WCHAR_T
117 const wchar_t* a_wide_string;
118#endif
119 void* a_pointer;
120 signed char * a_count_schar_pointer;
121 short * a_count_short_pointer;
122 int * a_count_int_pointer;
123 long int * a_count_longint_pointer;
124#if HAVE_LONG_LONG_INT
125 long long int * a_count_longlongint_pointer;
126#endif
127#if ENABLE_UNISTDIO
128 /* The unistdio extensions. */
129 const uint8_t * a_u8_string;
130 const uint16_t * a_u16_string;
131 const uint32_t * a_u32_string;
132#endif
133 }
134 a;
135}
136argument;
137
138typedef struct
139{
140 size_t count;
141 argument *arg;
142}
143arguments;
144
145
146/* Fetch the arguments, putting them into a. */
147#ifdef STATIC
148STATIC
149#else
150extern
151#endif
152int PRINTF_FETCHARGS (va_list args, arguments *a);
153
154#endif /* _PRINTF_ARGS_H */
diff --git a/src/daemon/https/lgl/printf-parse.c b/src/daemon/https/lgl/printf-parse.c
new file mode 100644
index 00000000..e0b83a39
--- /dev/null
+++ b/src/daemon/https/lgl/printf-parse.c
@@ -0,0 +1,599 @@
1/* Formatted output to strings.
2 Copyright (C) 1999-2000, 2002-2003, 2006-2007 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License along
15 with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18/* This file can be parametrized with the following macros:
19 CHAR_T The element type of the format string.
20 CHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters
21 in the format string are ASCII.
22 DIRECTIVE Structure denoting a format directive.
23 Depends on CHAR_T.
24 DIRECTIVES Structure denoting the set of format directives of a
25 format string. Depends on CHAR_T.
26 PRINTF_PARSE Function that parses a format string.
27 Depends on CHAR_T.
28 STATIC Set to 'static' to declare the function static.
29 ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. */
30
31#ifndef PRINTF_PARSE
32# include <config.h>
33#endif
34
35/* Specification. */
36#ifndef PRINTF_PARSE
37# include "printf-parse.h"
38#endif
39
40/* Default parameters. */
41#ifndef PRINTF_PARSE
42# define PRINTF_PARSE printf_parse
43# define CHAR_T char
44# define DIRECTIVE char_directive
45# define DIRECTIVES char_directives
46#endif
47
48/* Get size_t, NULL. */
49#include <stddef.h>
50
51/* Get intmax_t. */
52#if defined IN_LIBINTL || defined IN_LIBASPRINTF
53# if HAVE_STDINT_H_WITH_UINTMAX
54# include <stdint.h>
55# endif
56# if HAVE_INTTYPES_H_WITH_UINTMAX
57# include <inttypes.h>
58# endif
59#else
60# include <stdint.h>
61#endif
62
63/* malloc(), realloc(), free(). */
64#include <stdlib.h>
65
66/* errno. */
67#include <errno.h>
68
69/* Checked size_t computations. */
70#include "xsize.h"
71
72#if CHAR_T_ONLY_ASCII
73/* c_isascii(). */
74# include "c-ctype.h"
75#endif
76
77#ifdef STATIC
78STATIC
79#endif
80 int
81PRINTF_PARSE (const CHAR_T * format, DIRECTIVES * d, arguments * a)
82{
83 const CHAR_T *cp = format; /* pointer into format */
84 size_t arg_posn = 0; /* number of regular arguments consumed */
85 size_t d_allocated; /* allocated elements of d->dir */
86 size_t a_allocated; /* allocated elements of a->arg */
87 size_t max_width_length = 0;
88 size_t max_precision_length = 0;
89
90 d->count = 0;
91 d_allocated = 1;
92 d->dir = (DIRECTIVE *) malloc (d_allocated * sizeof (DIRECTIVE));
93 if (d->dir == NULL)
94 /* Out of memory. */
95 goto out_of_memory_1;
96
97 a->count = 0;
98 a_allocated = 0;
99 a->arg = NULL;
100
101#define REGISTER_ARG(_index_,_type_) \
102 { \
103 size_t n = (_index_); \
104 if (n >= a_allocated) \
105 { \
106 size_t memory_size; \
107 argument *memory; \
108 \
109 a_allocated = xtimes (a_allocated, 2); \
110 if (a_allocated <= n) \
111 a_allocated = xsum (n, 1); \
112 memory_size = xtimes (a_allocated, sizeof (argument)); \
113 if (size_overflow_p (memory_size)) \
114 /* Overflow, would lead to out of memory. */ \
115 goto out_of_memory; \
116 memory = (argument *) (a->arg \
117 ? realloc (a->arg, memory_size) \
118 : malloc (memory_size)); \
119 if (memory == NULL) \
120 /* Out of memory. */ \
121 goto out_of_memory; \
122 a->arg = memory; \
123 } \
124 while (a->count <= n) \
125 a->arg[a->count++].type = TYPE_NONE; \
126 if (a->arg[n].type == TYPE_NONE) \
127 a->arg[n].type = (_type_); \
128 else if (a->arg[n].type != (_type_)) \
129 /* Ambiguous type for positional argument. */ \
130 goto error; \
131 }
132
133 while (*cp != '\0')
134 {
135 CHAR_T c = *cp++;
136 if (c == '%')
137 {
138 size_t arg_index = ARG_NONE;
139 DIRECTIVE *dp = &d->dir[d->count]; /* pointer to next directive */
140
141 /* Initialize the next directive. */
142 dp->dir_start = cp - 1;
143 dp->flags = 0;
144 dp->width_start = NULL;
145 dp->width_end = NULL;
146 dp->width_arg_index = ARG_NONE;
147 dp->precision_start = NULL;
148 dp->precision_end = NULL;
149 dp->precision_arg_index = ARG_NONE;
150 dp->arg_index = ARG_NONE;
151
152 /* Test for positional argument. */
153 if (*cp >= '0' && *cp <= '9')
154 {
155 const CHAR_T *np;
156
157 for (np = cp; *np >= '0' && *np <= '9'; np++)
158 ;
159 if (*np == '$')
160 {
161 size_t n = 0;
162
163 for (np = cp; *np >= '0' && *np <= '9'; np++)
164 n = xsum (xtimes (n, 10), *np - '0');
165 if (n == 0)
166 /* Positional argument 0. */
167 goto error;
168 if (size_overflow_p (n))
169 /* n too large, would lead to out of memory later. */
170 goto error;
171 arg_index = n - 1;
172 cp = np + 1;
173 }
174 }
175
176 /* Read the flags. */
177 for (;;)
178 {
179 if (*cp == '\'')
180 {
181 dp->flags |= FLAG_GROUP;
182 cp++;
183 }
184 else if (*cp == '-')
185 {
186 dp->flags |= FLAG_LEFT;
187 cp++;
188 }
189 else if (*cp == '+')
190 {
191 dp->flags |= FLAG_SHOWSIGN;
192 cp++;
193 }
194 else if (*cp == ' ')
195 {
196 dp->flags |= FLAG_SPACE;
197 cp++;
198 }
199 else if (*cp == '#')
200 {
201 dp->flags |= FLAG_ALT;
202 cp++;
203 }
204 else if (*cp == '0')
205 {
206 dp->flags |= FLAG_ZERO;
207 cp++;
208 }
209 else
210 break;
211 }
212
213 /* Parse the field width. */
214 if (*cp == '*')
215 {
216 dp->width_start = cp;
217 cp++;
218 dp->width_end = cp;
219 if (max_width_length < 1)
220 max_width_length = 1;
221
222 /* Test for positional argument. */
223 if (*cp >= '0' && *cp <= '9')
224 {
225 const CHAR_T *np;
226
227 for (np = cp; *np >= '0' && *np <= '9'; np++)
228 ;
229 if (*np == '$')
230 {
231 size_t n = 0;
232
233 for (np = cp; *np >= '0' && *np <= '9'; np++)
234 n = xsum (xtimes (n, 10), *np - '0');
235 if (n == 0)
236 /* Positional argument 0. */
237 goto error;
238 if (size_overflow_p (n))
239 /* n too large, would lead to out of memory later. */
240 goto error;
241 dp->width_arg_index = n - 1;
242 cp = np + 1;
243 }
244 }
245 if (dp->width_arg_index == ARG_NONE)
246 {
247 dp->width_arg_index = arg_posn++;
248 if (dp->width_arg_index == ARG_NONE)
249 /* arg_posn wrapped around. */
250 goto error;
251 }
252 REGISTER_ARG (dp->width_arg_index, TYPE_INT);
253 }
254 else if (*cp >= '0' && *cp <= '9')
255 {
256 size_t width_length;
257
258 dp->width_start = cp;
259 for (; *cp >= '0' && *cp <= '9'; cp++)
260 ;
261 dp->width_end = cp;
262 width_length = dp->width_end - dp->width_start;
263 if (max_width_length < width_length)
264 max_width_length = width_length;
265 }
266
267 /* Parse the precision. */
268 if (*cp == '.')
269 {
270 cp++;
271 if (*cp == '*')
272 {
273 dp->precision_start = cp - 1;
274 cp++;
275 dp->precision_end = cp;
276 if (max_precision_length < 2)
277 max_precision_length = 2;
278
279 /* Test for positional argument. */
280 if (*cp >= '0' && *cp <= '9')
281 {
282 const CHAR_T *np;
283
284 for (np = cp; *np >= '0' && *np <= '9'; np++)
285 ;
286 if (*np == '$')
287 {
288 size_t n = 0;
289
290 for (np = cp; *np >= '0' && *np <= '9'; np++)
291 n = xsum (xtimes (n, 10), *np - '0');
292 if (n == 0)
293 /* Positional argument 0. */
294 goto error;
295 if (size_overflow_p (n))
296 /* n too large, would lead to out of memory
297 later. */
298 goto error;
299 dp->precision_arg_index = n - 1;
300 cp = np + 1;
301 }
302 }
303 if (dp->precision_arg_index == ARG_NONE)
304 {
305 dp->precision_arg_index = arg_posn++;
306 if (dp->precision_arg_index == ARG_NONE)
307 /* arg_posn wrapped around. */
308 goto error;
309 }
310 REGISTER_ARG (dp->precision_arg_index, TYPE_INT);
311 }
312 else
313 {
314 size_t precision_length;
315
316 dp->precision_start = cp - 1;
317 for (; *cp >= '0' && *cp <= '9'; cp++)
318 ;
319 dp->precision_end = cp;
320 precision_length = dp->precision_end - dp->precision_start;
321 if (max_precision_length < precision_length)
322 max_precision_length = precision_length;
323 }
324 }
325
326 {
327 arg_type type;
328
329 /* Parse argument type/size specifiers. */
330 {
331 int flags = 0;
332
333 for (;;)
334 {
335 if (*cp == 'h')
336 {
337 flags |= (1 << (flags & 1));
338 cp++;
339 }
340 else if (*cp == 'L')
341 {
342 flags |= 4;
343 cp++;
344 }
345 else if (*cp == 'l')
346 {
347 flags += 8;
348 cp++;
349 }
350 else if (*cp == 'j')
351 {
352 if (sizeof (intmax_t) > sizeof (long))
353 {
354 /* intmax_t = long long */
355 flags += 16;
356 }
357 else if (sizeof (intmax_t) > sizeof (int))
358 {
359 /* intmax_t = long */
360 flags += 8;
361 }
362 cp++;
363 }
364 else if (*cp == 'z' || *cp == 'Z')
365 {
366 /* 'z' is standardized in ISO C 99, but glibc uses 'Z'
367 because the warning facility in gcc-2.95.2 understands
368 only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784). */
369 if (sizeof (size_t) > sizeof (long))
370 {
371 /* size_t = long long */
372 flags += 16;
373 }
374 else if (sizeof (size_t) > sizeof (int))
375 {
376 /* size_t = long */
377 flags += 8;
378 }
379 cp++;
380 }
381 else if (*cp == 't')
382 {
383 if (sizeof (ptrdiff_t) > sizeof (long))
384 {
385 /* ptrdiff_t = long long */
386 flags += 16;
387 }
388 else if (sizeof (ptrdiff_t) > sizeof (int))
389 {
390 /* ptrdiff_t = long */
391 flags += 8;
392 }
393 cp++;
394 }
395 else
396 break;
397 }
398
399 /* Read the conversion character. */
400 c = *cp++;
401 switch (c)
402 {
403 case 'd':
404 case 'i':
405#if HAVE_LONG_LONG_INT
406 /* If 'long long' exists and is larger than 'long': */
407 if (flags >= 16 || (flags & 4))
408 type = TYPE_LONGLONGINT;
409 else
410#endif
411 /* If 'long long' exists and is the same as 'long', we parse
412 "lld" into TYPE_LONGINT. */
413 if (flags >= 8)
414 type = TYPE_LONGINT;
415 else if (flags & 2)
416 type = TYPE_SCHAR;
417 else if (flags & 1)
418 type = TYPE_SHORT;
419 else
420 type = TYPE_INT;
421 break;
422 case 'o':
423 case 'u':
424 case 'x':
425 case 'X':
426#if HAVE_LONG_LONG_INT
427 /* If 'long long' exists and is larger than 'long': */
428 if (flags >= 16 || (flags & 4))
429 type = TYPE_ULONGLONGINT;
430 else
431#endif
432 /* If 'unsigned long long' exists and is the same as
433 'unsigned long', we parse "llu" into TYPE_ULONGINT. */
434 if (flags >= 8)
435 type = TYPE_ULONGINT;
436 else if (flags & 2)
437 type = TYPE_UCHAR;
438 else if (flags & 1)
439 type = TYPE_USHORT;
440 else
441 type = TYPE_UINT;
442 break;
443 case 'f':
444 case 'F':
445 case 'e':
446 case 'E':
447 case 'g':
448 case 'G':
449 case 'a':
450 case 'A':
451 if (flags >= 16 || (flags & 4))
452 type = TYPE_LONGDOUBLE;
453 else
454 type = TYPE_DOUBLE;
455 break;
456 case 'c':
457 if (flags >= 8)
458#if HAVE_WINT_T
459 type = TYPE_WIDE_CHAR;
460#else
461 goto error;
462#endif
463 else
464 type = TYPE_CHAR;
465 break;
466#if HAVE_WINT_T
467 case 'C':
468 type = TYPE_WIDE_CHAR;
469 c = 'c';
470 break;
471#endif
472 case 's':
473 if (flags >= 8)
474#if HAVE_WCHAR_T
475 type = TYPE_WIDE_STRING;
476#else
477 goto error;
478#endif
479 else
480 type = TYPE_STRING;
481 break;
482#if HAVE_WCHAR_T
483 case 'S':
484 type = TYPE_WIDE_STRING;
485 c = 's';
486 break;
487#endif
488 case 'p':
489 type = TYPE_POINTER;
490 break;
491 case 'n':
492#if HAVE_LONG_LONG_INT
493 /* If 'long long' exists and is larger than 'long': */
494 if (flags >= 16 || (flags & 4))
495 type = TYPE_COUNT_LONGLONGINT_POINTER;
496 else
497#endif
498 /* If 'long long' exists and is the same as 'long', we parse
499 "lln" into TYPE_COUNT_LONGINT_POINTER. */
500 if (flags >= 8)
501 type = TYPE_COUNT_LONGINT_POINTER;
502 else if (flags & 2)
503 type = TYPE_COUNT_SCHAR_POINTER;
504 else if (flags & 1)
505 type = TYPE_COUNT_SHORT_POINTER;
506 else
507 type = TYPE_COUNT_INT_POINTER;
508 break;
509#if ENABLE_UNISTDIO
510 /* The unistdio extensions. */
511 case 'U':
512 if (flags >= 16)
513 type = TYPE_U32_STRING;
514 else if (flags >= 8)
515 type = TYPE_U16_STRING;
516 else
517 type = TYPE_U8_STRING;
518 break;
519#endif
520 case '%':
521 type = TYPE_NONE;
522 break;
523 default:
524 /* Unknown conversion character. */
525 goto error;
526 }
527 }
528
529 if (type != TYPE_NONE)
530 {
531 dp->arg_index = arg_index;
532 if (dp->arg_index == ARG_NONE)
533 {
534 dp->arg_index = arg_posn++;
535 if (dp->arg_index == ARG_NONE)
536 /* arg_posn wrapped around. */
537 goto error;
538 }
539 REGISTER_ARG (dp->arg_index, type);
540 }
541 dp->conversion = c;
542 dp->dir_end = cp;
543 }
544
545 d->count++;
546 if (d->count >= d_allocated)
547 {
548 size_t memory_size;
549 DIRECTIVE *memory;
550
551 d_allocated = xtimes (d_allocated, 2);
552 memory_size = xtimes (d_allocated, sizeof (DIRECTIVE));
553 if (size_overflow_p (memory_size))
554 /* Overflow, would lead to out of memory. */
555 goto out_of_memory;
556 memory = (DIRECTIVE *) realloc (d->dir, memory_size);
557 if (memory == NULL)
558 /* Out of memory. */
559 goto out_of_memory;
560 d->dir = memory;
561 }
562 }
563#if CHAR_T_ONLY_ASCII
564 else if (!c_isascii (c))
565 {
566 /* Non-ASCII character. Not supported. */
567 goto error;
568 }
569#endif
570 }
571 d->dir[d->count].dir_start = cp;
572
573 d->max_width_length = max_width_length;
574 d->max_precision_length = max_precision_length;
575 return 0;
576
577error:
578 if (a->arg)
579 free (a->arg);
580 if (d->dir)
581 free (d->dir);
582 errno = EINVAL;
583 return -1;
584
585out_of_memory:
586 if (a->arg)
587 free (a->arg);
588 if (d->dir)
589 free (d->dir);
590out_of_memory_1:
591 errno = ENOMEM;
592 return -1;
593}
594
595#undef PRINTF_PARSE
596#undef DIRECTIVES
597#undef DIRECTIVE
598#undef CHAR_T_ONLY_ASCII
599#undef CHAR_T
diff --git a/src/daemon/https/lgl/printf-parse.h b/src/daemon/https/lgl/printf-parse.h
new file mode 100644
index 00000000..f9013278
--- /dev/null
+++ b/src/daemon/https/lgl/printf-parse.h
@@ -0,0 +1,178 @@
1/* Parse printf format string.
2 Copyright (C) 1999, 2002-2003, 2005, 2007 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License along
15 with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18#ifndef _PRINTF_PARSE_H
19#define _PRINTF_PARSE_H
20
21/* This file can be parametrized with the following macros:
22 ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions.
23 STATIC Set to 'static' to declare the function static. */
24
25#include "printf-args.h"
26
27/* Flags */
28#define FLAG_GROUP 1 /* ' flag */
29#define FLAG_LEFT 2 /* - flag */
30#define FLAG_SHOWSIGN 4 /* + flag */
31#define FLAG_SPACE 8 /* space flag */
32#define FLAG_ALT 16 /* # flag */
33#define FLAG_ZERO 32
34
35/* arg_index value indicating that no argument is consumed. */
36#define ARG_NONE (~(size_t)0)
37
38/* xxx_directive: A parsed directive.
39 xxx_directives: A parsed format string. */
40
41/* A parsed directive. */
42typedef struct
43{
44 const char* dir_start;
45 const char* dir_end;
46 int flags;
47 const char* width_start;
48 const char* width_end;
49 size_t width_arg_index;
50 const char* precision_start;
51 const char* precision_end;
52 size_t precision_arg_index;
53 char conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */
54 size_t arg_index;
55}
56char_directive;
57
58/* A parsed format string. */
59typedef struct
60{
61 size_t count;
62 char_directive *dir;
63 size_t max_width_length;
64 size_t max_precision_length;
65}
66char_directives;
67
68#if ENABLE_UNISTDIO
69
70/* A parsed directive. */
71typedef struct
72{
73 const uint8_t* dir_start;
74 const uint8_t* dir_end;
75 int flags;
76 const uint8_t* width_start;
77 const uint8_t* width_end;
78 size_t width_arg_index;
79 const uint8_t* precision_start;
80 const uint8_t* precision_end;
81 size_t precision_arg_index;
82 uint8_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */
83 size_t arg_index;
84}
85u8_directive;
86
87/* A parsed format string. */
88typedef struct
89{
90 size_t count;
91 u8_directive *dir;
92 size_t max_width_length;
93 size_t max_precision_length;
94}
95u8_directives;
96
97/* A parsed directive. */
98typedef struct
99{
100 const uint16_t* dir_start;
101 const uint16_t* dir_end;
102 int flags;
103 const uint16_t* width_start;
104 const uint16_t* width_end;
105 size_t width_arg_index;
106 const uint16_t* precision_start;
107 const uint16_t* precision_end;
108 size_t precision_arg_index;
109 uint16_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */
110 size_t arg_index;
111}
112u16_directive;
113
114/* A parsed format string. */
115typedef struct
116{
117 size_t count;
118 u16_directive *dir;
119 size_t max_width_length;
120 size_t max_precision_length;
121}
122u16_directives;
123
124/* A parsed directive. */
125typedef struct
126{
127 const uint32_t* dir_start;
128 const uint32_t* dir_end;
129 int flags;
130 const uint32_t* width_start;
131 const uint32_t* width_end;
132 size_t width_arg_index;
133 const uint32_t* precision_start;
134 const uint32_t* precision_end;
135 size_t precision_arg_index;
136 uint32_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */
137 size_t arg_index;
138}
139u32_directive;
140
141/* A parsed format string. */
142typedef struct
143{
144 size_t count;
145 u32_directive *dir;
146 size_t max_width_length;
147 size_t max_precision_length;
148}
149u32_directives;
150
151#endif
152
153
154/* Parses the format string. Fills in the number N of directives, and fills
155 in directives[0], ..., directives[N-1], and sets directives[N].dir_start
156 to the end of the format string. Also fills in the arg_type fields of the
157 arguments and the needed count of arguments. */
158#if ENABLE_UNISTDIO
159extern int
160 ulc_printf_parse (const char *format, char_directives *d, arguments *a);
161extern int
162 u8_printf_parse (const uint8_t *format, u8_directives *d, arguments *a);
163extern int
164 u16_printf_parse (const uint16_t *format, u16_directives *d,
165 arguments *a);
166extern int
167 u32_printf_parse (const uint32_t *format, u32_directives *d,
168 arguments *a);
169#else
170# ifdef STATIC
171STATIC
172# else
173extern
174# endif
175int printf_parse (const char *format, char_directives *d, arguments *a);
176#endif
177
178#endif /* _PRINTF_PARSE_H */
diff --git a/src/daemon/https/lgl/read-file.c b/src/daemon/https/lgl/read-file.c
new file mode 100644
index 00000000..9172a6ef
--- /dev/null
+++ b/src/daemon/https/lgl/read-file.c
@@ -0,0 +1,136 @@
1/* read-file.c -- read file contents into a string
2 Copyright (C) 2006 Free Software Foundation, Inc.
3 Written by Simon Josefsson and Bruno Haible.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
18
19#include <config.h>
20
21#include "read-file.h"
22
23/* Get realloc, free. */
24#include <stdlib.h>
25
26/* Get errno. */
27#include <errno.h>
28
29/* Read a STREAM and return a newly allocated string with the content,
30 and set *LENGTH to the length of the string. The string is
31 zero-terminated, but the terminating zero byte is not counted in
32 *LENGTH. On errors, *LENGTH is undefined, errno preserves the
33 values set by system functions (if any), and NULL is returned. */
34char *
35fread_file (FILE * stream, size_t * length)
36{
37 char *buf = NULL;
38 size_t alloc = 0;
39 size_t size = 0;
40 int save_errno;
41
42 for (;;)
43 {
44 size_t count;
45 size_t requested;
46
47 if (size + BUFSIZ + 1 > alloc)
48 {
49 char *new_buf;
50
51 alloc += alloc / 2;
52 if (alloc < size + BUFSIZ + 1)
53 alloc = size + BUFSIZ + 1;
54
55 new_buf = realloc (buf, alloc);
56 if (!new_buf)
57 {
58 save_errno = errno;
59 break;
60 }
61
62 buf = new_buf;
63 }
64
65 requested = alloc - size - 1;
66 count = fread (buf + size, 1, requested, stream);
67 size += count;
68
69 if (count != requested)
70 {
71 save_errno = errno;
72 if (ferror (stream))
73 break;
74 buf[size] = '\0';
75 *length = size;
76 return buf;
77 }
78 }
79
80 free (buf);
81 errno = save_errno;
82 return NULL;
83}
84
85static char *
86internal_read_file (const char *filename, size_t * length, const char *mode)
87{
88 FILE *stream = fopen (filename, mode);
89 char *out;
90 int save_errno;
91
92 if (!stream)
93 return NULL;
94
95 out = fread_file (stream, length);
96
97 save_errno = errno;
98
99 if (fclose (stream) != 0)
100 {
101 if (out)
102 {
103 save_errno = errno;
104 free (out);
105 }
106 errno = save_errno;
107 return NULL;
108 }
109
110 return out;
111}
112
113/* Open and read the contents of FILENAME, and return a newly
114 allocated string with the content, and set *LENGTH to the length of
115 the string. The string is zero-terminated, but the terminating
116 zero byte is not counted in *LENGTH. On errors, *LENGTH is
117 undefined, errno preserves the values set by system functions (if
118 any), and NULL is returned. */
119char *
120read_file (const char *filename, size_t * length)
121{
122 return internal_read_file (filename, length, "r");
123}
124
125/* Open (on non-POSIX systems, in binary mode) and read the contents
126 of FILENAME, and return a newly allocated string with the content,
127 and set LENGTH to the length of the string. The string is
128 zero-terminated, but the terminating zero byte is not counted in
129 the LENGTH variable. On errors, *LENGTH is undefined, errno
130 preserves the values set by system functions (if any), and NULL is
131 returned. */
132char *
133read_binary_file (const char *filename, size_t * length)
134{
135 return internal_read_file (filename, length, "rb");
136}
diff --git a/src/daemon/https/lgl/read-file.h b/src/daemon/https/lgl/read-file.h
new file mode 100644
index 00000000..798d841f
--- /dev/null
+++ b/src/daemon/https/lgl/read-file.h
@@ -0,0 +1,34 @@
1/* read-file.h -- read file contents into a string
2 Copyright (C) 2006 Free Software Foundation, Inc.
3 Written by Simon Josefsson.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
18
19#ifndef READ_FILE_H
20#define READ_FILE_H
21
22/* Get size_t. */
23#include <stddef.h>
24
25/* Get FILE. */
26#include <stdio.h>
27
28extern char *fread_file (FILE * stream, size_t * length);
29
30extern char *read_file (const char *filename, size_t * length);
31
32extern char *read_binary_file (const char *filename, size_t * length);
33
34#endif /* READ_FILE_H */
diff --git a/src/daemon/https/lgl/realloc.c b/src/daemon/https/lgl/realloc.c
new file mode 100644
index 00000000..4661f913
--- /dev/null
+++ b/src/daemon/https/lgl/realloc.c
@@ -0,0 +1,87 @@
1/* realloc() function that is glibc compatible.
2
3 Copyright (C) 1997, 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18/* written by Jim Meyering and Bruno Haible */
19
20#include <config.h>
21
22/* Only the AC_FUNC_REALLOC macro defines 'realloc' already in config.h. */
23#ifdef realloc
24# define NEED_REALLOC_GNU 1
25#endif
26
27/* Infer the properties of the system's malloc function.
28 Only the AC_FUNC_MALLOC macro defines 'malloc' already in config.h. */
29#if GNULIB_MALLOC_GNU && !defined malloc
30# define SYSTEM_MALLOC_GLIBC_COMPATIBLE 1
31#endif
32
33/* Below we want to call the system's malloc and realloc.
34 Undefine the symbols here so that including <stdlib.h> provides a
35 declaration of malloc(), not of rpl_malloc(), and likewise for realloc. */
36#undef malloc
37#undef realloc
38
39/* Specification. */
40#include <stdlib.h>
41
42#include <errno.h>
43
44/* Below we want to call the system's malloc and realloc.
45 Undefine the symbols, if they were defined by gnulib's <stdlib.h>
46 replacement. */
47#undef malloc
48#undef realloc
49
50/* Change the size of an allocated block of memory P to N bytes,
51 with error checking. If N is zero, change it to 1. If P is NULL,
52 use malloc. */
53
54void *
55rpl_realloc (void *p, size_t n)
56{
57 void *result;
58
59#if NEED_REALLOC_GNU
60 if (n == 0)
61 {
62 n = 1;
63
64 /* In theory realloc might fail, so don't rely on it to free. */
65 free (p);
66 p = NULL;
67 }
68#endif
69
70 if (p == NULL)
71 {
72#if GNULIB_REALLOC_GNU && !NEED_REALLOC_GNU && !SYSTEM_MALLOC_GLIBC_COMPATIBLE
73 if (n == 0)
74 n = 1;
75#endif
76 result = malloc (n);
77 }
78 else
79 result = realloc (p, n);
80
81#if !HAVE_REALLOC_POSIX
82 if (result == NULL)
83 errno = ENOMEM;
84#endif
85
86 return result;
87}
diff --git a/src/daemon/https/lgl/rijndael-alg-fst.c b/src/daemon/https/lgl/rijndael-alg-fst.c
new file mode 100644
index 00000000..5baa0e95
--- /dev/null
+++ b/src/daemon/https/lgl/rijndael-alg-fst.c
@@ -0,0 +1,1083 @@
1/* rijndael-alg-fst.c --- Rijndael cipher implementation.
2 * Copyright (C) 2005, 2006 Free Software Foundation, Inc.
3 *
4 * This file is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; either version 2.1, or (at your
7 * option) any later version.
8 *
9 * This file is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this file; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 */
20
21/* Adapted for gnulib by Simon Josefsson.
22 *
23 * Based on public domain "Optimised C code" retrieved from (SHA1
24 * 7c8e4b00d06685d1dbc6724a9e0d502353de339e):
25 * http://www.iaik.tu-graz.ac.at/research/krypto/AES/old/~rijmen/rijndael/rijndael-fst-3.0.zip
26 */
27
28#include <config.h>
29
30/**
31 * rijndael-alg-fst.c
32 *
33 * @version 3.0 (December 2000)
34 *
35 * Optimised ANSI C code for the Rijndael cipher (now AES)
36 *
37 * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
38 * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
39 * @author Paulo Barreto <paulo.barreto@terra.com.br>
40 *
41 * This code is hereby placed in the public domain.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
44 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
45 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
47 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
48 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
49 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
50 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
51 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
52 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
53 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 */
55
56#include "rijndael-alg-fst.h"
57
58/*
59Te0[x] = S [x].[02, 01, 01, 03];
60Te1[x] = S [x].[03, 02, 01, 01];
61Te2[x] = S [x].[01, 03, 02, 01];
62Te3[x] = S [x].[01, 01, 03, 02];
63Te4[x] = S [x].[01, 01, 01, 01];
64
65Td0[x] = Si[x].[0e, 09, 0d, 0b];
66Td1[x] = Si[x].[0b, 0e, 09, 0d];
67Td2[x] = Si[x].[0d, 0b, 0e, 09];
68Td3[x] = Si[x].[09, 0d, 0b, 0e];
69Td4[x] = Si[x].[01, 01, 01, 01];
70*/
71
72static const uint32_t Te0[256] = {
73 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d,
74 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554,
75 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d,
76 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a,
77 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87,
78 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b,
79 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea,
80 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b,
81 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a,
82 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f,
83 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108,
84 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f,
85 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e,
86 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5,
87 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d,
88 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f,
89 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e,
90 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb,
91 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce,
92 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497,
93 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c,
94 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed,
95 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b,
96 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a,
97 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16,
98 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594,
99 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81,
100 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3,
101 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a,
102 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504,
103 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163,
104 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d,
105 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f,
106 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739,
107 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47,
108 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395,
109 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f,
110 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883,
111 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c,
112 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76,
113 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e,
114 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4,
115 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6,
116 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b,
117 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7,
118 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0,
119 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25,
120 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818,
121 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72,
122 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651,
123 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21,
124 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85,
125 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa,
126 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12,
127 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0,
128 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9,
129 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133,
130 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7,
131 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920,
132 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a,
133 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17,
134 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8,
135 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11,
136 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a,
137};
138static const uint32_t Te1[256] = {
139 0xa5c66363, 0x84f87c7c, 0x99ee7777, 0x8df67b7b,
140 0x0dfff2f2, 0xbdd66b6b, 0xb1de6f6f, 0x5491c5c5,
141 0x50603030, 0x03020101, 0xa9ce6767, 0x7d562b2b,
142 0x19e7fefe, 0x62b5d7d7, 0xe64dabab, 0x9aec7676,
143 0x458fcaca, 0x9d1f8282, 0x4089c9c9, 0x87fa7d7d,
144 0x15effafa, 0xebb25959, 0xc98e4747, 0x0bfbf0f0,
145 0xec41adad, 0x67b3d4d4, 0xfd5fa2a2, 0xea45afaf,
146 0xbf239c9c, 0xf753a4a4, 0x96e47272, 0x5b9bc0c0,
147 0xc275b7b7, 0x1ce1fdfd, 0xae3d9393, 0x6a4c2626,
148 0x5a6c3636, 0x417e3f3f, 0x02f5f7f7, 0x4f83cccc,
149 0x5c683434, 0xf451a5a5, 0x34d1e5e5, 0x08f9f1f1,
150 0x93e27171, 0x73abd8d8, 0x53623131, 0x3f2a1515,
151 0x0c080404, 0x5295c7c7, 0x65462323, 0x5e9dc3c3,
152 0x28301818, 0xa1379696, 0x0f0a0505, 0xb52f9a9a,
153 0x090e0707, 0x36241212, 0x9b1b8080, 0x3ddfe2e2,
154 0x26cdebeb, 0x694e2727, 0xcd7fb2b2, 0x9fea7575,
155 0x1b120909, 0x9e1d8383, 0x74582c2c, 0x2e341a1a,
156 0x2d361b1b, 0xb2dc6e6e, 0xeeb45a5a, 0xfb5ba0a0,
157 0xf6a45252, 0x4d763b3b, 0x61b7d6d6, 0xce7db3b3,
158 0x7b522929, 0x3edde3e3, 0x715e2f2f, 0x97138484,
159 0xf5a65353, 0x68b9d1d1, 0x00000000, 0x2cc1eded,
160 0x60402020, 0x1fe3fcfc, 0xc879b1b1, 0xedb65b5b,
161 0xbed46a6a, 0x468dcbcb, 0xd967bebe, 0x4b723939,
162 0xde944a4a, 0xd4984c4c, 0xe8b05858, 0x4a85cfcf,
163 0x6bbbd0d0, 0x2ac5efef, 0xe54faaaa, 0x16edfbfb,
164 0xc5864343, 0xd79a4d4d, 0x55663333, 0x94118585,
165 0xcf8a4545, 0x10e9f9f9, 0x06040202, 0x81fe7f7f,
166 0xf0a05050, 0x44783c3c, 0xba259f9f, 0xe34ba8a8,
167 0xf3a25151, 0xfe5da3a3, 0xc0804040, 0x8a058f8f,
168 0xad3f9292, 0xbc219d9d, 0x48703838, 0x04f1f5f5,
169 0xdf63bcbc, 0xc177b6b6, 0x75afdada, 0x63422121,
170 0x30201010, 0x1ae5ffff, 0x0efdf3f3, 0x6dbfd2d2,
171 0x4c81cdcd, 0x14180c0c, 0x35261313, 0x2fc3ecec,
172 0xe1be5f5f, 0xa2359797, 0xcc884444, 0x392e1717,
173 0x5793c4c4, 0xf255a7a7, 0x82fc7e7e, 0x477a3d3d,
174 0xacc86464, 0xe7ba5d5d, 0x2b321919, 0x95e67373,
175 0xa0c06060, 0x98198181, 0xd19e4f4f, 0x7fa3dcdc,
176 0x66442222, 0x7e542a2a, 0xab3b9090, 0x830b8888,
177 0xca8c4646, 0x29c7eeee, 0xd36bb8b8, 0x3c281414,
178 0x79a7dede, 0xe2bc5e5e, 0x1d160b0b, 0x76addbdb,
179 0x3bdbe0e0, 0x56643232, 0x4e743a3a, 0x1e140a0a,
180 0xdb924949, 0x0a0c0606, 0x6c482424, 0xe4b85c5c,
181 0x5d9fc2c2, 0x6ebdd3d3, 0xef43acac, 0xa6c46262,
182 0xa8399191, 0xa4319595, 0x37d3e4e4, 0x8bf27979,
183 0x32d5e7e7, 0x438bc8c8, 0x596e3737, 0xb7da6d6d,
184 0x8c018d8d, 0x64b1d5d5, 0xd29c4e4e, 0xe049a9a9,
185 0xb4d86c6c, 0xfaac5656, 0x07f3f4f4, 0x25cfeaea,
186 0xafca6565, 0x8ef47a7a, 0xe947aeae, 0x18100808,
187 0xd56fbaba, 0x88f07878, 0x6f4a2525, 0x725c2e2e,
188 0x24381c1c, 0xf157a6a6, 0xc773b4b4, 0x5197c6c6,
189 0x23cbe8e8, 0x7ca1dddd, 0x9ce87474, 0x213e1f1f,
190 0xdd964b4b, 0xdc61bdbd, 0x860d8b8b, 0x850f8a8a,
191 0x90e07070, 0x427c3e3e, 0xc471b5b5, 0xaacc6666,
192 0xd8904848, 0x05060303, 0x01f7f6f6, 0x121c0e0e,
193 0xa3c26161, 0x5f6a3535, 0xf9ae5757, 0xd069b9b9,
194 0x91178686, 0x5899c1c1, 0x273a1d1d, 0xb9279e9e,
195 0x38d9e1e1, 0x13ebf8f8, 0xb32b9898, 0x33221111,
196 0xbbd26969, 0x70a9d9d9, 0x89078e8e, 0xa7339494,
197 0xb62d9b9b, 0x223c1e1e, 0x92158787, 0x20c9e9e9,
198 0x4987cece, 0xffaa5555, 0x78502828, 0x7aa5dfdf,
199 0x8f038c8c, 0xf859a1a1, 0x80098989, 0x171a0d0d,
200 0xda65bfbf, 0x31d7e6e6, 0xc6844242, 0xb8d06868,
201 0xc3824141, 0xb0299999, 0x775a2d2d, 0x111e0f0f,
202 0xcb7bb0b0, 0xfca85454, 0xd66dbbbb, 0x3a2c1616,
203};
204static const uint32_t Te2[256] = {
205 0x63a5c663, 0x7c84f87c, 0x7799ee77, 0x7b8df67b,
206 0xf20dfff2, 0x6bbdd66b, 0x6fb1de6f, 0xc55491c5,
207 0x30506030, 0x01030201, 0x67a9ce67, 0x2b7d562b,
208 0xfe19e7fe, 0xd762b5d7, 0xabe64dab, 0x769aec76,
209 0xca458fca, 0x829d1f82, 0xc94089c9, 0x7d87fa7d,
210 0xfa15effa, 0x59ebb259, 0x47c98e47, 0xf00bfbf0,
211 0xadec41ad, 0xd467b3d4, 0xa2fd5fa2, 0xafea45af,
212 0x9cbf239c, 0xa4f753a4, 0x7296e472, 0xc05b9bc0,
213 0xb7c275b7, 0xfd1ce1fd, 0x93ae3d93, 0x266a4c26,
214 0x365a6c36, 0x3f417e3f, 0xf702f5f7, 0xcc4f83cc,
215 0x345c6834, 0xa5f451a5, 0xe534d1e5, 0xf108f9f1,
216 0x7193e271, 0xd873abd8, 0x31536231, 0x153f2a15,
217 0x040c0804, 0xc75295c7, 0x23654623, 0xc35e9dc3,
218 0x18283018, 0x96a13796, 0x050f0a05, 0x9ab52f9a,
219 0x07090e07, 0x12362412, 0x809b1b80, 0xe23ddfe2,
220 0xeb26cdeb, 0x27694e27, 0xb2cd7fb2, 0x759fea75,
221 0x091b1209, 0x839e1d83, 0x2c74582c, 0x1a2e341a,
222 0x1b2d361b, 0x6eb2dc6e, 0x5aeeb45a, 0xa0fb5ba0,
223 0x52f6a452, 0x3b4d763b, 0xd661b7d6, 0xb3ce7db3,
224 0x297b5229, 0xe33edde3, 0x2f715e2f, 0x84971384,
225 0x53f5a653, 0xd168b9d1, 0x00000000, 0xed2cc1ed,
226 0x20604020, 0xfc1fe3fc, 0xb1c879b1, 0x5bedb65b,
227 0x6abed46a, 0xcb468dcb, 0xbed967be, 0x394b7239,
228 0x4ade944a, 0x4cd4984c, 0x58e8b058, 0xcf4a85cf,
229 0xd06bbbd0, 0xef2ac5ef, 0xaae54faa, 0xfb16edfb,
230 0x43c58643, 0x4dd79a4d, 0x33556633, 0x85941185,
231 0x45cf8a45, 0xf910e9f9, 0x02060402, 0x7f81fe7f,
232 0x50f0a050, 0x3c44783c, 0x9fba259f, 0xa8e34ba8,
233 0x51f3a251, 0xa3fe5da3, 0x40c08040, 0x8f8a058f,
234 0x92ad3f92, 0x9dbc219d, 0x38487038, 0xf504f1f5,
235 0xbcdf63bc, 0xb6c177b6, 0xda75afda, 0x21634221,
236 0x10302010, 0xff1ae5ff, 0xf30efdf3, 0xd26dbfd2,
237 0xcd4c81cd, 0x0c14180c, 0x13352613, 0xec2fc3ec,
238 0x5fe1be5f, 0x97a23597, 0x44cc8844, 0x17392e17,
239 0xc45793c4, 0xa7f255a7, 0x7e82fc7e, 0x3d477a3d,
240 0x64acc864, 0x5de7ba5d, 0x192b3219, 0x7395e673,
241 0x60a0c060, 0x81981981, 0x4fd19e4f, 0xdc7fa3dc,
242 0x22664422, 0x2a7e542a, 0x90ab3b90, 0x88830b88,
243 0x46ca8c46, 0xee29c7ee, 0xb8d36bb8, 0x143c2814,
244 0xde79a7de, 0x5ee2bc5e, 0x0b1d160b, 0xdb76addb,
245 0xe03bdbe0, 0x32566432, 0x3a4e743a, 0x0a1e140a,
246 0x49db9249, 0x060a0c06, 0x246c4824, 0x5ce4b85c,
247 0xc25d9fc2, 0xd36ebdd3, 0xacef43ac, 0x62a6c462,
248 0x91a83991, 0x95a43195, 0xe437d3e4, 0x798bf279,
249 0xe732d5e7, 0xc8438bc8, 0x37596e37, 0x6db7da6d,
250 0x8d8c018d, 0xd564b1d5, 0x4ed29c4e, 0xa9e049a9,
251 0x6cb4d86c, 0x56faac56, 0xf407f3f4, 0xea25cfea,
252 0x65afca65, 0x7a8ef47a, 0xaee947ae, 0x08181008,
253 0xbad56fba, 0x7888f078, 0x256f4a25, 0x2e725c2e,
254 0x1c24381c, 0xa6f157a6, 0xb4c773b4, 0xc65197c6,
255 0xe823cbe8, 0xdd7ca1dd, 0x749ce874, 0x1f213e1f,
256 0x4bdd964b, 0xbddc61bd, 0x8b860d8b, 0x8a850f8a,
257 0x7090e070, 0x3e427c3e, 0xb5c471b5, 0x66aacc66,
258 0x48d89048, 0x03050603, 0xf601f7f6, 0x0e121c0e,
259 0x61a3c261, 0x355f6a35, 0x57f9ae57, 0xb9d069b9,
260 0x86911786, 0xc15899c1, 0x1d273a1d, 0x9eb9279e,
261 0xe138d9e1, 0xf813ebf8, 0x98b32b98, 0x11332211,
262 0x69bbd269, 0xd970a9d9, 0x8e89078e, 0x94a73394,
263 0x9bb62d9b, 0x1e223c1e, 0x87921587, 0xe920c9e9,
264 0xce4987ce, 0x55ffaa55, 0x28785028, 0xdf7aa5df,
265 0x8c8f038c, 0xa1f859a1, 0x89800989, 0x0d171a0d,
266 0xbfda65bf, 0xe631d7e6, 0x42c68442, 0x68b8d068,
267 0x41c38241, 0x99b02999, 0x2d775a2d, 0x0f111e0f,
268 0xb0cb7bb0, 0x54fca854, 0xbbd66dbb, 0x163a2c16,
269};
270static const uint32_t Te3[256] = {
271 0x6363a5c6, 0x7c7c84f8, 0x777799ee, 0x7b7b8df6,
272 0xf2f20dff, 0x6b6bbdd6, 0x6f6fb1de, 0xc5c55491,
273 0x30305060, 0x01010302, 0x6767a9ce, 0x2b2b7d56,
274 0xfefe19e7, 0xd7d762b5, 0xababe64d, 0x76769aec,
275 0xcaca458f, 0x82829d1f, 0xc9c94089, 0x7d7d87fa,
276 0xfafa15ef, 0x5959ebb2, 0x4747c98e, 0xf0f00bfb,
277 0xadadec41, 0xd4d467b3, 0xa2a2fd5f, 0xafafea45,
278 0x9c9cbf23, 0xa4a4f753, 0x727296e4, 0xc0c05b9b,
279 0xb7b7c275, 0xfdfd1ce1, 0x9393ae3d, 0x26266a4c,
280 0x36365a6c, 0x3f3f417e, 0xf7f702f5, 0xcccc4f83,
281 0x34345c68, 0xa5a5f451, 0xe5e534d1, 0xf1f108f9,
282 0x717193e2, 0xd8d873ab, 0x31315362, 0x15153f2a,
283 0x04040c08, 0xc7c75295, 0x23236546, 0xc3c35e9d,
284 0x18182830, 0x9696a137, 0x05050f0a, 0x9a9ab52f,
285 0x0707090e, 0x12123624, 0x80809b1b, 0xe2e23ddf,
286 0xebeb26cd, 0x2727694e, 0xb2b2cd7f, 0x75759fea,
287 0x09091b12, 0x83839e1d, 0x2c2c7458, 0x1a1a2e34,
288 0x1b1b2d36, 0x6e6eb2dc, 0x5a5aeeb4, 0xa0a0fb5b,
289 0x5252f6a4, 0x3b3b4d76, 0xd6d661b7, 0xb3b3ce7d,
290 0x29297b52, 0xe3e33edd, 0x2f2f715e, 0x84849713,
291 0x5353f5a6, 0xd1d168b9, 0x00000000, 0xeded2cc1,
292 0x20206040, 0xfcfc1fe3, 0xb1b1c879, 0x5b5bedb6,
293 0x6a6abed4, 0xcbcb468d, 0xbebed967, 0x39394b72,
294 0x4a4ade94, 0x4c4cd498, 0x5858e8b0, 0xcfcf4a85,
295 0xd0d06bbb, 0xefef2ac5, 0xaaaae54f, 0xfbfb16ed,
296 0x4343c586, 0x4d4dd79a, 0x33335566, 0x85859411,
297 0x4545cf8a, 0xf9f910e9, 0x02020604, 0x7f7f81fe,
298 0x5050f0a0, 0x3c3c4478, 0x9f9fba25, 0xa8a8e34b,
299 0x5151f3a2, 0xa3a3fe5d, 0x4040c080, 0x8f8f8a05,
300 0x9292ad3f, 0x9d9dbc21, 0x38384870, 0xf5f504f1,
301 0xbcbcdf63, 0xb6b6c177, 0xdada75af, 0x21216342,
302 0x10103020, 0xffff1ae5, 0xf3f30efd, 0xd2d26dbf,
303 0xcdcd4c81, 0x0c0c1418, 0x13133526, 0xecec2fc3,
304 0x5f5fe1be, 0x9797a235, 0x4444cc88, 0x1717392e,
305 0xc4c45793, 0xa7a7f255, 0x7e7e82fc, 0x3d3d477a,
306 0x6464acc8, 0x5d5de7ba, 0x19192b32, 0x737395e6,
307 0x6060a0c0, 0x81819819, 0x4f4fd19e, 0xdcdc7fa3,
308 0x22226644, 0x2a2a7e54, 0x9090ab3b, 0x8888830b,
309 0x4646ca8c, 0xeeee29c7, 0xb8b8d36b, 0x14143c28,
310 0xdede79a7, 0x5e5ee2bc, 0x0b0b1d16, 0xdbdb76ad,
311 0xe0e03bdb, 0x32325664, 0x3a3a4e74, 0x0a0a1e14,
312 0x4949db92, 0x06060a0c, 0x24246c48, 0x5c5ce4b8,
313 0xc2c25d9f, 0xd3d36ebd, 0xacacef43, 0x6262a6c4,
314 0x9191a839, 0x9595a431, 0xe4e437d3, 0x79798bf2,
315 0xe7e732d5, 0xc8c8438b, 0x3737596e, 0x6d6db7da,
316 0x8d8d8c01, 0xd5d564b1, 0x4e4ed29c, 0xa9a9e049,
317 0x6c6cb4d8, 0x5656faac, 0xf4f407f3, 0xeaea25cf,
318 0x6565afca, 0x7a7a8ef4, 0xaeaee947, 0x08081810,
319 0xbabad56f, 0x787888f0, 0x25256f4a, 0x2e2e725c,
320 0x1c1c2438, 0xa6a6f157, 0xb4b4c773, 0xc6c65197,
321 0xe8e823cb, 0xdddd7ca1, 0x74749ce8, 0x1f1f213e,
322 0x4b4bdd96, 0xbdbddc61, 0x8b8b860d, 0x8a8a850f,
323 0x707090e0, 0x3e3e427c, 0xb5b5c471, 0x6666aacc,
324 0x4848d890, 0x03030506, 0xf6f601f7, 0x0e0e121c,
325 0x6161a3c2, 0x35355f6a, 0x5757f9ae, 0xb9b9d069,
326 0x86869117, 0xc1c15899, 0x1d1d273a, 0x9e9eb927,
327 0xe1e138d9, 0xf8f813eb, 0x9898b32b, 0x11113322,
328 0x6969bbd2, 0xd9d970a9, 0x8e8e8907, 0x9494a733,
329 0x9b9bb62d, 0x1e1e223c, 0x87879215, 0xe9e920c9,
330 0xcece4987, 0x5555ffaa, 0x28287850, 0xdfdf7aa5,
331 0x8c8c8f03, 0xa1a1f859, 0x89898009, 0x0d0d171a,
332 0xbfbfda65, 0xe6e631d7, 0x4242c684, 0x6868b8d0,
333 0x4141c382, 0x9999b029, 0x2d2d775a, 0x0f0f111e,
334 0xb0b0cb7b, 0x5454fca8, 0xbbbbd66d, 0x16163a2c,
335};
336static const uint32_t Te4[256] = {
337 0x63636363, 0x7c7c7c7c, 0x77777777, 0x7b7b7b7b,
338 0xf2f2f2f2, 0x6b6b6b6b, 0x6f6f6f6f, 0xc5c5c5c5,
339 0x30303030, 0x01010101, 0x67676767, 0x2b2b2b2b,
340 0xfefefefe, 0xd7d7d7d7, 0xabababab, 0x76767676,
341 0xcacacaca, 0x82828282, 0xc9c9c9c9, 0x7d7d7d7d,
342 0xfafafafa, 0x59595959, 0x47474747, 0xf0f0f0f0,
343 0xadadadad, 0xd4d4d4d4, 0xa2a2a2a2, 0xafafafaf,
344 0x9c9c9c9c, 0xa4a4a4a4, 0x72727272, 0xc0c0c0c0,
345 0xb7b7b7b7, 0xfdfdfdfd, 0x93939393, 0x26262626,
346 0x36363636, 0x3f3f3f3f, 0xf7f7f7f7, 0xcccccccc,
347 0x34343434, 0xa5a5a5a5, 0xe5e5e5e5, 0xf1f1f1f1,
348 0x71717171, 0xd8d8d8d8, 0x31313131, 0x15151515,
349 0x04040404, 0xc7c7c7c7, 0x23232323, 0xc3c3c3c3,
350 0x18181818, 0x96969696, 0x05050505, 0x9a9a9a9a,
351 0x07070707, 0x12121212, 0x80808080, 0xe2e2e2e2,
352 0xebebebeb, 0x27272727, 0xb2b2b2b2, 0x75757575,
353 0x09090909, 0x83838383, 0x2c2c2c2c, 0x1a1a1a1a,
354 0x1b1b1b1b, 0x6e6e6e6e, 0x5a5a5a5a, 0xa0a0a0a0,
355 0x52525252, 0x3b3b3b3b, 0xd6d6d6d6, 0xb3b3b3b3,
356 0x29292929, 0xe3e3e3e3, 0x2f2f2f2f, 0x84848484,
357 0x53535353, 0xd1d1d1d1, 0x00000000, 0xedededed,
358 0x20202020, 0xfcfcfcfc, 0xb1b1b1b1, 0x5b5b5b5b,
359 0x6a6a6a6a, 0xcbcbcbcb, 0xbebebebe, 0x39393939,
360 0x4a4a4a4a, 0x4c4c4c4c, 0x58585858, 0xcfcfcfcf,
361 0xd0d0d0d0, 0xefefefef, 0xaaaaaaaa, 0xfbfbfbfb,
362 0x43434343, 0x4d4d4d4d, 0x33333333, 0x85858585,
363 0x45454545, 0xf9f9f9f9, 0x02020202, 0x7f7f7f7f,
364 0x50505050, 0x3c3c3c3c, 0x9f9f9f9f, 0xa8a8a8a8,
365 0x51515151, 0xa3a3a3a3, 0x40404040, 0x8f8f8f8f,
366 0x92929292, 0x9d9d9d9d, 0x38383838, 0xf5f5f5f5,
367 0xbcbcbcbc, 0xb6b6b6b6, 0xdadadada, 0x21212121,
368 0x10101010, 0xffffffff, 0xf3f3f3f3, 0xd2d2d2d2,
369 0xcdcdcdcd, 0x0c0c0c0c, 0x13131313, 0xecececec,
370 0x5f5f5f5f, 0x97979797, 0x44444444, 0x17171717,
371 0xc4c4c4c4, 0xa7a7a7a7, 0x7e7e7e7e, 0x3d3d3d3d,
372 0x64646464, 0x5d5d5d5d, 0x19191919, 0x73737373,
373 0x60606060, 0x81818181, 0x4f4f4f4f, 0xdcdcdcdc,
374 0x22222222, 0x2a2a2a2a, 0x90909090, 0x88888888,
375 0x46464646, 0xeeeeeeee, 0xb8b8b8b8, 0x14141414,
376 0xdededede, 0x5e5e5e5e, 0x0b0b0b0b, 0xdbdbdbdb,
377 0xe0e0e0e0, 0x32323232, 0x3a3a3a3a, 0x0a0a0a0a,
378 0x49494949, 0x06060606, 0x24242424, 0x5c5c5c5c,
379 0xc2c2c2c2, 0xd3d3d3d3, 0xacacacac, 0x62626262,
380 0x91919191, 0x95959595, 0xe4e4e4e4, 0x79797979,
381 0xe7e7e7e7, 0xc8c8c8c8, 0x37373737, 0x6d6d6d6d,
382 0x8d8d8d8d, 0xd5d5d5d5, 0x4e4e4e4e, 0xa9a9a9a9,
383 0x6c6c6c6c, 0x56565656, 0xf4f4f4f4, 0xeaeaeaea,
384 0x65656565, 0x7a7a7a7a, 0xaeaeaeae, 0x08080808,
385 0xbabababa, 0x78787878, 0x25252525, 0x2e2e2e2e,
386 0x1c1c1c1c, 0xa6a6a6a6, 0xb4b4b4b4, 0xc6c6c6c6,
387 0xe8e8e8e8, 0xdddddddd, 0x74747474, 0x1f1f1f1f,
388 0x4b4b4b4b, 0xbdbdbdbd, 0x8b8b8b8b, 0x8a8a8a8a,
389 0x70707070, 0x3e3e3e3e, 0xb5b5b5b5, 0x66666666,
390 0x48484848, 0x03030303, 0xf6f6f6f6, 0x0e0e0e0e,
391 0x61616161, 0x35353535, 0x57575757, 0xb9b9b9b9,
392 0x86868686, 0xc1c1c1c1, 0x1d1d1d1d, 0x9e9e9e9e,
393 0xe1e1e1e1, 0xf8f8f8f8, 0x98989898, 0x11111111,
394 0x69696969, 0xd9d9d9d9, 0x8e8e8e8e, 0x94949494,
395 0x9b9b9b9b, 0x1e1e1e1e, 0x87878787, 0xe9e9e9e9,
396 0xcececece, 0x55555555, 0x28282828, 0xdfdfdfdf,
397 0x8c8c8c8c, 0xa1a1a1a1, 0x89898989, 0x0d0d0d0d,
398 0xbfbfbfbf, 0xe6e6e6e6, 0x42424242, 0x68686868,
399 0x41414141, 0x99999999, 0x2d2d2d2d, 0x0f0f0f0f,
400 0xb0b0b0b0, 0x54545454, 0xbbbbbbbb, 0x16161616,
401};
402static const uint32_t Td0[256] = {
403 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96,
404 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393,
405 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25,
406 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f,
407 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1,
408 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6,
409 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da,
410 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844,
411 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd,
412 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4,
413 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45,
414 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94,
415 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7,
416 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a,
417 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5,
418 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c,
419 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1,
420 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a,
421 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75,
422 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051,
423 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46,
424 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff,
425 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77,
426 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb,
427 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000,
428 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e,
429 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927,
430 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a,
431 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e,
432 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16,
433 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d,
434 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8,
435 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd,
436 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34,
437 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163,
438 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120,
439 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d,
440 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0,
441 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422,
442 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef,
443 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36,
444 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4,
445 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662,
446 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5,
447 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3,
448 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b,
449 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8,
450 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6,
451 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6,
452 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0,
453 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815,
454 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f,
455 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df,
456 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f,
457 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e,
458 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713,
459 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89,
460 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c,
461 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf,
462 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86,
463 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f,
464 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541,
465 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190,
466 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742,
467};
468static const uint32_t Td1[256] = {
469 0x5051f4a7, 0x537e4165, 0xc31a17a4, 0x963a275e,
470 0xcb3bab6b, 0xf11f9d45, 0xabacfa58, 0x934be303,
471 0x552030fa, 0xf6ad766d, 0x9188cc76, 0x25f5024c,
472 0xfc4fe5d7, 0xd7c52acb, 0x80263544, 0x8fb562a3,
473 0x49deb15a, 0x6725ba1b, 0x9845ea0e, 0xe15dfec0,
474 0x02c32f75, 0x12814cf0, 0xa38d4697, 0xc66bd3f9,
475 0xe7038f5f, 0x9515929c, 0xebbf6d7a, 0xda955259,
476 0x2dd4be83, 0xd3587421, 0x2949e069, 0x448ec9c8,
477 0x6a75c289, 0x78f48e79, 0x6b99583e, 0xdd27b971,
478 0xb6bee14f, 0x17f088ad, 0x66c920ac, 0xb47dce3a,
479 0x1863df4a, 0x82e51a31, 0x60975133, 0x4562537f,
480 0xe0b16477, 0x84bb6bae, 0x1cfe81a0, 0x94f9082b,
481 0x58704868, 0x198f45fd, 0x8794de6c, 0xb7527bf8,
482 0x23ab73d3, 0xe2724b02, 0x57e31f8f, 0x2a6655ab,
483 0x07b2eb28, 0x032fb5c2, 0x9a86c57b, 0xa5d33708,
484 0xf2302887, 0xb223bfa5, 0xba02036a, 0x5ced1682,
485 0x2b8acf1c, 0x92a779b4, 0xf0f307f2, 0xa14e69e2,
486 0xcd65daf4, 0xd50605be, 0x1fd13462, 0x8ac4a6fe,
487 0x9d342e53, 0xa0a2f355, 0x32058ae1, 0x75a4f6eb,
488 0x390b83ec, 0xaa4060ef, 0x065e719f, 0x51bd6e10,
489 0xf93e218a, 0x3d96dd06, 0xaedd3e05, 0x464de6bd,
490 0xb591548d, 0x0571c45d, 0x6f0406d4, 0xff605015,
491 0x241998fb, 0x97d6bde9, 0xcc894043, 0x7767d99e,
492 0xbdb0e842, 0x8807898b, 0x38e7195b, 0xdb79c8ee,
493 0x47a17c0a, 0xe97c420f, 0xc9f8841e, 0x00000000,
494 0x83098086, 0x48322bed, 0xac1e1170, 0x4e6c5a72,
495 0xfbfd0eff, 0x560f8538, 0x1e3daed5, 0x27362d39,
496 0x640a0fd9, 0x21685ca6, 0xd19b5b54, 0x3a24362e,
497 0xb10c0a67, 0x0f9357e7, 0xd2b4ee96, 0x9e1b9b91,
498 0x4f80c0c5, 0xa261dc20, 0x695a774b, 0x161c121a,
499 0x0ae293ba, 0xe5c0a02a, 0x433c22e0, 0x1d121b17,
500 0x0b0e090d, 0xadf28bc7, 0xb92db6a8, 0xc8141ea9,
501 0x8557f119, 0x4caf7507, 0xbbee99dd, 0xfda37f60,
502 0x9ff70126, 0xbc5c72f5, 0xc544663b, 0x345bfb7e,
503 0x768b4329, 0xdccb23c6, 0x68b6edfc, 0x63b8e4f1,
504 0xcad731dc, 0x10426385, 0x40139722, 0x2084c611,
505 0x7d854a24, 0xf8d2bb3d, 0x11aef932, 0x6dc729a1,
506 0x4b1d9e2f, 0xf3dcb230, 0xec0d8652, 0xd077c1e3,
507 0x6c2bb316, 0x99a970b9, 0xfa119448, 0x2247e964,
508 0xc4a8fc8c, 0x1aa0f03f, 0xd8567d2c, 0xef223390,
509 0xc787494e, 0xc1d938d1, 0xfe8ccaa2, 0x3698d40b,
510 0xcfa6f581, 0x28a57ade, 0x26dab78e, 0xa43fadbf,
511 0xe42c3a9d, 0x0d507892, 0x9b6a5fcc, 0x62547e46,
512 0xc2f68d13, 0xe890d8b8, 0x5e2e39f7, 0xf582c3af,
513 0xbe9f5d80, 0x7c69d093, 0xa96fd52d, 0xb3cf2512,
514 0x3bc8ac99, 0xa710187d, 0x6ee89c63, 0x7bdb3bbb,
515 0x09cd2678, 0xf46e5918, 0x01ec9ab7, 0xa8834f9a,
516 0x65e6956e, 0x7eaaffe6, 0x0821bccf, 0xe6ef15e8,
517 0xd9bae79b, 0xce4a6f36, 0xd4ea9f09, 0xd629b07c,
518 0xaf31a4b2, 0x312a3f23, 0x30c6a594, 0xc035a266,
519 0x37744ebc, 0xa6fc82ca, 0xb0e090d0, 0x1533a7d8,
520 0x4af10498, 0xf741ecda, 0x0e7fcd50, 0x2f1791f6,
521 0x8d764dd6, 0x4d43efb0, 0x54ccaa4d, 0xdfe49604,
522 0xe39ed1b5, 0x1b4c6a88, 0xb8c12c1f, 0x7f466551,
523 0x049d5eea, 0x5d018c35, 0x73fa8774, 0x2efb0b41,
524 0x5ab3671d, 0x5292dbd2, 0x33e91056, 0x136dd647,
525 0x8c9ad761, 0x7a37a10c, 0x8e59f814, 0x89eb133c,
526 0xeecea927, 0x35b761c9, 0xede11ce5, 0x3c7a47b1,
527 0x599cd2df, 0x3f55f273, 0x791814ce, 0xbf73c737,
528 0xea53f7cd, 0x5b5ffdaa, 0x14df3d6f, 0x867844db,
529 0x81caaff3, 0x3eb968c4, 0x2c382434, 0x5fc2a340,
530 0x72161dc3, 0x0cbce225, 0x8b283c49, 0x41ff0d95,
531 0x7139a801, 0xde080cb3, 0x9cd8b4e4, 0x906456c1,
532 0x617bcb84, 0x70d532b6, 0x74486c5c, 0x42d0b857,
533};
534static const uint32_t Td2[256] = {
535 0xa75051f4, 0x65537e41, 0xa4c31a17, 0x5e963a27,
536 0x6bcb3bab, 0x45f11f9d, 0x58abacfa, 0x03934be3,
537 0xfa552030, 0x6df6ad76, 0x769188cc, 0x4c25f502,
538 0xd7fc4fe5, 0xcbd7c52a, 0x44802635, 0xa38fb562,
539 0x5a49deb1, 0x1b6725ba, 0x0e9845ea, 0xc0e15dfe,
540 0x7502c32f, 0xf012814c, 0x97a38d46, 0xf9c66bd3,
541 0x5fe7038f, 0x9c951592, 0x7aebbf6d, 0x59da9552,
542 0x832dd4be, 0x21d35874, 0x692949e0, 0xc8448ec9,
543 0x896a75c2, 0x7978f48e, 0x3e6b9958, 0x71dd27b9,
544 0x4fb6bee1, 0xad17f088, 0xac66c920, 0x3ab47dce,
545 0x4a1863df, 0x3182e51a, 0x33609751, 0x7f456253,
546 0x77e0b164, 0xae84bb6b, 0xa01cfe81, 0x2b94f908,
547 0x68587048, 0xfd198f45, 0x6c8794de, 0xf8b7527b,
548 0xd323ab73, 0x02e2724b, 0x8f57e31f, 0xab2a6655,
549 0x2807b2eb, 0xc2032fb5, 0x7b9a86c5, 0x08a5d337,
550 0x87f23028, 0xa5b223bf, 0x6aba0203, 0x825ced16,
551 0x1c2b8acf, 0xb492a779, 0xf2f0f307, 0xe2a14e69,
552 0xf4cd65da, 0xbed50605, 0x621fd134, 0xfe8ac4a6,
553 0x539d342e, 0x55a0a2f3, 0xe132058a, 0xeb75a4f6,
554 0xec390b83, 0xefaa4060, 0x9f065e71, 0x1051bd6e,
555 0x8af93e21, 0x063d96dd, 0x05aedd3e, 0xbd464de6,
556 0x8db59154, 0x5d0571c4, 0xd46f0406, 0x15ff6050,
557 0xfb241998, 0xe997d6bd, 0x43cc8940, 0x9e7767d9,
558 0x42bdb0e8, 0x8b880789, 0x5b38e719, 0xeedb79c8,
559 0x0a47a17c, 0x0fe97c42, 0x1ec9f884, 0x00000000,
560 0x86830980, 0xed48322b, 0x70ac1e11, 0x724e6c5a,
561 0xfffbfd0e, 0x38560f85, 0xd51e3dae, 0x3927362d,
562 0xd9640a0f, 0xa621685c, 0x54d19b5b, 0x2e3a2436,
563 0x67b10c0a, 0xe70f9357, 0x96d2b4ee, 0x919e1b9b,
564 0xc54f80c0, 0x20a261dc, 0x4b695a77, 0x1a161c12,
565 0xba0ae293, 0x2ae5c0a0, 0xe0433c22, 0x171d121b,
566 0x0d0b0e09, 0xc7adf28b, 0xa8b92db6, 0xa9c8141e,
567 0x198557f1, 0x074caf75, 0xddbbee99, 0x60fda37f,
568 0x269ff701, 0xf5bc5c72, 0x3bc54466, 0x7e345bfb,
569 0x29768b43, 0xc6dccb23, 0xfc68b6ed, 0xf163b8e4,
570 0xdccad731, 0x85104263, 0x22401397, 0x112084c6,
571 0x247d854a, 0x3df8d2bb, 0x3211aef9, 0xa16dc729,
572 0x2f4b1d9e, 0x30f3dcb2, 0x52ec0d86, 0xe3d077c1,
573 0x166c2bb3, 0xb999a970, 0x48fa1194, 0x642247e9,
574 0x8cc4a8fc, 0x3f1aa0f0, 0x2cd8567d, 0x90ef2233,
575 0x4ec78749, 0xd1c1d938, 0xa2fe8cca, 0x0b3698d4,
576 0x81cfa6f5, 0xde28a57a, 0x8e26dab7, 0xbfa43fad,
577 0x9de42c3a, 0x920d5078, 0xcc9b6a5f, 0x4662547e,
578 0x13c2f68d, 0xb8e890d8, 0xf75e2e39, 0xaff582c3,
579 0x80be9f5d, 0x937c69d0, 0x2da96fd5, 0x12b3cf25,
580 0x993bc8ac, 0x7da71018, 0x636ee89c, 0xbb7bdb3b,
581 0x7809cd26, 0x18f46e59, 0xb701ec9a, 0x9aa8834f,
582 0x6e65e695, 0xe67eaaff, 0xcf0821bc, 0xe8e6ef15,
583 0x9bd9bae7, 0x36ce4a6f, 0x09d4ea9f, 0x7cd629b0,
584 0xb2af31a4, 0x23312a3f, 0x9430c6a5, 0x66c035a2,
585 0xbc37744e, 0xcaa6fc82, 0xd0b0e090, 0xd81533a7,
586 0x984af104, 0xdaf741ec, 0x500e7fcd, 0xf62f1791,
587 0xd68d764d, 0xb04d43ef, 0x4d54ccaa, 0x04dfe496,
588 0xb5e39ed1, 0x881b4c6a, 0x1fb8c12c, 0x517f4665,
589 0xea049d5e, 0x355d018c, 0x7473fa87, 0x412efb0b,
590 0x1d5ab367, 0xd25292db, 0x5633e910, 0x47136dd6,
591 0x618c9ad7, 0x0c7a37a1, 0x148e59f8, 0x3c89eb13,
592 0x27eecea9, 0xc935b761, 0xe5ede11c, 0xb13c7a47,
593 0xdf599cd2, 0x733f55f2, 0xce791814, 0x37bf73c7,
594 0xcdea53f7, 0xaa5b5ffd, 0x6f14df3d, 0xdb867844,
595 0xf381caaf, 0xc43eb968, 0x342c3824, 0x405fc2a3,
596 0xc372161d, 0x250cbce2, 0x498b283c, 0x9541ff0d,
597 0x017139a8, 0xb3de080c, 0xe49cd8b4, 0xc1906456,
598 0x84617bcb, 0xb670d532, 0x5c74486c, 0x5742d0b8,
599};
600static const uint32_t Td3[256] = {
601 0xf4a75051, 0x4165537e, 0x17a4c31a, 0x275e963a,
602 0xab6bcb3b, 0x9d45f11f, 0xfa58abac, 0xe303934b,
603 0x30fa5520, 0x766df6ad, 0xcc769188, 0x024c25f5,
604 0xe5d7fc4f, 0x2acbd7c5, 0x35448026, 0x62a38fb5,
605 0xb15a49de, 0xba1b6725, 0xea0e9845, 0xfec0e15d,
606 0x2f7502c3, 0x4cf01281, 0x4697a38d, 0xd3f9c66b,
607 0x8f5fe703, 0x929c9515, 0x6d7aebbf, 0x5259da95,
608 0xbe832dd4, 0x7421d358, 0xe0692949, 0xc9c8448e,
609 0xc2896a75, 0x8e7978f4, 0x583e6b99, 0xb971dd27,
610 0xe14fb6be, 0x88ad17f0, 0x20ac66c9, 0xce3ab47d,
611 0xdf4a1863, 0x1a3182e5, 0x51336097, 0x537f4562,
612 0x6477e0b1, 0x6bae84bb, 0x81a01cfe, 0x082b94f9,
613 0x48685870, 0x45fd198f, 0xde6c8794, 0x7bf8b752,
614 0x73d323ab, 0x4b02e272, 0x1f8f57e3, 0x55ab2a66,
615 0xeb2807b2, 0xb5c2032f, 0xc57b9a86, 0x3708a5d3,
616 0x2887f230, 0xbfa5b223, 0x036aba02, 0x16825ced,
617 0xcf1c2b8a, 0x79b492a7, 0x07f2f0f3, 0x69e2a14e,
618 0xdaf4cd65, 0x05bed506, 0x34621fd1, 0xa6fe8ac4,
619 0x2e539d34, 0xf355a0a2, 0x8ae13205, 0xf6eb75a4,
620 0x83ec390b, 0x60efaa40, 0x719f065e, 0x6e1051bd,
621 0x218af93e, 0xdd063d96, 0x3e05aedd, 0xe6bd464d,
622 0x548db591, 0xc45d0571, 0x06d46f04, 0x5015ff60,
623 0x98fb2419, 0xbde997d6, 0x4043cc89, 0xd99e7767,
624 0xe842bdb0, 0x898b8807, 0x195b38e7, 0xc8eedb79,
625 0x7c0a47a1, 0x420fe97c, 0x841ec9f8, 0x00000000,
626 0x80868309, 0x2bed4832, 0x1170ac1e, 0x5a724e6c,
627 0x0efffbfd, 0x8538560f, 0xaed51e3d, 0x2d392736,
628 0x0fd9640a, 0x5ca62168, 0x5b54d19b, 0x362e3a24,
629 0x0a67b10c, 0x57e70f93, 0xee96d2b4, 0x9b919e1b,
630 0xc0c54f80, 0xdc20a261, 0x774b695a, 0x121a161c,
631 0x93ba0ae2, 0xa02ae5c0, 0x22e0433c, 0x1b171d12,
632 0x090d0b0e, 0x8bc7adf2, 0xb6a8b92d, 0x1ea9c814,
633 0xf1198557, 0x75074caf, 0x99ddbbee, 0x7f60fda3,
634 0x01269ff7, 0x72f5bc5c, 0x663bc544, 0xfb7e345b,
635 0x4329768b, 0x23c6dccb, 0xedfc68b6, 0xe4f163b8,
636 0x31dccad7, 0x63851042, 0x97224013, 0xc6112084,
637 0x4a247d85, 0xbb3df8d2, 0xf93211ae, 0x29a16dc7,
638 0x9e2f4b1d, 0xb230f3dc, 0x8652ec0d, 0xc1e3d077,
639 0xb3166c2b, 0x70b999a9, 0x9448fa11, 0xe9642247,
640 0xfc8cc4a8, 0xf03f1aa0, 0x7d2cd856, 0x3390ef22,
641 0x494ec787, 0x38d1c1d9, 0xcaa2fe8c, 0xd40b3698,
642 0xf581cfa6, 0x7ade28a5, 0xb78e26da, 0xadbfa43f,
643 0x3a9de42c, 0x78920d50, 0x5fcc9b6a, 0x7e466254,
644 0x8d13c2f6, 0xd8b8e890, 0x39f75e2e, 0xc3aff582,
645 0x5d80be9f, 0xd0937c69, 0xd52da96f, 0x2512b3cf,
646 0xac993bc8, 0x187da710, 0x9c636ee8, 0x3bbb7bdb,
647 0x267809cd, 0x5918f46e, 0x9ab701ec, 0x4f9aa883,
648 0x956e65e6, 0xffe67eaa, 0xbccf0821, 0x15e8e6ef,
649 0xe79bd9ba, 0x6f36ce4a, 0x9f09d4ea, 0xb07cd629,
650 0xa4b2af31, 0x3f23312a, 0xa59430c6, 0xa266c035,
651 0x4ebc3774, 0x82caa6fc, 0x90d0b0e0, 0xa7d81533,
652 0x04984af1, 0xecdaf741, 0xcd500e7f, 0x91f62f17,
653 0x4dd68d76, 0xefb04d43, 0xaa4d54cc, 0x9604dfe4,
654 0xd1b5e39e, 0x6a881b4c, 0x2c1fb8c1, 0x65517f46,
655 0x5eea049d, 0x8c355d01, 0x877473fa, 0x0b412efb,
656 0x671d5ab3, 0xdbd25292, 0x105633e9, 0xd647136d,
657 0xd7618c9a, 0xa10c7a37, 0xf8148e59, 0x133c89eb,
658 0xa927eece, 0x61c935b7, 0x1ce5ede1, 0x47b13c7a,
659 0xd2df599c, 0xf2733f55, 0x14ce7918, 0xc737bf73,
660 0xf7cdea53, 0xfdaa5b5f, 0x3d6f14df, 0x44db8678,
661 0xaff381ca, 0x68c43eb9, 0x24342c38, 0xa3405fc2,
662 0x1dc37216, 0xe2250cbc, 0x3c498b28, 0x0d9541ff,
663 0xa8017139, 0x0cb3de08, 0xb4e49cd8, 0x56c19064,
664 0xcb84617b, 0x32b670d5, 0x6c5c7448, 0xb85742d0,
665};
666static const uint32_t Td4[256] = {
667 0x52525252, 0x09090909, 0x6a6a6a6a, 0xd5d5d5d5,
668 0x30303030, 0x36363636, 0xa5a5a5a5, 0x38383838,
669 0xbfbfbfbf, 0x40404040, 0xa3a3a3a3, 0x9e9e9e9e,
670 0x81818181, 0xf3f3f3f3, 0xd7d7d7d7, 0xfbfbfbfb,
671 0x7c7c7c7c, 0xe3e3e3e3, 0x39393939, 0x82828282,
672 0x9b9b9b9b, 0x2f2f2f2f, 0xffffffff, 0x87878787,
673 0x34343434, 0x8e8e8e8e, 0x43434343, 0x44444444,
674 0xc4c4c4c4, 0xdededede, 0xe9e9e9e9, 0xcbcbcbcb,
675 0x54545454, 0x7b7b7b7b, 0x94949494, 0x32323232,
676 0xa6a6a6a6, 0xc2c2c2c2, 0x23232323, 0x3d3d3d3d,
677 0xeeeeeeee, 0x4c4c4c4c, 0x95959595, 0x0b0b0b0b,
678 0x42424242, 0xfafafafa, 0xc3c3c3c3, 0x4e4e4e4e,
679 0x08080808, 0x2e2e2e2e, 0xa1a1a1a1, 0x66666666,
680 0x28282828, 0xd9d9d9d9, 0x24242424, 0xb2b2b2b2,
681 0x76767676, 0x5b5b5b5b, 0xa2a2a2a2, 0x49494949,
682 0x6d6d6d6d, 0x8b8b8b8b, 0xd1d1d1d1, 0x25252525,
683 0x72727272, 0xf8f8f8f8, 0xf6f6f6f6, 0x64646464,
684 0x86868686, 0x68686868, 0x98989898, 0x16161616,
685 0xd4d4d4d4, 0xa4a4a4a4, 0x5c5c5c5c, 0xcccccccc,
686 0x5d5d5d5d, 0x65656565, 0xb6b6b6b6, 0x92929292,
687 0x6c6c6c6c, 0x70707070, 0x48484848, 0x50505050,
688 0xfdfdfdfd, 0xedededed, 0xb9b9b9b9, 0xdadadada,
689 0x5e5e5e5e, 0x15151515, 0x46464646, 0x57575757,
690 0xa7a7a7a7, 0x8d8d8d8d, 0x9d9d9d9d, 0x84848484,
691 0x90909090, 0xd8d8d8d8, 0xabababab, 0x00000000,
692 0x8c8c8c8c, 0xbcbcbcbc, 0xd3d3d3d3, 0x0a0a0a0a,
693 0xf7f7f7f7, 0xe4e4e4e4, 0x58585858, 0x05050505,
694 0xb8b8b8b8, 0xb3b3b3b3, 0x45454545, 0x06060606,
695 0xd0d0d0d0, 0x2c2c2c2c, 0x1e1e1e1e, 0x8f8f8f8f,
696 0xcacacaca, 0x3f3f3f3f, 0x0f0f0f0f, 0x02020202,
697 0xc1c1c1c1, 0xafafafaf, 0xbdbdbdbd, 0x03030303,
698 0x01010101, 0x13131313, 0x8a8a8a8a, 0x6b6b6b6b,
699 0x3a3a3a3a, 0x91919191, 0x11111111, 0x41414141,
700 0x4f4f4f4f, 0x67676767, 0xdcdcdcdc, 0xeaeaeaea,
701 0x97979797, 0xf2f2f2f2, 0xcfcfcfcf, 0xcececece,
702 0xf0f0f0f0, 0xb4b4b4b4, 0xe6e6e6e6, 0x73737373,
703 0x96969696, 0xacacacac, 0x74747474, 0x22222222,
704 0xe7e7e7e7, 0xadadadad, 0x35353535, 0x85858585,
705 0xe2e2e2e2, 0xf9f9f9f9, 0x37373737, 0xe8e8e8e8,
706 0x1c1c1c1c, 0x75757575, 0xdfdfdfdf, 0x6e6e6e6e,
707 0x47474747, 0xf1f1f1f1, 0x1a1a1a1a, 0x71717171,
708 0x1d1d1d1d, 0x29292929, 0xc5c5c5c5, 0x89898989,
709 0x6f6f6f6f, 0xb7b7b7b7, 0x62626262, 0x0e0e0e0e,
710 0xaaaaaaaa, 0x18181818, 0xbebebebe, 0x1b1b1b1b,
711 0xfcfcfcfc, 0x56565656, 0x3e3e3e3e, 0x4b4b4b4b,
712 0xc6c6c6c6, 0xd2d2d2d2, 0x79797979, 0x20202020,
713 0x9a9a9a9a, 0xdbdbdbdb, 0xc0c0c0c0, 0xfefefefe,
714 0x78787878, 0xcdcdcdcd, 0x5a5a5a5a, 0xf4f4f4f4,
715 0x1f1f1f1f, 0xdddddddd, 0xa8a8a8a8, 0x33333333,
716 0x88888888, 0x07070707, 0xc7c7c7c7, 0x31313131,
717 0xb1b1b1b1, 0x12121212, 0x10101010, 0x59595959,
718 0x27272727, 0x80808080, 0xecececec, 0x5f5f5f5f,
719 0x60606060, 0x51515151, 0x7f7f7f7f, 0xa9a9a9a9,
720 0x19191919, 0xb5b5b5b5, 0x4a4a4a4a, 0x0d0d0d0d,
721 0x2d2d2d2d, 0xe5e5e5e5, 0x7a7a7a7a, 0x9f9f9f9f,
722 0x93939393, 0xc9c9c9c9, 0x9c9c9c9c, 0xefefefef,
723 0xa0a0a0a0, 0xe0e0e0e0, 0x3b3b3b3b, 0x4d4d4d4d,
724 0xaeaeaeae, 0x2a2a2a2a, 0xf5f5f5f5, 0xb0b0b0b0,
725 0xc8c8c8c8, 0xebebebeb, 0xbbbbbbbb, 0x3c3c3c3c,
726 0x83838383, 0x53535353, 0x99999999, 0x61616161,
727 0x17171717, 0x2b2b2b2b, 0x04040404, 0x7e7e7e7e,
728 0xbabababa, 0x77777777, 0xd6d6d6d6, 0x26262626,
729 0xe1e1e1e1, 0x69696969, 0x14141414, 0x63636363,
730 0x55555555, 0x21212121, 0x0c0c0c0c, 0x7d7d7d7d,
731};
732static const uint32_t rcon[] = {
733 0x01000000, 0x02000000, 0x04000000, 0x08000000,
734 0x10000000, 0x20000000, 0x40000000, 0x80000000,
735 0x1B000000, 0x36000000
736 /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
737};
738
739#define GETU32(pt) (((uint32_t)((pt)[0] & 0xFF) << 24) ^ \
740 ((uint32_t)((pt)[1] & 0xFF) << 16) ^ \
741 ((uint32_t)((pt)[2] & 0xFF) << 8) ^ \
742 ((uint32_t)((pt)[3] & 0xFF)))
743#define PUTU32(ct, st) { \
744 (ct)[0] = (char)((st) >> 24); \
745 (ct)[1] = (char)((st) >> 16); \
746 (ct)[2] = (char)((st) >> 8); \
747 (ct)[3] = (char)(st); }
748
749/**
750 * Expand the cipher key into the encryption key schedule.
751 *
752 * @return the number of rounds for the given cipher key size.
753 */
754int
755rijndaelKeySetupEnc (uint32_t rk[ /*4*(Nr + 1) */ ],
756 const char cipherKey[], size_t keyBits)
757{
758 size_t i = 0;
759 uint32_t temp;
760
761 rk[0] = GETU32 (cipherKey);
762 rk[1] = GETU32 (cipherKey + 4);
763 rk[2] = GETU32 (cipherKey + 8);
764 rk[3] = GETU32 (cipherKey + 12);
765 if (keyBits == 128)
766 {
767 for (;;)
768 {
769 temp = rk[3];
770 rk[4] = rk[0] ^
771 (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
772 (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
773 (Te4[(temp) & 0xff] & 0x0000ff00) ^
774 (Te4[(temp >> 24)] & 0x000000ff) ^ rcon[i];
775 rk[5] = rk[1] ^ rk[4];
776 rk[6] = rk[2] ^ rk[5];
777 rk[7] = rk[3] ^ rk[6];
778 if (++i == 10)
779 {
780 return 10;
781 }
782 rk += 4;
783 }
784 }
785 rk[4] = GETU32 (cipherKey + 16);
786 rk[5] = GETU32 (cipherKey + 20);
787 if (keyBits == 192)
788 {
789 for (;;)
790 {
791 temp = rk[5];
792 rk[6] = rk[0] ^
793 (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
794 (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
795 (Te4[(temp) & 0xff] & 0x0000ff00) ^
796 (Te4[(temp >> 24)] & 0x000000ff) ^ rcon[i];
797 rk[7] = rk[1] ^ rk[6];
798 rk[8] = rk[2] ^ rk[7];
799 rk[9] = rk[3] ^ rk[8];
800 if (++i == 8)
801 {
802 return 12;
803 }
804 rk[10] = rk[4] ^ rk[9];
805 rk[11] = rk[5] ^ rk[10];
806 rk += 6;
807 }
808 }
809 rk[6] = GETU32 (cipherKey + 24);
810 rk[7] = GETU32 (cipherKey + 28);
811 if (keyBits == 256)
812 {
813 for (;;)
814 {
815 temp = rk[7];
816 rk[8] = rk[0] ^
817 (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
818 (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
819 (Te4[(temp) & 0xff] & 0x0000ff00) ^
820 (Te4[(temp >> 24)] & 0x000000ff) ^ rcon[i];
821 rk[9] = rk[1] ^ rk[8];
822 rk[10] = rk[2] ^ rk[9];
823 rk[11] = rk[3] ^ rk[10];
824 if (++i == 7)
825 {
826 return 14;
827 }
828 temp = rk[11];
829 rk[12] = rk[4] ^
830 (Te4[(temp >> 24)] & 0xff000000) ^
831 (Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
832 (Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
833 (Te4[(temp) & 0xff] & 0x000000ff);
834 rk[13] = rk[5] ^ rk[12];
835 rk[14] = rk[6] ^ rk[13];
836 rk[15] = rk[7] ^ rk[14];
837
838 rk += 8;
839 }
840 }
841 return 0;
842}
843
844/**
845 * Expand the cipher key into the decryption key schedule.
846 *
847 * @return the number of rounds for the given cipher key size.
848 */
849int
850rijndaelKeySetupDec (uint32_t rk[ /*4*(Nr + 1) */ ],
851 const char cipherKey[], size_t keyBits)
852{
853 size_t Nr, i, j;
854 uint32_t temp;
855
856 /* expand the cipher key: */
857 Nr = rijndaelKeySetupEnc (rk, cipherKey, keyBits);
858 /* invert the order of the round keys: */
859 for (i = 0, j = 4 * Nr; i < j; i += 4, j -= 4)
860 {
861 temp = rk[i];
862 rk[i] = rk[j];
863 rk[j] = temp;
864 temp = rk[i + 1];
865 rk[i + 1] = rk[j + 1];
866 rk[j + 1] = temp;
867 temp = rk[i + 2];
868 rk[i + 2] = rk[j + 2];
869 rk[j + 2] = temp;
870 temp = rk[i + 3];
871 rk[i + 3] = rk[j + 3];
872 rk[j + 3] = temp;
873 }
874 /* apply the inverse MixColumn transform to all round keys but the
875 first and the last: */
876 for (i = 1; i < Nr; i++)
877 {
878 rk += 4;
879 rk[0] =
880 Td0[Te4[(rk[0] >> 24)] & 0xff] ^
881 Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
882 Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^
883 Td3[Te4[(rk[0]) & 0xff] & 0xff];
884 rk[1] =
885 Td0[Te4[(rk[1] >> 24)] & 0xff] ^
886 Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
887 Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^
888 Td3[Te4[(rk[1]) & 0xff] & 0xff];
889 rk[2] =
890 Td0[Te4[(rk[2] >> 24)] & 0xff] ^
891 Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
892 Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^
893 Td3[Te4[(rk[2]) & 0xff] & 0xff];
894 rk[3] =
895 Td0[Te4[(rk[3] >> 24)] & 0xff] ^
896 Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
897 Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^
898 Td3[Te4[(rk[3]) & 0xff] & 0xff];
899 }
900 return Nr;
901}
902
903void
904rijndaelEncrypt (const uint32_t rk[ /*4*(Nr + 1) */ ], size_t Nr,
905 const char pt[16], char ct[16])
906{
907 uint32_t s0, s1, s2, s3, t0, t1, t2, t3;
908 size_t r;
909
910 /*
911 * map byte array block to cipher state
912 * and add initial round key:
913 */
914 s0 = GETU32 (pt) ^ rk[0];
915 s1 = GETU32 (pt + 4) ^ rk[1];
916 s2 = GETU32 (pt + 8) ^ rk[2];
917 s3 = GETU32 (pt + 12) ^ rk[3];
918 /*
919 * Nr - 1 full rounds:
920 */
921 r = Nr >> 1;
922 for (;;)
923 {
924 t0 =
925 Te0[(s0 >> 24)] ^
926 Te1[(s1 >> 16) & 0xff] ^
927 Te2[(s2 >> 8) & 0xff] ^ Te3[(s3) & 0xff] ^ rk[4];
928 t1 =
929 Te0[(s1 >> 24)] ^
930 Te1[(s2 >> 16) & 0xff] ^
931 Te2[(s3 >> 8) & 0xff] ^ Te3[(s0) & 0xff] ^ rk[5];
932 t2 =
933 Te0[(s2 >> 24)] ^
934 Te1[(s3 >> 16) & 0xff] ^
935 Te2[(s0 >> 8) & 0xff] ^ Te3[(s1) & 0xff] ^ rk[6];
936 t3 =
937 Te0[(s3 >> 24)] ^
938 Te1[(s0 >> 16) & 0xff] ^
939 Te2[(s1 >> 8) & 0xff] ^ Te3[(s2) & 0xff] ^ rk[7];
940
941 rk += 8;
942 if (--r == 0)
943 {
944 break;
945 }
946
947 s0 =
948 Te0[(t0 >> 24)] ^
949 Te1[(t1 >> 16) & 0xff] ^
950 Te2[(t2 >> 8) & 0xff] ^ Te3[(t3) & 0xff] ^ rk[0];
951 s1 =
952 Te0[(t1 >> 24)] ^
953 Te1[(t2 >> 16) & 0xff] ^
954 Te2[(t3 >> 8) & 0xff] ^ Te3[(t0) & 0xff] ^ rk[1];
955 s2 =
956 Te0[(t2 >> 24)] ^
957 Te1[(t3 >> 16) & 0xff] ^
958 Te2[(t0 >> 8) & 0xff] ^ Te3[(t1) & 0xff] ^ rk[2];
959 s3 =
960 Te0[(t3 >> 24)] ^
961 Te1[(t0 >> 16) & 0xff] ^
962 Te2[(t1 >> 8) & 0xff] ^ Te3[(t2) & 0xff] ^ rk[3];
963 }
964 /*
965 * apply last round and
966 * map cipher state to byte array block:
967 */
968 s0 =
969 (Te4[(t0 >> 24)] & 0xff000000) ^
970 (Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
971 (Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
972 (Te4[(t3) & 0xff] & 0x000000ff) ^ rk[0];
973 PUTU32 (ct, s0);
974 s1 =
975 (Te4[(t1 >> 24)] & 0xff000000) ^
976 (Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
977 (Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
978 (Te4[(t0) & 0xff] & 0x000000ff) ^ rk[1];
979 PUTU32 (ct + 4, s1);
980 s2 =
981 (Te4[(t2 >> 24)] & 0xff000000) ^
982 (Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
983 (Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
984 (Te4[(t1) & 0xff] & 0x000000ff) ^ rk[2];
985 PUTU32 (ct + 8, s2);
986 s3 =
987 (Te4[(t3 >> 24)] & 0xff000000) ^
988 (Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
989 (Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
990 (Te4[(t2) & 0xff] & 0x000000ff) ^ rk[3];
991 PUTU32 (ct + 12, s3);
992}
993
994void
995rijndaelDecrypt (const uint32_t rk[ /*4*(Nr + 1) */ ], size_t Nr,
996 const char ct[16], char pt[16])
997{
998 uint32_t s0, s1, s2, s3, t0, t1, t2, t3;
999 size_t r;
1000
1001 /*
1002 * map byte array block to cipher state
1003 * and add initial round key:
1004 */
1005 s0 = GETU32 (ct) ^ rk[0];
1006 s1 = GETU32 (ct + 4) ^ rk[1];
1007 s2 = GETU32 (ct + 8) ^ rk[2];
1008 s3 = GETU32 (ct + 12) ^ rk[3];
1009 /*
1010 * Nr - 1 full rounds:
1011 */
1012 r = Nr >> 1;
1013 for (;;)
1014 {
1015 t0 =
1016 Td0[(s0 >> 24)] ^
1017 Td1[(s3 >> 16) & 0xff] ^
1018 Td2[(s2 >> 8) & 0xff] ^ Td3[(s1) & 0xff] ^ rk[4];
1019 t1 =
1020 Td0[(s1 >> 24)] ^
1021 Td1[(s0 >> 16) & 0xff] ^
1022 Td2[(s3 >> 8) & 0xff] ^ Td3[(s2) & 0xff] ^ rk[5];
1023 t2 =
1024 Td0[(s2 >> 24)] ^
1025 Td1[(s1 >> 16) & 0xff] ^
1026 Td2[(s0 >> 8) & 0xff] ^ Td3[(s3) & 0xff] ^ rk[6];
1027 t3 =
1028 Td0[(s3 >> 24)] ^
1029 Td1[(s2 >> 16) & 0xff] ^
1030 Td2[(s1 >> 8) & 0xff] ^ Td3[(s0) & 0xff] ^ rk[7];
1031
1032 rk += 8;
1033 if (--r == 0)
1034 {
1035 break;
1036 }
1037
1038 s0 =
1039 Td0[(t0 >> 24)] ^
1040 Td1[(t3 >> 16) & 0xff] ^
1041 Td2[(t2 >> 8) & 0xff] ^ Td3[(t1) & 0xff] ^ rk[0];
1042 s1 =
1043 Td0[(t1 >> 24)] ^
1044 Td1[(t0 >> 16) & 0xff] ^
1045 Td2[(t3 >> 8) & 0xff] ^ Td3[(t2) & 0xff] ^ rk[1];
1046 s2 =
1047 Td0[(t2 >> 24)] ^
1048 Td1[(t1 >> 16) & 0xff] ^
1049 Td2[(t0 >> 8) & 0xff] ^ Td3[(t3) & 0xff] ^ rk[2];
1050 s3 =
1051 Td0[(t3 >> 24)] ^
1052 Td1[(t2 >> 16) & 0xff] ^
1053 Td2[(t1 >> 8) & 0xff] ^ Td3[(t0) & 0xff] ^ rk[3];
1054 }
1055 /*
1056 * apply last round and
1057 * map cipher state to byte array block:
1058 */
1059 s0 =
1060 (Td4[(t0 >> 24)] & 0xff000000) ^
1061 (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
1062 (Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
1063 (Td4[(t1) & 0xff] & 0x000000ff) ^ rk[0];
1064 PUTU32 (pt, s0);
1065 s1 =
1066 (Td4[(t1 >> 24)] & 0xff000000) ^
1067 (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
1068 (Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
1069 (Td4[(t2) & 0xff] & 0x000000ff) ^ rk[1];
1070 PUTU32 (pt + 4, s1);
1071 s2 =
1072 (Td4[(t2 >> 24)] & 0xff000000) ^
1073 (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
1074 (Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
1075 (Td4[(t3) & 0xff] & 0x000000ff) ^ rk[2];
1076 PUTU32 (pt + 8, s2);
1077 s3 =
1078 (Td4[(t3 >> 24)] & 0xff000000) ^
1079 (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
1080 (Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
1081 (Td4[(t0) & 0xff] & 0x000000ff) ^ rk[3];
1082 PUTU32 (pt + 12, s3);
1083}
diff --git a/src/daemon/https/lgl/rijndael-alg-fst.h b/src/daemon/https/lgl/rijndael-alg-fst.h
new file mode 100644
index 00000000..88391023
--- /dev/null
+++ b/src/daemon/https/lgl/rijndael-alg-fst.h
@@ -0,0 +1,67 @@
1/* rijndael-alg-fst.h --- Rijndael cipher implementation.
2 * Copyright (C) 2005 Free Software Foundation, Inc.
3 *
4 * This file is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; either version 2.1, or (at your
7 * option) any later version.
8 *
9 * This file is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this file; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 */
20
21/* Adapted for gnulib by Simon Josefsson. */
22
23/**
24 * rijndael-alg-fst.h
25 *
26 * @version 3.0 (December 2000)
27 *
28 * Optimised ANSI C code for the Rijndael cipher (now AES)
29 *
30 * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
31 * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
32 * @author Paulo Barreto <paulo.barreto@terra.com.br>
33 *
34 * This code is hereby placed in the public domain.
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
37 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
38 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
40 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
41 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
42 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
45 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
46 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47 */
48#ifndef __RIJNDAEL_ALG_FST_H
49#define __RIJNDAEL_ALG_FST_H
50
51#include <stdint.h>
52#include <stddef.h>
53
54#define RIJNDAEL_MAXKC (256/32)
55#define RIJNDAEL_MAXKB (256/8)
56#define RIJNDAEL_MAXNR 14
57
58int rijndaelKeySetupEnc (uint32_t rk[ /*4*(Nr + 1) */ ],
59 const char cipherKey[], size_t keyBits);
60int rijndaelKeySetupDec (uint32_t rk[ /*4*(Nr + 1) */ ],
61 const char cipherKey[], size_t keyBits);
62void rijndaelEncrypt (const uint32_t rk[ /*4*(Nr + 1) */ ], size_t Nr,
63 const char pt[16], char ct[16]);
64void rijndaelDecrypt (const uint32_t rk[ /*4*(Nr + 1) */ ], size_t Nr,
65 const char ct[16], char pt[16]);
66
67#endif /* __RIJNDAEL_ALG_FST_H */
diff --git a/src/daemon/https/lgl/rijndael-api-fst.c b/src/daemon/https/lgl/rijndael-api-fst.c
new file mode 100644
index 00000000..35d920a9
--- /dev/null
+++ b/src/daemon/https/lgl/rijndael-api-fst.c
@@ -0,0 +1,517 @@
1/* rijndael-api-fst.c --- Rijndael cipher implementation.
2 * Copyright (C) 2005, 2006 Free Software Foundation, Inc.
3 *
4 * This file is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; either version 2.1, or (at your
7 * option) any later version.
8 *
9 * This file is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this file; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 */
20
21/* Adapted for gnulib by Simon Josefsson.
22 *
23 * Based on public domain "Optimised C code" retrieved from (SHA1
24 * 7c8e4b00d06685d1dbc6724a9e0d502353de339e):
25 * http://www.iaik.tu-graz.ac.at/research/krypto/AES/old/~rijmen/rijndael/rijndael-fst-3.0.zip
26 */
27
28#include <config.h>
29
30/**
31 * rijndael-api-fst.c
32 *
33 * @version 2.9 (December 2000)
34 *
35 * Optimised ANSI C code for the Rijndael cipher (now AES)
36 *
37 * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
38 * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
39 * @author Paulo Barreto <paulo.barreto@terra.com.br>
40 *
41 * This code is hereby placed in the public domain.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
44 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
45 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
47 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
48 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
49 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
50 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
51 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
52 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
53 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 *
55 * Acknowledgements:
56 *
57 * We are deeply indebted to the following people for their bug reports,
58 * fixes, and improvement suggestions to this implementation. Though we
59 * tried to list all contributions, we apologise in advance for any
60 * missing reference.
61 *
62 * Andrew Bales <Andrew.Bales@Honeywell.com>
63 * Markus Friedl <markus.friedl@informatik.uni-erlangen.de>
64 * John Skodon <skodonj@webquill.com>
65 */
66
67#include "rijndael-alg-fst.h"
68#include "rijndael-api-fst.h"
69
70#include <assert.h>
71#include <stdlib.h>
72#include <string.h>
73
74rijndael_rc
75rijndaelMakeKey (rijndaelKeyInstance * key, rijndael_direction direction,
76 size_t keyLen, const char *keyMaterial)
77{
78 size_t i;
79 char *keyMat;
80 char cipherKey[RIJNDAEL_MAXKB];
81
82 if (key == NULL)
83 {
84 return RIJNDAEL_BAD_KEY_INSTANCE;
85 }
86
87 if ((direction == RIJNDAEL_DIR_ENCRYPT)
88 || (direction == RIJNDAEL_DIR_DECRYPT))
89 {
90 key->direction = direction;
91 }
92 else
93 {
94 return RIJNDAEL_BAD_KEY_DIR;
95 }
96
97 if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256))
98 {
99 key->keyLen = keyLen;
100 }
101 else
102 {
103 return RIJNDAEL_BAD_KEY_MAT;
104 }
105
106 if (keyMaterial != NULL)
107 {
108 strncpy (key->keyMaterial, keyMaterial, keyLen / 4);
109 }
110
111 /* initialize key schedule: */
112 keyMat = key->keyMaterial;
113 for (i = 0; i < key->keyLen / 8; i++)
114 {
115 char t, v;
116
117 t = *keyMat++;
118 if ((t >= '0') && (t <= '9'))
119 v = (t - '0') << 4;
120 else if ((t >= 'a') && (t <= 'f'))
121 v = (t - 'a' + 10) << 4;
122 else if ((t >= 'A') && (t <= 'F'))
123 v = (t - 'A' + 10) << 4;
124 else
125 return RIJNDAEL_BAD_KEY_MAT;
126
127 t = *keyMat++;
128 if ((t >= '0') && (t <= '9'))
129 v ^= (t - '0');
130 else if ((t >= 'a') && (t <= 'f'))
131 v ^= (t - 'a' + 10);
132 else if ((t >= 'A') && (t <= 'F'))
133 v ^= (t - 'A' + 10);
134 else
135 return RIJNDAEL_BAD_KEY_MAT;
136
137 cipherKey[i] = v;
138 }
139 if (direction == RIJNDAEL_DIR_ENCRYPT)
140 {
141 key->Nr = rijndaelKeySetupEnc (key->rk, cipherKey, keyLen);
142 }
143 else
144 {
145 key->Nr = rijndaelKeySetupDec (key->rk, cipherKey, keyLen);
146 }
147 rijndaelKeySetupEnc (key->ek, cipherKey, keyLen);
148 return 0;
149}
150
151rijndael_rc
152rijndaelCipherInit (rijndaelCipherInstance * cipher, rijndael_mode mode,
153 const char *IV)
154{
155 if ((mode == RIJNDAEL_MODE_ECB) || (mode == RIJNDAEL_MODE_CBC)
156 || (mode == RIJNDAEL_MODE_CFB1))
157 {
158 cipher->mode = mode;
159 }
160 else
161 {
162 return RIJNDAEL_BAD_CIPHER_MODE;
163 }
164 if (IV != NULL)
165 {
166 int i;
167 for (i = 0; i < RIJNDAEL_MAX_IV_SIZE; i++)
168 {
169 int t, j;
170
171 t = IV[2 * i];
172 if ((t >= '0') && (t <= '9'))
173 j = (t - '0') << 4;
174 else if ((t >= 'a') && (t <= 'f'))
175 j = (t - 'a' + 10) << 4;
176 else if ((t >= 'A') && (t <= 'F'))
177 j = (t - 'A' + 10) << 4;
178 else
179 return RIJNDAEL_BAD_CIPHER_INSTANCE;
180
181 t = IV[2 * i + 1];
182 if ((t >= '0') && (t <= '9'))
183 j ^= (t - '0');
184 else if ((t >= 'a') && (t <= 'f'))
185 j ^= (t - 'a' + 10);
186 else if ((t >= 'A') && (t <= 'F'))
187 j ^= (t - 'A' + 10);
188 else
189 return RIJNDAEL_BAD_CIPHER_INSTANCE;
190
191 cipher->IV[i] = (uint8_t) j;
192 }
193 }
194 else
195 {
196 memset (cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE);
197 }
198 return 0;
199}
200
201int
202rijndaelBlockEncrypt (rijndaelCipherInstance * cipher,
203 const rijndaelKeyInstance * key,
204 const char *input, size_t inputLen, char *outBuffer)
205{
206 size_t i, k, t, numBlocks;
207 char block[16], *iv;
208
209 if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_DECRYPT)
210 {
211 return RIJNDAEL_BAD_CIPHER_STATE;
212 }
213 if (input == NULL || inputLen <= 0)
214 {
215 return 0; /* nothing to do */
216 }
217
218 numBlocks = inputLen / 128;
219
220 switch (cipher->mode)
221 {
222 case RIJNDAEL_MODE_ECB:
223 for (i = numBlocks; i > 0; i--)
224 {
225 rijndaelEncrypt (key->rk, key->Nr, input, outBuffer);
226 input += 16;
227 outBuffer += 16;
228 }
229 break;
230
231 case RIJNDAEL_MODE_CBC:
232 iv = cipher->IV;
233 for (i = numBlocks; i > 0; i--)
234 {
235 ((uint32_t *) block)[0] = ((uint32_t *) input)[0] ^
236 ((uint32_t *) iv)[0];
237 ((uint32_t *) block)[1] = ((uint32_t *) input)[1] ^
238 ((uint32_t *) iv)[1];
239 ((uint32_t *) block)[2] = ((uint32_t *) input)[2] ^
240 ((uint32_t *) iv)[2];
241 ((uint32_t *) block)[3] = ((uint32_t *) input)[3] ^
242 ((uint32_t *) iv)[3];
243 rijndaelEncrypt (key->rk, key->Nr, block, outBuffer);
244 memcpy (cipher->IV, outBuffer, 16);
245 input += 16;
246 outBuffer += 16;
247 }
248 break;
249
250 case RIJNDAEL_MODE_CFB1:
251 iv = cipher->IV;
252 for (i = numBlocks; i > 0; i--)
253 {
254 memcpy (outBuffer, input, 16);
255 for (k = 0; k < 128; k++)
256 {
257 rijndaelEncrypt (key->ek, key->Nr, iv, block);
258 outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7);
259 for (t = 0; t < 15; t++)
260 {
261 iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
262 }
263 iv[15] = (iv[15] << 1) |
264 ((outBuffer[k >> 3] >> (7 - (k & 7))) & 1);
265 }
266 outBuffer += 16;
267 input += 16;
268 }
269 break;
270
271 default:
272 return RIJNDAEL_BAD_CIPHER_STATE;
273 }
274
275 return 128 * numBlocks;
276}
277
278int
279rijndaelPadEncrypt (rijndaelCipherInstance * cipher,
280 const rijndaelKeyInstance * key,
281 const char *input, size_t inputOctets, char *outBuffer)
282{
283 size_t i, numBlocks, padLen;
284 char block[16], *iv;
285
286 if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_DECRYPT)
287 {
288 return RIJNDAEL_BAD_CIPHER_STATE;
289 }
290 if (input == NULL || inputOctets <= 0)
291 {
292 return 0; /* nothing to do */
293 }
294
295 numBlocks = inputOctets / 16;
296
297 switch (cipher->mode)
298 {
299 case RIJNDAEL_MODE_ECB:
300 for (i = numBlocks; i > 0; i--)
301 {
302 rijndaelEncrypt (key->rk, key->Nr, input, outBuffer);
303 input += 16;
304 outBuffer += 16;
305 }
306 padLen = 16 - (inputOctets - 16 * numBlocks);
307 assert (padLen > 0 && padLen <= 16);
308 memcpy (block, input, 16 - padLen);
309 memset (block + 16 - padLen, padLen, padLen);
310 rijndaelEncrypt (key->rk, key->Nr, block, outBuffer);
311 break;
312
313 case RIJNDAEL_MODE_CBC:
314 iv = cipher->IV;
315 for (i = numBlocks; i > 0; i--)
316 {
317 ((uint32_t *) block)[0] = ((uint32_t *) input)[0] ^
318 ((uint32_t *) iv)[0];
319 ((uint32_t *) block)[1] = ((uint32_t *) input)[1] ^
320 ((uint32_t *) iv)[1];
321 ((uint32_t *) block)[2] = ((uint32_t *) input)[2] ^
322 ((uint32_t *) iv)[2];
323 ((uint32_t *) block)[3] = ((uint32_t *) input)[3] ^
324 ((uint32_t *) iv)[3];
325 rijndaelEncrypt (key->rk, key->Nr, block, outBuffer);
326 memcpy (cipher->IV, outBuffer, 16);
327 input += 16;
328 outBuffer += 16;
329 }
330 padLen = 16 - (inputOctets - 16 * numBlocks);
331 assert (padLen > 0 && padLen <= 16);
332 for (i = 0; i < 16 - padLen; i++)
333 {
334 block[i] = input[i] ^ iv[i];
335 }
336 for (i = 16 - padLen; i < 16; i++)
337 {
338 block[i] = (char) padLen ^ iv[i];
339 }
340 rijndaelEncrypt (key->rk, key->Nr, block, outBuffer);
341 memcpy (cipher->IV, outBuffer, 16);
342 break;
343
344 default:
345 return RIJNDAEL_BAD_CIPHER_STATE;
346 }
347
348 return 16 * (numBlocks + 1);
349}
350
351int
352rijndaelBlockDecrypt (rijndaelCipherInstance * cipher,
353 const rijndaelKeyInstance * key,
354 const char *input, size_t inputLen, char *outBuffer)
355{
356 size_t i, k, t, numBlocks;
357 char block[16], *iv;
358
359 if (cipher == NULL
360 || key == NULL
361 || (cipher->mode != RIJNDAEL_MODE_CFB1
362 && key->direction == RIJNDAEL_DIR_ENCRYPT))
363 {
364 return RIJNDAEL_BAD_CIPHER_STATE;
365 }
366 if (input == NULL || inputLen <= 0)
367 {
368 return 0; /* nothing to do */
369 }
370
371 numBlocks = inputLen / 128;
372
373 switch (cipher->mode)
374 {
375 case RIJNDAEL_MODE_ECB:
376 for (i = numBlocks; i > 0; i--)
377 {
378 rijndaelDecrypt (key->rk, key->Nr, input, outBuffer);
379 input += 16;
380 outBuffer += 16;
381 }
382 break;
383
384 case RIJNDAEL_MODE_CBC:
385 iv = cipher->IV;
386 for (i = numBlocks; i > 0; i--)
387 {
388 rijndaelDecrypt (key->rk, key->Nr, input, block);
389 ((uint32_t *) block)[0] ^= ((uint32_t *) iv)[0];
390 ((uint32_t *) block)[1] ^= ((uint32_t *) iv)[1];
391 ((uint32_t *) block)[2] ^= ((uint32_t *) iv)[2];
392 ((uint32_t *) block)[3] ^= ((uint32_t *) iv)[3];
393 memcpy (cipher->IV, input, 16);
394 memcpy (outBuffer, block, 16);
395 input += 16;
396 outBuffer += 16;
397 }
398 break;
399
400 case RIJNDAEL_MODE_CFB1:
401 iv = cipher->IV;
402 for (i = numBlocks; i > 0; i--)
403 {
404 memcpy (outBuffer, input, 16);
405 for (k = 0; k < 128; k++)
406 {
407 rijndaelEncrypt (key->ek, key->Nr, iv, block);
408 for (t = 0; t < 15; t++)
409 {
410 iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
411 }
412 iv[15] = (iv[15] << 1) | ((input[k >> 3] >> (7 - (k & 7))) & 1);
413 outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7);
414 }
415 outBuffer += 16;
416 input += 16;
417 }
418 break;
419
420 default:
421 return RIJNDAEL_BAD_CIPHER_STATE;
422 }
423
424 return 128 * numBlocks;
425}
426
427int
428rijndaelPadDecrypt (rijndaelCipherInstance * cipher,
429 const rijndaelKeyInstance * key,
430 const char *input, size_t inputOctets, char *outBuffer)
431{
432 size_t i, numBlocks, padLen;
433 char block[16];
434
435 if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_ENCRYPT)
436 {
437 return RIJNDAEL_BAD_CIPHER_STATE;
438 }
439 if (input == NULL || inputOctets <= 0)
440 {
441 return 0; /* nothing to do */
442 }
443 if (inputOctets % 16 != 0)
444 {
445 return RIJNDAEL_BAD_DATA;
446 }
447
448 numBlocks = inputOctets / 16;
449
450 switch (cipher->mode)
451 {
452 case RIJNDAEL_MODE_ECB:
453 /* all blocks but last */
454 for (i = numBlocks - 1; i > 0; i--)
455 {
456 rijndaelDecrypt (key->rk, key->Nr, input, outBuffer);
457 input += 16;
458 outBuffer += 16;
459 }
460 /* last block */
461 rijndaelDecrypt (key->rk, key->Nr, input, block);
462 padLen = block[15];
463 if (padLen >= 16)
464 {
465 return RIJNDAEL_BAD_DATA;
466 }
467 for (i = 16 - padLen; i < 16; i++)
468 {
469 if (block[i] != padLen)
470 {
471 return RIJNDAEL_BAD_DATA;
472 }
473 }
474 memcpy (outBuffer, block, 16 - padLen);
475 break;
476
477 case RIJNDAEL_MODE_CBC:
478 /* all blocks but last */
479 for (i = numBlocks - 1; i > 0; i--)
480 {
481 rijndaelDecrypt (key->rk, key->Nr, input, block);
482 ((uint32_t *) block)[0] ^= ((uint32_t *) cipher->IV)[0];
483 ((uint32_t *) block)[1] ^= ((uint32_t *) cipher->IV)[1];
484 ((uint32_t *) block)[2] ^= ((uint32_t *) cipher->IV)[2];
485 ((uint32_t *) block)[3] ^= ((uint32_t *) cipher->IV)[3];
486 memcpy (cipher->IV, input, 16);
487 memcpy (outBuffer, block, 16);
488 input += 16;
489 outBuffer += 16;
490 }
491 /* last block */
492 rijndaelDecrypt (key->rk, key->Nr, input, block);
493 ((uint32_t *) block)[0] ^= ((uint32_t *) cipher->IV)[0];
494 ((uint32_t *) block)[1] ^= ((uint32_t *) cipher->IV)[1];
495 ((uint32_t *) block)[2] ^= ((uint32_t *) cipher->IV)[2];
496 ((uint32_t *) block)[3] ^= ((uint32_t *) cipher->IV)[3];
497 padLen = block[15];
498 if (padLen <= 0 || padLen > 16)
499 {
500 return RIJNDAEL_BAD_DATA;
501 }
502 for (i = 16 - padLen; i < 16; i++)
503 {
504 if (block[i] != padLen)
505 {
506 return RIJNDAEL_BAD_DATA;
507 }
508 }
509 memcpy (outBuffer, block, 16 - padLen);
510 break;
511
512 default:
513 return RIJNDAEL_BAD_CIPHER_STATE;
514 }
515
516 return 16 * numBlocks - padLen;
517}
diff --git a/src/daemon/https/lgl/rijndael-api-fst.h b/src/daemon/https/lgl/rijndael-api-fst.h
new file mode 100644
index 00000000..d0ff60ac
--- /dev/null
+++ b/src/daemon/https/lgl/rijndael-api-fst.h
@@ -0,0 +1,207 @@
1/* rijndael-api-fst.h --- Rijndael cipher implementation.
2 * Copyright (C) 2005 Free Software Foundation, Inc.
3 *
4 * This file is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; either version 2.1, or (at your
7 * option) any later version.
8 *
9 * This file is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this file; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301, USA.
18 *
19 */
20
21/* Adapted for gnulib by Simon Josefsson. */
22
23/**
24 * rijndael-api-fst.h
25 *
26 * @version 2.9 (December 2000)
27 *
28 * Optimised ANSI C code for the Rijndael cipher (now AES)
29 *
30 * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
31 * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
32 * @author Paulo Barreto <paulo.barreto@terra.com.br>
33 *
34 * This code is hereby placed in the public domain.
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
37 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
38 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
40 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
41 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
42 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
45 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
46 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47 *
48 * Acknowledgements:
49 *
50 * We are deeply indebted to the following people for their bug reports,
51 * fixes, and improvement suggestions to this implementation. Though we
52 * tried to list all contributions, we apologise in advance for any
53 * missing reference.
54 *
55 * Andrew Bales <Andrew.Bales@Honeywell.com>
56 * Markus Friedl <markus.friedl@informatik.uni-erlangen.de>
57 * John Skodon <skodonj@webquill.com>
58 */
59
60#ifndef __RIJNDAEL_API_FST_H
61#define __RIJNDAEL_API_FST_H
62
63#include "rijndael-alg-fst.h"
64
65#include <stdio.h>
66
67/* Default number of bits in a cipher block */
68#define RIJNDAEL_BITSPERBLOCK 128
69
70/* Number of ASCII char's needed to represent a key */
71#define RIJNDAEL_MAX_KEY_SIZE 64
72
73/* Number bytes needed to represent an IV */
74#define RIJNDAEL_MAX_IV_SIZE 16
75
76typedef enum
77{
78 /* Key direction is invalid, e.g., unknown value */
79 RIJNDAEL_BAD_KEY_DIR = -1,
80 /* Key material not of correct length */
81 RIJNDAEL_BAD_KEY_MAT = -2,
82 /* Key passed is not valid */
83 RIJNDAEL_BAD_KEY_INSTANCE = -3,
84 /* Params struct passed to cipherInit invalid */
85 RIJNDAEL_BAD_CIPHER_MODE = -4,
86 /* Cipher in wrong state (e.g., not initialized) */
87 RIJNDAEL_BAD_CIPHER_STATE = -5,
88 RIJNDAEL_BAD_BLOCK_LENGTH = -6,
89 RIJNDAEL_BAD_CIPHER_INSTANCE = -7,
90 /* Data contents are invalid, e.g., invalid padding */
91 RIJNDAEL_BAD_DATA = -8,
92 /* Unknown error */
93 RIJNDAEL_BAD_OTHER = -9
94} rijndael_rc;
95
96typedef enum
97{
98 RIJNDAEL_DIR_ENCRYPT = 0, /* Are we encrypting? */
99 RIJNDAEL_DIR_DECRYPT = 1 /* Are we decrypting? */
100} rijndael_direction;
101
102typedef enum
103{
104 RIJNDAEL_MODE_ECB = 1, /* Are we ciphering in ECB mode? */
105 RIJNDAEL_MODE_CBC = 2, /* Are we ciphering in CBC mode? */
106 RIJNDAEL_MODE_CFB1 = 3 /* Are we ciphering in 1-bit CFB mode? */
107} rijndael_mode;
108
109/* The structure for key information */
110typedef struct
111{
112 /* Key used for encrypting or decrypting? */
113 rijndael_direction direction;
114 /* Length of the key */
115 size_t keyLen;
116 /* Raw key data in ASCII, e.g., user input or KAT values */
117 char keyMaterial[RIJNDAEL_MAX_KEY_SIZE + 1];
118 /* key-length-dependent number of rounds */
119 int Nr;
120 /* key schedule */
121 uint32_t rk[4 * (RIJNDAEL_MAXNR + 1)];
122 /* CFB1 key schedule (encryption only) */
123 uint32_t ek[4 * (RIJNDAEL_MAXNR + 1)];
124} rijndaelKeyInstance;
125
126/* The structure for cipher information */
127typedef struct
128{ /* changed order of the components */
129 rijndael_mode mode; /* MODE_ECB, MODE_CBC, or MODE_CFB1 */
130 /* A possible Initialization Vector for ciphering */
131 char IV[RIJNDAEL_MAX_IV_SIZE];
132} rijndaelCipherInstance;
133
134/* Function prototypes */
135
136/* Create KEY, for encryption or decryption depending on DIRECTION,
137 from KEYMATERIAL, a hex string, of KEYLEN size. KEYLEN should be
138 128, 192 or 256. Returns 0 on success, or an error code. */
139extern rijndael_rc
140rijndaelMakeKey (rijndaelKeyInstance *key, rijndael_direction direction,
141 size_t keyLen, const char *keyMaterial);
142
143/* Initialize cipher state CIPHER for encryption MODE (e.g.,
144 RIJNDAEL_MODE_CBC) with initialization vector IV, a hex string of
145 2*RIJNDAEL_MAX_IV_SIZE length. IV may be NULL for modes that do
146 not need an IV (i.e., RIJNDAEL_MODE_ECB). */
147extern rijndael_rc
148rijndaelCipherInit (rijndaelCipherInstance *cipher,
149 rijndael_mode mode, const char *IV);
150
151/* Encrypt data in INPUT, of INPUTLEN/8 bytes length, placing the
152 output in the pre-allocated OUTBUFFER which must hold at least
153 INPUTLEN/8 bytes of data. The CIPHER is used as state, and must be
154 initialized with rijndaelCipherInit before calling this function.
155 The encryption KEY must be initialized with rijndaelMakeKey before
156 calling this function. Return the number of bits written, or a
157 negative rijndael_rc error code. */
158extern int
159rijndaelBlockEncrypt (rijndaelCipherInstance *cipher,
160 const rijndaelKeyInstance *key,
161 const char *input, size_t inputLen,
162 char *outBuffer);
163
164/* Encrypt data in INPUT, of INPUTOCTETS bytes length, placing the
165 output in the pre-allocated OUTBUFFER which must hold at least
166 INPUTOCTETS aligned to the next block size boundary.
167 Ciphertext-Stealing as described in RFC 2040 is used to encrypt
168 partial blocks. The CIPHER is used as state, and must be
169 initialized with rijndaelCipherInit before calling this function.
170 The encryption KEY must be initialized with rijndaelMakeKey before
171 calling this function. Return the number of bits written, or a
172 negative rijndael_rc error code. */
173extern int
174rijndaelPadEncrypt (rijndaelCipherInstance *cipher,
175 const rijndaelKeyInstance *key,
176 const char *input, size_t inputOctets,
177 char *outBuffer);
178
179/* Decrypt data in INPUT, of INPUTLEN/8 bytes length, placing the
180 output in the pre-allocated OUTBUFFER which must hold at least
181 INPUTLEN/8 bytes of data. The CIPHER is used as state, and must be
182 initialized with rijndaelCipherInit before calling this function.
183 The encryption KEY must be initialized with rijndaelMakeKey before
184 calling this function. Return the number of bits written, or a
185 negative rijndael_rc error code. */
186extern int
187rijndaelBlockDecrypt (rijndaelCipherInstance *cipher,
188 const rijndaelKeyInstance *key,
189 const char *input, size_t inputLen,
190 char *outBuffer);
191
192/* Decrypt data in INPUT, of INPUTOCTETS bytes length, placing the
193 output in the pre-allocated OUTBUFFER which must hold at least
194 INPUTOCTETS aligned to the next block size boundary.
195 Ciphertext-Stealing as described in RFC 2040 is used to encrypt
196 partial blocks. The CIPHER is used as state, and must be
197 initialized with rijndaelCipherInit before calling this function.
198 The encryption KEY must be initialized with rijndaelMakeKey before
199 calling this function. Return the number of bits written, or a
200 negative rijndael_rc error code. */
201extern int
202rijndaelPadDecrypt (rijndaelCipherInstance *cipher,
203 const rijndaelKeyInstance *key,
204 const char *input, size_t inputOctets,
205 char *outBuffer);
206
207#endif /* __RIJNDAEL_API_FST_H */
diff --git a/src/daemon/https/lgl/sha1.c b/src/daemon/https/lgl/sha1.c
new file mode 100644
index 00000000..f5573da5
--- /dev/null
+++ b/src/daemon/https/lgl/sha1.c
@@ -0,0 +1,416 @@
1/* sha1.c - Functions to compute SHA1 message digest of files or
2 memory blocks according to the NIST specification FIPS-180-1.
3
4 Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006 Free Software
5 Foundation, Inc.
6
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by the
9 Free Software Foundation; either version 2.1, or (at your option) any
10 later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
20
21/* Written by Scott G. Miller
22 Credits:
23 Robert Klep <robert@ilse.nl> -- Expansion function fix
24*/
25
26#include <config.h>
27
28#include "sha1.h"
29
30#include <stddef.h>
31#include <string.h>
32
33#if USE_UNLOCKED_IO
34# include "unlocked-io.h"
35#endif
36
37#ifdef WORDS_BIGENDIAN
38# define SWAP(n) (n)
39#else
40# define SWAP(n) \
41 (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
42#endif
43
44#define BLOCKSIZE 4096
45#if BLOCKSIZE % 64 != 0
46# error "invalid BLOCKSIZE"
47#endif
48
49/* This array contains the bytes used to pad the buffer to the next
50 64-byte boundary. (RFC 1321, 3.1: Step 1) */
51static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
52
53
54/* Take a pointer to a 160 bit block of data (five 32 bit ints) and
55 initialize it to the start constants of the SHA1 algorithm. This
56 must be called before using hash in the call to sha1_hash. */
57void
58sha1_init_ctx (struct sha1_ctx *ctx)
59{
60 ctx->A = 0x67452301;
61 ctx->B = 0xefcdab89;
62 ctx->C = 0x98badcfe;
63 ctx->D = 0x10325476;
64 ctx->E = 0xc3d2e1f0;
65
66 ctx->total[0] = ctx->total[1] = 0;
67 ctx->buflen = 0;
68}
69
70/* Put result from CTX in first 20 bytes following RESBUF. The result
71 must be in little endian byte order.
72
73 IMPORTANT: On some systems it is required that RESBUF is correctly
74 aligned for a 32-bit value. */
75void *
76sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf)
77{
78 ((uint32_t *) resbuf)[0] = SWAP (ctx->A);
79 ((uint32_t *) resbuf)[1] = SWAP (ctx->B);
80 ((uint32_t *) resbuf)[2] = SWAP (ctx->C);
81 ((uint32_t *) resbuf)[3] = SWAP (ctx->D);
82 ((uint32_t *) resbuf)[4] = SWAP (ctx->E);
83
84 return resbuf;
85}
86
87/* Process the remaining bytes in the internal buffer and the usual
88 prolog according to the standard and write the result to RESBUF.
89
90 IMPORTANT: On some systems it is required that RESBUF is correctly
91 aligned for a 32-bit value. */
92void *
93sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf)
94{
95 /* Take yet unprocessed bytes into account. */
96 uint32_t bytes = ctx->buflen;
97 size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4;
98
99 /* Now count remaining bytes. */
100 ctx->total[0] += bytes;
101 if (ctx->total[0] < bytes)
102 ++ctx->total[1];
103
104 /* Put the 64-bit file length in *bits* at the end of the buffer. */
105 ctx->buffer[size - 2] = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29));
106 ctx->buffer[size - 1] = SWAP (ctx->total[0] << 3);
107
108 memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes);
109
110 /* Process last bytes. */
111 sha1_process_block (ctx->buffer, size * 4, ctx);
112
113 return sha1_read_ctx (ctx, resbuf);
114}
115
116/* Compute SHA1 message digest for bytes read from STREAM. The
117 resulting message digest number will be written into the 16 bytes
118 beginning at RESBLOCK. */
119int
120sha1_stream (FILE * stream, void *resblock)
121{
122 struct sha1_ctx ctx;
123 char buffer[BLOCKSIZE + 72];
124 size_t sum;
125
126 /* Initialize the computation context. */
127 sha1_init_ctx (&ctx);
128
129 /* Iterate over full file contents. */
130 while (1)
131 {
132 /* We read the file in blocks of BLOCKSIZE bytes. One call of the
133 computation function processes the whole buffer so that with the
134 next round of the loop another block can be read. */
135 size_t n;
136 sum = 0;
137
138 /* Read block. Take care for partial reads. */
139 while (1)
140 {
141 n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
142
143 sum += n;
144
145 if (sum == BLOCKSIZE)
146 break;
147
148 if (n == 0)
149 {
150 /* Check for the error flag IFF N == 0, so that we don't
151 exit the loop after a partial read due to e.g., EAGAIN
152 or EWOULDBLOCK. */
153 if (ferror (stream))
154 return 1;
155 goto process_partial_block;
156 }
157
158 /* We've read at least one byte, so ignore errors. But always
159 check for EOF, since feof may be true even though N > 0.
160 Otherwise, we could end up calling fread after EOF. */
161 if (feof (stream))
162 goto process_partial_block;
163 }
164
165 /* Process buffer with BLOCKSIZE bytes. Note that
166 BLOCKSIZE % 64 == 0
167 */
168 sha1_process_block (buffer, BLOCKSIZE, &ctx);
169 }
170
171process_partial_block:;
172
173 /* Process any remaining bytes. */
174 if (sum > 0)
175 sha1_process_bytes (buffer, sum, &ctx);
176
177 /* Construct result in desired memory. */
178 sha1_finish_ctx (&ctx, resblock);
179 return 0;
180}
181
182/* Compute SHA1 message digest for LEN bytes beginning at BUFFER. The
183 result is always in little endian byte order, so that a byte-wise
184 output yields to the wanted ASCII representation of the message
185 digest. */
186void *
187sha1_buffer (const char *buffer, size_t len, void *resblock)
188{
189 struct sha1_ctx ctx;
190
191 /* Initialize the computation context. */
192 sha1_init_ctx (&ctx);
193
194 /* Process whole buffer but last len % 64 bytes. */
195 sha1_process_bytes (buffer, len, &ctx);
196
197 /* Put result in desired memory area. */
198 return sha1_finish_ctx (&ctx, resblock);
199}
200
201void
202sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx)
203{
204 /* When we already have some bits in our internal buffer concatenate
205 both inputs first. */
206 if (ctx->buflen != 0)
207 {
208 size_t left_over = ctx->buflen;
209 size_t add = 128 - left_over > len ? len : 128 - left_over;
210
211 memcpy (&((char *) ctx->buffer)[left_over], buffer, add);
212 ctx->buflen += add;
213
214 if (ctx->buflen > 64)
215 {
216 sha1_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
217
218 ctx->buflen &= 63;
219 /* The regions in the following copy operation cannot overlap. */
220 memcpy (ctx->buffer,
221 &((char *) ctx->buffer)[(left_over + add) & ~63],
222 ctx->buflen);
223 }
224
225 buffer = (const char *) buffer + add;
226 len -= add;
227 }
228
229 /* Process available complete blocks. */
230 if (len >= 64)
231 {
232#if !_STRING_ARCH_unaligned
233# define alignof(type) offsetof (struct { char c; type x; }, x)
234# define UNALIGNED_P(p) (((size_t) p) % alignof (uint32_t) != 0)
235 if (UNALIGNED_P (buffer))
236 while (len > 64)
237 {
238 sha1_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
239 buffer = (const char *) buffer + 64;
240 len -= 64;
241 }
242 else
243#endif
244 {
245 sha1_process_block (buffer, len & ~63, ctx);
246 buffer = (const char *) buffer + (len & ~63);
247 len &= 63;
248 }
249 }
250
251 /* Move remaining bytes in internal buffer. */
252 if (len > 0)
253 {
254 size_t left_over = ctx->buflen;
255
256 memcpy (&((char *) ctx->buffer)[left_over], buffer, len);
257 left_over += len;
258 if (left_over >= 64)
259 {
260 sha1_process_block (ctx->buffer, 64, ctx);
261 left_over -= 64;
262 memcpy (ctx->buffer, &ctx->buffer[16], left_over);
263 }
264 ctx->buflen = left_over;
265 }
266}
267
268/* --- Code below is the primary difference between md5.c and sha1.c --- */
269
270/* SHA1 round constants */
271#define K1 0x5a827999
272#define K2 0x6ed9eba1
273#define K3 0x8f1bbcdc
274#define K4 0xca62c1d6
275
276/* Round functions. Note that F2 is the same as F4. */
277#define F1(B,C,D) ( D ^ ( B & ( C ^ D ) ) )
278#define F2(B,C,D) (B ^ C ^ D)
279#define F3(B,C,D) ( ( B & C ) | ( D & ( B | C ) ) )
280#define F4(B,C,D) (B ^ C ^ D)
281
282/* Process LEN bytes of BUFFER, accumulating context into CTX.
283 It is assumed that LEN % 64 == 0.
284 Most of this code comes from GnuPG's cipher/sha1.c. */
285
286void
287sha1_process_block (const void *buffer, size_t len, struct sha1_ctx *ctx)
288{
289 const uint32_t *words = buffer;
290 size_t nwords = len / sizeof (uint32_t);
291 const uint32_t *endp = words + nwords;
292 uint32_t x[16];
293 uint32_t a = ctx->A;
294 uint32_t b = ctx->B;
295 uint32_t c = ctx->C;
296 uint32_t d = ctx->D;
297 uint32_t e = ctx->E;
298
299 /* First increment the byte count. RFC 1321 specifies the possible
300 length of the file up to 2^64 bits. Here we only compute the
301 number of bytes. Do a double word increment. */
302 ctx->total[0] += len;
303 if (ctx->total[0] < len)
304 ++ctx->total[1];
305
306#define rol(x, n) (((x) << (n)) | ((uint32_t) (x) >> (32 - (n))))
307
308#define M(I) ( tm = x[I&0x0f] ^ x[(I-14)&0x0f] \
309 ^ x[(I-8)&0x0f] ^ x[(I-3)&0x0f] \
310 , (x[I&0x0f] = rol(tm, 1)) )
311
312#define R(A,B,C,D,E,F,K,M) do { E += rol( A, 5 ) \
313 + F( B, C, D ) \
314 + K \
315 + M; \
316 B = rol( B, 30 ); \
317 } while(0)
318
319 while (words < endp)
320 {
321 uint32_t tm;
322 int t;
323 for (t = 0; t < 16; t++)
324 {
325 x[t] = SWAP (*words);
326 words++;
327 }
328
329 R (a, b, c, d, e, F1, K1, x[0]);
330 R (e, a, b, c, d, F1, K1, x[1]);
331 R (d, e, a, b, c, F1, K1, x[2]);
332 R (c, d, e, a, b, F1, K1, x[3]);
333 R (b, c, d, e, a, F1, K1, x[4]);
334 R (a, b, c, d, e, F1, K1, x[5]);
335 R (e, a, b, c, d, F1, K1, x[6]);
336 R (d, e, a, b, c, F1, K1, x[7]);
337 R (c, d, e, a, b, F1, K1, x[8]);
338 R (b, c, d, e, a, F1, K1, x[9]);
339 R (a, b, c, d, e, F1, K1, x[10]);
340 R (e, a, b, c, d, F1, K1, x[11]);
341 R (d, e, a, b, c, F1, K1, x[12]);
342 R (c, d, e, a, b, F1, K1, x[13]);
343 R (b, c, d, e, a, F1, K1, x[14]);
344 R (a, b, c, d, e, F1, K1, x[15]);
345 R (e, a, b, c, d, F1, K1, M (16));
346 R (d, e, a, b, c, F1, K1, M (17));
347 R (c, d, e, a, b, F1, K1, M (18));
348 R (b, c, d, e, a, F1, K1, M (19));
349 R (a, b, c, d, e, F2, K2, M (20));
350 R (e, a, b, c, d, F2, K2, M (21));
351 R (d, e, a, b, c, F2, K2, M (22));
352 R (c, d, e, a, b, F2, K2, M (23));
353 R (b, c, d, e, a, F2, K2, M (24));
354 R (a, b, c, d, e, F2, K2, M (25));
355 R (e, a, b, c, d, F2, K2, M (26));
356 R (d, e, a, b, c, F2, K2, M (27));
357 R (c, d, e, a, b, F2, K2, M (28));
358 R (b, c, d, e, a, F2, K2, M (29));
359 R (a, b, c, d, e, F2, K2, M (30));
360 R (e, a, b, c, d, F2, K2, M (31));
361 R (d, e, a, b, c, F2, K2, M (32));
362 R (c, d, e, a, b, F2, K2, M (33));
363 R (b, c, d, e, a, F2, K2, M (34));
364 R (a, b, c, d, e, F2, K2, M (35));
365 R (e, a, b, c, d, F2, K2, M (36));
366 R (d, e, a, b, c, F2, K2, M (37));
367 R (c, d, e, a, b, F2, K2, M (38));
368 R (b, c, d, e, a, F2, K2, M (39));
369 R (a, b, c, d, e, F3, K3, M (40));
370 R (e, a, b, c, d, F3, K3, M (41));
371 R (d, e, a, b, c, F3, K3, M (42));
372 R (c, d, e, a, b, F3, K3, M (43));
373 R (b, c, d, e, a, F3, K3, M (44));
374 R (a, b, c, d, e, F3, K3, M (45));
375 R (e, a, b, c, d, F3, K3, M (46));
376 R (d, e, a, b, c, F3, K3, M (47));
377 R (c, d, e, a, b, F3, K3, M (48));
378 R (b, c, d, e, a, F3, K3, M (49));
379 R (a, b, c, d, e, F3, K3, M (50));
380 R (e, a, b, c, d, F3, K3, M (51));
381 R (d, e, a, b, c, F3, K3, M (52));
382 R (c, d, e, a, b, F3, K3, M (53));
383 R (b, c, d, e, a, F3, K3, M (54));
384 R (a, b, c, d, e, F3, K3, M (55));
385 R (e, a, b, c, d, F3, K3, M (56));
386 R (d, e, a, b, c, F3, K3, M (57));
387 R (c, d, e, a, b, F3, K3, M (58));
388 R (b, c, d, e, a, F3, K3, M (59));
389 R (a, b, c, d, e, F4, K4, M (60));
390 R (e, a, b, c, d, F4, K4, M (61));
391 R (d, e, a, b, c, F4, K4, M (62));
392 R (c, d, e, a, b, F4, K4, M (63));
393 R (b, c, d, e, a, F4, K4, M (64));
394 R (a, b, c, d, e, F4, K4, M (65));
395 R (e, a, b, c, d, F4, K4, M (66));
396 R (d, e, a, b, c, F4, K4, M (67));
397 R (c, d, e, a, b, F4, K4, M (68));
398 R (b, c, d, e, a, F4, K4, M (69));
399 R (a, b, c, d, e, F4, K4, M (70));
400 R (e, a, b, c, d, F4, K4, M (71));
401 R (d, e, a, b, c, F4, K4, M (72));
402 R (c, d, e, a, b, F4, K4, M (73));
403 R (b, c, d, e, a, F4, K4, M (74));
404 R (a, b, c, d, e, F4, K4, M (75));
405 R (e, a, b, c, d, F4, K4, M (76));
406 R (d, e, a, b, c, F4, K4, M (77));
407 R (c, d, e, a, b, F4, K4, M (78));
408 R (b, c, d, e, a, F4, K4, M (79));
409
410 a = ctx->A += a;
411 b = ctx->B += b;
412 c = ctx->C += c;
413 d = ctx->D += d;
414 e = ctx->E += e;
415 }
416}
diff --git a/src/daemon/https/lgl/sha1.h b/src/daemon/https/lgl/sha1.h
new file mode 100644
index 00000000..ed0de2b4
--- /dev/null
+++ b/src/daemon/https/lgl/sha1.h
@@ -0,0 +1,87 @@
1/* Declarations of functions and data types used for SHA1 sum
2 library functions.
3 Copyright (C) 2000, 2001, 2003, 2005, 2006 Free Software Foundation, Inc.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU Lesser General Public License as published by the
7 Free Software Foundation; either version 2.1, or (at your option) any
8 later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
18
19#ifndef SHA1_H
20# define SHA1_H 1
21
22# include <stdio.h>
23# include <stdint.h>
24
25/* Structure to save state of computation between the single steps. */
26struct sha1_ctx
27{
28 uint32_t A;
29 uint32_t B;
30 uint32_t C;
31 uint32_t D;
32 uint32_t E;
33
34 uint32_t total[2];
35 uint32_t buflen;
36 uint32_t buffer[32];
37};
38
39
40/* Initialize structure containing state of computation. */
41extern void sha1_init_ctx (struct sha1_ctx *ctx);
42
43/* Starting with the result of former calls of this function (or the
44 initialization function update the context for the next LEN bytes
45 starting at BUFFER.
46 It is necessary that LEN is a multiple of 64!!! */
47extern void sha1_process_block (const void *buffer, size_t len,
48 struct sha1_ctx *ctx);
49
50/* Starting with the result of former calls of this function (or the
51 initialization function update the context for the next LEN bytes
52 starting at BUFFER.
53 It is NOT required that LEN is a multiple of 64. */
54extern void sha1_process_bytes (const void *buffer, size_t len,
55 struct sha1_ctx *ctx);
56
57/* Process the remaining bytes in the buffer and put result from CTX
58 in first 20 bytes following RESBUF. The result is always in little
59 endian byte order, so that a byte-wise output yields to the wanted
60 ASCII representation of the message digest.
61
62 IMPORTANT: On some systems it is required that RESBUF be correctly
63 aligned for a 32 bits value. */
64extern void *sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf);
65
66
67/* Put result from CTX in first 20 bytes following RESBUF. The result is
68 always in little endian byte order, so that a byte-wise output yields
69 to the wanted ASCII representation of the message digest.
70
71 IMPORTANT: On some systems it is required that RESBUF is correctly
72 aligned for a 32 bits value. */
73extern void *sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf);
74
75
76/* Compute SHA1 message digest for bytes read from STREAM. The
77 resulting message digest number will be written into the 20 bytes
78 beginning at RESBLOCK. */
79extern int sha1_stream (FILE *stream, void *resblock);
80
81/* Compute SHA1 message digest for LEN bytes beginning at BUFFER. The
82 result is always in little endian byte order, so that a byte-wise
83 output yields to the wanted ASCII representation of the message
84 digest. */
85extern void *sha1_buffer (const char *buffer, size_t len, void *resblock);
86
87#endif
diff --git a/src/daemon/https/lgl/snprintf.c b/src/daemon/https/lgl/snprintf.c
new file mode 100644
index 00000000..538ee08e
--- /dev/null
+++ b/src/daemon/https/lgl/snprintf.c
@@ -0,0 +1,77 @@
1/* Formatted output to strings.
2 Copyright (C) 2004, 2006-2007 Free Software Foundation, Inc.
3 Written by Simon Josefsson and Paul Eggert.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
18
19#include <config.h>
20
21/* Specification. */
22#include <stdio.h>
23
24#include <errno.h>
25#include <limits.h>
26#include <stdarg.h>
27#include <stdlib.h>
28#include <string.h>
29
30#include "vasnprintf.h"
31
32/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */
33#ifndef EOVERFLOW
34# define EOVERFLOW E2BIG
35#endif
36
37/* Print formatted output to string STR. Similar to sprintf, but
38 additional length SIZE limit how much is written into STR. Returns
39 string length of formatted string (which may be larger than SIZE).
40 STR may be NULL, in which case nothing will be written. On error,
41 return a negative value. */
42int
43snprintf (char *str, size_t size, const char *format, ...)
44{
45 char *output;
46 size_t len;
47 size_t lenbuf = size;
48 va_list args;
49
50 va_start (args, format);
51 output = vasnprintf (str, &lenbuf, format, args);
52 len = lenbuf;
53 va_end (args);
54
55 if (!output)
56 return -1;
57
58 if (output != str)
59 {
60 if (size)
61 {
62 size_t pruned_len = (len < size ? len : size - 1);
63 memcpy (str, output, pruned_len);
64 str[pruned_len] = '\0';
65 }
66
67 free (output);
68 }
69
70 if (INT_MAX < len)
71 {
72 errno = EOVERFLOW;
73 return -1;
74 }
75
76 return len;
77}
diff --git a/src/daemon/https/lgl/strverscmp.c b/src/daemon/https/lgl/strverscmp.c
new file mode 100644
index 00000000..3b6bd20e
--- /dev/null
+++ b/src/daemon/https/lgl/strverscmp.c
@@ -0,0 +1,130 @@
1/* Compare strings while treating digits characters numerically.
2 Copyright (C) 1997, 2000, 2002, 2004, 2006 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Jean-François Bignolles <bignolle@ecoledoc.ibp.fr>, 1997.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License along
17 with this program; if not, write to the Free Software Foundation,
18 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
19
20#if !_LIBC
21# include <config.h>
22#endif
23
24#include <string.h>
25#include <ctype.h>
26
27/* states: S_N: normal, S_I: comparing integral part, S_F: comparing
28 fractional parts, S_Z: idem but with leading Zeroes only */
29#define S_N 0x0
30#define S_I 0x4
31#define S_F 0x8
32#define S_Z 0xC
33
34/* result_type: CMP: return diff; LEN: compare using len_diff/diff */
35#define CMP 2
36#define LEN 3
37
38
39/* ISDIGIT differs from isdigit, as follows:
40 - Its arg may be any int or unsigned int; it need not be an unsigned char
41 or EOF.
42 - It's typically faster.
43 POSIX says that only '0' through '9' are digits. Prefer ISDIGIT to
44 isdigit unless it's important to use the locale's definition
45 of `digit' even when the host does not conform to POSIX. */
46#define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9)
47
48#undef __strverscmp
49#undef strverscmp
50
51#ifndef weak_alias
52# define __strverscmp strverscmp
53#endif
54
55/* Compare S1 and S2 as strings holding indices/version numbers,
56 returning less than, equal to or greater than zero if S1 is less than,
57 equal to or greater than S2 (for more info, see the texinfo doc).
58*/
59
60int
61__strverscmp (const char *s1, const char *s2)
62{
63 const unsigned char *p1 = (const unsigned char *) s1;
64 const unsigned char *p2 = (const unsigned char *) s2;
65 unsigned char c1, c2;
66 int state;
67 int diff;
68
69 /* Symbol(s) 0 [1-9] others (padding)
70 Transition (10) 0 (01) d (00) x (11) - */
71 static const unsigned int next_state[] = {
72 /* state x d 0 - */
73 /* S_N */ S_N, S_I, S_Z, S_N,
74 /* S_I */ S_N, S_I, S_I, S_I,
75 /* S_F */ S_N, S_F, S_F, S_F,
76 /* S_Z */ S_N, S_F, S_Z, S_Z
77 };
78
79 static const int result_type[] = {
80 /* state x/x x/d x/0 x/- d/x d/d d/0 d/-
81 0/x 0/d 0/0 0/- -/x -/d -/0 -/- */
82
83 /* S_N */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
84 CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
85 /* S_I */ CMP, -1, -1, CMP, 1, LEN, LEN, CMP,
86 1, LEN, LEN, CMP, CMP, CMP, CMP, CMP,
87 /* S_F */ CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP,
88 CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP,
89 /* S_Z */ CMP, 1, 1, CMP, -1, CMP, CMP, CMP,
90 -1, CMP, CMP, CMP
91 };
92
93 if (p1 == p2)
94 return 0;
95
96 c1 = *p1++;
97 c2 = *p2++;
98 /* Hint: '0' is a digit too. */
99 state = S_N | ((c1 == '0') + (ISDIGIT (c1) != 0));
100
101 while ((diff = c1 - c2) == 0 && c1 != '\0')
102 {
103 state = next_state[state];
104 c1 = *p1++;
105 c2 = *p2++;
106 state |= (c1 == '0') + (ISDIGIT (c1) != 0);
107 }
108
109 state = result_type[state << 2 | ((c2 == '0') + (ISDIGIT (c2) != 0))];
110
111 switch (state)
112 {
113 case CMP:
114 return diff;
115
116 case LEN:
117 while (ISDIGIT (*p1++))
118 if (!ISDIGIT (*p2++))
119 return 1;
120
121 return ISDIGIT (*p2) ? -1 : diff;
122
123 default:
124 return state;
125 }
126}
127
128#ifdef weak_alias
129weak_alias (__strverscmp, strverscmp)
130#endif
diff --git a/src/daemon/https/lgl/strverscmp.h b/src/daemon/https/lgl/strverscmp.h
new file mode 100644
index 00000000..d95d7b31
--- /dev/null
+++ b/src/daemon/https/lgl/strverscmp.h
@@ -0,0 +1,24 @@
1/* Compare strings while treating digits characters numerically.
2
3 Copyright (C) 1997, 2003 Free Software Foundation, Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
18
19#ifndef STRVERSCMP_H_
20# define STRVERSCMP_H_
21
22int strverscmp (const char *, const char *);
23
24#endif /* not STRVERSCMP_H_ */
diff --git a/src/daemon/https/lgl/time_r.c b/src/daemon/https/lgl/time_r.c
new file mode 100644
index 00000000..691525df
--- /dev/null
+++ b/src/daemon/https/lgl/time_r.c
@@ -0,0 +1,46 @@
1/* Reentrant time functions like localtime_r.
2
3 Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
18
19/* Written by Paul Eggert. */
20
21#include <config.h>
22
23#include <time.h>
24
25#include <string.h>
26
27static struct tm *
28copy_tm_result (struct tm *dest, struct tm const *src)
29{
30 if (!src)
31 return 0;
32 *dest = *src;
33 return dest;
34}
35
36struct tm *
37gmtime_r (time_t const *restrict t, struct tm *restrict tp)
38{
39 return copy_tm_result (tp, gmtime (t));
40}
41
42struct tm *
43localtime_r (time_t const *restrict t, struct tm *restrict tp)
44{
45 return copy_tm_result (tp, localtime (t));
46}
diff --git a/src/daemon/https/lgl/vasnprintf.c b/src/daemon/https/lgl/vasnprintf.c
new file mode 100644
index 00000000..d247b592
--- /dev/null
+++ b/src/daemon/https/lgl/vasnprintf.c
@@ -0,0 +1,4825 @@
1/* vsprintf with automatic memory allocation.
2 Copyright (C) 1999, 2002-2007 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License along
15 with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18/* This file can be parametrized with the following macros:
19 VASNPRINTF The name of the function being defined.
20 FCHAR_T The element type of the format string.
21 DCHAR_T The element type of the destination (result) string.
22 FCHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters
23 in the format string are ASCII. MUST be set if
24 FCHAR_T and DCHAR_T are not the same type.
25 DIRECTIVE Structure denoting a format directive.
26 Depends on FCHAR_T.
27 DIRECTIVES Structure denoting the set of format directives of a
28 format string. Depends on FCHAR_T.
29 PRINTF_PARSE Function that parses a format string.
30 Depends on FCHAR_T.
31 DCHAR_CPY memcpy like function for DCHAR_T[] arrays.
32 DCHAR_SET memset like function for DCHAR_T[] arrays.
33 DCHAR_MBSNLEN mbsnlen like function for DCHAR_T[] arrays.
34 SNPRINTF The system's snprintf (or similar) function.
35 This may be either snprintf or swprintf.
36 TCHAR_T The element type of the argument and result string
37 of the said SNPRINTF function. This may be either
38 char or wchar_t. The code exploits that
39 sizeof (TCHAR_T) | sizeof (DCHAR_T) and
40 alignof (TCHAR_T) <= alignof (DCHAR_T).
41 DCHAR_IS_TCHAR Set to 1 if DCHAR_T and TCHAR_T are the same type.
42 DCHAR_CONV_FROM_ENCODING A function to convert from char[] to DCHAR[].
43 DCHAR_IS_UINT8_T Set to 1 if DCHAR_T is uint8_t.
44 DCHAR_IS_UINT16_T Set to 1 if DCHAR_T is uint16_t.
45 DCHAR_IS_UINT32_T Set to 1 if DCHAR_T is uint32_t. */
46
47/* Tell glibc's <stdio.h> to provide a prototype for snprintf().
48 This must come before <config.h> because <config.h> may include
49 <features.h>, and once <features.h> has been included, it's too late. */
50#ifndef _GNU_SOURCE
51# define _GNU_SOURCE 1
52#endif
53
54#ifndef VASNPRINTF
55# include <config.h>
56#endif
57#ifndef IN_LIBINTL
58# include <alloca.h>
59#endif
60
61/* Specification. */
62#ifndef VASNPRINTF
63# if WIDE_CHAR_VERSION
64# include "vasnwprintf.h"
65# else
66# include "vasnprintf.h"
67# endif
68#endif
69
70#include <locale.h> /* localeconv() */
71#include <stdio.h> /* snprintf(), sprintf() */
72#include <stdlib.h> /* abort(), malloc(), realloc(), free() */
73#include <string.h> /* memcpy(), strlen() */
74#include <errno.h> /* errno */
75#include <limits.h> /* CHAR_BIT */
76#include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP */
77#if HAVE_NL_LANGINFO
78# include <langinfo.h>
79#endif
80#ifndef VASNPRINTF
81# if WIDE_CHAR_VERSION
82# include "wprintf-parse.h"
83# else
84# include "printf-parse.h"
85# endif
86#endif
87
88/* Checked size_t computations. */
89#include "xsize.h"
90
91#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
92# include <math.h>
93# include "float+.h"
94#endif
95
96#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
97# include <math.h>
98# include "isnan.h"
99#endif
100
101#if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL
102# include <math.h>
103# include "isnanl-nolibm.h"
104# include "fpucw.h"
105#endif
106
107#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
108# include <math.h>
109# include "isnan.h"
110# include "printf-frexp.h"
111#endif
112
113#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
114# include <math.h>
115# include "isnanl-nolibm.h"
116# include "printf-frexpl.h"
117# include "fpucw.h"
118#endif
119
120/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */
121#ifndef EOVERFLOW
122# define EOVERFLOW E2BIG
123#endif
124
125#if HAVE_WCHAR_T
126# if HAVE_WCSLEN
127# define local_wcslen wcslen
128# else
129 /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
130 a dependency towards this library, here is a local substitute.
131 Define this substitute only once, even if this file is included
132 twice in the same compilation unit. */
133# ifndef local_wcslen_defined
134# define local_wcslen_defined 1
135static size_t
136local_wcslen (const wchar_t * s)
137{
138 const wchar_t *ptr;
139
140 for (ptr = s; *ptr != (wchar_t) 0; ptr++)
141 ;
142 return ptr - s;
143}
144# endif
145# endif
146#endif
147
148/* Default parameters. */
149#ifndef VASNPRINTF
150# if WIDE_CHAR_VERSION
151# define VASNPRINTF vasnwprintf
152# define FCHAR_T wchar_t
153# define DCHAR_T wchar_t
154# define TCHAR_T wchar_t
155# define DCHAR_IS_TCHAR 1
156# define DIRECTIVE wchar_t_directive
157# define DIRECTIVES wchar_t_directives
158# define PRINTF_PARSE wprintf_parse
159# define DCHAR_CPY wmemcpy
160# else
161# define VASNPRINTF vasnprintf
162# define FCHAR_T char
163# define DCHAR_T char
164# define TCHAR_T char
165# define DCHAR_IS_TCHAR 1
166# define DIRECTIVE char_directive
167# define DIRECTIVES char_directives
168# define PRINTF_PARSE printf_parse
169# define DCHAR_CPY memcpy
170# endif
171#endif
172#if WIDE_CHAR_VERSION
173 /* TCHAR_T is wchar_t. */
174# define USE_SNPRINTF 1
175# if HAVE_DECL__SNWPRINTF
176 /* On Windows, the function swprintf() has a different signature than
177 on Unix; we use the _snwprintf() function instead. */
178# define SNPRINTF _snwprintf
179# else
180 /* Unix. */
181# define SNPRINTF swprintf
182# endif
183#else
184 /* TCHAR_T is char. */
185# /* Use snprintf if it exists under the name 'snprintf' or '_snprintf'.
186 But don't use it on BeOS, since BeOS snprintf produces no output if the
187 size argument is >= 0x3000000. */
188# if (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF) && !defined __BEOS__
189# define USE_SNPRINTF 1
190# else
191# define USE_SNPRINTF 0
192# endif
193# if HAVE_DECL__SNPRINTF
194 /* Windows. */
195# define SNPRINTF _snprintf
196# else
197 /* Unix. */
198# define SNPRINTF snprintf
199 /* Here we need to call the native snprintf, not rpl_snprintf. */
200# undef snprintf
201# endif
202#endif
203/* Here we need to call the native sprintf, not rpl_sprintf. */
204#undef sprintf
205
206#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
207/* Determine the decimal-point character according to the current locale. */
208# ifndef decimal_point_char_defined
209# define decimal_point_char_defined 1
210static char
211decimal_point_char ()
212{
213 const char *point;
214 /* Determine it in a multithread-safe way. We know nl_langinfo is
215 multithread-safe on glibc systems, but is not required to be multithread-
216 safe by POSIX. sprintf(), however, is multithread-safe. localeconv()
217 is rarely multithread-safe. */
218# if HAVE_NL_LANGINFO && __GLIBC__
219 point = nl_langinfo (RADIXCHAR);
220# elif 1
221 char pointbuf[5];
222 sprintf (pointbuf, "%#.0f", 1.0);
223 point = &pointbuf[1];
224# else
225 point = localeconv ()->decimal_point;
226# endif
227 /* The decimal point is always a single byte: either '.' or ','. */
228 return (point[0] != '\0' ? point[0] : '.');
229}
230# endif
231#endif
232
233#if NEED_PRINTF_INFINITE_DOUBLE && !NEED_PRINTF_DOUBLE && !defined IN_LIBINTL
234
235/* Equivalent to !isfinite(x) || x == 0, but does not require libm. */
236static int
237is_infinite_or_zero (double x)
238{
239 return isnan (x) || x + x == x;
240}
241
242#endif
243
244#if NEED_PRINTF_INFINITE_LONG_DOUBLE && !NEED_PRINTF_LONG_DOUBLE && !defined IN_LIBINTL
245
246/* Equivalent to !isfinite(x), but does not require libm. */
247static int
248is_infinitel (long double x)
249{
250 return isnanl (x) || (x + x == x && x != 0.0L);
251}
252
253#endif
254
255#if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
256
257/* Converting 'long double' to decimal without rare rounding bugs requires
258 real bignums. We use the naming conventions of GNU gmp, but vastly simpler
259 (and slower) algorithms. */
260
261typedef unsigned int mp_limb_t;
262# define GMP_LIMB_BITS 32
263typedef int mp_limb_verify[2 *
264 (sizeof (mp_limb_t) * CHAR_BIT ==
265 GMP_LIMB_BITS) - 1];
266
267typedef unsigned long long mp_twolimb_t;
268# define GMP_TWOLIMB_BITS 64
269typedef int mp_twolimb_verify[2 *
270 (sizeof (mp_twolimb_t) * CHAR_BIT ==
271 GMP_TWOLIMB_BITS) - 1];
272
273/* Representation of a bignum >= 0. */
274typedef struct
275{
276 size_t nlimbs;
277 mp_limb_t *limbs; /* Bits in little-endian order, allocated with malloc(). */
278} mpn_t;
279
280/* Compute the product of two bignums >= 0.
281 Return the allocated memory in case of success, NULL in case of memory
282 allocation failure. */
283static void *
284multiply (mpn_t src1, mpn_t src2, mpn_t * dest)
285{
286 const mp_limb_t *p1;
287 const mp_limb_t *p2;
288 size_t len1;
289 size_t len2;
290
291 if (src1.nlimbs <= src2.nlimbs)
292 {
293 len1 = src1.nlimbs;
294 p1 = src1.limbs;
295 len2 = src2.nlimbs;
296 p2 = src2.limbs;
297 }
298 else
299 {
300 len1 = src2.nlimbs;
301 p1 = src2.limbs;
302 len2 = src1.nlimbs;
303 p2 = src1.limbs;
304 }
305 /* Now 0 <= len1 <= len2. */
306 if (len1 == 0)
307 {
308 /* src1 or src2 is zero. */
309 dest->nlimbs = 0;
310 dest->limbs = (mp_limb_t *) malloc (1);
311 }
312 else
313 {
314 /* Here 1 <= len1 <= len2. */
315 size_t dlen;
316 mp_limb_t *dp;
317 size_t k, i, j;
318
319 dlen = len1 + len2;
320 dp = (mp_limb_t *) malloc (dlen * sizeof (mp_limb_t));
321 if (dp == NULL)
322 return NULL;
323 for (k = len2; k > 0;)
324 dp[--k] = 0;
325 for (i = 0; i < len1; i++)
326 {
327 mp_limb_t digit1 = p1[i];
328 mp_twolimb_t carry = 0;
329 for (j = 0; j < len2; j++)
330 {
331 mp_limb_t digit2 = p2[j];
332 carry += (mp_twolimb_t) digit1 *(mp_twolimb_t) digit2;
333 carry += dp[i + j];
334 dp[i + j] = (mp_limb_t) carry;
335 carry = carry >> GMP_LIMB_BITS;
336 }
337 dp[i + len2] = (mp_limb_t) carry;
338 }
339 /* Normalise. */
340 while (dlen > 0 && dp[dlen - 1] == 0)
341 dlen--;
342 dest->nlimbs = dlen;
343 dest->limbs = dp;
344 }
345 return dest->limbs;
346}
347
348/* Compute the quotient of a bignum a >= 0 and a bignum b > 0.
349 a is written as a = q * b + r with 0 <= r < b. q is the quotient, r
350 the remainder.
351 Finally, round-to-even is performed: If r > b/2 or if r = b/2 and q is odd,
352 q is incremented.
353 Return the allocated memory in case of success, NULL in case of memory
354 allocation failure. */
355static void *
356divide (mpn_t a, mpn_t b, mpn_t * q)
357{
358 /* Algorithm:
359 First normalise a and b: a=[a[m-1],...,a[0]], b=[b[n-1],...,b[0]]
360 with m>=0 and n>0 (in base beta = 2^GMP_LIMB_BITS).
361 If m<n, then q:=0 and r:=a.
362 If m>=n=1, perform a single-precision division:
363 r:=0, j:=m,
364 while j>0 do
365 {Here (q[m-1]*beta^(m-1)+...+q[j]*beta^j) * b[0] + r*beta^j =
366 = a[m-1]*beta^(m-1)+...+a[j]*beta^j und 0<=r<b[0]<beta}
367 j:=j-1, r:=r*beta+a[j], q[j]:=floor(r/b[0]), r:=r-b[0]*q[j].
368 Normalise [q[m-1],...,q[0]], yields q.
369 If m>=n>1, perform a multiple-precision division:
370 We have a/b < beta^(m-n+1).
371 s:=intDsize-1-(hightest bit in b[n-1]), 0<=s<intDsize.
372 Shift a and b left by s bits, copying them. r:=a.
373 r=[r[m],...,r[0]], b=[b[n-1],...,b[0]] with b[n-1]>=beta/2.
374 For j=m-n,...,0: {Here 0 <= r < b*beta^(j+1).}
375 Compute q* :
376 q* := floor((r[j+n]*beta+r[j+n-1])/b[n-1]).
377 In case of overflow (q* >= beta) set q* := beta-1.
378 Compute c2 := ((r[j+n]*beta+r[j+n-1]) - q* * b[n-1])*beta + r[j+n-2]
379 and c3 := b[n-2] * q*.
380 {We have 0 <= c2 < 2*beta^2, even 0 <= c2 < beta^2 if no overflow
381 occurred. Furthermore 0 <= c3 < beta^2.
382 If there was overflow and
383 r[j+n]*beta+r[j+n-1] - q* * b[n-1] >= beta, i.e. c2 >= beta^2,
384 the next test can be skipped.}
385 While c3 > c2, {Here 0 <= c2 < c3 < beta^2}
386 Put q* := q* - 1, c2 := c2 + b[n-1]*beta, c3 := c3 - b[n-2].
387 If q* > 0:
388 Put r := r - b * q* * beta^j. In detail:
389 [r[n+j],...,r[j]] := [r[n+j],...,r[j]] - q* * [b[n-1],...,b[0]].
390 hence: u:=0, for i:=0 to n-1 do
391 u := u + q* * b[i],
392 r[j+i]:=r[j+i]-(u mod beta) (+ beta, if carry),
393 u:=u div beta (+ 1, if carry in subtraction)
394 r[n+j]:=r[n+j]-u.
395 {Since always u = (q* * [b[i-1],...,b[0]] div beta^i) + 1
396 < q* + 1 <= beta,
397 the carry u does not overflow.}
398 If a negative carry occurs, put q* := q* - 1
399 and [r[n+j],...,r[j]] := [r[n+j],...,r[j]] + [0,b[n-1],...,b[0]].
400 Set q[j] := q*.
401 Normalise [q[m-n],..,q[0]]; this yields the quotient q.
402 Shift [r[n-1],...,r[0]] right by s bits and normalise; this yields the
403 rest r.
404 The room for q[j] can be allocated at the memory location of r[n+j].
405 Finally, round-to-even:
406 Shift r left by 1 bit.
407 If r > b or if r = b and q[0] is odd, q := q+1.
408 */
409 const mp_limb_t *a_ptr = a.limbs;
410 size_t a_len = a.nlimbs;
411 const mp_limb_t *b_ptr = b.limbs;
412 size_t b_len = b.nlimbs;
413 mp_limb_t *roomptr;
414 mp_limb_t *tmp_roomptr = NULL;
415 mp_limb_t *q_ptr;
416 size_t q_len;
417 mp_limb_t *r_ptr;
418 size_t r_len;
419
420 /* Allocate room for a_len+2 digits.
421 (Need a_len+1 digits for the real division and 1 more digit for the
422 final rounding of q.) */
423 roomptr = (mp_limb_t *) malloc ((a_len + 2) * sizeof (mp_limb_t));
424 if (roomptr == NULL)
425 return NULL;
426
427 /* Normalise a. */
428 while (a_len > 0 && a_ptr[a_len - 1] == 0)
429 a_len--;
430
431 /* Normalise b. */
432 for (;;)
433 {
434 if (b_len == 0)
435 /* Division by zero. */
436 abort ();
437 if (b_ptr[b_len - 1] == 0)
438 b_len--;
439 else
440 break;
441 }
442
443 /* Here m = a_len >= 0 and n = b_len > 0. */
444
445 if (a_len < b_len)
446 {
447 /* m<n: trivial case. q=0, r := copy of a. */
448 r_ptr = roomptr;
449 r_len = a_len;
450 memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
451 q_ptr = roomptr + a_len;
452 q_len = 0;
453 }
454 else if (b_len == 1)
455 {
456 /* n=1: single precision division.
457 beta^(m-1) <= a < beta^m ==> beta^(m-2) <= a/b < beta^m */
458 r_ptr = roomptr;
459 q_ptr = roomptr + 1;
460 {
461 mp_limb_t den = b_ptr[0];
462 mp_limb_t remainder = 0;
463 const mp_limb_t *sourceptr = a_ptr + a_len;
464 mp_limb_t *destptr = q_ptr + a_len;
465 size_t count;
466 for (count = a_len; count > 0; count--)
467 {
468 mp_twolimb_t num =
469 ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--sourceptr;
470 *--destptr = num / den;
471 remainder = num % den;
472 }
473 /* Normalise and store r. */
474 if (remainder > 0)
475 {
476 r_ptr[0] = remainder;
477 r_len = 1;
478 }
479 else
480 r_len = 0;
481 /* Normalise q. */
482 q_len = a_len;
483 if (q_ptr[q_len - 1] == 0)
484 q_len--;
485 }
486 }
487 else
488 {
489 /* n>1: multiple precision division.
490 beta^(m-1) <= a < beta^m, beta^(n-1) <= b < beta^n ==>
491 beta^(m-n-1) <= a/b < beta^(m-n+1). */
492 /* Determine s. */
493 size_t s;
494 {
495 mp_limb_t msd = b_ptr[b_len - 1]; /* = b[n-1], > 0 */
496 s = 31;
497 if (msd >= 0x10000)
498 {
499 msd = msd >> 16;
500 s -= 16;
501 }
502 if (msd >= 0x100)
503 {
504 msd = msd >> 8;
505 s -= 8;
506 }
507 if (msd >= 0x10)
508 {
509 msd = msd >> 4;
510 s -= 4;
511 }
512 if (msd >= 0x4)
513 {
514 msd = msd >> 2;
515 s -= 2;
516 }
517 if (msd >= 0x2)
518 {
519 msd = msd >> 1;
520 s -= 1;
521 }
522 }
523 /* 0 <= s < GMP_LIMB_BITS.
524 Copy b, shifting it left by s bits. */
525 if (s > 0)
526 {
527 tmp_roomptr = (mp_limb_t *) malloc (b_len * sizeof (mp_limb_t));
528 if (tmp_roomptr == NULL)
529 {
530 free (roomptr);
531 return NULL;
532 }
533 {
534 const mp_limb_t *sourceptr = b_ptr;
535 mp_limb_t *destptr = tmp_roomptr;
536 mp_twolimb_t accu = 0;
537 size_t count;
538 for (count = b_len; count > 0; count--)
539 {
540 accu += (mp_twolimb_t) * sourceptr++ << s;
541 *destptr++ = (mp_limb_t) accu;
542 accu = accu >> GMP_LIMB_BITS;
543 }
544 /* accu must be zero, since that was how s was determined. */
545 if (accu != 0)
546 abort ();
547 }
548 b_ptr = tmp_roomptr;
549 }
550 /* Copy a, shifting it left by s bits, yields r.
551 Memory layout:
552 At the beginning: r = roomptr[0..a_len],
553 at the end: r = roomptr[0..b_len-1], q = roomptr[b_len..a_len] */
554 r_ptr = roomptr;
555 if (s == 0)
556 {
557 memcpy (r_ptr, a_ptr, a_len * sizeof (mp_limb_t));
558 r_ptr[a_len] = 0;
559 }
560 else
561 {
562 const mp_limb_t *sourceptr = a_ptr;
563 mp_limb_t *destptr = r_ptr;
564 mp_twolimb_t accu = 0;
565 size_t count;
566 for (count = a_len; count > 0; count--)
567 {
568 accu += (mp_twolimb_t) * sourceptr++ << s;
569 *destptr++ = (mp_limb_t) accu;
570 accu = accu >> GMP_LIMB_BITS;
571 }
572 *destptr++ = (mp_limb_t) accu;
573 }
574 q_ptr = roomptr + b_len;
575 q_len = a_len - b_len + 1; /* q will have m-n+1 limbs */
576 {
577 size_t j = a_len - b_len; /* m-n */
578 mp_limb_t b_msd = b_ptr[b_len - 1]; /* b[n-1] */
579 mp_limb_t b_2msd = b_ptr[b_len - 2]; /* b[n-2] */
580 mp_twolimb_t b_msdd = /* b[n-1]*beta+b[n-2] */
581 ((mp_twolimb_t) b_msd << GMP_LIMB_BITS) | b_2msd;
582 /* Division loop, traversed m-n+1 times.
583 j counts down, b is unchanged, beta/2 <= b[n-1] < beta. */
584 for (;;)
585 {
586 mp_limb_t q_star;
587 mp_limb_t c1;
588 if (r_ptr[j + b_len] < b_msd) /* r[j+n] < b[n-1] ? */
589 {
590 /* Divide r[j+n]*beta+r[j+n-1] by b[n-1], no overflow. */
591 mp_twolimb_t num =
592 ((mp_twolimb_t) r_ptr[j + b_len] << GMP_LIMB_BITS)
593 | r_ptr[j + b_len - 1];
594 q_star = num / b_msd;
595 c1 = num % b_msd;
596 }
597 else
598 {
599 /* Overflow, hence r[j+n]*beta+r[j+n-1] >= beta*b[n-1]. */
600 q_star = (mp_limb_t) ~ (mp_limb_t) 0; /* q* = beta-1 */
601 /* Test whether r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] >= beta
602 <==> r[j+n]*beta+r[j+n-1] + b[n-1] >= beta*b[n-1]+beta
603 <==> b[n-1] < floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta)
604 {<= beta !}.
605 If yes, jump directly to the subtraction loop.
606 (Otherwise, r[j+n]*beta+r[j+n-1] - (beta-1)*b[n-1] < beta
607 <==> floor((r[j+n]*beta+r[j+n-1]+b[n-1])/beta) = b[n-1] ) */
608 if (r_ptr[j + b_len] > b_msd
609 || (c1 = r_ptr[j + b_len - 1] + b_msd) < b_msd)
610 /* r[j+n] >= b[n-1]+1 or
611 r[j+n] = b[n-1] and the addition r[j+n-1]+b[n-1] gives a
612 carry. */
613 goto subtract;
614 }
615 /* q_star = q*,
616 c1 = (r[j+n]*beta+r[j+n-1]) - q* * b[n-1] (>=0, <beta). */
617 {
618 mp_twolimb_t c2 = /* c1*beta+r[j+n-2] */
619 ((mp_twolimb_t) c1 << GMP_LIMB_BITS) | r_ptr[j + b_len - 2];
620 mp_twolimb_t c3 = /* b[n-2] * q* */
621 (mp_twolimb_t) b_2msd * (mp_twolimb_t) q_star;
622 /* While c2 < c3, increase c2 and decrease c3.
623 Consider c3-c2. While it is > 0, decrease it by
624 b[n-1]*beta+b[n-2]. Because of b[n-1]*beta+b[n-2] >= beta^2/2
625 this can happen only twice. */
626 if (c3 > c2)
627 {
628 q_star = q_star - 1; /* q* := q* - 1 */
629 if (c3 - c2 > b_msdd)
630 q_star = q_star - 1; /* q* := q* - 1 */
631 }
632 }
633 if (q_star > 0)
634 subtract:
635 {
636 /* Subtract r := r - b * q* * beta^j. */
637 mp_limb_t cr;
638 {
639 const mp_limb_t *sourceptr = b_ptr;
640 mp_limb_t *destptr = r_ptr + j;
641 mp_twolimb_t carry = 0;
642 size_t count;
643 for (count = b_len; count > 0; count--)
644 {
645 /* Here 0 <= carry <= q*. */
646 carry =
647 carry
648 + (mp_twolimb_t) q_star *(mp_twolimb_t) * sourceptr++
649 + (mp_limb_t) ~ (*destptr);
650 /* Here 0 <= carry <= beta*q* + beta-1. */
651 *destptr++ = ~(mp_limb_t) carry;
652 carry = carry >> GMP_LIMB_BITS; /* <= q* */
653 }
654 cr = (mp_limb_t) carry;
655 }
656 /* Subtract cr from r_ptr[j + b_len], then forget about
657 r_ptr[j + b_len]. */
658 if (cr > r_ptr[j + b_len])
659 {
660 /* Subtraction gave a carry. */
661 q_star = q_star - 1; /* q* := q* - 1 */
662 /* Add b back. */
663 {
664 const mp_limb_t *sourceptr = b_ptr;
665 mp_limb_t *destptr = r_ptr + j;
666 mp_limb_t carry = 0;
667 size_t count;
668 for (count = b_len; count > 0; count--)
669 {
670 mp_limb_t source1 = *sourceptr++;
671 mp_limb_t source2 = *destptr;
672 *destptr++ = source1 + source2 + carry;
673 carry =
674 (carry
675 ? source1 >= (mp_limb_t) ~ source2
676 : source1 > (mp_limb_t) ~ source2);
677 }
678 }
679 /* Forget about the carry and about r[j+n]. */
680 }
681 }
682 /* q* is determined. Store it as q[j]. */
683 q_ptr[j] = q_star;
684 if (j == 0)
685 break;
686 j--;
687 }
688 }
689 r_len = b_len;
690 /* Normalise q. */
691 if (q_ptr[q_len - 1] == 0)
692 q_len--;
693# if 0 /* Not needed here, since we need r only to compare it with b/2, and
694 b is shifted left by s bits. */
695 /* Shift r right by s bits. */
696 if (s > 0)
697 {
698 mp_limb_t ptr = r_ptr + r_len;
699 mp_twolimb_t accu = 0;
700 size_t count;
701 for (count = r_len; count > 0; count--)
702 {
703 accu = (mp_twolimb_t) (mp_limb_t) accu << GMP_LIMB_BITS;
704 accu += (mp_twolimb_t) * --ptr << (GMP_LIMB_BITS - s);
705 *ptr = (mp_limb_t) (accu >> GMP_LIMB_BITS);
706 }
707 }
708# endif
709 /* Normalise r. */
710 while (r_len > 0 && r_ptr[r_len - 1] == 0)
711 r_len--;
712 }
713 /* Compare r << 1 with b. */
714 if (r_len > b_len)
715 goto increment_q;
716 {
717 size_t i;
718 for (i = b_len;;)
719 {
720 mp_limb_t r_i =
721 (i <= r_len && i > 0 ? r_ptr[i - 1] >> (GMP_LIMB_BITS - 1) : 0)
722 | (i < r_len ? r_ptr[i] << 1 : 0);
723 mp_limb_t b_i = (i < b_len ? b_ptr[i] : 0);
724 if (r_i > b_i)
725 goto increment_q;
726 if (r_i < b_i)
727 goto keep_q;
728 if (i == 0)
729 break;
730 i--;
731 }
732 }
733 if (q_len > 0 && ((q_ptr[0] & 1) != 0))
734 /* q is odd. */
735 increment_q:
736 {
737 size_t i;
738 for (i = 0; i < q_len; i++)
739 if (++(q_ptr[i]) != 0)
740 goto keep_q;
741 q_ptr[q_len++] = 1;
742 }
743keep_q:
744 if (tmp_roomptr != NULL)
745 free (tmp_roomptr);
746 q->limbs = q_ptr;
747 q->nlimbs = q_len;
748 return roomptr;
749}
750
751/* Convert a bignum a >= 0, multiplied with 10^extra_zeroes, to decimal
752 representation.
753 Destroys the contents of a.
754 Return the allocated memory - containing the decimal digits in low-to-high
755 order, terminated with a NUL character - in case of success, NULL in case
756 of memory allocation failure. */
757static char *
758convert_to_decimal (mpn_t a, size_t extra_zeroes)
759{
760 mp_limb_t *a_ptr = a.limbs;
761 size_t a_len = a.nlimbs;
762 /* 0.03345 is slightly larger than log(2)/(9*log(10)). */
763 size_t c_len = 9 * ((size_t) (a_len * (GMP_LIMB_BITS * 0.03345f)) + 1);
764 char *c_ptr = (char *) malloc (xsum (c_len, extra_zeroes));
765 if (c_ptr != NULL)
766 {
767 char *d_ptr = c_ptr;
768 for (; extra_zeroes > 0; extra_zeroes--)
769 *d_ptr++ = '0';
770 while (a_len > 0)
771 {
772 /* Divide a by 10^9, in-place. */
773 mp_limb_t remainder = 0;
774 mp_limb_t *ptr = a_ptr + a_len;
775 size_t count;
776 for (count = a_len; count > 0; count--)
777 {
778 mp_twolimb_t num =
779 ((mp_twolimb_t) remainder << GMP_LIMB_BITS) | *--ptr;
780 *ptr = num / 1000000000;
781 remainder = num % 1000000000;
782 }
783 /* Store the remainder as 9 decimal digits. */
784 for (count = 9; count > 0; count--)
785 {
786 *d_ptr++ = '0' + (remainder % 10);
787 remainder = remainder / 10;
788 }
789 /* Normalize a. */
790 if (a_ptr[a_len - 1] == 0)
791 a_len--;
792 }
793 /* Remove leading zeroes. */
794 while (d_ptr > c_ptr && d_ptr[-1] == '0')
795 d_ptr--;
796 /* But keep at least one zero. */
797 if (d_ptr == c_ptr)
798 *d_ptr++ = '0';
799 /* Terminate the string. */
800 *d_ptr = '\0';
801 }
802 return c_ptr;
803}
804
805# if NEED_PRINTF_LONG_DOUBLE
806
807/* Assuming x is finite and >= 0:
808 write x as x = 2^e * m, where m is a bignum.
809 Return the allocated memory in case of success, NULL in case of memory
810 allocation failure. */
811static void *
812decode_long_double (long double x, int *ep, mpn_t * mp)
813{
814 mpn_t m;
815 int exp;
816 long double y;
817 size_t i;
818
819 /* Allocate memory for result. */
820 m.nlimbs = (LDBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
821 m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
822 if (m.limbs == NULL)
823 return NULL;
824 /* Split into exponential part and mantissa. */
825 y = frexpl (x, &exp);
826 if (!(y >= 0.0L && y < 1.0L))
827 abort ();
828 /* x = 2^exp * y = 2^(exp - LDBL_MANT_BIT) * (y * LDBL_MANT_BIT), and the
829 latter is an integer. */
830 /* Convert the mantissa (y * LDBL_MANT_BIT) to a sequence of limbs.
831 I'm not sure whether it's safe to cast a 'long double' value between
832 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
833 'long double' values between 0 and 2^16 (to 'unsigned int' or 'int',
834 doesn't matter). */
835# if (LDBL_MANT_BIT % GMP_LIMB_BITS) != 0
836# if (LDBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
837 {
838 mp_limb_t hi, lo;
839 y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % (GMP_LIMB_BITS / 2));
840 hi = (int) y;
841 y -= hi;
842 if (!(y >= 0.0L && y < 1.0L))
843 abort ();
844 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
845 lo = (int) y;
846 y -= lo;
847 if (!(y >= 0.0L && y < 1.0L))
848 abort ();
849 m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
850 }
851# else
852 {
853 mp_limb_t d;
854 y *= (mp_limb_t) 1 << (LDBL_MANT_BIT % GMP_LIMB_BITS);
855 d = (int) y;
856 y -= d;
857 if (!(y >= 0.0L && y < 1.0L))
858 abort ();
859 m.limbs[LDBL_MANT_BIT / GMP_LIMB_BITS] = d;
860 }
861# endif
862# endif
863 for (i = LDBL_MANT_BIT / GMP_LIMB_BITS; i > 0;)
864 {
865 mp_limb_t hi, lo;
866 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
867 hi = (int) y;
868 y -= hi;
869 if (!(y >= 0.0L && y < 1.0L))
870 abort ();
871 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
872 lo = (int) y;
873 y -= lo;
874 if (!(y >= 0.0L && y < 1.0L))
875 abort ();
876 m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
877 }
878#if 0 /* On FreeBSD 6.1/x86, 'long double' numbers sometimes have excess
879 precision. */
880 if (!(y == 0.0L))
881 abort ();
882#endif
883 /* Normalise. */
884 while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
885 m.nlimbs--;
886 *mp = m;
887 *ep = exp - LDBL_MANT_BIT;
888 return m.limbs;
889}
890
891# endif
892
893# if NEED_PRINTF_DOUBLE
894
895/* Assuming x is finite and >= 0:
896 write x as x = 2^e * m, where m is a bignum.
897 Return the allocated memory in case of success, NULL in case of memory
898 allocation failure. */
899static void *
900decode_double (double x, int *ep, mpn_t * mp)
901{
902 mpn_t m;
903 int exp;
904 double y;
905 size_t i;
906
907 /* Allocate memory for result. */
908 m.nlimbs = (DBL_MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS;
909 m.limbs = (mp_limb_t *) malloc (m.nlimbs * sizeof (mp_limb_t));
910 if (m.limbs == NULL)
911 return NULL;
912 /* Split into exponential part and mantissa. */
913 y = frexp (x, &exp);
914 if (!(y >= 0.0 && y < 1.0))
915 abort ();
916 /* x = 2^exp * y = 2^(exp - DBL_MANT_BIT) * (y * DBL_MANT_BIT), and the
917 latter is an integer. */
918 /* Convert the mantissa (y * DBL_MANT_BIT) to a sequence of limbs.
919 I'm not sure whether it's safe to cast a 'double' value between
920 2^31 and 2^32 to 'unsigned int', therefore play safe and cast only
921 'double' values between 0 and 2^16 (to 'unsigned int' or 'int',
922 doesn't matter). */
923# if (DBL_MANT_BIT % GMP_LIMB_BITS) != 0
924# if (DBL_MANT_BIT % GMP_LIMB_BITS) > GMP_LIMB_BITS / 2
925 {
926 mp_limb_t hi, lo;
927 y *= (mp_limb_t) 1 << (DBL_MANT_BIT % (GMP_LIMB_BITS / 2));
928 hi = (int) y;
929 y -= hi;
930 if (!(y >= 0.0 && y < 1.0))
931 abort ();
932 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
933 lo = (int) y;
934 y -= lo;
935 if (!(y >= 0.0 && y < 1.0))
936 abort ();
937 m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = (hi << (GMP_LIMB_BITS / 2)) | lo;
938 }
939# else
940 {
941 mp_limb_t d;
942 y *= (mp_limb_t) 1 << (DBL_MANT_BIT % GMP_LIMB_BITS);
943 d = (int) y;
944 y -= d;
945 if (!(y >= 0.0 && y < 1.0))
946 abort ();
947 m.limbs[DBL_MANT_BIT / GMP_LIMB_BITS] = d;
948 }
949# endif
950# endif
951 for (i = DBL_MANT_BIT / GMP_LIMB_BITS; i > 0;)
952 {
953 mp_limb_t hi, lo;
954 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
955 hi = (int) y;
956 y -= hi;
957 if (!(y >= 0.0 && y < 1.0))
958 abort ();
959 y *= (mp_limb_t) 1 << (GMP_LIMB_BITS / 2);
960 lo = (int) y;
961 y -= lo;
962 if (!(y >= 0.0 && y < 1.0))
963 abort ();
964 m.limbs[--i] = (hi << (GMP_LIMB_BITS / 2)) | lo;
965 }
966 if (!(y == 0.0))
967 abort ();
968 /* Normalise. */
969 while (m.nlimbs > 0 && m.limbs[m.nlimbs - 1] == 0)
970 m.nlimbs--;
971 *mp = m;
972 *ep = exp - DBL_MANT_BIT;
973 return m.limbs;
974}
975
976# endif
977
978/* Assuming x = 2^e * m is finite and >= 0, and n is an integer:
979 Returns the decimal representation of round (x * 10^n).
980 Return the allocated memory - containing the decimal digits in low-to-high
981 order, terminated with a NUL character - in case of success, NULL in case
982 of memory allocation failure. */
983static char *
984scale10_round_decimal_decoded (int e, mpn_t m, void *memory, int n)
985{
986 int s;
987 size_t extra_zeroes;
988 unsigned int abs_n;
989 unsigned int abs_s;
990 mp_limb_t *pow5_ptr;
991 size_t pow5_len;
992 unsigned int s_limbs;
993 unsigned int s_bits;
994 mpn_t pow5;
995 mpn_t z;
996 void *z_memory;
997 char *digits;
998
999 if (memory == NULL)
1000 return NULL;
1001 /* x = 2^e * m, hence
1002 y = round (2^e * 10^n * m) = round (2^(e+n) * 5^n * m)
1003 = round (2^s * 5^n * m). */
1004 s = e + n;
1005 extra_zeroes = 0;
1006 /* Factor out a common power of 10 if possible. */
1007 if (s > 0 && n > 0)
1008 {
1009 extra_zeroes = (s < n ? s : n);
1010 s -= extra_zeroes;
1011 n -= extra_zeroes;
1012 }
1013 /* Here y = round (2^s * 5^n * m) * 10^extra_zeroes.
1014 Before converting to decimal, we need to compute
1015 z = round (2^s * 5^n * m). */
1016 /* Compute 5^|n|, possibly shifted by |s| bits if n and s have the same
1017 sign. 2.322 is slightly larger than log(5)/log(2). */
1018 abs_n = (n >= 0 ? n : -n);
1019 abs_s = (s >= 0 ? s : -s);
1020 pow5_ptr =
1021 (mp_limb_t *)
1022 malloc (((int) (abs_n * (2.322f / GMP_LIMB_BITS)) + 1 +
1023 abs_s / GMP_LIMB_BITS + 1) * sizeof (mp_limb_t));
1024 if (pow5_ptr == NULL)
1025 {
1026 free (memory);
1027 return NULL;
1028 }
1029 /* Initialize with 1. */
1030 pow5_ptr[0] = 1;
1031 pow5_len = 1;
1032 /* Multiply with 5^|n|. */
1033 if (abs_n > 0)
1034 {
1035 static mp_limb_t const small_pow5[13 + 1] = {
1036 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625,
1037 48828125, 244140625, 1220703125
1038 };
1039 unsigned int n13;
1040 for (n13 = 0; n13 <= abs_n; n13 += 13)
1041 {
1042 mp_limb_t digit1 = small_pow5[n13 + 13 <= abs_n ? 13 : abs_n - n13];
1043 size_t j;
1044 mp_twolimb_t carry = 0;
1045 for (j = 0; j < pow5_len; j++)
1046 {
1047 mp_limb_t digit2 = pow5_ptr[j];
1048 carry += (mp_twolimb_t) digit1 *(mp_twolimb_t) digit2;
1049 pow5_ptr[j] = (mp_limb_t) carry;
1050 carry = carry >> GMP_LIMB_BITS;
1051 }
1052 if (carry > 0)
1053 pow5_ptr[pow5_len++] = (mp_limb_t) carry;
1054 }
1055 }
1056 s_limbs = abs_s / GMP_LIMB_BITS;
1057 s_bits = abs_s % GMP_LIMB_BITS;
1058 if (n >= 0 ? s >= 0 : s <= 0)
1059 {
1060 /* Multiply with 2^|s|. */
1061 if (s_bits > 0)
1062 {
1063 mp_limb_t *ptr = pow5_ptr;
1064 mp_twolimb_t accu = 0;
1065 size_t count;
1066 for (count = pow5_len; count > 0; count--)
1067 {
1068 accu += (mp_twolimb_t) * ptr << s_bits;
1069 *ptr++ = (mp_limb_t) accu;
1070 accu = accu >> GMP_LIMB_BITS;
1071 }
1072 if (accu > 0)
1073 {
1074 *ptr = (mp_limb_t) accu;
1075 pow5_len++;
1076 }
1077 }
1078 if (s_limbs > 0)
1079 {
1080 size_t count;
1081 for (count = pow5_len; count > 0;)
1082 {
1083 count--;
1084 pow5_ptr[s_limbs + count] = pow5_ptr[count];
1085 }
1086 for (count = s_limbs; count > 0;)
1087 {
1088 count--;
1089 pow5_ptr[count] = 0;
1090 }
1091 pow5_len += s_limbs;
1092 }
1093 pow5.limbs = pow5_ptr;
1094 pow5.nlimbs = pow5_len;
1095 if (n >= 0)
1096 {
1097 /* Multiply m with pow5. No division needed. */
1098 z_memory = multiply (m, pow5, &z);
1099 }
1100 else
1101 {
1102 /* Divide m by pow5 and round. */
1103 z_memory = divide (m, pow5, &z);
1104 }
1105 }
1106 else
1107 {
1108 pow5.limbs = pow5_ptr;
1109 pow5.nlimbs = pow5_len;
1110 if (n >= 0)
1111 {
1112 /* n >= 0, s < 0.
1113 Multiply m with pow5, then divide by 2^|s|. */
1114 mpn_t numerator;
1115 mpn_t denominator;
1116 void *tmp_memory;
1117 tmp_memory = multiply (m, pow5, &numerator);
1118 if (tmp_memory == NULL)
1119 {
1120 free (pow5_ptr);
1121 free (memory);
1122 return NULL;
1123 }
1124 /* Construct 2^|s|. */
1125 {
1126 mp_limb_t *ptr = pow5_ptr + pow5_len;
1127 size_t i;
1128 for (i = 0; i < s_limbs; i++)
1129 ptr[i] = 0;
1130 ptr[s_limbs] = (mp_limb_t) 1 << s_bits;
1131 denominator.limbs = ptr;
1132 denominator.nlimbs = s_limbs + 1;
1133 }
1134 z_memory = divide (numerator, denominator, &z);
1135 free (tmp_memory);
1136 }
1137 else
1138 {
1139 /* n < 0, s > 0.
1140 Multiply m with 2^s, then divide by pow5. */
1141 mpn_t numerator;
1142 mp_limb_t *num_ptr;
1143 num_ptr = (mp_limb_t *) malloc ((m.nlimbs + s_limbs + 1)
1144 * sizeof (mp_limb_t));
1145 if (num_ptr == NULL)
1146 {
1147 free (pow5_ptr);
1148 free (memory);
1149 return NULL;
1150 }
1151 {
1152 mp_limb_t *destptr = num_ptr;
1153 {
1154 size_t i;
1155 for (i = 0; i < s_limbs; i++)
1156 *destptr++ = 0;
1157 }
1158 if (s_bits > 0)
1159 {
1160 const mp_limb_t *sourceptr = m.limbs;
1161 mp_twolimb_t accu = 0;
1162 size_t count;
1163 for (count = m.nlimbs; count > 0; count--)
1164 {
1165 accu += (mp_twolimb_t) * sourceptr++ << s_bits;
1166 *destptr++ = (mp_limb_t) accu;
1167 accu = accu >> GMP_LIMB_BITS;
1168 }
1169 if (accu > 0)
1170 *destptr++ = (mp_limb_t) accu;
1171 }
1172 else
1173 {
1174 const mp_limb_t *sourceptr = m.limbs;
1175 size_t count;
1176 for (count = m.nlimbs; count > 0; count--)
1177 *destptr++ = *sourceptr++;
1178 }
1179 numerator.limbs = num_ptr;
1180 numerator.nlimbs = destptr - num_ptr;
1181 }
1182 z_memory = divide (numerator, pow5, &z);
1183 free (num_ptr);
1184 }
1185 }
1186 free (pow5_ptr);
1187 free (memory);
1188
1189 /* Here y = round (x * 10^n) = z * 10^extra_zeroes. */
1190
1191 if (z_memory == NULL)
1192 return NULL;
1193 digits = convert_to_decimal (z, extra_zeroes);
1194 free (z_memory);
1195 return digits;
1196}
1197
1198# if NEED_PRINTF_LONG_DOUBLE
1199
1200/* Assuming x is finite and >= 0, and n is an integer:
1201 Returns the decimal representation of round (x * 10^n).
1202 Return the allocated memory - containing the decimal digits in low-to-high
1203 order, terminated with a NUL character - in case of success, NULL in case
1204 of memory allocation failure. */
1205static char *
1206scale10_round_decimal_long_double (long double x, int n)
1207{
1208 int e;
1209 mpn_t m;
1210 void *memory = decode_long_double (x, &e, &m);
1211 return scale10_round_decimal_decoded (e, m, memory, n);
1212}
1213
1214# endif
1215
1216# if NEED_PRINTF_DOUBLE
1217
1218/* Assuming x is finite and >= 0, and n is an integer:
1219 Returns the decimal representation of round (x * 10^n).
1220 Return the allocated memory - containing the decimal digits in low-to-high
1221 order, terminated with a NUL character - in case of success, NULL in case
1222 of memory allocation failure. */
1223static char *
1224scale10_round_decimal_double (double x, int n)
1225{
1226 int e;
1227 mpn_t m;
1228 void *memory = decode_double (x, &e, &m);
1229 return scale10_round_decimal_decoded (e, m, memory, n);
1230}
1231
1232# endif
1233
1234# if NEED_PRINTF_LONG_DOUBLE
1235
1236/* Assuming x is finite and > 0:
1237 Return an approximation for n with 10^n <= x < 10^(n+1).
1238 The approximation is usually the right n, but may be off by 1 sometimes. */
1239static int
1240floorlog10l (long double x)
1241{
1242 int exp;
1243 long double y;
1244 double z;
1245 double l;
1246
1247 /* Split into exponential part and mantissa. */
1248 y = frexpl (x, &exp);
1249 if (!(y >= 0.0L && y < 1.0L))
1250 abort ();
1251 if (y == 0.0L)
1252 return INT_MIN;
1253 if (y < 0.5L)
1254 {
1255 while (y <
1256 (1.0L / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1257 {
1258 y *= 1.0L * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1259 exp -= GMP_LIMB_BITS;
1260 }
1261 if (y < (1.0L / (1 << 16)))
1262 {
1263 y *= 1.0L * (1 << 16);
1264 exp -= 16;
1265 }
1266 if (y < (1.0L / (1 << 8)))
1267 {
1268 y *= 1.0L * (1 << 8);
1269 exp -= 8;
1270 }
1271 if (y < (1.0L / (1 << 4)))
1272 {
1273 y *= 1.0L * (1 << 4);
1274 exp -= 4;
1275 }
1276 if (y < (1.0L / (1 << 2)))
1277 {
1278 y *= 1.0L * (1 << 2);
1279 exp -= 2;
1280 }
1281 if (y < (1.0L / (1 << 1)))
1282 {
1283 y *= 1.0L * (1 << 1);
1284 exp -= 1;
1285 }
1286 }
1287 if (!(y >= 0.5L && y < 1.0L))
1288 abort ();
1289 /* Compute an approximation for l = log2(x) = exp + log2(y). */
1290 l = exp;
1291 z = y;
1292 if (z < 0.70710678118654752444)
1293 {
1294 z *= 1.4142135623730950488;
1295 l -= 0.5;
1296 }
1297 if (z < 0.8408964152537145431)
1298 {
1299 z *= 1.1892071150027210667;
1300 l -= 0.25;
1301 }
1302 if (z < 0.91700404320467123175)
1303 {
1304 z *= 1.0905077326652576592;
1305 l -= 0.125;
1306 }
1307 if (z < 0.9576032806985736469)
1308 {
1309 z *= 1.0442737824274138403;
1310 l -= 0.0625;
1311 }
1312 /* Now 0.95 <= z <= 1.01. */
1313 z = 1 - z;
1314 /* log(1-z) = - z - z^2/2 - z^3/3 - z^4/4 - ...
1315 Four terms are enough to get an approximation with error < 10^-7. */
1316 l -= z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1317 /* Finally multiply with log(2)/log(10), yields an approximation for
1318 log10(x). */
1319 l *= 0.30102999566398119523;
1320 /* Round down to the next integer. */
1321 return (int) l + (l < 0 ? -1 : 0);
1322}
1323
1324# endif
1325
1326# if NEED_PRINTF_DOUBLE
1327
1328/* Assuming x is finite and > 0:
1329 Return an approximation for n with 10^n <= x < 10^(n+1).
1330 The approximation is usually the right n, but may be off by 1 sometimes. */
1331static int
1332floorlog10 (double x)
1333{
1334 int exp;
1335 double y;
1336 double z;
1337 double l;
1338
1339 /* Split into exponential part and mantissa. */
1340 y = frexp (x, &exp);
1341 if (!(y >= 0.0 && y < 1.0))
1342 abort ();
1343 if (y == 0.0)
1344 return INT_MIN;
1345 if (y < 0.5)
1346 {
1347 while (y <
1348 (1.0 / (1 << (GMP_LIMB_BITS / 2)) / (1 << (GMP_LIMB_BITS / 2))))
1349 {
1350 y *= 1.0 * (1 << (GMP_LIMB_BITS / 2)) * (1 << (GMP_LIMB_BITS / 2));
1351 exp -= GMP_LIMB_BITS;
1352 }
1353 if (y < (1.0 / (1 << 16)))
1354 {
1355 y *= 1.0 * (1 << 16);
1356 exp -= 16;
1357 }
1358 if (y < (1.0 / (1 << 8)))
1359 {
1360 y *= 1.0 * (1 << 8);
1361 exp -= 8;
1362 }
1363 if (y < (1.0 / (1 << 4)))
1364 {
1365 y *= 1.0 * (1 << 4);
1366 exp -= 4;
1367 }
1368 if (y < (1.0 / (1 << 2)))
1369 {
1370 y *= 1.0 * (1 << 2);
1371 exp -= 2;
1372 }
1373 if (y < (1.0 / (1 << 1)))
1374 {
1375 y *= 1.0 * (1 << 1);
1376 exp -= 1;
1377 }
1378 }
1379 if (!(y >= 0.5 && y < 1.0))
1380 abort ();
1381 /* Compute an approximation for l = log2(x) = exp + log2(y). */
1382 l = exp;
1383 z = y;
1384 if (z < 0.70710678118654752444)
1385 {
1386 z *= 1.4142135623730950488;
1387 l -= 0.5;
1388 }
1389 if (z < 0.8408964152537145431)
1390 {
1391 z *= 1.1892071150027210667;
1392 l -= 0.25;
1393 }
1394 if (z < 0.91700404320467123175)
1395 {
1396 z *= 1.0905077326652576592;
1397 l -= 0.125;
1398 }
1399 if (z < 0.9576032806985736469)
1400 {
1401 z *= 1.0442737824274138403;
1402 l -= 0.0625;
1403 }
1404 /* Now 0.95 <= z <= 1.01. */
1405 z = 1 - z;
1406 /* log(1-z) = - z - z^2/2 - z^3/3 - z^4/4 - ...
1407 Four terms are enough to get an approximation with error < 10^-7. */
1408 l -= z * (1.0 + z * (0.5 + z * ((1.0 / 3) + z * 0.25)));
1409 /* Finally multiply with log(2)/log(10), yields an approximation for
1410 log10(x). */
1411 l *= 0.30102999566398119523;
1412 /* Round down to the next integer. */
1413 return (int) l + (l < 0 ? -1 : 0);
1414}
1415
1416# endif
1417
1418#endif
1419
1420DCHAR_T *
1421VASNPRINTF (DCHAR_T * resultbuf, size_t * lengthp,
1422 const FCHAR_T * format, va_list args)
1423{
1424 DIRECTIVES d;
1425 arguments a;
1426
1427 if (PRINTF_PARSE (format, &d, &a) < 0)
1428 /* errno is already set. */
1429 return NULL;
1430
1431#define CLEANUP() \
1432 free (d.dir); \
1433 if (a.arg) \
1434 free (a.arg);
1435
1436 if (PRINTF_FETCHARGS (args, &a) < 0)
1437 {
1438 CLEANUP ();
1439 errno = EINVAL;
1440 return NULL;
1441 }
1442
1443 {
1444 size_t buf_neededlength;
1445 TCHAR_T *buf;
1446 TCHAR_T *buf_malloced;
1447 const FCHAR_T *cp;
1448 size_t i;
1449 DIRECTIVE *dp;
1450 /* Output string accumulator. */
1451 DCHAR_T *result;
1452 size_t allocated;
1453 size_t length;
1454
1455 /* Allocate a small buffer that will hold a directive passed to
1456 sprintf or snprintf. */
1457 buf_neededlength =
1458 xsum4 (7, d.max_width_length, d.max_precision_length, 6);
1459#if HAVE_ALLOCA
1460 if (buf_neededlength < 4000 / sizeof (TCHAR_T))
1461 {
1462 buf = (TCHAR_T *) alloca (buf_neededlength * sizeof (TCHAR_T));
1463 buf_malloced = NULL;
1464 }
1465 else
1466#endif
1467 {
1468 size_t buf_memsize = xtimes (buf_neededlength, sizeof (TCHAR_T));
1469 if (size_overflow_p (buf_memsize))
1470 goto out_of_memory_1;
1471 buf = (TCHAR_T *) malloc (buf_memsize);
1472 if (buf == NULL)
1473 goto out_of_memory_1;
1474 buf_malloced = buf;
1475 }
1476
1477 if (resultbuf != NULL)
1478 {
1479 result = resultbuf;
1480 allocated = *lengthp;
1481 }
1482 else
1483 {
1484 result = NULL;
1485 allocated = 0;
1486 }
1487 length = 0;
1488 /* Invariants:
1489 result is either == resultbuf or == NULL or malloc-allocated.
1490 If length > 0, then result != NULL. */
1491
1492 /* Ensures that allocated >= needed. Aborts through a jump to
1493 out_of_memory if needed is SIZE_MAX or otherwise too big. */
1494#define ENSURE_ALLOCATION(needed) \
1495 if ((needed) > allocated) \
1496 { \
1497 size_t memory_size; \
1498 DCHAR_T *memory; \
1499 \
1500 allocated = (allocated > 0 ? xtimes (allocated, 2) : 12); \
1501 if ((needed) > allocated) \
1502 allocated = (needed); \
1503 memory_size = xtimes (allocated, sizeof (DCHAR_T)); \
1504 if (size_overflow_p (memory_size)) \
1505 goto out_of_memory; \
1506 if (result == resultbuf || result == NULL) \
1507 memory = (DCHAR_T *) malloc (memory_size); \
1508 else \
1509 memory = (DCHAR_T *) realloc (result, memory_size); \
1510 if (memory == NULL) \
1511 goto out_of_memory; \
1512 if (result == resultbuf && length > 0) \
1513 DCHAR_CPY (memory, result, length); \
1514 result = memory; \
1515 }
1516
1517 for (cp = format, i = 0, dp = &d.dir[0];; cp = dp->dir_end, i++, dp++)
1518 {
1519 if (cp != dp->dir_start)
1520 {
1521 size_t n = dp->dir_start - cp;
1522 size_t augmented_length = xsum (length, n);
1523
1524 ENSURE_ALLOCATION (augmented_length);
1525 /* This copies a piece of FCHAR_T[] into a DCHAR_T[]. Here we
1526 need that the format string contains only ASCII characters
1527 if FCHAR_T and DCHAR_T are not the same type. */
1528 if (sizeof (FCHAR_T) == sizeof (DCHAR_T))
1529 {
1530 DCHAR_CPY (result + length, (const DCHAR_T *) cp, n);
1531 length = augmented_length;
1532 }
1533 else
1534 {
1535 do
1536 result[length++] = (unsigned char) *cp++;
1537 while (--n > 0);
1538 }
1539 }
1540 if (i == d.count)
1541 break;
1542
1543 /* Execute a single directive. */
1544 if (dp->conversion == '%')
1545 {
1546 size_t augmented_length;
1547
1548 if (!(dp->arg_index == ARG_NONE))
1549 abort ();
1550 augmented_length = xsum (length, 1);
1551 ENSURE_ALLOCATION (augmented_length);
1552 result[length] = '%';
1553 length = augmented_length;
1554 }
1555 else
1556 {
1557 if (!(dp->arg_index != ARG_NONE))
1558 abort ();
1559
1560 if (dp->conversion == 'n')
1561 {
1562 switch (a.arg[dp->arg_index].type)
1563 {
1564 case TYPE_COUNT_SCHAR_POINTER:
1565 *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
1566 break;
1567 case TYPE_COUNT_SHORT_POINTER:
1568 *a.arg[dp->arg_index].a.a_count_short_pointer = length;
1569 break;
1570 case TYPE_COUNT_INT_POINTER:
1571 *a.arg[dp->arg_index].a.a_count_int_pointer = length;
1572 break;
1573 case TYPE_COUNT_LONGINT_POINTER:
1574 *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
1575 break;
1576#if HAVE_LONG_LONG_INT
1577 case TYPE_COUNT_LONGLONGINT_POINTER:
1578 *a.arg[dp->arg_index].a.a_count_longlongint_pointer =
1579 length;
1580 break;
1581#endif
1582 default:
1583 abort ();
1584 }
1585 }
1586#if ENABLE_UNISTDIO
1587 /* The unistdio extensions. */
1588 else if (dp->conversion == 'U')
1589 {
1590 arg_type type = a.arg[dp->arg_index].type;
1591 int flags = dp->flags;
1592 int has_width;
1593 size_t width;
1594 int has_precision;
1595 size_t precision;
1596
1597 has_width = 0;
1598 width = 0;
1599 if (dp->width_start != dp->width_end)
1600 {
1601 if (dp->width_arg_index != ARG_NONE)
1602 {
1603 int arg;
1604
1605 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
1606 abort ();
1607 arg = a.arg[dp->width_arg_index].a.a_int;
1608 if (arg < 0)
1609 {
1610 /* "A negative field width is taken as a '-' flag
1611 followed by a positive field width." */
1612 flags |= FLAG_LEFT;
1613 width = (unsigned int) (-arg);
1614 }
1615 else
1616 width = arg;
1617 }
1618 else
1619 {
1620 const FCHAR_T *digitp = dp->width_start;
1621
1622 do
1623 width = xsum (xtimes (width, 10), *digitp++ - '0');
1624 while (digitp != dp->width_end);
1625 }
1626 has_width = 1;
1627 }
1628
1629 has_precision = 0;
1630 precision = 0;
1631 if (dp->precision_start != dp->precision_end)
1632 {
1633 if (dp->precision_arg_index != ARG_NONE)
1634 {
1635 int arg;
1636
1637 if (!
1638 (a.arg[dp->precision_arg_index].type == TYPE_INT))
1639 abort ();
1640 arg = a.arg[dp->precision_arg_index].a.a_int;
1641 /* "A negative precision is taken as if the precision
1642 were omitted." */
1643 if (arg >= 0)
1644 {
1645 precision = arg;
1646 has_precision = 1;
1647 }
1648 }
1649 else
1650 {
1651 const FCHAR_T *digitp = dp->precision_start + 1;
1652
1653 precision = 0;
1654 while (digitp != dp->precision_end)
1655 precision =
1656 xsum (xtimes (precision, 10), *digitp++ - '0');
1657 has_precision = 1;
1658 }
1659 }
1660
1661 switch (type)
1662 {
1663 case TYPE_U8_STRING:
1664 {
1665 const uint8_t *arg = a.arg[dp->arg_index].a.a_u8_string;
1666 const uint8_t *arg_end;
1667 size_t characters;
1668
1669 if (has_precision)
1670 {
1671 /* Use only PRECISION characters, from the left. */
1672 arg_end = arg;
1673 characters = 0;
1674 for (; precision > 0; precision--)
1675 {
1676 int count = u8_strmblen (arg_end);
1677 if (count == 0)
1678 break;
1679 if (count < 0)
1680 {
1681 if (!
1682 (result == resultbuf || result == NULL))
1683 free (result);
1684 if (buf_malloced != NULL)
1685 free (buf_malloced);
1686 CLEANUP ();
1687 errno = EILSEQ;
1688 return NULL;
1689 }
1690 arg_end += count;
1691 characters++;
1692 }
1693 }
1694 else if (has_width)
1695 {
1696 /* Use the entire string, and count the number of
1697 characters. */
1698 arg_end = arg;
1699 characters = 0;
1700 for (;;)
1701 {
1702 int count = u8_strmblen (arg_end);
1703 if (count == 0)
1704 break;
1705 if (count < 0)
1706 {
1707 if (!
1708 (result == resultbuf || result == NULL))
1709 free (result);
1710 if (buf_malloced != NULL)
1711 free (buf_malloced);
1712 CLEANUP ();
1713 errno = EILSEQ;
1714 return NULL;
1715 }
1716 arg_end += count;
1717 characters++;
1718 }
1719 }
1720 else
1721 {
1722 /* Use the entire string. */
1723 arg_end = arg + u8_strlen (arg);
1724 /* The number of characters doesn't matter. */
1725 characters = 0;
1726 }
1727
1728 if (has_width && width > characters
1729 && !(dp->flags & FLAG_LEFT))
1730 {
1731 size_t n = width - characters;
1732 ENSURE_ALLOCATION (xsum (length, n));
1733 DCHAR_SET (result + length, ' ', n);
1734 length += n;
1735 }
1736
1737# if DCHAR_IS_UINT8_T
1738 {
1739 size_t n = arg_end - arg;
1740 ENSURE_ALLOCATION (xsum (length, n));
1741 DCHAR_CPY (result + length, arg, n);
1742 length += n;
1743 }
1744# else
1745 { /* Convert. */
1746 DCHAR_T *converted = result + length;
1747 size_t converted_len = allocated - length;
1748# if DCHAR_IS_TCHAR
1749 /* Convert from UTF-8 to locale encoding. */
1750 if (u8_conv_to_encoding (locale_charset (),
1751 iconveh_question_mark,
1752 arg, arg_end - arg, NULL,
1753 &converted, &converted_len)
1754 < 0)
1755# else
1756 /* Convert from UTF-8 to UTF-16/UTF-32. */
1757 converted =
1758 U8_TO_DCHAR (arg, arg_end - arg,
1759 converted, &converted_len);
1760 if (converted == NULL)
1761# endif
1762 {
1763 int saved_errno = errno;
1764 if (!(result == resultbuf || result == NULL))
1765 free (result);
1766 if (buf_malloced != NULL)
1767 free (buf_malloced);
1768 CLEANUP ();
1769 errno = saved_errno;
1770 return NULL;
1771 }
1772 if (converted != result + length)
1773 {
1774 ENSURE_ALLOCATION (xsum (length, converted_len));
1775 DCHAR_CPY (result + length, converted,
1776 converted_len);
1777 free (converted);
1778 }
1779 length += converted_len;
1780 }
1781# endif
1782
1783 if (has_width && width > characters
1784 && (dp->flags & FLAG_LEFT))
1785 {
1786 size_t n = width - characters;
1787 ENSURE_ALLOCATION (xsum (length, n));
1788 DCHAR_SET (result + length, ' ', n);
1789 length += n;
1790 }
1791 }
1792 break;
1793
1794 case TYPE_U16_STRING:
1795 {
1796 const uint16_t *arg =
1797 a.arg[dp->arg_index].a.a_u16_string;
1798 const uint16_t *arg_end;
1799 size_t characters;
1800
1801 if (has_precision)
1802 {
1803 /* Use only PRECISION characters, from the left. */
1804 arg_end = arg;
1805 characters = 0;
1806 for (; precision > 0; precision--)
1807 {
1808 int count = u16_strmblen (arg_end);
1809 if (count == 0)
1810 break;
1811 if (count < 0)
1812 {
1813 if (!
1814 (result == resultbuf || result == NULL))
1815 free (result);
1816 if (buf_malloced != NULL)
1817 free (buf_malloced);
1818 CLEANUP ();
1819 errno = EILSEQ;
1820 return NULL;
1821 }
1822 arg_end += count;
1823 characters++;
1824 }
1825 }
1826 else if (has_width)
1827 {
1828 /* Use the entire string, and count the number of
1829 characters. */
1830 arg_end = arg;
1831 characters = 0;
1832 for (;;)
1833 {
1834 int count = u16_strmblen (arg_end);
1835 if (count == 0)
1836 break;
1837 if (count < 0)
1838 {
1839 if (!
1840 (result == resultbuf || result == NULL))
1841 free (result);
1842 if (buf_malloced != NULL)
1843 free (buf_malloced);
1844 CLEANUP ();
1845 errno = EILSEQ;
1846 return NULL;
1847 }
1848 arg_end += count;
1849 characters++;
1850 }
1851 }
1852 else
1853 {
1854 /* Use the entire string. */
1855 arg_end = arg + u16_strlen (arg);
1856 /* The number of characters doesn't matter. */
1857 characters = 0;
1858 }
1859
1860 if (has_width && width > characters
1861 && !(dp->flags & FLAG_LEFT))
1862 {
1863 size_t n = width - characters;
1864 ENSURE_ALLOCATION (xsum (length, n));
1865 DCHAR_SET (result + length, ' ', n);
1866 length += n;
1867 }
1868
1869# if DCHAR_IS_UINT16_T
1870 {
1871 size_t n = arg_end - arg;
1872 ENSURE_ALLOCATION (xsum (length, n));
1873 DCHAR_CPY (result + length, arg, n);
1874 length += n;
1875 }
1876# else
1877 { /* Convert. */
1878 DCHAR_T *converted = result + length;
1879 size_t converted_len = allocated - length;
1880# if DCHAR_IS_TCHAR
1881 /* Convert from UTF-16 to locale encoding. */
1882 if (u16_conv_to_encoding (locale_charset (),
1883 iconveh_question_mark,
1884 arg, arg_end - arg, NULL,
1885 &converted, &converted_len)
1886 < 0)
1887# else
1888 /* Convert from UTF-16 to UTF-8/UTF-32. */
1889 converted =
1890 U16_TO_DCHAR (arg, arg_end - arg,
1891 converted, &converted_len);
1892 if (converted == NULL)
1893# endif
1894 {
1895 int saved_errno = errno;
1896 if (!(result == resultbuf || result == NULL))
1897 free (result);
1898 if (buf_malloced != NULL)
1899 free (buf_malloced);
1900 CLEANUP ();
1901 errno = saved_errno;
1902 return NULL;
1903 }
1904 if (converted != result + length)
1905 {
1906 ENSURE_ALLOCATION (xsum (length, converted_len));
1907 DCHAR_CPY (result + length, converted,
1908 converted_len);
1909 free (converted);
1910 }
1911 length += converted_len;
1912 }
1913# endif
1914
1915 if (has_width && width > characters
1916 && (dp->flags & FLAG_LEFT))
1917 {
1918 size_t n = width - characters;
1919 ENSURE_ALLOCATION (xsum (length, n));
1920 DCHAR_SET (result + length, ' ', n);
1921 length += n;
1922 }
1923 }
1924 break;
1925
1926 case TYPE_U32_STRING:
1927 {
1928 const uint32_t *arg =
1929 a.arg[dp->arg_index].a.a_u32_string;
1930 const uint32_t *arg_end;
1931 size_t characters;
1932
1933 if (has_precision)
1934 {
1935 /* Use only PRECISION characters, from the left. */
1936 arg_end = arg;
1937 characters = 0;
1938 for (; precision > 0; precision--)
1939 {
1940 int count = u32_strmblen (arg_end);
1941 if (count == 0)
1942 break;
1943 if (count < 0)
1944 {
1945 if (!
1946 (result == resultbuf || result == NULL))
1947 free (result);
1948 if (buf_malloced != NULL)
1949 free (buf_malloced);
1950 CLEANUP ();
1951 errno = EILSEQ;
1952 return NULL;
1953 }
1954 arg_end += count;
1955 characters++;
1956 }
1957 }
1958 else if (has_width)
1959 {
1960 /* Use the entire string, and count the number of
1961 characters. */
1962 arg_end = arg;
1963 characters = 0;
1964 for (;;)
1965 {
1966 int count = u32_strmblen (arg_end);
1967 if (count == 0)
1968 break;
1969 if (count < 0)
1970 {
1971 if (!
1972 (result == resultbuf || result == NULL))
1973 free (result);
1974 if (buf_malloced != NULL)
1975 free (buf_malloced);
1976 CLEANUP ();
1977 errno = EILSEQ;
1978 return NULL;
1979 }
1980 arg_end += count;
1981 characters++;
1982 }
1983 }
1984 else
1985 {
1986 /* Use the entire string. */
1987 arg_end = arg + u32_strlen (arg);
1988 /* The number of characters doesn't matter. */
1989 characters = 0;
1990 }
1991
1992 if (has_width && width > characters
1993 && !(dp->flags & FLAG_LEFT))
1994 {
1995 size_t n = width - characters;
1996 ENSURE_ALLOCATION (xsum (length, n));
1997 DCHAR_SET (result + length, ' ', n);
1998 length += n;
1999 }
2000
2001# if DCHAR_IS_UINT32_T
2002 {
2003 size_t n = arg_end - arg;
2004 ENSURE_ALLOCATION (xsum (length, n));
2005 DCHAR_CPY (result + length, arg, n);
2006 length += n;
2007 }
2008# else
2009 { /* Convert. */
2010 DCHAR_T *converted = result + length;
2011 size_t converted_len = allocated - length;
2012# if DCHAR_IS_TCHAR
2013 /* Convert from UTF-32 to locale encoding. */
2014 if (u32_conv_to_encoding (locale_charset (),
2015 iconveh_question_mark,
2016 arg, arg_end - arg, NULL,
2017 &converted, &converted_len)
2018 < 0)
2019# else
2020 /* Convert from UTF-32 to UTF-8/UTF-16. */
2021 converted =
2022 U32_TO_DCHAR (arg, arg_end - arg,
2023 converted, &converted_len);
2024 if (converted == NULL)
2025# endif
2026 {
2027 int saved_errno = errno;
2028 if (!(result == resultbuf || result == NULL))
2029 free (result);
2030 if (buf_malloced != NULL)
2031 free (buf_malloced);
2032 CLEANUP ();
2033 errno = saved_errno;
2034 return NULL;
2035 }
2036 if (converted != result + length)
2037 {
2038 ENSURE_ALLOCATION (xsum (length, converted_len));
2039 DCHAR_CPY (result + length, converted,
2040 converted_len);
2041 free (converted);
2042 }
2043 length += converted_len;
2044 }
2045# endif
2046
2047 if (has_width && width > characters
2048 && (dp->flags & FLAG_LEFT))
2049 {
2050 size_t n = width - characters;
2051 ENSURE_ALLOCATION (xsum (length, n));
2052 DCHAR_SET (result + length, ' ', n);
2053 length += n;
2054 }
2055 }
2056 break;
2057
2058 default:
2059 abort ();
2060 }
2061 }
2062#endif
2063#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
2064 else if ((dp->conversion == 'a' || dp->conversion == 'A')
2065# if !(NEED_PRINTF_DIRECTIVE_A || (NEED_PRINTF_LONG_DOUBLE && NEED_PRINTF_DOUBLE))
2066 && (0
2067# if NEED_PRINTF_DOUBLE
2068 || a.arg[dp->arg_index].type == TYPE_DOUBLE
2069# endif
2070# if NEED_PRINTF_LONG_DOUBLE
2071 || a.arg[dp->arg_index].type == TYPE_LONGDOUBLE
2072# endif
2073 )
2074# endif
2075 )
2076 {
2077 arg_type type = a.arg[dp->arg_index].type;
2078 int flags = dp->flags;
2079 int has_width;
2080 size_t width;
2081 int has_precision;
2082 size_t precision;
2083 size_t tmp_length;
2084 DCHAR_T tmpbuf[700];
2085 DCHAR_T *tmp;
2086 DCHAR_T *pad_ptr;
2087 DCHAR_T *p;
2088
2089 has_width = 0;
2090 width = 0;
2091 if (dp->width_start != dp->width_end)
2092 {
2093 if (dp->width_arg_index != ARG_NONE)
2094 {
2095 int arg;
2096
2097 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2098 abort ();
2099 arg = a.arg[dp->width_arg_index].a.a_int;
2100 if (arg < 0)
2101 {
2102 /* "A negative field width is taken as a '-' flag
2103 followed by a positive field width." */
2104 flags |= FLAG_LEFT;
2105 width = (unsigned int) (-arg);
2106 }
2107 else
2108 width = arg;
2109 }
2110 else
2111 {
2112 const FCHAR_T *digitp = dp->width_start;
2113
2114 do
2115 width = xsum (xtimes (width, 10), *digitp++ - '0');
2116 while (digitp != dp->width_end);
2117 }
2118 has_width = 1;
2119 }
2120
2121 has_precision = 0;
2122 precision = 0;
2123 if (dp->precision_start != dp->precision_end)
2124 {
2125 if (dp->precision_arg_index != ARG_NONE)
2126 {
2127 int arg;
2128
2129 if (!
2130 (a.arg[dp->precision_arg_index].type == TYPE_INT))
2131 abort ();
2132 arg = a.arg[dp->precision_arg_index].a.a_int;
2133 /* "A negative precision is taken as if the precision
2134 were omitted." */
2135 if (arg >= 0)
2136 {
2137 precision = arg;
2138 has_precision = 1;
2139 }
2140 }
2141 else
2142 {
2143 const FCHAR_T *digitp = dp->precision_start + 1;
2144
2145 precision = 0;
2146 while (digitp != dp->precision_end)
2147 precision =
2148 xsum (xtimes (precision, 10), *digitp++ - '0');
2149 has_precision = 1;
2150 }
2151 }
2152
2153 /* Allocate a temporary buffer of sufficient size. */
2154 if (type == TYPE_LONGDOUBLE)
2155 tmp_length = (unsigned int) ((LDBL_DIG + 1) * 0.831 /* decimal -> hexadecimal */
2156 ) + 1; /* turn floor into ceil */
2157 else
2158 tmp_length = (unsigned int) ((DBL_DIG + 1) * 0.831 /* decimal -> hexadecimal */
2159 ) + 1; /* turn floor into ceil */
2160 if (tmp_length < precision)
2161 tmp_length = precision;
2162 /* Account for sign, decimal point etc. */
2163 tmp_length = xsum (tmp_length, 12);
2164
2165 if (tmp_length < width)
2166 tmp_length = width;
2167
2168 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
2169
2170 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
2171 tmp = tmpbuf;
2172 else
2173 {
2174 size_t tmp_memsize =
2175 xtimes (tmp_length, sizeof (DCHAR_T));
2176
2177 if (size_overflow_p (tmp_memsize))
2178 /* Overflow, would lead to out of memory. */
2179 goto out_of_memory;
2180 tmp = (DCHAR_T *) malloc (tmp_memsize);
2181 if (tmp == NULL)
2182 /* Out of memory. */
2183 goto out_of_memory;
2184 }
2185
2186 pad_ptr = NULL;
2187 p = tmp;
2188 if (type == TYPE_LONGDOUBLE)
2189 {
2190# if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE
2191 long double arg = a.arg[dp->arg_index].a.a_longdouble;
2192
2193 if (isnanl (arg))
2194 {
2195 if (dp->conversion == 'A')
2196 {
2197 *p++ = 'N';
2198 *p++ = 'A';
2199 *p++ = 'N';
2200 }
2201 else
2202 {
2203 *p++ = 'n';
2204 *p++ = 'a';
2205 *p++ = 'n';
2206 }
2207 }
2208 else
2209 {
2210 int sign = 0;
2211 DECL_LONG_DOUBLE_ROUNDING
2212 BEGIN_LONG_DOUBLE_ROUNDING ();
2213
2214 if (signbit (arg)) /* arg < 0.0L or negative zero */
2215 {
2216 sign = -1;
2217 arg = -arg;
2218 }
2219
2220 if (sign < 0)
2221 *p++ = '-';
2222 else if (flags & FLAG_SHOWSIGN)
2223 *p++ = '+';
2224 else if (flags & FLAG_SPACE)
2225 *p++ = ' ';
2226
2227 if (arg > 0.0L && arg + arg == arg)
2228 {
2229 if (dp->conversion == 'A')
2230 {
2231 *p++ = 'I';
2232 *p++ = 'N';
2233 *p++ = 'F';
2234 }
2235 else
2236 {
2237 *p++ = 'i';
2238 *p++ = 'n';
2239 *p++ = 'f';
2240 }
2241 }
2242 else
2243 {
2244 int exponent;
2245 long double mantissa;
2246
2247 if (arg > 0.0L)
2248 mantissa = printf_frexpl (arg, &exponent);
2249 else
2250 {
2251 exponent = 0;
2252 mantissa = 0.0L;
2253 }
2254
2255 if (has_precision
2256 && precision <
2257 (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
2258 {
2259 /* Round the mantissa. */
2260 long double tail = mantissa;
2261 size_t q;
2262
2263 for (q = precision;; q--)
2264 {
2265 int digit = (int) tail;
2266 tail -= digit;
2267 if (q == 0)
2268 {
2269 if (digit & 1 ? tail >= 0.5L : tail >
2270 0.5L)
2271 tail = 1 - tail;
2272 else
2273 tail = -tail;
2274 break;
2275 }
2276 tail *= 16.0L;
2277 }
2278 if (tail != 0.0L)
2279 for (q = precision; q > 0; q--)
2280 tail *= 0.0625L;
2281 mantissa += tail;
2282 }
2283
2284 *p++ = '0';
2285 *p++ = dp->conversion - 'A' + 'X';
2286 pad_ptr = p;
2287 {
2288 int digit;
2289
2290 digit = (int) mantissa;
2291 mantissa -= digit;
2292 *p++ = '0' + digit;
2293 if ((flags & FLAG_ALT)
2294 || mantissa > 0.0L || precision > 0)
2295 {
2296 *p++ = decimal_point_char ();
2297 /* This loop terminates because we assume
2298 that FLT_RADIX is a power of 2. */
2299 while (mantissa > 0.0L)
2300 {
2301 mantissa *= 16.0L;
2302 digit = (int) mantissa;
2303 mantissa -= digit;
2304 *p++ = digit
2305 + (digit < 10
2306 ? '0' : dp->conversion - 10);
2307 if (precision > 0)
2308 precision--;
2309 }
2310 while (precision > 0)
2311 {
2312 *p++ = '0';
2313 precision--;
2314 }
2315 }
2316 }
2317 *p++ = dp->conversion - 'A' + 'P';
2318# if WIDE_CHAR_VERSION
2319 {
2320 static const wchar_t decimal_format[] =
2321 { '%', '+', 'd', '\0' };
2322 SNPRINTF (p, 6 + 1, decimal_format, exponent);
2323 }
2324 while (*p != '\0')
2325 p++;
2326# else
2327 if (sizeof (DCHAR_T) == 1)
2328 {
2329 sprintf ((char *) p, "%+d", exponent);
2330 while (*p != '\0')
2331 p++;
2332 }
2333 else
2334 {
2335 char expbuf[6 + 1];
2336 const char *ep;
2337 sprintf (expbuf, "%+d", exponent);
2338 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
2339 p++;
2340 }
2341# endif
2342 }
2343
2344 END_LONG_DOUBLE_ROUNDING ();
2345 }
2346# else
2347 abort ();
2348# endif
2349 }
2350 else
2351 {
2352# if NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE
2353 double arg = a.arg[dp->arg_index].a.a_double;
2354
2355 if (isnan (arg))
2356 {
2357 if (dp->conversion == 'A')
2358 {
2359 *p++ = 'N';
2360 *p++ = 'A';
2361 *p++ = 'N';
2362 }
2363 else
2364 {
2365 *p++ = 'n';
2366 *p++ = 'a';
2367 *p++ = 'n';
2368 }
2369 }
2370 else
2371 {
2372 int sign = 0;
2373
2374 if (signbit (arg)) /* arg < 0.0 or negative zero */
2375 {
2376 sign = -1;
2377 arg = -arg;
2378 }
2379
2380 if (sign < 0)
2381 *p++ = '-';
2382 else if (flags & FLAG_SHOWSIGN)
2383 *p++ = '+';
2384 else if (flags & FLAG_SPACE)
2385 *p++ = ' ';
2386
2387 if (arg > 0.0 && arg + arg == arg)
2388 {
2389 if (dp->conversion == 'A')
2390 {
2391 *p++ = 'I';
2392 *p++ = 'N';
2393 *p++ = 'F';
2394 }
2395 else
2396 {
2397 *p++ = 'i';
2398 *p++ = 'n';
2399 *p++ = 'f';
2400 }
2401 }
2402 else
2403 {
2404 int exponent;
2405 double mantissa;
2406
2407 if (arg > 0.0)
2408 mantissa = printf_frexp (arg, &exponent);
2409 else
2410 {
2411 exponent = 0;
2412 mantissa = 0.0;
2413 }
2414
2415 if (has_precision
2416 && precision <
2417 (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
2418 {
2419 /* Round the mantissa. */
2420 double tail = mantissa;
2421 size_t q;
2422
2423 for (q = precision;; q--)
2424 {
2425 int digit = (int) tail;
2426 tail -= digit;
2427 if (q == 0)
2428 {
2429 if (digit & 1 ? tail >= 0.5 : tail >
2430 0.5)
2431 tail = 1 - tail;
2432 else
2433 tail = -tail;
2434 break;
2435 }
2436 tail *= 16.0;
2437 }
2438 if (tail != 0.0)
2439 for (q = precision; q > 0; q--)
2440 tail *= 0.0625;
2441 mantissa += tail;
2442 }
2443
2444 *p++ = '0';
2445 *p++ = dp->conversion - 'A' + 'X';
2446 pad_ptr = p;
2447 {
2448 int digit;
2449
2450 digit = (int) mantissa;
2451 mantissa -= digit;
2452 *p++ = '0' + digit;
2453 if ((flags & FLAG_ALT)
2454 || mantissa > 0.0 || precision > 0)
2455 {
2456 *p++ = decimal_point_char ();
2457 /* This loop terminates because we assume
2458 that FLT_RADIX is a power of 2. */
2459 while (mantissa > 0.0)
2460 {
2461 mantissa *= 16.0;
2462 digit = (int) mantissa;
2463 mantissa -= digit;
2464 *p++ = digit
2465 + (digit < 10
2466 ? '0' : dp->conversion - 10);
2467 if (precision > 0)
2468 precision--;
2469 }
2470 while (precision > 0)
2471 {
2472 *p++ = '0';
2473 precision--;
2474 }
2475 }
2476 }
2477 *p++ = dp->conversion - 'A' + 'P';
2478# if WIDE_CHAR_VERSION
2479 {
2480 static const wchar_t decimal_format[] =
2481 { '%', '+', 'd', '\0' };
2482 SNPRINTF (p, 6 + 1, decimal_format, exponent);
2483 }
2484 while (*p != '\0')
2485 p++;
2486# else
2487 if (sizeof (DCHAR_T) == 1)
2488 {
2489 sprintf ((char *) p, "%+d", exponent);
2490 while (*p != '\0')
2491 p++;
2492 }
2493 else
2494 {
2495 char expbuf[6 + 1];
2496 const char *ep;
2497 sprintf (expbuf, "%+d", exponent);
2498 for (ep = expbuf; (*p = *ep) != '\0'; ep++)
2499 p++;
2500 }
2501# endif
2502 }
2503 }
2504# else
2505 abort ();
2506# endif
2507 }
2508 /* The generated string now extends from tmp to p, with the
2509 zero padding insertion point being at pad_ptr. */
2510 if (has_width && p - tmp < width)
2511 {
2512 size_t pad = width - (p - tmp);
2513 DCHAR_T *end = p + pad;
2514
2515 if (flags & FLAG_LEFT)
2516 {
2517 /* Pad with spaces on the right. */
2518 for (; pad > 0; pad--)
2519 *p++ = ' ';
2520 }
2521 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
2522 {
2523 /* Pad with zeroes. */
2524 DCHAR_T *q = end;
2525
2526 while (p > pad_ptr)
2527 *--q = *--p;
2528 for (; pad > 0; pad--)
2529 *p++ = '0';
2530 }
2531 else
2532 {
2533 /* Pad with spaces on the left. */
2534 DCHAR_T *q = end;
2535
2536 while (p > tmp)
2537 *--q = *--p;
2538 for (; pad > 0; pad--)
2539 *p++ = ' ';
2540 }
2541
2542 p = end;
2543 }
2544
2545 {
2546 size_t count = p - tmp;
2547
2548 if (count >= tmp_length)
2549 /* tmp_length was incorrectly calculated - fix the
2550 code above! */
2551 abort ();
2552
2553 /* Make room for the result. */
2554 if (count >= allocated - length)
2555 {
2556 size_t n = xsum (length, count);
2557
2558 ENSURE_ALLOCATION (n);
2559 }
2560
2561 /* Append the result. */
2562 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
2563 if (tmp != tmpbuf)
2564 free (tmp);
2565 length += count;
2566 }
2567 }
2568#endif
2569#if (NEED_PRINTF_INFINITE_DOUBLE || NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
2570 else if ((dp->conversion == 'f' || dp->conversion == 'F'
2571 || dp->conversion == 'e' || dp->conversion == 'E'
2572 || dp->conversion == 'g' || dp->conversion == 'G'
2573 || dp->conversion == 'a' || dp->conversion == 'A') && (0
2574# if NEED_PRINTF_DOUBLE
2575 ||
2576 a.
2577 arg
2578 [dp->
2579 arg_index].
2580 type
2581 ==
2582 TYPE_DOUBLE
2583# elif NEED_PRINTF_INFINITE_DOUBLE
2584 ||
2585 (a.
2586 arg
2587 [dp->
2588 arg_index].
2589 type
2590 ==
2591 TYPE_DOUBLE
2592 /* The systems (mingw) which produce wrong output
2593 for Inf, -Inf, and NaN also do so for -0.0.
2594 Therefore we treat this case here as well. */
2595 &&
2596 is_infinite_or_zero
2597 (a.
2598 arg
2599 [dp->
2600 arg_index].
2601 a.
2602 a_double))
2603# endif
2604# if NEED_PRINTF_LONG_DOUBLE
2605 ||
2606 a.
2607 arg
2608 [dp->
2609 arg_index].
2610 type
2611 ==
2612 TYPE_LONGDOUBLE
2613# elif NEED_PRINTF_INFINITE_LONG_DOUBLE
2614 ||
2615 (a.
2616 arg
2617 [dp->
2618 arg_index].
2619 type
2620 ==
2621 TYPE_LONGDOUBLE
2622 /* Some systems produce wrong output for Inf,
2623 -Inf, and NaN. */
2624 &&
2625 is_infinitel
2626 (a.
2627 arg
2628 [dp->
2629 arg_index].
2630 a.
2631 a_longdouble))
2632# endif
2633 ))
2634 {
2635# if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE)
2636 arg_type type = a.arg[dp->arg_index].type;
2637# endif
2638 int flags = dp->flags;
2639 int has_width;
2640 size_t width;
2641 int has_precision;
2642 size_t precision;
2643 size_t tmp_length;
2644 DCHAR_T tmpbuf[700];
2645 DCHAR_T *tmp;
2646 DCHAR_T *pad_ptr;
2647 DCHAR_T *p;
2648
2649 has_width = 0;
2650 width = 0;
2651 if (dp->width_start != dp->width_end)
2652 {
2653 if (dp->width_arg_index != ARG_NONE)
2654 {
2655 int arg;
2656
2657 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
2658 abort ();
2659 arg = a.arg[dp->width_arg_index].a.a_int;
2660 if (arg < 0)
2661 {
2662 /* "A negative field width is taken as a '-' flag
2663 followed by a positive field width." */
2664 flags |= FLAG_LEFT;
2665 width = (unsigned int) (-arg);
2666 }
2667 else
2668 width = arg;
2669 }
2670 else
2671 {
2672 const FCHAR_T *digitp = dp->width_start;
2673
2674 do
2675 width = xsum (xtimes (width, 10), *digitp++ - '0');
2676 while (digitp != dp->width_end);
2677 }
2678 has_width = 1;
2679 }
2680
2681 has_precision = 0;
2682 precision = 0;
2683 if (dp->precision_start != dp->precision_end)
2684 {
2685 if (dp->precision_arg_index != ARG_NONE)
2686 {
2687 int arg;
2688
2689 if (!
2690 (a.arg[dp->precision_arg_index].type == TYPE_INT))
2691 abort ();
2692 arg = a.arg[dp->precision_arg_index].a.a_int;
2693 /* "A negative precision is taken as if the precision
2694 were omitted." */
2695 if (arg >= 0)
2696 {
2697 precision = arg;
2698 has_precision = 1;
2699 }
2700 }
2701 else
2702 {
2703 const FCHAR_T *digitp = dp->precision_start + 1;
2704
2705 precision = 0;
2706 while (digitp != dp->precision_end)
2707 precision =
2708 xsum (xtimes (precision, 10), *digitp++ - '0');
2709 has_precision = 1;
2710 }
2711 }
2712
2713 /* POSIX specifies the default precision to be 6 for %f, %F,
2714 %e, %E, but not for %g, %G. Implementations appear to use
2715 the same default precision also for %g, %G. */
2716 if (!has_precision)
2717 precision = 6;
2718
2719 /* Allocate a temporary buffer of sufficient size. */
2720# if NEED_PRINTF_DOUBLE && NEED_PRINTF_LONG_DOUBLE
2721 tmp_length =
2722 (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : DBL_DIG + 1);
2723# elif NEED_PRINTF_INFINITE_DOUBLE && NEED_PRINTF_LONG_DOUBLE
2724 tmp_length = (type == TYPE_LONGDOUBLE ? LDBL_DIG + 1 : 0);
2725# elif NEED_PRINTF_LONG_DOUBLE
2726 tmp_length = LDBL_DIG + 1;
2727# elif NEED_PRINTF_DOUBLE
2728 tmp_length = DBL_DIG + 1;
2729# else
2730 tmp_length = 0;
2731# endif
2732 if (tmp_length < precision)
2733 tmp_length = precision;
2734# if NEED_PRINTF_LONG_DOUBLE
2735# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
2736 if (type == TYPE_LONGDOUBLE)
2737# endif
2738 if (dp->conversion == 'f' || dp->conversion == 'F')
2739 {
2740 long double arg = a.arg[dp->arg_index].a.a_longdouble;
2741 if (!(isnanl (arg) || arg + arg == arg))
2742 {
2743 /* arg is finite and nonzero. */
2744 int exponent = floorlog10l (arg < 0 ? -arg : arg);
2745 if (exponent >= 0
2746 && tmp_length < exponent + precision)
2747 tmp_length = exponent + precision;
2748 }
2749 }
2750# endif
2751# if NEED_PRINTF_DOUBLE
2752# if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
2753 if (type == TYPE_DOUBLE)
2754# endif
2755 if (dp->conversion == 'f' || dp->conversion == 'F')
2756 {
2757 double arg = a.arg[dp->arg_index].a.a_double;
2758 if (!(isnan (arg) || arg + arg == arg))
2759 {
2760 /* arg is finite and nonzero. */
2761 int exponent = floorlog10 (arg < 0 ? -arg : arg);
2762 if (exponent >= 0
2763 && tmp_length < exponent + precision)
2764 tmp_length = exponent + precision;
2765 }
2766 }
2767# endif
2768 /* Account for sign, decimal point etc. */
2769 tmp_length = xsum (tmp_length, 12);
2770
2771 if (tmp_length < width)
2772 tmp_length = width;
2773
2774 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
2775
2776 if (tmp_length <= sizeof (tmpbuf) / sizeof (DCHAR_T))
2777 tmp = tmpbuf;
2778 else
2779 {
2780 size_t tmp_memsize =
2781 xtimes (tmp_length, sizeof (DCHAR_T));
2782
2783 if (size_overflow_p (tmp_memsize))
2784 /* Overflow, would lead to out of memory. */
2785 goto out_of_memory;
2786 tmp = (DCHAR_T *) malloc (tmp_memsize);
2787 if (tmp == NULL)
2788 /* Out of memory. */
2789 goto out_of_memory;
2790 }
2791
2792 pad_ptr = NULL;
2793 p = tmp;
2794
2795# if NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE
2796# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
2797 if (type == TYPE_LONGDOUBLE)
2798# endif
2799 {
2800 long double arg = a.arg[dp->arg_index].a.a_longdouble;
2801
2802 if (isnanl (arg))
2803 {
2804 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
2805 {
2806 *p++ = 'N';
2807 *p++ = 'A';
2808 *p++ = 'N';
2809 }
2810 else
2811 {
2812 *p++ = 'n';
2813 *p++ = 'a';
2814 *p++ = 'n';
2815 }
2816 }
2817 else
2818 {
2819 int sign = 0;
2820 DECL_LONG_DOUBLE_ROUNDING
2821 BEGIN_LONG_DOUBLE_ROUNDING ();
2822
2823 if (signbit (arg)) /* arg < 0.0L or negative zero */
2824 {
2825 sign = -1;
2826 arg = -arg;
2827 }
2828
2829 if (sign < 0)
2830 *p++ = '-';
2831 else if (flags & FLAG_SHOWSIGN)
2832 *p++ = '+';
2833 else if (flags & FLAG_SPACE)
2834 *p++ = ' ';
2835
2836 if (arg > 0.0L && arg + arg == arg)
2837 {
2838 if (dp->conversion >= 'A'
2839 && dp->conversion <= 'Z')
2840 {
2841 *p++ = 'I';
2842 *p++ = 'N';
2843 *p++ = 'F';
2844 }
2845 else
2846 {
2847 *p++ = 'i';
2848 *p++ = 'n';
2849 *p++ = 'f';
2850 }
2851 }
2852 else
2853 {
2854# if NEED_PRINTF_LONG_DOUBLE
2855 pad_ptr = p;
2856
2857 if (dp->conversion == 'f'
2858 || dp->conversion == 'F')
2859 {
2860 char *digits;
2861 size_t ndigits;
2862
2863 digits =
2864 scale10_round_decimal_long_double (arg,
2865 precision);
2866 if (digits == NULL)
2867 {
2868 END_LONG_DOUBLE_ROUNDING ();
2869 goto out_of_memory;
2870 }
2871 ndigits = strlen (digits);
2872
2873 if (ndigits > precision)
2874 do
2875 {
2876 --ndigits;
2877 *p++ = digits[ndigits];
2878 }
2879 while (ndigits > precision);
2880 else
2881 *p++ = '0';
2882 /* Here ndigits <= precision. */
2883 if ((flags & FLAG_ALT) || precision > 0)
2884 {
2885 *p++ = decimal_point_char ();
2886 for (; precision > ndigits; precision--)
2887 *p++ = '0';
2888 while (ndigits > 0)
2889 {
2890 --ndigits;
2891 *p++ = digits[ndigits];
2892 }
2893 }
2894
2895 free (digits);
2896 }
2897 else if (dp->conversion == 'e'
2898 || dp->conversion == 'E')
2899 {
2900 int exponent;
2901
2902 if (arg == 0.0L)
2903 {
2904 exponent = 0;
2905 *p++ = '0';
2906 if ((flags & FLAG_ALT) || precision > 0)
2907 {
2908 *p++ = decimal_point_char ();
2909 for (; precision > 0; precision--)
2910 *p++ = '0';
2911 }
2912 }
2913 else
2914 {
2915 /* arg > 0.0L. */
2916 int adjusted;
2917 char *digits;
2918 size_t ndigits;
2919
2920 exponent = floorlog10l (arg);
2921 adjusted = 0;
2922 for (;;)
2923 {
2924 digits =
2925 scale10_round_decimal_long_double
2926 (arg, (int) precision - exponent);
2927 if (digits == NULL)
2928 {
2929 END_LONG_DOUBLE_ROUNDING ();
2930 goto out_of_memory;
2931 }
2932 ndigits = strlen (digits);
2933
2934 if (ndigits == precision + 1)
2935 break;
2936 if (ndigits < precision
2937 || ndigits > precision + 2)
2938 /* The exponent was not guessed
2939 precisely enough. */
2940 abort ();
2941 if (adjusted)
2942 /* None of two values of exponent is
2943 the right one. Prevent an endless
2944 loop. */
2945 abort ();
2946 free (digits);
2947 if (ndigits == precision)
2948 exponent -= 1;
2949 else
2950 exponent += 1;
2951 adjusted = 1;
2952 }
2953
2954 /* Here ndigits = precision+1. */
2955 *p++ = digits[--ndigits];
2956 if ((flags & FLAG_ALT) || precision > 0)
2957 {
2958 *p++ = decimal_point_char ();
2959 while (ndigits > 0)
2960 {
2961 --ndigits;
2962 *p++ = digits[ndigits];
2963 }
2964 }
2965
2966 free (digits);
2967 }
2968
2969 *p++ = dp->conversion; /* 'e' or 'E' */
2970# if WIDE_CHAR_VERSION
2971 {
2972 static const wchar_t decimal_format[] =
2973 { '%', '+', '.', '2', 'd', '\0' };
2974 SNPRINTF (p, 6 + 1, decimal_format,
2975 exponent);
2976 }
2977 while (*p != '\0')
2978 p++;
2979# else
2980 if (sizeof (DCHAR_T) == 1)
2981 {
2982 sprintf ((char *) p, "%+.2d", exponent);
2983 while (*p != '\0')
2984 p++;
2985 }
2986 else
2987 {
2988 char expbuf[6 + 1];
2989 const char *ep;
2990 sprintf (expbuf, "%+.2d", exponent);
2991 for (ep = expbuf; (*p = *ep) != '\0';
2992 ep++)
2993 p++;
2994 }
2995# endif
2996 }
2997 else if (dp->conversion == 'g'
2998 || dp->conversion == 'G')
2999 {
3000 if (precision == 0)
3001 precision = 1;
3002 /* precision >= 1. */
3003
3004 if (arg == 0.0L)
3005 /* The exponent is 0, >= -4, < precision.
3006 Use fixed-point notation. */
3007 {
3008 size_t ndigits = precision;
3009 /* Number of trailing zeroes that have to be
3010 dropped. */
3011 size_t nzeroes =
3012 (flags & FLAG_ALT ? 0 : precision - 1);
3013
3014 --ndigits;
3015 *p++ = '0';
3016 if ((flags & FLAG_ALT)
3017 || ndigits > nzeroes)
3018 {
3019 *p++ = decimal_point_char ();
3020 while (ndigits > nzeroes)
3021 {
3022 --ndigits;
3023 *p++ = '0';
3024 }
3025 }
3026 }
3027 else
3028 {
3029 /* arg > 0.0L. */
3030 int exponent;
3031 int adjusted;
3032 char *digits;
3033 size_t ndigits;
3034 size_t nzeroes;
3035
3036 exponent = floorlog10l (arg);
3037 adjusted = 0;
3038 for (;;)
3039 {
3040 digits =
3041 scale10_round_decimal_long_double
3042 (arg,
3043 (int) (precision - 1) - exponent);
3044 if (digits == NULL)
3045 {
3046 END_LONG_DOUBLE_ROUNDING ();
3047 goto out_of_memory;
3048 }
3049 ndigits = strlen (digits);
3050
3051 if (ndigits == precision)
3052 break;
3053 if (ndigits < precision - 1
3054 || ndigits > precision + 1)
3055 /* The exponent was not guessed
3056 precisely enough. */
3057 abort ();
3058 if (adjusted)
3059 /* None of two values of exponent is
3060 the right one. Prevent an endless
3061 loop. */
3062 abort ();
3063 free (digits);
3064 if (ndigits < precision)
3065 exponent -= 1;
3066 else
3067 exponent += 1;
3068 adjusted = 1;
3069 }
3070 /* Here ndigits = precision. */
3071
3072 /* Determine the number of trailing zeroes
3073 that have to be dropped. */
3074 nzeroes = 0;
3075 if ((flags & FLAG_ALT) == 0)
3076 while (nzeroes < ndigits
3077 && digits[nzeroes] == '0')
3078 nzeroes++;
3079
3080 /* The exponent is now determined. */
3081 if (exponent >= -4
3082 && exponent < (long) precision)
3083 {
3084 /* Fixed-point notation:
3085 max(exponent,0)+1 digits, then the
3086 decimal point, then the remaining
3087 digits without trailing zeroes. */
3088 if (exponent >= 0)
3089 {
3090 size_t count = exponent + 1;
3091 /* Note: count <= precision = ndigits. */
3092 for (; count > 0; count--)
3093 *p++ = digits[--ndigits];
3094 if ((flags & FLAG_ALT)
3095 || ndigits > nzeroes)
3096 {
3097 *p++ = decimal_point_char ();
3098 while (ndigits > nzeroes)
3099 {
3100 --ndigits;
3101 *p++ = digits[ndigits];
3102 }
3103 }
3104 }
3105 else
3106 {
3107 size_t count = -exponent - 1;
3108 *p++ = '0';
3109 *p++ = decimal_point_char ();
3110 for (; count > 0; count--)
3111 *p++ = '0';
3112 while (ndigits > nzeroes)
3113 {
3114 --ndigits;
3115 *p++ = digits[ndigits];
3116 }
3117 }
3118 }
3119 else
3120 {
3121 /* Exponential notation. */
3122 *p++ = digits[--ndigits];
3123 if ((flags & FLAG_ALT)
3124 || ndigits > nzeroes)
3125 {
3126 *p++ = decimal_point_char ();
3127 while (ndigits > nzeroes)
3128 {
3129 --ndigits;
3130 *p++ = digits[ndigits];
3131 }
3132 }
3133 *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
3134# if WIDE_CHAR_VERSION
3135 {
3136 static const wchar_t
3137 decimal_format[] =
3138 { '%', '+', '.', '2', 'd', '\0' };
3139 SNPRINTF (p, 6 + 1, decimal_format,
3140 exponent);
3141 }
3142 while (*p != '\0')
3143 p++;
3144# else
3145 if (sizeof (DCHAR_T) == 1)
3146 {
3147 sprintf ((char *) p, "%+.2d",
3148 exponent);
3149 while (*p != '\0')
3150 p++;
3151 }
3152 else
3153 {
3154 char expbuf[6 + 1];
3155 const char *ep;
3156 sprintf (expbuf, "%+.2d",
3157 exponent);
3158 for (ep = expbuf;
3159 (*p = *ep) != '\0'; ep++)
3160 p++;
3161 }
3162# endif
3163 }
3164
3165 free (digits);
3166 }
3167 }
3168 else
3169 abort ();
3170# else
3171 /* arg is finite. */
3172 abort ();
3173# endif
3174 }
3175
3176 END_LONG_DOUBLE_ROUNDING ();
3177 }
3178 }
3179# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3180 else
3181# endif
3182# endif
3183# if NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE
3184 {
3185 double arg = a.arg[dp->arg_index].a.a_double;
3186
3187 if (isnan (arg))
3188 {
3189 if (dp->conversion >= 'A' && dp->conversion <= 'Z')
3190 {
3191 *p++ = 'N';
3192 *p++ = 'A';
3193 *p++ = 'N';
3194 }
3195 else
3196 {
3197 *p++ = 'n';
3198 *p++ = 'a';
3199 *p++ = 'n';
3200 }
3201 }
3202 else
3203 {
3204 int sign = 0;
3205
3206 if (signbit (arg)) /* arg < 0.0 or negative zero */
3207 {
3208 sign = -1;
3209 arg = -arg;
3210 }
3211
3212 if (sign < 0)
3213 *p++ = '-';
3214 else if (flags & FLAG_SHOWSIGN)
3215 *p++ = '+';
3216 else if (flags & FLAG_SPACE)
3217 *p++ = ' ';
3218
3219 if (arg > 0.0 && arg + arg == arg)
3220 {
3221 if (dp->conversion >= 'A'
3222 && dp->conversion <= 'Z')
3223 {
3224 *p++ = 'I';
3225 *p++ = 'N';
3226 *p++ = 'F';
3227 }
3228 else
3229 {
3230 *p++ = 'i';
3231 *p++ = 'n';
3232 *p++ = 'f';
3233 }
3234 }
3235 else
3236 {
3237# if NEED_PRINTF_DOUBLE
3238 pad_ptr = p;
3239
3240 if (dp->conversion == 'f'
3241 || dp->conversion == 'F')
3242 {
3243 char *digits;
3244 size_t ndigits;
3245
3246 digits =
3247 scale10_round_decimal_double (arg,
3248 precision);
3249 if (digits == NULL)
3250 goto out_of_memory;
3251 ndigits = strlen (digits);
3252
3253 if (ndigits > precision)
3254 do
3255 {
3256 --ndigits;
3257 *p++ = digits[ndigits];
3258 }
3259 while (ndigits > precision);
3260 else
3261 *p++ = '0';
3262 /* Here ndigits <= precision. */
3263 if ((flags & FLAG_ALT) || precision > 0)
3264 {
3265 *p++ = decimal_point_char ();
3266 for (; precision > ndigits; precision--)
3267 *p++ = '0';
3268 while (ndigits > 0)
3269 {
3270 --ndigits;
3271 *p++ = digits[ndigits];
3272 }
3273 }
3274
3275 free (digits);
3276 }
3277 else if (dp->conversion == 'e'
3278 || dp->conversion == 'E')
3279 {
3280 int exponent;
3281
3282 if (arg == 0.0)
3283 {
3284 exponent = 0;
3285 *p++ = '0';
3286 if ((flags & FLAG_ALT) || precision > 0)
3287 {
3288 *p++ = decimal_point_char ();
3289 for (; precision > 0; precision--)
3290 *p++ = '0';
3291 }
3292 }
3293 else
3294 {
3295 /* arg > 0.0. */
3296 int adjusted;
3297 char *digits;
3298 size_t ndigits;
3299
3300 exponent = floorlog10 (arg);
3301 adjusted = 0;
3302 for (;;)
3303 {
3304 digits =
3305 scale10_round_decimal_double (arg,
3306 (int)
3307 precision
3308 -
3309 exponent);
3310 if (digits == NULL)
3311 goto out_of_memory;
3312 ndigits = strlen (digits);
3313
3314 if (ndigits == precision + 1)
3315 break;
3316 if (ndigits < precision
3317 || ndigits > precision + 2)
3318 /* The exponent was not guessed
3319 precisely enough. */
3320 abort ();
3321 if (adjusted)
3322 /* None of two values of exponent is
3323 the right one. Prevent an endless
3324 loop. */
3325 abort ();
3326 free (digits);
3327 if (ndigits == precision)
3328 exponent -= 1;
3329 else
3330 exponent += 1;
3331 adjusted = 1;
3332 }
3333
3334 /* Here ndigits = precision+1. */
3335 *p++ = digits[--ndigits];
3336 if ((flags & FLAG_ALT) || precision > 0)
3337 {
3338 *p++ = decimal_point_char ();
3339 while (ndigits > 0)
3340 {
3341 --ndigits;
3342 *p++ = digits[ndigits];
3343 }
3344 }
3345
3346 free (digits);
3347 }
3348
3349 *p++ = dp->conversion; /* 'e' or 'E' */
3350# if WIDE_CHAR_VERSION
3351 {
3352 static const wchar_t decimal_format[] =
3353 /* Produce the same number of exponent digits
3354 as the native printf implementation. */
3355# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
3356 { '%', '+', '.', '3', 'd', '\0' };
3357# else
3358 { '%', '+', '.', '2', 'd', '\0' };
3359# endif
3360 SNPRINTF (p, 6 + 1, decimal_format,
3361 exponent);
3362 }
3363 while (*p != '\0')
3364 p++;
3365# else
3366 {
3367 static const char decimal_format[] =
3368 /* Produce the same number of exponent digits
3369 as the native printf implementation. */
3370# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
3371 "%+.3d";
3372# else
3373 "%+.2d";
3374# endif
3375 if (sizeof (DCHAR_T) == 1)
3376 {
3377 sprintf ((char *) p, decimal_format,
3378 exponent);
3379 while (*p != '\0')
3380 p++;
3381 }
3382 else
3383 {
3384 char expbuf[6 + 1];
3385 const char *ep;
3386 sprintf (expbuf, decimal_format,
3387 exponent);
3388 for (ep = expbuf; (*p = *ep) != '\0';
3389 ep++)
3390 p++;
3391 }
3392 }
3393# endif
3394 }
3395 else if (dp->conversion == 'g'
3396 || dp->conversion == 'G')
3397 {
3398 if (precision == 0)
3399 precision = 1;
3400 /* precision >= 1. */
3401
3402 if (arg == 0.0)
3403 /* The exponent is 0, >= -4, < precision.
3404 Use fixed-point notation. */
3405 {
3406 size_t ndigits = precision;
3407 /* Number of trailing zeroes that have to be
3408 dropped. */
3409 size_t nzeroes =
3410 (flags & FLAG_ALT ? 0 : precision - 1);
3411
3412 --ndigits;
3413 *p++ = '0';
3414 if ((flags & FLAG_ALT)
3415 || ndigits > nzeroes)
3416 {
3417 *p++ = decimal_point_char ();
3418 while (ndigits > nzeroes)
3419 {
3420 --ndigits;
3421 *p++ = '0';
3422 }
3423 }
3424 }
3425 else
3426 {
3427 /* arg > 0.0. */
3428 int exponent;
3429 int adjusted;
3430 char *digits;
3431 size_t ndigits;
3432 size_t nzeroes;
3433
3434 exponent = floorlog10 (arg);
3435 adjusted = 0;
3436 for (;;)
3437 {
3438 digits =
3439 scale10_round_decimal_double (arg,
3440 (int)
3441 (precision
3442 -
3443 1) -
3444 exponent);
3445 if (digits == NULL)
3446 goto out_of_memory;
3447 ndigits = strlen (digits);
3448
3449 if (ndigits == precision)
3450 break;
3451 if (ndigits < precision - 1
3452 || ndigits > precision + 1)
3453 /* The exponent was not guessed
3454 precisely enough. */
3455 abort ();
3456 if (adjusted)
3457 /* None of two values of exponent is
3458 the right one. Prevent an endless
3459 loop. */
3460 abort ();
3461 free (digits);
3462 if (ndigits < precision)
3463 exponent -= 1;
3464 else
3465 exponent += 1;
3466 adjusted = 1;
3467 }
3468 /* Here ndigits = precision. */
3469
3470 /* Determine the number of trailing zeroes
3471 that have to be dropped. */
3472 nzeroes = 0;
3473 if ((flags & FLAG_ALT) == 0)
3474 while (nzeroes < ndigits
3475 && digits[nzeroes] == '0')
3476 nzeroes++;
3477
3478 /* The exponent is now determined. */
3479 if (exponent >= -4
3480 && exponent < (long) precision)
3481 {
3482 /* Fixed-point notation:
3483 max(exponent,0)+1 digits, then the
3484 decimal point, then the remaining
3485 digits without trailing zeroes. */
3486 if (exponent >= 0)
3487 {
3488 size_t count = exponent + 1;
3489 /* Note: count <= precision = ndigits. */
3490 for (; count > 0; count--)
3491 *p++ = digits[--ndigits];
3492 if ((flags & FLAG_ALT)
3493 || ndigits > nzeroes)
3494 {
3495 *p++ = decimal_point_char ();
3496 while (ndigits > nzeroes)
3497 {
3498 --ndigits;
3499 *p++ = digits[ndigits];
3500 }
3501 }
3502 }
3503 else
3504 {
3505 size_t count = -exponent - 1;
3506 *p++ = '0';
3507 *p++ = decimal_point_char ();
3508 for (; count > 0; count--)
3509 *p++ = '0';
3510 while (ndigits > nzeroes)
3511 {
3512 --ndigits;
3513 *p++ = digits[ndigits];
3514 }
3515 }
3516 }
3517 else
3518 {
3519 /* Exponential notation. */
3520 *p++ = digits[--ndigits];
3521 if ((flags & FLAG_ALT)
3522 || ndigits > nzeroes)
3523 {
3524 *p++ = decimal_point_char ();
3525 while (ndigits > nzeroes)
3526 {
3527 --ndigits;
3528 *p++ = digits[ndigits];
3529 }
3530 }
3531 *p++ = dp->conversion - 'G' + 'E'; /* 'e' or 'E' */
3532# if WIDE_CHAR_VERSION
3533 {
3534 static const wchar_t
3535 decimal_format[] =
3536 /* Produce the same number of exponent digits
3537 as the native printf implementation. */
3538# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
3539 { '%', '+', '.', '3', 'd', '\0' };
3540# else
3541 { '%', '+', '.', '2', 'd', '\0' };
3542# endif
3543 SNPRINTF (p, 6 + 1, decimal_format,
3544 exponent);
3545 }
3546 while (*p != '\0')
3547 p++;
3548# else
3549 {
3550 static const char decimal_format[] =
3551 /* Produce the same number of exponent digits
3552 as the native printf implementation. */
3553# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
3554 "%+.3d";
3555# else
3556 "%+.2d";
3557# endif
3558 if (sizeof (DCHAR_T) == 1)
3559 {
3560 sprintf ((char *) p,
3561 decimal_format,
3562 exponent);
3563 while (*p != '\0')
3564 p++;
3565 }
3566 else
3567 {
3568 char expbuf[6 + 1];
3569 const char *ep;
3570 sprintf (expbuf, decimal_format,
3571 exponent);
3572 for (ep = expbuf;
3573 (*p = *ep) != '\0'; ep++)
3574 p++;
3575 }
3576 }
3577# endif
3578 }
3579
3580 free (digits);
3581 }
3582 }
3583 else
3584 abort ();
3585# else
3586 /* arg is finite. */
3587 if (!(arg == 0.0))
3588 abort ();
3589
3590 pad_ptr = p;
3591
3592 if (dp->conversion == 'f'
3593 || dp->conversion == 'F')
3594 {
3595 *p++ = '0';
3596 if ((flags & FLAG_ALT) || precision > 0)
3597 {
3598 *p++ = decimal_point_char ();
3599 for (; precision > 0; precision--)
3600 *p++ = '0';
3601 }
3602 }
3603 else if (dp->conversion == 'e'
3604 || dp->conversion == 'E')
3605 {
3606 *p++ = '0';
3607 if ((flags & FLAG_ALT) || precision > 0)
3608 {
3609 *p++ = decimal_point_char ();
3610 for (; precision > 0; precision--)
3611 *p++ = '0';
3612 }
3613 *p++ = dp->conversion; /* 'e' or 'E' */
3614 *p++ = '+';
3615 /* Produce the same number of exponent digits as
3616 the native printf implementation. */
3617# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
3618 *p++ = '0';
3619# endif
3620 *p++ = '0';
3621 *p++ = '0';
3622 }
3623 else if (dp->conversion == 'g'
3624 || dp->conversion == 'G')
3625 {
3626 *p++ = '0';
3627 if (flags & FLAG_ALT)
3628 {
3629 size_t ndigits =
3630 (precision > 0 ? precision - 1 : 0);
3631 *p++ = decimal_point_char ();
3632 for (; ndigits > 0; --ndigits)
3633 *p++ = '0';
3634 }
3635 }
3636 else
3637 abort ();
3638# endif
3639 }
3640 }
3641 }
3642# endif
3643
3644 /* The generated string now extends from tmp to p, with the
3645 zero padding insertion point being at pad_ptr. */
3646 if (has_width && p - tmp < width)
3647 {
3648 size_t pad = width - (p - tmp);
3649 DCHAR_T *end = p + pad;
3650
3651 if (flags & FLAG_LEFT)
3652 {
3653 /* Pad with spaces on the right. */
3654 for (; pad > 0; pad--)
3655 *p++ = ' ';
3656 }
3657 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
3658 {
3659 /* Pad with zeroes. */
3660 DCHAR_T *q = end;
3661
3662 while (p > pad_ptr)
3663 *--q = *--p;
3664 for (; pad > 0; pad--)
3665 *p++ = '0';
3666 }
3667 else
3668 {
3669 /* Pad with spaces on the left. */
3670 DCHAR_T *q = end;
3671
3672 while (p > tmp)
3673 *--q = *--p;
3674 for (; pad > 0; pad--)
3675 *p++ = ' ';
3676 }
3677
3678 p = end;
3679 }
3680
3681 {
3682 size_t count = p - tmp;
3683
3684 if (count >= tmp_length)
3685 /* tmp_length was incorrectly calculated - fix the
3686 code above! */
3687 abort ();
3688
3689 /* Make room for the result. */
3690 if (count >= allocated - length)
3691 {
3692 size_t n = xsum (length, count);
3693
3694 ENSURE_ALLOCATION (n);
3695 }
3696
3697 /* Append the result. */
3698 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
3699 if (tmp != tmpbuf)
3700 free (tmp);
3701 length += count;
3702 }
3703 }
3704#endif
3705 else
3706 {
3707 arg_type type = a.arg[dp->arg_index].type;
3708 int flags = dp->flags;
3709#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
3710 int has_width;
3711 size_t width;
3712#endif
3713#if !USE_SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
3714 int has_precision;
3715 size_t precision;
3716#endif
3717#if NEED_PRINTF_UNBOUNDED_PRECISION
3718 int prec_ourselves;
3719#else
3720# define prec_ourselves 0
3721#endif
3722#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
3723 int pad_ourselves;
3724#else
3725# define pad_ourselves 0
3726#endif
3727 TCHAR_T *fbp;
3728 unsigned int prefix_count;
3729 int prefixes[2];
3730#if !USE_SNPRINTF
3731 size_t tmp_length;
3732 TCHAR_T tmpbuf[700];
3733 TCHAR_T *tmp;
3734#endif
3735
3736#if !USE_SNPRINTF || !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
3737 has_width = 0;
3738 width = 0;
3739 if (dp->width_start != dp->width_end)
3740 {
3741 if (dp->width_arg_index != ARG_NONE)
3742 {
3743 int arg;
3744
3745 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
3746 abort ();
3747 arg = a.arg[dp->width_arg_index].a.a_int;
3748 if (arg < 0)
3749 {
3750 /* "A negative field width is taken as a '-' flag
3751 followed by a positive field width." */
3752 flags |= FLAG_LEFT;
3753 width = (unsigned int) (-arg);
3754 }
3755 else
3756 width = arg;
3757 }
3758 else
3759 {
3760 const FCHAR_T *digitp = dp->width_start;
3761
3762 do
3763 width = xsum (xtimes (width, 10), *digitp++ - '0');
3764 while (digitp != dp->width_end);
3765 }
3766 has_width = 1;
3767 }
3768#endif
3769
3770#if !USE_SNPRINTF || NEED_PRINTF_UNBOUNDED_PRECISION
3771 has_precision = 0;
3772 precision = 6;
3773 if (dp->precision_start != dp->precision_end)
3774 {
3775 if (dp->precision_arg_index != ARG_NONE)
3776 {
3777 int arg;
3778
3779 if (!
3780 (a.arg[dp->precision_arg_index].type == TYPE_INT))
3781 abort ();
3782 arg = a.arg[dp->precision_arg_index].a.a_int;
3783 /* "A negative precision is taken as if the precision
3784 were omitted." */
3785 if (arg >= 0)
3786 {
3787 precision = arg;
3788 has_precision = 1;
3789 }
3790 }
3791 else
3792 {
3793 const FCHAR_T *digitp = dp->precision_start + 1;
3794
3795 precision = 0;
3796 while (digitp != dp->precision_end)
3797 precision =
3798 xsum (xtimes (precision, 10), *digitp++ - '0');
3799 has_precision = 1;
3800 }
3801 }
3802#endif
3803
3804#if !USE_SNPRINTF
3805 /* Allocate a temporary buffer of sufficient size for calling
3806 sprintf. */
3807 {
3808 switch (dp->conversion)
3809 {
3810
3811 case 'd':
3812 case 'i':
3813 case 'u':
3814# if HAVE_LONG_LONG_INT
3815 if (type == TYPE_LONGLONGINT
3816 || type == TYPE_ULONGLONGINT)
3817 tmp_length = (unsigned int) (sizeof (unsigned long long) * CHAR_BIT * 0.30103 /* binary -> decimal */
3818 ) + 1; /* turn floor into ceil */
3819 else
3820# endif
3821 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
3822 tmp_length = (unsigned int) (sizeof (unsigned long) * CHAR_BIT * 0.30103 /* binary -> decimal */
3823 ) + 1; /* turn floor into ceil */
3824 else
3825 tmp_length = (unsigned int) (sizeof (unsigned int) * CHAR_BIT * 0.30103 /* binary -> decimal */
3826 ) + 1; /* turn floor into ceil */
3827 if (tmp_length < precision)
3828 tmp_length = precision;
3829 /* Multiply by 2, as an estimate for FLAG_GROUP. */
3830 tmp_length = xsum (tmp_length, tmp_length);
3831 /* Add 1, to account for a leading sign. */
3832 tmp_length = xsum (tmp_length, 1);
3833 break;
3834
3835 case 'o':
3836# if HAVE_LONG_LONG_INT
3837 if (type == TYPE_LONGLONGINT
3838 || type == TYPE_ULONGLONGINT)
3839 tmp_length = (unsigned int) (sizeof (unsigned long long) * CHAR_BIT * 0.333334 /* binary -> octal */
3840 ) + 1; /* turn floor into ceil */
3841 else
3842# endif
3843 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
3844 tmp_length = (unsigned int) (sizeof (unsigned long) * CHAR_BIT * 0.333334 /* binary -> octal */
3845 ) + 1; /* turn floor into ceil */
3846 else
3847 tmp_length = (unsigned int) (sizeof (unsigned int) * CHAR_BIT * 0.333334 /* binary -> octal */
3848 ) + 1; /* turn floor into ceil */
3849 if (tmp_length < precision)
3850 tmp_length = precision;
3851 /* Add 1, to account for a leading sign. */
3852 tmp_length = xsum (tmp_length, 1);
3853 break;
3854
3855 case 'x':
3856 case 'X':
3857# if HAVE_LONG_LONG_INT
3858 if (type == TYPE_LONGLONGINT
3859 || type == TYPE_ULONGLONGINT)
3860 tmp_length = (unsigned int) (sizeof (unsigned long long) * CHAR_BIT * 0.25 /* binary -> hexadecimal */
3861 ) + 1; /* turn floor into ceil */
3862 else
3863# endif
3864 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
3865 tmp_length = (unsigned int) (sizeof (unsigned long) * CHAR_BIT * 0.25 /* binary -> hexadecimal */
3866 ) + 1; /* turn floor into ceil */
3867 else
3868 tmp_length = (unsigned int) (sizeof (unsigned int) * CHAR_BIT * 0.25 /* binary -> hexadecimal */
3869 ) + 1; /* turn floor into ceil */
3870 if (tmp_length < precision)
3871 tmp_length = precision;
3872 /* Add 2, to account for a leading sign or alternate form. */
3873 tmp_length = xsum (tmp_length, 2);
3874 break;
3875
3876 case 'f':
3877 case 'F':
3878 if (type == TYPE_LONGDOUBLE)
3879 tmp_length = (unsigned int) (LDBL_MAX_EXP * 0.30103 /* binary -> decimal */
3880 * 2 /* estimate for FLAG_GROUP */
3881 ) + 1 /* turn floor into ceil */
3882 + 10; /* sign, decimal point etc. */
3883 else
3884 tmp_length = (unsigned int) (DBL_MAX_EXP * 0.30103 /* binary -> decimal */
3885 * 2 /* estimate for FLAG_GROUP */
3886 ) + 1 /* turn floor into ceil */
3887 + 10; /* sign, decimal point etc. */
3888 tmp_length = xsum (tmp_length, precision);
3889 break;
3890
3891 case 'e':
3892 case 'E':
3893 case 'g':
3894 case 'G':
3895 tmp_length = 12; /* sign, decimal point, exponent etc. */
3896 tmp_length = xsum (tmp_length, precision);
3897 break;
3898
3899 case 'a':
3900 case 'A':
3901 if (type == TYPE_LONGDOUBLE)
3902 tmp_length = (unsigned int) (LDBL_DIG * 0.831 /* decimal -> hexadecimal */
3903 ) + 1; /* turn floor into ceil */
3904 else
3905 tmp_length = (unsigned int) (DBL_DIG * 0.831 /* decimal -> hexadecimal */
3906 ) + 1; /* turn floor into ceil */
3907 if (tmp_length < precision)
3908 tmp_length = precision;
3909 /* Account for sign, decimal point etc. */
3910 tmp_length = xsum (tmp_length, 12);
3911 break;
3912
3913 case 'c':
3914# if HAVE_WINT_T && !WIDE_CHAR_VERSION
3915 if (type == TYPE_WIDE_CHAR)
3916 tmp_length = MB_CUR_MAX;
3917 else
3918# endif
3919 tmp_length = 1;
3920 break;
3921
3922 case 's':
3923# if HAVE_WCHAR_T
3924 if (type == TYPE_WIDE_STRING)
3925 {
3926 tmp_length =
3927 local_wcslen (a.arg[dp->arg_index].a.
3928 a_wide_string);
3929
3930# if !WIDE_CHAR_VERSION
3931 tmp_length = xtimes (tmp_length, MB_CUR_MAX);
3932# endif
3933 }
3934 else
3935# endif
3936 tmp_length = strlen (a.arg[dp->arg_index].a.a_string);
3937 break;
3938
3939 case 'p':
3940 tmp_length = (unsigned int) (sizeof (void *) * CHAR_BIT * 0.25 /* binary -> hexadecimal */
3941 ) + 1 /* turn floor into ceil */
3942 + 2; /* account for leading 0x */
3943 break;
3944
3945 default:
3946 abort ();
3947 }
3948
3949# if ENABLE_UNISTDIO
3950 /* Padding considers the number of characters, therefore the
3951 number of elements after padding may be
3952 > max (tmp_length, width)
3953 but is certainly
3954 <= tmp_length + width. */
3955 tmp_length = xsum (tmp_length, width);
3956# else
3957 /* Padding considers the number of elements, says POSIX. */
3958 if (tmp_length < width)
3959 tmp_length = width;
3960# endif
3961
3962 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
3963 }
3964
3965 if (tmp_length <= sizeof (tmpbuf) / sizeof (TCHAR_T))
3966 tmp = tmpbuf;
3967 else
3968 {
3969 size_t tmp_memsize =
3970 xtimes (tmp_length, sizeof (TCHAR_T));
3971
3972 if (size_overflow_p (tmp_memsize))
3973 /* Overflow, would lead to out of memory. */
3974 goto out_of_memory;
3975 tmp = (TCHAR_T *) malloc (tmp_memsize);
3976 if (tmp == NULL)
3977 /* Out of memory. */
3978 goto out_of_memory;
3979 }
3980#endif
3981
3982 /* Decide whether to handle the precision ourselves. */
3983#if NEED_PRINTF_UNBOUNDED_PRECISION
3984 switch (dp->conversion)
3985 {
3986 case 'd':
3987 case 'i':
3988 case 'u':
3989 case 'o':
3990 case 'x':
3991 case 'X':
3992 case 'p':
3993 prec_ourselves = has_precision && (precision > 0);
3994 break;
3995 default:
3996 prec_ourselves = 0;
3997 break;
3998 }
3999#endif
4000
4001 /* Decide whether to perform the padding ourselves. */
4002#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4003 switch (dp->conversion)
4004 {
4005# if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO
4006 /* If we need conversion from TCHAR_T[] to DCHAR_T[], we need
4007 to perform the padding after this conversion. Functions
4008 with unistdio extensions perform the padding based on
4009 character count rather than element count. */
4010 case 'c':
4011 case 's':
4012# endif
4013# if NEED_PRINTF_FLAG_ZERO
4014 case 'f':
4015 case 'F':
4016 case 'e':
4017 case 'E':
4018 case 'g':
4019 case 'G':
4020 case 'a':
4021 case 'A':
4022# endif
4023 pad_ourselves = 1;
4024 break;
4025 default:
4026 pad_ourselves = prec_ourselves;
4027 break;
4028 }
4029#endif
4030
4031 /* Construct the format string for calling snprintf or
4032 sprintf. */
4033 fbp = buf;
4034 *fbp++ = '%';
4035#if NEED_PRINTF_FLAG_GROUPING
4036 /* The underlying implementation doesn't support the ' flag.
4037 Produce no grouping characters in this case; this is
4038 acceptable because the grouping is locale dependent. */
4039#else
4040 if (flags & FLAG_GROUP)
4041 *fbp++ = '\'';
4042#endif
4043 if (flags & FLAG_LEFT)
4044 *fbp++ = '-';
4045 if (flags & FLAG_SHOWSIGN)
4046 *fbp++ = '+';
4047 if (flags & FLAG_SPACE)
4048 *fbp++ = ' ';
4049 if (flags & FLAG_ALT)
4050 *fbp++ = '#';
4051 if (!pad_ourselves)
4052 {
4053 if (flags & FLAG_ZERO)
4054 *fbp++ = '0';
4055 if (dp->width_start != dp->width_end)
4056 {
4057 size_t n = dp->width_end - dp->width_start;
4058 /* The width specification is known to consist only
4059 of standard ASCII characters. */
4060 if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
4061 {
4062 memcpy (fbp, dp->width_start,
4063 n * sizeof (TCHAR_T));
4064 fbp += n;
4065 }
4066 else
4067 {
4068 const FCHAR_T *mp = dp->width_start;
4069 do
4070 *fbp++ = (unsigned char) *mp++;
4071 while (--n > 0);
4072 }
4073 }
4074 }
4075 if (!prec_ourselves)
4076 {
4077 if (dp->precision_start != dp->precision_end)
4078 {
4079 size_t n = dp->precision_end - dp->precision_start;
4080 /* The precision specification is known to consist only
4081 of standard ASCII characters. */
4082 if (sizeof (FCHAR_T) == sizeof (TCHAR_T))
4083 {
4084 memcpy (fbp, dp->precision_start,
4085 n * sizeof (TCHAR_T));
4086 fbp += n;
4087 }
4088 else
4089 {
4090 const FCHAR_T *mp = dp->precision_start;
4091 do
4092 *fbp++ = (unsigned char) *mp++;
4093 while (--n > 0);
4094 }
4095 }
4096 }
4097
4098 switch (type)
4099 {
4100#if HAVE_LONG_LONG_INT
4101 case TYPE_LONGLONGINT:
4102 case TYPE_ULONGLONGINT:
4103# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
4104 *fbp++ = 'I';
4105 *fbp++ = '6';
4106 *fbp++ = '4';
4107 break;
4108# else
4109 *fbp++ = 'l';
4110 /*FALLTHROUGH*/
4111# endif
4112#endif
4113 case TYPE_LONGINT:
4114 case TYPE_ULONGINT:
4115#if HAVE_WINT_T
4116 case TYPE_WIDE_CHAR:
4117#endif
4118#if HAVE_WCHAR_T
4119 case TYPE_WIDE_STRING:
4120#endif
4121 *fbp++ = 'l';
4122 break;
4123 case TYPE_LONGDOUBLE:
4124 *fbp++ = 'L';
4125 break;
4126 default:
4127 break;
4128 }
4129#if NEED_PRINTF_DIRECTIVE_F
4130 if (dp->conversion == 'F')
4131 *fbp = 'f';
4132 else
4133#endif
4134 *fbp = dp->conversion;
4135#if USE_SNPRINTF
4136# if !(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3))
4137 fbp[1] = '%';
4138 fbp[2] = 'n';
4139 fbp[3] = '\0';
4140# else
4141 /* On glibc2 systems from glibc >= 2.3 - probably also older
4142 ones - we know that snprintf's returns value conforms to
4143 ISO C 99: the gl_SNPRINTF_DIRECTIVE_N test passes.
4144 Therefore we can avoid using %n in this situation.
4145 On glibc2 systems from 2004-10-18 or newer, the use of %n
4146 in format strings in writable memory may crash the program
4147 (if compiled with _FORTIFY_SOURCE=2), so we should avoid it
4148 in this situation. */
4149 fbp[1] = '\0';
4150# endif
4151#else
4152 fbp[1] = '\0';
4153#endif
4154
4155 /* Construct the arguments for calling snprintf or sprintf. */
4156 prefix_count = 0;
4157 if (!pad_ourselves && dp->width_arg_index != ARG_NONE)
4158 {
4159 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
4160 abort ();
4161 prefixes[prefix_count++] =
4162 a.arg[dp->width_arg_index].a.a_int;
4163 }
4164 if (dp->precision_arg_index != ARG_NONE)
4165 {
4166 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
4167 abort ();
4168 prefixes[prefix_count++] =
4169 a.arg[dp->precision_arg_index].a.a_int;
4170 }
4171
4172#if USE_SNPRINTF
4173 /* The SNPRINTF result is appended after result[0..length].
4174 The latter is an array of DCHAR_T; SNPRINTF appends an
4175 array of TCHAR_T to it. This is possible because
4176 sizeof (TCHAR_T) divides sizeof (DCHAR_T) and
4177 alignof (TCHAR_T) <= alignof (DCHAR_T). */
4178# define TCHARS_PER_DCHAR (sizeof (DCHAR_T) / sizeof (TCHAR_T))
4179 /* Ensure that maxlen below will be >= 2. Needed on BeOS,
4180 where an snprintf() with maxlen==1 acts like sprintf(). */
4181 ENSURE_ALLOCATION (xsum (length,
4182 (2 + TCHARS_PER_DCHAR - 1)
4183 / TCHARS_PER_DCHAR));
4184 /* Prepare checking whether snprintf returns the count
4185 via %n. */
4186 *(TCHAR_T *) (result + length) = '\0';
4187#endif
4188
4189 for (;;)
4190 {
4191 int count = -1;
4192
4193#if USE_SNPRINTF
4194 int retcount = 0;
4195 size_t maxlen = allocated - length;
4196 /* SNPRINTF can fail if its second argument is
4197 > INT_MAX. */
4198 if (maxlen > INT_MAX / TCHARS_PER_DCHAR)
4199 maxlen = INT_MAX / TCHARS_PER_DCHAR;
4200 maxlen = maxlen * TCHARS_PER_DCHAR;
4201# define SNPRINTF_BUF(arg) \
4202 switch (prefix_count) \
4203 { \
4204 case 0: \
4205 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4206 maxlen, buf, \
4207 arg, &count); \
4208 break; \
4209 case 1: \
4210 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4211 maxlen, buf, \
4212 prefixes[0], arg, &count); \
4213 break; \
4214 case 2: \
4215 retcount = SNPRINTF ((TCHAR_T *) (result + length), \
4216 maxlen, buf, \
4217 prefixes[0], prefixes[1], arg, \
4218 &count); \
4219 break; \
4220 default: \
4221 abort (); \
4222 }
4223#else
4224# define SNPRINTF_BUF(arg) \
4225 switch (prefix_count) \
4226 { \
4227 case 0: \
4228 count = sprintf (tmp, buf, arg); \
4229 break; \
4230 case 1: \
4231 count = sprintf (tmp, buf, prefixes[0], arg); \
4232 break; \
4233 case 2: \
4234 count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
4235 arg); \
4236 break; \
4237 default: \
4238 abort (); \
4239 }
4240#endif
4241
4242 switch (type)
4243 {
4244 case TYPE_SCHAR:
4245 {
4246 int arg = a.arg[dp->arg_index].a.a_schar;
4247 SNPRINTF_BUF (arg);
4248 }
4249 break;
4250 case TYPE_UCHAR:
4251 {
4252 unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
4253 SNPRINTF_BUF (arg);
4254 }
4255 break;
4256 case TYPE_SHORT:
4257 {
4258 int arg = a.arg[dp->arg_index].a.a_short;
4259 SNPRINTF_BUF (arg);
4260 }
4261 break;
4262 case TYPE_USHORT:
4263 {
4264 unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
4265 SNPRINTF_BUF (arg);
4266 }
4267 break;
4268 case TYPE_INT:
4269 {
4270 int arg = a.arg[dp->arg_index].a.a_int;
4271 SNPRINTF_BUF (arg);
4272 }
4273 break;
4274 case TYPE_UINT:
4275 {
4276 unsigned int arg = a.arg[dp->arg_index].a.a_uint;
4277 SNPRINTF_BUF (arg);
4278 }
4279 break;
4280 case TYPE_LONGINT:
4281 {
4282 long int arg = a.arg[dp->arg_index].a.a_longint;
4283 SNPRINTF_BUF (arg);
4284 }
4285 break;
4286 case TYPE_ULONGINT:
4287 {
4288 unsigned long int arg =
4289 a.arg[dp->arg_index].a.a_ulongint;
4290 SNPRINTF_BUF (arg);
4291 }
4292 break;
4293#if HAVE_LONG_LONG_INT
4294 case TYPE_LONGLONGINT:
4295 {
4296 long long int arg =
4297 a.arg[dp->arg_index].a.a_longlongint;
4298 SNPRINTF_BUF (arg);
4299 }
4300 break;
4301 case TYPE_ULONGLONGINT:
4302 {
4303 unsigned long long int arg =
4304 a.arg[dp->arg_index].a.a_ulonglongint;
4305 SNPRINTF_BUF (arg);
4306 }
4307 break;
4308#endif
4309 case TYPE_DOUBLE:
4310 {
4311 double arg = a.arg[dp->arg_index].a.a_double;
4312 SNPRINTF_BUF (arg);
4313 }
4314 break;
4315 case TYPE_LONGDOUBLE:
4316 {
4317 long double arg =
4318 a.arg[dp->arg_index].a.a_longdouble;
4319 SNPRINTF_BUF (arg);
4320 }
4321 break;
4322 case TYPE_CHAR:
4323 {
4324 int arg = a.arg[dp->arg_index].a.a_char;
4325 SNPRINTF_BUF (arg);
4326 }
4327 break;
4328#if HAVE_WINT_T
4329 case TYPE_WIDE_CHAR:
4330 {
4331 wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
4332 SNPRINTF_BUF (arg);
4333 }
4334 break;
4335#endif
4336 case TYPE_STRING:
4337 {
4338 const char *arg = a.arg[dp->arg_index].a.a_string;
4339 SNPRINTF_BUF (arg);
4340 }
4341 break;
4342#if HAVE_WCHAR_T
4343 case TYPE_WIDE_STRING:
4344 {
4345 const wchar_t *arg =
4346 a.arg[dp->arg_index].a.a_wide_string;
4347 SNPRINTF_BUF (arg);
4348 }
4349 break;
4350#endif
4351 case TYPE_POINTER:
4352 {
4353 void *arg = a.arg[dp->arg_index].a.a_pointer;
4354 SNPRINTF_BUF (arg);
4355 }
4356 break;
4357 default:
4358 abort ();
4359 }
4360
4361#if USE_SNPRINTF
4362 /* Portability: Not all implementations of snprintf()
4363 are ISO C 99 compliant. Determine the number of
4364 bytes that snprintf() has produced or would have
4365 produced. */
4366 if (count >= 0)
4367 {
4368 /* Verify that snprintf() has NUL-terminated its
4369 result. */
4370 if (count < maxlen
4371 && ((TCHAR_T *) (result + length))[count] != '\0')
4372 abort ();
4373 /* Portability hack. */
4374 if (retcount > count)
4375 count = retcount;
4376 }
4377 else
4378 {
4379 /* snprintf() doesn't understand the '%n'
4380 directive. */
4381 if (fbp[1] != '\0')
4382 {
4383 /* Don't use the '%n' directive; instead, look
4384 at the snprintf() return value. */
4385 fbp[1] = '\0';
4386 continue;
4387 }
4388 else
4389 {
4390 /* Look at the snprintf() return value. */
4391 if (retcount < 0)
4392 {
4393 /* HP-UX 10.20 snprintf() is doubly deficient:
4394 It doesn't understand the '%n' directive,
4395 *and* it returns -1 (rather than the length
4396 that would have been required) when the
4397 buffer is too small. */
4398 size_t bigger_need =
4399 xsum (xtimes (allocated, 2), 12);
4400 ENSURE_ALLOCATION (bigger_need);
4401 continue;
4402 }
4403 else
4404 count = retcount;
4405 }
4406 }
4407#endif
4408
4409 /* Attempt to handle failure. */
4410 if (count < 0)
4411 {
4412 if (!(result == resultbuf || result == NULL))
4413 free (result);
4414 if (buf_malloced != NULL)
4415 free (buf_malloced);
4416 CLEANUP ();
4417 errno = EINVAL;
4418 return NULL;
4419 }
4420
4421#if USE_SNPRINTF
4422 /* Handle overflow of the allocated buffer.
4423 If such an overflow occurs, a C99 compliant snprintf()
4424 returns a count >= maxlen. However, a non-compliant
4425 snprintf() function returns only count = maxlen - 1. To
4426 cover both cases, test whether count >= maxlen - 1. */
4427 if ((unsigned int) count + 1 >= maxlen)
4428 {
4429 /* If maxlen already has attained its allowed maximum,
4430 allocating more memory will not increase maxlen.
4431 Instead of looping, bail out. */
4432 if (maxlen == INT_MAX / TCHARS_PER_DCHAR)
4433 goto overflow;
4434 else
4435 {
4436 /* Need at least (count + 1) * sizeof (TCHAR_T)
4437 bytes. (The +1 is for the trailing NUL.)
4438 But ask for (count + 2) * sizeof (TCHAR_T)
4439 bytes, so that in the next round, we likely get
4440 maxlen > (unsigned int) count + 1
4441 and so we don't get here again.
4442 And allocate proportionally, to avoid looping
4443 eternally if snprintf() reports a too small
4444 count. */
4445 size_t n = xmax (xsum (length,
4446 ((unsigned int) count + 2
4447 + TCHARS_PER_DCHAR - 1)
4448 / TCHARS_PER_DCHAR),
4449 xtimes (allocated, 2));
4450
4451 ENSURE_ALLOCATION (n);
4452 continue;
4453 }
4454 }
4455#endif
4456
4457#if NEED_PRINTF_UNBOUNDED_PRECISION
4458 if (prec_ourselves)
4459 {
4460 /* Handle the precision. */
4461 TCHAR_T *prec_ptr =
4462# if USE_SNPRINTF
4463 (TCHAR_T *) (result + length);
4464# else
4465 tmp;
4466# endif
4467 size_t prefix_count;
4468 size_t move;
4469
4470 prefix_count = 0;
4471 /* Put the additional zeroes after the sign. */
4472 if (count >= 1
4473 && (*prec_ptr == '-' || *prec_ptr == '+'
4474 || *prec_ptr == ' '))
4475 prefix_count = 1;
4476 /* Put the additional zeroes after the 0x prefix if
4477 (flags & FLAG_ALT) || (dp->conversion == 'p'). */
4478 else if (count >= 2
4479 && prec_ptr[0] == '0'
4480 && (prec_ptr[1] == 'x'
4481 || prec_ptr[1] == 'X'))
4482 prefix_count = 2;
4483
4484 move = count - prefix_count;
4485 if (precision > move)
4486 {
4487 /* Insert zeroes. */
4488 size_t insert = precision - move;
4489 TCHAR_T *prec_end;
4490
4491# if USE_SNPRINTF
4492 size_t n = xsum (length,
4493 (count + insert +
4494 TCHARS_PER_DCHAR -
4495 1) / TCHARS_PER_DCHAR);
4496 length +=
4497 (count + TCHARS_PER_DCHAR -
4498 1) / TCHARS_PER_DCHAR;
4499 ENSURE_ALLOCATION (n);
4500 length -=
4501 (count + TCHARS_PER_DCHAR -
4502 1) / TCHARS_PER_DCHAR;
4503 prec_ptr = (TCHAR_T *) (result + length);
4504# endif
4505
4506 prec_end = prec_ptr + count;
4507 prec_ptr += prefix_count;
4508
4509 while (prec_end > prec_ptr)
4510 {
4511 prec_end--;
4512 prec_end[insert] = prec_end[0];
4513 }
4514
4515 prec_end += insert;
4516 do
4517 *--prec_end = '0';
4518 while (prec_end > prec_ptr);
4519
4520 count += insert;
4521 }
4522 }
4523#endif
4524
4525#if !DCHAR_IS_TCHAR
4526# if !USE_SNPRINTF
4527 if (count >= tmp_length)
4528 /* tmp_length was incorrectly calculated - fix the
4529 code above! */
4530 abort ();
4531# endif
4532
4533 /* Convert from TCHAR_T[] to DCHAR_T[]. */
4534 if (dp->conversion == 'c' || dp->conversion == 's')
4535 {
4536 /* type = TYPE_CHAR or TYPE_WIDE_CHAR or TYPE_STRING
4537 TYPE_WIDE_STRING.
4538 The result string is not certainly ASCII. */
4539 const TCHAR_T *tmpsrc;
4540 DCHAR_T *tmpdst;
4541 size_t tmpdst_len;
4542 /* This code assumes that TCHAR_T is 'char'. */
4543 typedef int TCHAR_T_verify
4544 [2 * (sizeof (TCHAR_T) == 1) - 1];
4545# if USE_SNPRINTF
4546 tmpsrc = (TCHAR_T *) (result + length);
4547# else
4548 tmpsrc = tmp;
4549# endif
4550 tmpdst = NULL;
4551 tmpdst_len = 0;
4552 if (DCHAR_CONV_FROM_ENCODING (locale_charset (),
4553 iconveh_question_mark,
4554 tmpsrc, count,
4555 NULL,
4556 &tmpdst, &tmpdst_len)
4557 < 0)
4558 {
4559 int saved_errno = errno;
4560 if (!(result == resultbuf || result == NULL))
4561 free (result);
4562 if (buf_malloced != NULL)
4563 free (buf_malloced);
4564 CLEANUP ();
4565 errno = saved_errno;
4566 return NULL;
4567 }
4568 ENSURE_ALLOCATION (xsum (length, tmpdst_len));
4569 DCHAR_CPY (result + length, tmpdst, tmpdst_len);
4570 free (tmpdst);
4571 count = tmpdst_len;
4572 }
4573 else
4574 {
4575 /* The result string is ASCII.
4576 Simple 1:1 conversion. */
4577# if USE_SNPRINTF
4578 /* If sizeof (DCHAR_T) == sizeof (TCHAR_T), it's a
4579 no-op conversion, in-place on the array starting
4580 at (result + length). */
4581 if (sizeof (DCHAR_T) != sizeof (TCHAR_T))
4582# endif
4583 {
4584 const TCHAR_T *tmpsrc;
4585 DCHAR_T *tmpdst;
4586 size_t n;
4587
4588# if USE_SNPRINTF
4589 if (result == resultbuf)
4590 {
4591 tmpsrc = (TCHAR_T *) (result + length);
4592 /* ENSURE_ALLOCATION will not move tmpsrc
4593 (because it's part of resultbuf). */
4594 ENSURE_ALLOCATION (xsum (length, count));
4595 }
4596 else
4597 {
4598 /* ENSURE_ALLOCATION will move the array
4599 (because it uses realloc(). */
4600 ENSURE_ALLOCATION (xsum (length, count));
4601 tmpsrc = (TCHAR_T *) (result + length);
4602 }
4603# else
4604 tmpsrc = tmp;
4605 ENSURE_ALLOCATION (xsum (length, count));
4606# endif
4607 tmpdst = result + length;
4608 /* Copy backwards, because of overlapping. */
4609 tmpsrc += count;
4610 tmpdst += count;
4611 for (n = count; n > 0; n--)
4612 *--tmpdst = (unsigned char) *--tmpsrc;
4613 }
4614 }
4615#endif
4616
4617#if DCHAR_IS_TCHAR && !USE_SNPRINTF
4618 /* Make room for the result. */
4619 if (count > allocated - length)
4620 {
4621 /* Need at least count elements. But allocate
4622 proportionally. */
4623 size_t n =
4624 xmax (xsum (length, count), xtimes (allocated, 2));
4625
4626 ENSURE_ALLOCATION (n);
4627 }
4628#endif
4629
4630 /* Here count <= allocated - length. */
4631
4632 /* Perform padding. */
4633#if !DCHAR_IS_TCHAR || ENABLE_UNISTDIO || NEED_PRINTF_FLAG_ZERO || NEED_PRINTF_UNBOUNDED_PRECISION
4634 if (pad_ourselves && has_width)
4635 {
4636 size_t w;
4637# if ENABLE_UNISTDIO
4638 /* Outside POSIX, it's preferrable to compare the width
4639 against the number of _characters_ of the converted
4640 value. */
4641 w = DCHAR_MBSNLEN (result + length, count);
4642# else
4643 /* The width is compared against the number of _bytes_
4644 of the converted value, says POSIX. */
4645 w = count;
4646# endif
4647 if (w < width)
4648 {
4649 size_t pad = width - w;
4650# if USE_SNPRINTF
4651 /* Make room for the result. */
4652 if (xsum (count, pad) > allocated - length)
4653 {
4654 /* Need at least count + pad elements. But
4655 allocate proportionally. */
4656 size_t n = xmax (xsum3 (length, count, pad),
4657 xtimes (allocated, 2));
4658
4659 length += count;
4660 ENSURE_ALLOCATION (n);
4661 length -= count;
4662 }
4663 /* Here count + pad <= allocated - length. */
4664# endif
4665 {
4666# if !DCHAR_IS_TCHAR || USE_SNPRINTF
4667 DCHAR_T *const rp = result + length;
4668# else
4669 DCHAR_T *const rp = tmp;
4670# endif
4671 DCHAR_T *p = rp + count;
4672 DCHAR_T *end = p + pad;
4673# if NEED_PRINTF_FLAG_ZERO
4674 DCHAR_T *pad_ptr;
4675# if !DCHAR_IS_TCHAR
4676 if (dp->conversion == 'c'
4677 || dp->conversion == 's')
4678 /* No zero-padding for string directives. */
4679 pad_ptr = NULL;
4680 else
4681# endif
4682 {
4683 pad_ptr = (*rp == '-' ? rp + 1 : rp);
4684 /* No zero-padding of "inf" and "nan". */
4685 if ((*pad_ptr >= 'A' && *pad_ptr <= 'Z')
4686 || (*pad_ptr >= 'a' && *pad_ptr <= 'z'))
4687 pad_ptr = NULL;
4688 }
4689# endif
4690 /* The generated string now extends from rp to p,
4691 with the zero padding insertion point being at
4692 pad_ptr. */
4693
4694 count = count + pad; /* = end - rp */
4695
4696 if (flags & FLAG_LEFT)
4697 {
4698 /* Pad with spaces on the right. */
4699 for (; pad > 0; pad--)
4700 *p++ = ' ';
4701 }
4702# if NEED_PRINTF_FLAG_ZERO
4703 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
4704 {
4705 /* Pad with zeroes. */
4706 DCHAR_T *q = end;
4707
4708 while (p > pad_ptr)
4709 *--q = *--p;
4710 for (; pad > 0; pad--)
4711 *p++ = '0';
4712 }
4713# endif
4714 else
4715 {
4716 /* Pad with spaces on the left. */
4717 DCHAR_T *q = end;
4718
4719 while (p > rp)
4720 *--q = *--p;
4721 for (; pad > 0; pad--)
4722 *p++ = ' ';
4723 }
4724 }
4725 }
4726 }
4727#endif
4728
4729#if DCHAR_IS_TCHAR && !USE_SNPRINTF
4730 if (count >= tmp_length)
4731 /* tmp_length was incorrectly calculated - fix the
4732 code above! */
4733 abort ();
4734#endif
4735
4736 /* Here still count <= allocated - length. */
4737
4738#if !DCHAR_IS_TCHAR || USE_SNPRINTF
4739 /* The snprintf() result did fit. */
4740#else
4741 /* Append the sprintf() result. */
4742 memcpy (result + length, tmp, count * sizeof (DCHAR_T));
4743#endif
4744#if !USE_SNPRINTF
4745 if (tmp != tmpbuf)
4746 free (tmp);
4747#endif
4748
4749#if NEED_PRINTF_DIRECTIVE_F
4750 if (dp->conversion == 'F')
4751 {
4752 /* Convert the %f result to upper case for %F. */
4753 DCHAR_T *rp = result + length;
4754 size_t rc;
4755 for (rc = count; rc > 0; rc--, rp++)
4756 if (*rp >= 'a' && *rp <= 'z')
4757 *rp = *rp - 'a' + 'A';
4758 }
4759#endif
4760
4761 length += count;
4762 break;
4763 }
4764 }
4765 }
4766 }
4767
4768 /* Add the final NUL. */
4769 ENSURE_ALLOCATION (xsum (length, 1));
4770 result[length] = '\0';
4771
4772 if (result != resultbuf && length + 1 < allocated)
4773 {
4774 /* Shrink the allocated memory if possible. */
4775 DCHAR_T *memory;
4776
4777 memory =
4778 (DCHAR_T *) realloc (result, (length + 1) * sizeof (DCHAR_T));
4779 if (memory != NULL)
4780 result = memory;
4781 }
4782
4783 if (buf_malloced != NULL)
4784 free (buf_malloced);
4785 CLEANUP ();
4786 *lengthp = length;
4787 /* Note that we can produce a big string of a length > INT_MAX. POSIX
4788 says that snprintf() fails with errno = EOVERFLOW in this case, but
4789 that's only because snprintf() returns an 'int'. This function does
4790 not have this limitation. */
4791 return result;
4792
4793 overflow:
4794 if (!(result == resultbuf || result == NULL))
4795 free (result);
4796 if (buf_malloced != NULL)
4797 free (buf_malloced);
4798 CLEANUP ();
4799 errno = EOVERFLOW;
4800 return NULL;
4801
4802 out_of_memory:
4803 if (!(result == resultbuf || result == NULL))
4804 free (result);
4805 if (buf_malloced != NULL)
4806 free (buf_malloced);
4807 out_of_memory_1:
4808 CLEANUP ();
4809 errno = ENOMEM;
4810 return NULL;
4811 }
4812}
4813
4814#undef TCHARS_PER_DCHAR
4815#undef SNPRINTF
4816#undef USE_SNPRINTF
4817#undef DCHAR_CPY
4818#undef PRINTF_PARSE
4819#undef DIRECTIVES
4820#undef DIRECTIVE
4821#undef DCHAR_IS_TCHAR
4822#undef TCHAR_T
4823#undef DCHAR_T
4824#undef FCHAR_T
4825#undef VASNPRINTF
diff --git a/src/daemon/https/lgl/vasnprintf.h b/src/daemon/https/lgl/vasnprintf.h
new file mode 100644
index 00000000..4524ce77
--- /dev/null
+++ b/src/daemon/https/lgl/vasnprintf.h
@@ -0,0 +1,81 @@
1/* vsprintf with automatic memory allocation.
2 Copyright (C) 2002-2004, 2007 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License along
15 with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18#ifndef _VASNPRINTF_H
19#define _VASNPRINTF_H
20
21/* Get va_list. */
22#include <stdarg.h>
23
24/* Get size_t. */
25#include <stddef.h>
26
27#ifndef __attribute__
28/* This feature is available in gcc versions 2.5 and later. */
29# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
30# define __attribute__(Spec) /* empty */
31# endif
32/* The __-protected variants of `format' and `printf' attributes
33 are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
34# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
35# define __format__ format
36# define __printf__ printf
37# endif
38#endif
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
44/* Write formatted output to a string dynamically allocated with malloc().
45 You can pass a preallocated buffer for the result in RESULTBUF and its
46 size in *LENGTHP; otherwise you pass RESULTBUF = NULL.
47 If successful, return the address of the string (this may be = RESULTBUF
48 if no dynamic memory allocation was necessary) and set *LENGTHP to the
49 number of resulting bytes, excluding the trailing NUL. Upon error, set
50 errno and return NULL.
51
52 When dynamic memory allocation occurs, the preallocated buffer is left
53 alone (with possibly modified contents). This makes it possible to use
54 a statically allocated or stack-allocated buffer, like this:
55
56 char buf[100];
57 size_t len = sizeof (buf);
58 char *output = vasnprintf (buf, &len, format, args);
59 if (output == NULL)
60 ... error handling ...;
61 else
62 {
63 ... use the output string ...;
64 if (output != buf)
65 free (output);
66 }
67 */
68#if REPLACE_VASNPRINTF
69# define asnprintf rpl_asnprintf
70# define vasnprintf rpl_vasnprintf
71#endif
72extern char * asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...)
73 __attribute__ ((__format__ (__printf__, 3, 4)));
74extern char * vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args)
75 __attribute__ ((__format__ (__printf__, 3, 0)));
76
77#ifdef __cplusplus
78}
79#endif
80
81#endif /* _VASNPRINTF_H */
diff --git a/src/daemon/https/lgl/vasprintf.c b/src/daemon/https/lgl/vasprintf.c
new file mode 100644
index 00000000..7b645460
--- /dev/null
+++ b/src/daemon/https/lgl/vasprintf.c
@@ -0,0 +1,56 @@
1/* Formatted output to strings.
2 Copyright (C) 1999, 2002, 2006-2007 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License along
15 with this program; if not, write to the Free Software Foundation,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18#include <config.h>
19
20/* Specification. */
21#ifdef IN_LIBASPRINTF
22# include "vasprintf.h"
23#else
24# include <stdio.h>
25#endif
26
27#include <errno.h>
28#include <limits.h>
29#include <stdlib.h>
30
31#include "vasnprintf.h"
32
33/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */
34#ifndef EOVERFLOW
35# define EOVERFLOW E2BIG
36#endif
37
38int
39vasprintf (char **resultp, const char *format, va_list args)
40{
41 size_t length;
42 char *result = vasnprintf (NULL, &length, format, args);
43 if (result == NULL)
44 return -1;
45
46 if (length > INT_MAX)
47 {
48 free (result);
49 errno = EOVERFLOW;
50 return -1;
51 }
52
53 *resultp = result;
54 /* Return the number of resulting bytes, excluding the trailing NUL. */
55 return length;
56}
diff --git a/src/daemon/https/lgl/xsize.h b/src/daemon/https/lgl/xsize.h
new file mode 100644
index 00000000..d37de38a
--- /dev/null
+++ b/src/daemon/https/lgl/xsize.h
@@ -0,0 +1,109 @@
1/* xsize.h -- Checked size_t computations.
2
3 Copyright (C) 2003 Free Software Foundation, Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program; if not, write to the Free Software Foundation,
17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
18
19#ifndef _XSIZE_H
20#define _XSIZE_H
21
22/* Get size_t. */
23#include <stddef.h>
24
25/* Get SIZE_MAX. */
26#include <limits.h>
27#if HAVE_STDINT_H
28# include <stdint.h>
29#endif
30
31/* The size of memory objects is often computed through expressions of
32 type size_t. Example:
33 void* p = malloc (header_size + n * element_size).
34 These computations can lead to overflow. When this happens, malloc()
35 returns a piece of memory that is way too small, and the program then
36 crashes while attempting to fill the memory.
37 To avoid this, the functions and macros in this file check for overflow.
38 The convention is that SIZE_MAX represents overflow.
39 malloc (SIZE_MAX) is not guaranteed to fail -- think of a malloc
40 implementation that uses mmap --, it's recommended to use size_overflow_p()
41 or size_in_bounds_p() before invoking malloc().
42 The example thus becomes:
43 size_t size = xsum (header_size, xtimes (n, element_size));
44 void *p = (size_in_bounds_p (size) ? malloc (size) : NULL);
45*/
46
47/* Convert an arbitrary value >= 0 to type size_t. */
48#define xcast_size_t(N) \
49 ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX)
50
51/* Sum of two sizes, with overflow check. */
52static inline size_t
53#if __GNUC__ >= 3
54__attribute__ ((__pure__))
55#endif
56xsum (size_t size1, size_t size2)
57{
58 size_t sum = size1 + size2;
59 return (sum >= size1 ? sum : SIZE_MAX);
60}
61
62/* Sum of three sizes, with overflow check. */
63static inline size_t
64#if __GNUC__ >= 3
65__attribute__ ((__pure__))
66#endif
67xsum3 (size_t size1, size_t size2, size_t size3)
68{
69 return xsum (xsum (size1, size2), size3);
70}
71
72/* Sum of four sizes, with overflow check. */
73static inline size_t
74#if __GNUC__ >= 3
75__attribute__ ((__pure__))
76#endif
77xsum4 (size_t size1, size_t size2, size_t size3, size_t size4)
78{
79 return xsum (xsum (xsum (size1, size2), size3), size4);
80}
81
82/* Maximum of two sizes, with overflow check. */
83static inline size_t
84#if __GNUC__ >= 3
85__attribute__ ((__pure__))
86#endif
87xmax (size_t size1, size_t size2)
88{
89 /* No explicit check is needed here, because for any n:
90 max (SIZE_MAX, n) == SIZE_MAX and max (n, SIZE_MAX) == SIZE_MAX. */
91 return (size1 >= size2 ? size1 : size2);
92}
93
94/* Multiplication of a count with an element size, with overflow check.
95 The count must be >= 0 and the element size must be > 0.
96 This is a macro, not an inline function, so that it works correctly even
97 when N is of a wider tupe and N > SIZE_MAX. */
98#define xtimes(N, ELSIZE) \
99 ((N) <= SIZE_MAX / (ELSIZE) ? (size_t) (N) * (ELSIZE) : SIZE_MAX)
100
101/* Check for overflow. */
102#define size_overflow_p(SIZE) \
103 ((SIZE) == SIZE_MAX)
104/* Check against overflow. */
105#define size_in_bounds_p(SIZE) \
106 ((SIZE) != SIZE_MAX)
107
108#endif /* _XSIZE_H */
109
diff --git a/src/daemon/https/list.h b/src/daemon/https/list.h
new file mode 100644
index 00000000..f1c2faa1
--- /dev/null
+++ b/src/daemon/https/list.h
@@ -0,0 +1,449 @@
1/*
2 * Copyright (C) 2001,2002 Paul Sheer
3 *
4 * This file is part of GNUTLS.
5 *
6 * GNUTLS is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GNUTLS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21/*
22 SOAP:
23
24 Academics always want to implement hash tables (i.e. dictionaries),
25 singly or doubly linked lists, and queues, because ... well ... they
26 know how.
27
28 These datatypes are nonsense for the following reasons:
29 hash tables: Hash tables are a mapping of some
30 string to some data, where that data is going to
31 be accessed COMPLETELY RANDOMLY. This is what it
32 is for. However it is extremely rare to have a
33 large number of data elements which really are
34 being accessed in a completely random way.
35
36 lists: appending and searching through lists is always
37 slow because these operations search all the way
38 through the list.
39
40 queues: whats the difference between a queue and a list?
41 very little really.
42
43 The system implemented here is a doubly linked list with previous
44 search index that can be appended or prepended with no overhead,
45 implemented entirely in macros. It is hence as versatile as a
46 doubly/singly linked list or queue and blazingly fast. Hence doing
47 sequential searches where the next search result is likely to be
48 closely indexed to the previous (usual case), is efficient.
49
50 Of course this doesn't mean you should use this as a hash table
51 where you REALLY need a hash table.
52
53*/
54
55/********** example usage **********/
56/*
57
58#include "list.h"
59
60extern void free (void *x);
61extern char *strdup (char *s);
62
63// consider a list of elements containing an `int' and a `char *'
64LIST_TYPE_DECLARE (names, char *s; int i;);
65
66// for sorting, to compare elements
67static int cm (names **a, names **b)
68{
69 return strcmp ((*a)->s, (*b)->s);
70}
71
72// to free the contents of an element
73static void free_item (names *a)
74{
75 free (a->s);
76 a->s = 0; // say
77 a->i = 0; // say
78}
79
80int main (int argc, char **argv)
81{
82// you can separate these into LIST_TYPE_DECLARE(), LIST_DECLARE() and linit() if needed.
83 LIST_DECLARE_INIT (l, names, free_item);
84 names *j;
85
86 lappend (l);
87 l.tail->s = strdup ("hello");
88 l.tail->i = 1;
89 lappend (l);
90 l.tail->s = strdup ("there");
91 l.tail->i = 2;
92 lappend (l);
93 l.tail->s = strdup ("my");
94 l.tail->i = 3;
95 lappend (l);
96 l.tail->s = strdup ("name");
97 l.tail->i = 4;
98 lappend (l);
99 l.tail->s = strdup ("is");
100 l.tail->i = 5;
101 lappend (l);
102 l.tail->s = strdup ("fred");
103 l.tail->i = 6;
104
105 printf ("%ld\n\n", lcount (l));
106 lloopforward (l, j, printf ("%d %s\n", j->i, j->s));
107 printf ("\n");
108
109 lsort (l, cm);
110 lloopforward (l, j, printf ("%d %s\n", j->i, j->s));
111
112 lloopreverse (l, j, if (j->i <= 3) ldeleteinc (l, j););
113
114 printf ("\n");
115 lloopforward (l, j, printf ("%d %s\n", j->i, j->s));
116
117 ldeleteall (l);
118
119 printf ("\n");
120 lloopforward (l, j, printf ("%d %s\n", j->i, j->s));
121 return 0;
122}
123
124*/
125
126
127#ifndef _LIST_H
128#define _LIST_H
129
130/* the `search' member points to the last found.
131 this speeds up repeated searches on the same list-item,
132 the consecutive list-item, or the pre-consecutive list-item.
133 this obviates the need for a hash table for 99% of
134 cercumstances the time */
135struct list
136{
137 long length;
138 long item_size;
139 struct list_item
140 {
141 struct list_item *next;
142 struct list_item *prev;
143 char data[1];
144 } *head, *tail, *search;
145 void (*free_func) (struct list_item *);
146};
147
148/* declare a list of type `x', also called `x' having members `typelist' */
149
150#define LIST_TYPE_DECLARE(type,typelist) \
151 typedef struct type { \
152 struct type *next; \
153 struct type *prev; \
154 typelist \
155 } type
156
157#define LIST_DECLARE(l,type) \
158 struct { \
159 long length; \
160 long item_size; \
161 type *head, *tail, *search; \
162 void (*free_func) (type *); \
163 } l
164
165#define LIST_DECLARE_INIT(l,type,free) \
166 struct { \
167 long length; \
168 long item_size; \
169 type *head, *tail, *search; \
170 void (*free_func) (type *); \
171 } l = {0, sizeof (type), 0, 0, 0, (void (*) (type *)) free}
172
173#define linit(l,type,free) \
174 { \
175 memset (&(l), 0, sizeof (l)); \
176 (l).item_size = sizeof (type); \
177 (l).free_func = free; \
178 }
179
180/* returns a pointer to the data of an item */
181#define ldata(i) ((void *) &((i)->data[0]))
182
183/* returns a pointer to the list head */
184#define lhead(l) ((l).head)
185
186/* returns a pointer to the list tail */
187#define ltail(l) ((l).tail)
188
189#define lnewsearch(l) \
190 (l).search = 0;
191
192/* adds to the beginning of the list */
193#define lprepend(l) \
194 { \
195 struct list_item *__t; \
196 __t = (struct list_item *) malloc ((l).item_size); \
197 memset (__t, 0, (l).item_size); \
198 __t->next = (l).head; \
199 if (__t->next) \
200 __t->next->prev = __t; \
201 __t->prev = 0; \
202 if (!(l).tail) \
203 (l).tail = __t; \
204 (l).head = __t; \
205 length++; \
206 }
207
208/* adds to the end of the list */
209#define lappend(l) \
210 { \
211 struct list_item *__t; \
212 __t = (struct list_item *) malloc ((l).item_size); \
213 memset (__t, 0, (l).item_size); \
214 __t->prev = (struct list_item *) (l).tail; \
215 if (__t->prev) \
216 __t->prev->next = __t; \
217 __t->next = 0; \
218 if (!(l).head) \
219 (l).head = (void *) __t; \
220 (l).tail = (void *) __t; \
221 (l).length++; \
222 }
223
224/* you should free these manually */
225#define lunlink(l,e) \
226 { \
227 struct list_item *__t; \
228 (l).search = 0; \
229 __t = (void *) e; \
230 if ((void *) (l).head == (void *) __t) \
231 (l).head = (l).head->next; \
232 if ((void *) (l).tail == (void *) __t) \
233 (l).tail = (l).tail->prev; \
234 if (__t->next) \
235 __t->next->prev = __t->prev; \
236 if (__t->prev) \
237 __t->prev->next = __t->next; \
238 (l).length--; \
239 }
240
241/* deletes list entry at point e, and increments e to the following list entry */
242#define ldeleteinc(l,e) \
243 { \
244 struct list_item *__t; \
245 (l).search = 0; \
246 __t = (void *) e; \
247 if ((void *) (l).head == (void *) __t) \
248 (l).head = (l).head->next; \
249 if ((void *) (l).tail == (void *) __t) \
250 (l).tail = (l).tail->prev; \
251 if (__t->next) \
252 __t->next->prev = __t->prev; \
253 if (__t->prev) \
254 __t->prev->next = __t->next; \
255 __t = __t->next; \
256 if ((l).free_func) \
257 (*(l).free_func) ((void *) e); \
258 free (e); \
259 e = (void *) __t; \
260 (l).length--; \
261 }
262
263/* deletes list entry at point e, and deccrements e to the preceding list emtry */
264#define ldeletedec(l,e) \
265 { \
266 struct list_item *__t; \
267 (l).search = 0; \
268 __t = (void *) e; \
269 if ((void *) (l).head == (void *) __t) \
270 (l).head = (l).head->next; \
271 if ((void *) (l).tail == (void *) __t) \
272 (l).tail = (l).tail->prev; \
273 if (__t->next) \
274 __t->next->prev = __t->prev; \
275 if (__t->prev) \
276 __t->prev->next = __t->next; \
277 __t = __t->prev; \
278 if ((l).free_func) \
279 (*(l).free_func) ((void *) e); \
280 free (e); \
281 e = (void *) __t; \
282 (l).length--; \
283 }
284
285/* p and q must be consecutive and neither must be zero */
286#define linsert(l,p,q) \
287 { \
288 struct list_item *__t; \
289 __t = (struct list_item *) malloc ((l).item_size); \
290 memset (__t, 0, (l).item_size); \
291 __t->prev = (void *) p; \
292 __t->next = (void *) q; \
293 q->prev = (void *) __t; \
294 p->next = (void *) __t; \
295 (l).length++; \
296 }
297
298/* p and q must be consecutive and neither must be zero */
299#define ldeleteall(l) \
300 { \
301 (l).search = 0; \
302 while ((l).head) { \
303 struct list_item *__p; \
304 __p = (struct list_item *) (l).head; \
305 lunlink(l, __p); \
306 if ((l).free_func) \
307 (*(l).free_func) ((void *) __p); \
308 free (__p); \
309 } \
310 }
311
312#define lloopstart(l,i) \
313 for (i = (void *) (l).head; i;) { \
314 struct list_item *__tl; \
315 __tl = (void *) i->next; \
316
317#define lloopend(l,i) \
318 i = (void *) __tl; \
319 } \
320
321#define lloopforward(l,i,op) \
322 { \
323 for (i = (void *) (l).head; i;) { \
324 struct list_item *__t; \
325 __t = (void *) i->next; \
326 op; \
327 i = (void *) __t; \
328 } \
329 }
330
331#define lloopreverse(l,i,op) \
332 { \
333 for (i = (void *) (l).tail; i;) { \
334 struct list_item *__t; \
335 __t = (void *) i->prev; \
336 op; \
337 i = (void *) __t; \
338 } \
339 }
340
341#define lindex(l,i,n) \
342 { \
343 int __k; \
344 for (__k = 0, i = (void *) (l).head; i && __k != n; i = i->next, __k++); \
345 }
346
347#define lsearchforward(l,i,op) \
348 { \
349 int __found = 0; \
350 if (!__found) \
351 if ((i = (void *) (l).search)) { \
352 if (op) { \
353 __found = 1; \
354 (l).search = (void *) i; \
355 } \
356 if (!__found) \
357 if ((i = (void *) (l).search->next)) \
358 if (op) { \
359 __found = 1; \
360 (l).search = (void *) i; \
361 } \
362 if (!__found) \
363 if ((i = (void *) (l).search->prev)) \
364 if (op) { \
365 __found = 1; \
366 (l).search = (void *) i; \
367 } \
368 } \
369 if (!__found) \
370 for (i = (void *) (l).head; i; i = i->next) \
371 if (op) { \
372 __found = 1; \
373 (l).search = (void *) i; \
374 break; \
375 } \
376 }
377
378#define lsearchreverse(l,i,op) \
379 { \
380 int __found = 0; \
381 if (!__found) \
382 if ((i = (void *) (l).search)) { \
383 if (op) { \
384 __found = 1; \
385 (l).search = (void *) i; \
386 } \
387 if (!__found) \
388 if ((i = (void *) (l).search->prev)) \
389 if (op) { \
390 __found = 1; \
391 (l).search = (void *) i; \
392 } \
393 if (!__found) \
394 if ((i = (void *) (l).search->next)) \
395 if (op) { \
396 __found = 1; \
397 (l).search = (void *) i; \
398 } \
399 } \
400 if (!__found) \
401 for (i = (void *) (l).tail; i; i = i->prev) \
402 if (op) { \
403 __found = 1; \
404 (l).search = (void *) i; \
405 break; \
406 } \
407 }
408
409#define lcount(l) ((l).length)
410
411/* sort with comparison function see qsort(3) */
412#define larray(l,a) \
413 { \
414 long __i; \
415 struct list_item *__p; \
416 a = (void *) malloc (((l).length + 1) * sizeof (void *)); \
417 for (__i = 0, __p = (void *) (l).head; __p; __p = __p->next, __i++) \
418 a[__i] = (void *) __p; \
419 a[__i] = 0; \
420 } \
421
422/* sort with comparison function see qsort(3) */
423#define llist(l,a) \
424 { \
425 struct list_item *__p; \
426 (l).head = (void *) a[0]; \
427 (l).search = 0; \
428 __p = (void *) a[0]; \
429 __p->prev = 0; \
430 for (__j = 1; a[__j]; __j++, __p = __p->next) { \
431 __p->next = (void *) a[__j]; \
432 __p->next->prev = __p; \
433 } \
434 (l).tail = (void *) __p; \
435 __p->next = 0; \
436 } \
437
438/* sort with comparison function see qsort(3) */
439#define lsort(l,compare) \
440 { \
441 void **__t; \
442 long __j; \
443 larray (l,__t); \
444 qsort (__t, (l).length, sizeof (void *), (int (*) (const void *, const void *)) compare); \
445 llist (l,__t); \
446 free (__t); \
447 } \
448
449#endif /* _LIST_H */
diff --git a/src/daemon/https/minitasn1/Makefile.am b/src/daemon/https/minitasn1/Makefile.am
new file mode 100644
index 00000000..fc924cc4
--- /dev/null
+++ b/src/daemon/https/minitasn1/Makefile.am
@@ -0,0 +1,16 @@
1
2AM_CPPFLAGS = -I./includes \
3-I$(top_srcdir)/src/daemon/https/lgl \
4-I$(top_srcdir)/src/daemon/https/tls \
5-I$(top_srcdir)/src/daemon/https/includes
6
7noinst_LTLIBRARIES = libasn1.la
8
9libasn1_la_SOURCES = \
10libtasn1.h \
11mem.h \
12gstr.h \
13errors.h \
14int.h \
15parser_aux.h structure.h element.h decoding.c gstr.c errors.c \
16parser_aux.c structure.c element.c coding.c
diff --git a/src/daemon/https/minitasn1/README b/src/daemon/https/minitasn1/README
new file mode 100644
index 00000000..9d484dfc
--- /dev/null
+++ b/src/daemon/https/minitasn1/README
@@ -0,0 +1,3 @@
1This is just a mirror of the files in the libtasn1's
2lib/ directory.
3
diff --git a/src/daemon/https/minitasn1/coding.c b/src/daemon/https/minitasn1/coding.c
new file mode 100644
index 00000000..10870e01
--- /dev/null
+++ b/src/daemon/https/minitasn1/coding.c
@@ -0,0 +1,1229 @@
1/*
2 * Copyright (C) 2004, 2006 Free Software Foundation
3 * Copyright (C) 2002 Fabio Fiorina
4 *
5 * This file is part of LIBTASN1.
6 *
7 * The LIBTASN1 library is free software; you can redistribute it
8 * and/or modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 */
22
23
24/*****************************************************/
25/* File: coding.c */
26/* Description: Functions to create a DER coding of */
27/* an ASN1 type. */
28/*****************************************************/
29
30#include <int.h>
31#include <errors.h>
32#include "parser_aux.h"
33#include <gstr.h>
34#include "element.h"
35#include <structure.h>
36
37#define MAX_TAG_LEN 16
38
39/******************************************************/
40/* Function : _asn1_error_description_value_not_found */
41/* Description: creates the ErrorDescription string */
42/* for the ASN1_VALUE_NOT_FOUND error. */
43/* Parameters: */
44/* node: node of the tree where the value is NULL. */
45/* ErrorDescription: string returned. */
46/* Return: */
47/******************************************************/
48void
49_asn1_error_description_value_not_found (node_asn * node,
50 char *ErrorDescription)
51{
52
53 if (ErrorDescription == NULL)
54 return;
55
56 Estrcpy (ErrorDescription, ":: value of element '");
57 _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription),
58 MAX_ERROR_DESCRIPTION_SIZE - 40);
59 Estrcat (ErrorDescription, "' not found");
60
61}
62
63/**
64 * asn1_length_der:
65 * @len: value to convert.
66 * @ans: string returned.
67 * @ans_len: number of meaningful bytes of ANS (ans[0]..ans[ans_len-1]).
68 *
69 * Creates the DER coding for the LEN parameter (only the length).
70 * The @ans buffer is pre-allocated and must have room for the output.
71 **/
72void
73asn1_length_der (unsigned long int len, unsigned char *ans, int *ans_len)
74{
75 int k;
76 unsigned char temp[SIZEOF_UNSIGNED_LONG_INT];
77
78 if (len < 128)
79 {
80 /* short form */
81 if (ans != NULL)
82 ans[0] = (unsigned char) len;
83 *ans_len = 1;
84 }
85 else
86 {
87 /* Long form */
88 k = 0;
89 while (len)
90 {
91 temp[k++] = len & 0xFF;
92 len = len >> 8;
93 }
94 *ans_len = k + 1;
95 if (ans != NULL)
96 {
97 ans[0] = ((unsigned char) k & 0x7F) + 128;
98 while (k--)
99 ans[*ans_len - 1 - k] = temp[k];
100 }
101 }
102}
103
104/******************************************************/
105/* Function : _asn1_tag_der */
106/* Description: creates the DER coding for the CLASS */
107/* and TAG parameters. */
108/* Parameters: */
109/* class: value to convert. */
110/* tag_value: value to convert. */
111/* ans: string returned. */
112/* ans_len: number of meaningful bytes of ANS */
113/* (ans[0]..ans[ans_len-1]). */
114/* Return: */
115/******************************************************/
116void
117_asn1_tag_der (unsigned char class, unsigned int tag_value,
118 unsigned char *ans, int *ans_len)
119{
120 int k;
121 unsigned char temp[SIZEOF_UNSIGNED_INT];
122
123 if (tag_value < 31)
124 {
125 /* short form */
126 ans[0] = (class & 0xE0) + ((unsigned char) (tag_value & 0x1F));
127 *ans_len = 1;
128 }
129 else
130 {
131 /* Long form */
132 ans[0] = (class & 0xE0) + 31;
133 k = 0;
134 while (tag_value)
135 {
136 temp[k++] = tag_value & 0x7F;
137 tag_value = tag_value >> 7;
138 }
139 *ans_len = k + 1;
140 while (k--)
141 ans[*ans_len - 1 - k] = temp[k] + 128;
142 ans[*ans_len - 1] -= 128;
143 }
144}
145
146/**
147 * asn1_octet_der:
148 * @str: OCTET string.
149 * @str_len: STR length (str[0]..str[str_len-1]).
150 * @der: string returned.
151 * @der_len: number of meaningful bytes of DER (der[0]..der[ans_len-1]).
152 *
153 * Creates the DER coding for an OCTET type (length included).
154 **/
155void
156asn1_octet_der (const unsigned char *str, int str_len,
157 unsigned char *der, int *der_len)
158{
159 int len_len;
160
161 if (der == NULL || str_len < 0)
162 return;
163 asn1_length_der (str_len, der, &len_len);
164 memcpy (der + len_len, str, str_len);
165 *der_len = str_len + len_len;
166}
167
168/******************************************************/
169/* Function : _asn1_time_der */
170/* Description: creates the DER coding for a TIME */
171/* type (length included). */
172/* Parameters: */
173/* str: TIME null-terminated string. */
174/* der: string returned. */
175/* der_len: number of meaningful bytes of DER */
176/* (der[0]..der[ans_len-1]). Initially it */
177/* if must store the lenght of DER. */
178/* Return: */
179/* ASN1_MEM_ERROR when DER isn't big enough */
180/* ASN1_SUCCESS otherwise */
181/******************************************************/
182asn1_retCode
183_asn1_time_der (unsigned char *str, unsigned char *der, int *der_len)
184{
185 int len_len;
186 int max_len;
187
188 max_len = *der_len;
189
190 asn1_length_der (strlen (str), (max_len > 0) ? der : NULL, &len_len);
191
192 if ((len_len + (int) strlen (str)) <= max_len)
193 memcpy (der + len_len, str, strlen (str));
194 *der_len = len_len + strlen (str);
195
196 if ((*der_len) > max_len)
197 return ASN1_MEM_ERROR;
198
199 return ASN1_SUCCESS;
200}
201
202
203/*
204void
205_asn1_get_utctime_der(unsigned char *der,int *der_len,unsigned char *str)
206{
207 int len_len,str_len;
208 char temp[20];
209
210 if(str==NULL) return;
211 str_len=asn1_get_length_der(der,*der_len,&len_len);
212 if (str_len<0) return;
213 memcpy(temp,der+len_len,str_len);
214 *der_len=str_len+len_len;
215 switch(str_len){
216 case 11:
217 temp[10]=0;
218 strcat(temp,"00+0000");
219 break;
220 case 13:
221 temp[12]=0;
222 strcat(temp,"+0000");
223 break;
224 case 15:
225 temp[15]=0;
226 memmove(temp+12,temp+10,6);
227 temp[10]=temp[11]='0';
228 break;
229 case 17:
230 temp[17]=0;
231 break;
232 default:
233 return;
234 }
235 strcpy(str,temp);
236}
237*/
238
239/******************************************************/
240/* Function : _asn1_objectid_der */
241/* Description: creates the DER coding for an */
242/* OBJECT IDENTIFIER type (length included). */
243/* Parameters: */
244/* str: OBJECT IDENTIFIER null-terminated string. */
245/* der: string returned. */
246/* der_len: number of meaningful bytes of DER */
247/* (der[0]..der[ans_len-1]). Initially it */
248/* must store the length of DER. */
249/* Return: */
250/* ASN1_MEM_ERROR when DER isn't big enough */
251/* ASN1_SUCCESS otherwise */
252/******************************************************/
253asn1_retCode
254_asn1_objectid_der (unsigned char *str, unsigned char *der, int *der_len)
255{
256 int len_len, counter, k, first, max_len;
257 char *temp, *n_end, *n_start;
258 unsigned char bit7;
259 unsigned long val, val1 = 0;
260
261 max_len = *der_len;
262
263 temp = (char *) _asn1_alloca (strlen (str) + 2);
264 if (temp == NULL)
265 return ASN1_MEM_ALLOC_ERROR;
266
267 strcpy (temp, str);
268 strcat (temp, ".");
269
270 counter = 0;
271 n_start = temp;
272 while ((n_end = strchr (n_start, '.')))
273 {
274 *n_end = 0;
275 val = strtoul (n_start, NULL, 10);
276 counter++;
277
278 if (counter == 1)
279 val1 = val;
280 else if (counter == 2)
281 {
282 if (max_len > 0)
283 der[0] = 40 * val1 + val;
284 *der_len = 1;
285 }
286 else
287 {
288 first = 0;
289 for (k = 4; k >= 0; k--)
290 {
291 bit7 = (val >> (k * 7)) & 0x7F;
292 if (bit7 || first || !k)
293 {
294 if (k)
295 bit7 |= 0x80;
296 if (max_len > (*der_len))
297 der[*der_len] = bit7;
298 (*der_len)++;
299 first = 1;
300 }
301 }
302
303 }
304 n_start = n_end + 1;
305 }
306
307 asn1_length_der (*der_len, NULL, &len_len);
308 if (max_len >= (*der_len + len_len))
309 {
310 memmove (der + len_len, der, *der_len);
311 asn1_length_der (*der_len, der, &len_len);
312 }
313 *der_len += len_len;
314
315 _asn1_afree (temp);
316
317 if (max_len < (*der_len))
318 return ASN1_MEM_ERROR;
319
320 return ASN1_SUCCESS;
321}
322
323
324const char bit_mask[] = { 0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80 };
325
326/**
327 * asn1_bit_der:
328 * @str: BIT string.
329 * @bit_len: number of meaningful bits in STR.
330 * @der: string returned.
331 * @der_len: number of meaningful bytes of DER
332 * (der[0]..der[ans_len-1]).
333 *
334 * Creates the DER coding for a BIT STRING type (length and pad
335 * included).
336 **/
337void
338asn1_bit_der (const unsigned char *str, int bit_len,
339 unsigned char *der, int *der_len)
340{
341 int len_len, len_byte, len_pad;
342
343 if (der == NULL)
344 return;
345 len_byte = bit_len >> 3;
346 len_pad = 8 - (bit_len & 7);
347 if (len_pad == 8)
348 len_pad = 0;
349 else
350 len_byte++;
351 asn1_length_der (len_byte + 1, der, &len_len);
352 der[len_len] = len_pad;
353 memcpy (der + len_len + 1, str, len_byte);
354 der[len_len + len_byte] &= bit_mask[len_pad];
355 *der_len = len_byte + len_len + 1;
356}
357
358
359/******************************************************/
360/* Function : _asn1_complete_explicit_tag */
361/* Description: add the length coding to the EXPLICIT */
362/* tags. */
363/* Parameters: */
364/* node: pointer to the tree element. */
365/* der: string with the DER coding of the whole tree*/
366/* counter: number of meaningful bytes of DER */
367/* (der[0]..der[*counter-1]). */
368/* max_len: size of der vector */
369/* Return: */
370/* ASN1_MEM_ERROR if der vector isn't big enough, */
371/* otherwise ASN1_SUCCESS. */
372/******************************************************/
373asn1_retCode
374_asn1_complete_explicit_tag (node_asn * node, unsigned char *der,
375 int *counter, int *max_len)
376{
377 node_asn *p;
378 int is_tag_implicit, len2, len3;
379 unsigned char temp[SIZEOF_UNSIGNED_INT];
380
381 is_tag_implicit = 0;
382
383 if (node->type & CONST_TAG)
384 {
385 p = node->down;
386 /* When there are nested tags we must complete them reverse to
387 the order they were created. This is because completing a tag
388 modifies all data within it, including the incomplete tags
389 which store buffer positions -- simon@josefsson.org 2002-09-06
390 */
391 while (p->right)
392 p = p->right;
393 while (p && p != node->down->left)
394 {
395 if (type_field (p->type) == TYPE_TAG)
396 {
397 if (p->type & CONST_EXPLICIT)
398 {
399 len2 = strtol (p->name, NULL, 10);
400 _asn1_set_name (p, NULL);
401 asn1_length_der (*counter - len2, temp, &len3);
402 if (len3 <= (*max_len))
403 {
404 memmove (der + len2 + len3, der + len2,
405 *counter - len2);
406 memcpy (der + len2, temp, len3);
407 }
408 *max_len -= len3;
409 *counter += len3;
410 is_tag_implicit = 0;
411 }
412 else
413 { /* CONST_IMPLICIT */
414 if (!is_tag_implicit)
415 {
416 is_tag_implicit = 1;
417 }
418 }
419 }
420 p = p->left;
421 }
422 }
423
424 if (*max_len < 0)
425 return ASN1_MEM_ERROR;
426
427 return ASN1_SUCCESS;
428}
429
430
431/******************************************************/
432/* Function : _asn1_insert_tag_der */
433/* Description: creates the DER coding of tags of one */
434/* NODE. */
435/* Parameters: */
436/* node: pointer to the tree element. */
437/* der: string returned */
438/* counter: number of meaningful bytes of DER */
439/* (counter[0]..der[*counter-1]). */
440/* max_len: size of der vector */
441/* Return: */
442/* ASN1_GENERIC_ERROR if the type is unknown, */
443/* ASN1_MEM_ERROR if der vector isn't big enough, */
444/* otherwise ASN1_SUCCESS. */
445/******************************************************/
446asn1_retCode
447_asn1_insert_tag_der (node_asn * node, unsigned char *der, int *counter,
448 int *max_len)
449{
450 node_asn *p;
451 int tag_len, is_tag_implicit;
452 unsigned char class, class_implicit = 0, temp[SIZEOF_UNSIGNED_INT * 3 + 1];
453 unsigned long tag_implicit = 0;
454 char tag_der[MAX_TAG_LEN];
455
456 is_tag_implicit = 0;
457
458 if (node->type & CONST_TAG)
459 {
460 p = node->down;
461 while (p)
462 {
463 if (type_field (p->type) == TYPE_TAG)
464 {
465 if (p->type & CONST_APPLICATION)
466 class = ASN1_CLASS_APPLICATION;
467 else if (p->type & CONST_UNIVERSAL)
468 class = ASN1_CLASS_UNIVERSAL;
469 else if (p->type & CONST_PRIVATE)
470 class = ASN1_CLASS_PRIVATE;
471 else
472 class = ASN1_CLASS_CONTEXT_SPECIFIC;
473
474 if (p->type & CONST_EXPLICIT)
475 {
476 if (is_tag_implicit)
477 _asn1_tag_der (class_implicit, tag_implicit, tag_der,
478 &tag_len);
479 else
480 _asn1_tag_der (class | ASN1_CLASS_STRUCTURED,
481 strtoul (p->value, NULL, 10), tag_der,
482 &tag_len);
483
484 *max_len -= tag_len;
485 if (*max_len >= 0)
486 memcpy (der + *counter, tag_der, tag_len);
487 *counter += tag_len;
488
489 _asn1_ltostr (*counter, temp);
490 _asn1_set_name (p, temp);
491
492 is_tag_implicit = 0;
493 }
494 else
495 { /* CONST_IMPLICIT */
496 if (!is_tag_implicit)
497 {
498 if ((type_field (node->type) == TYPE_SEQUENCE) ||
499 (type_field (node->type) == TYPE_SEQUENCE_OF) ||
500 (type_field (node->type) == TYPE_SET) ||
501 (type_field (node->type) == TYPE_SET_OF))
502 class |= ASN1_CLASS_STRUCTURED;
503 class_implicit = class;
504 tag_implicit = strtoul (p->value, NULL, 10);
505 is_tag_implicit = 1;
506 }
507 }
508 }
509 p = p->right;
510 }
511 }
512
513 if (is_tag_implicit)
514 {
515 _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len);
516 }
517 else
518 {
519 switch (type_field (node->type))
520 {
521 case TYPE_NULL:
522 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_NULL, tag_der,
523 &tag_len);
524 break;
525 case TYPE_BOOLEAN:
526 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BOOLEAN, tag_der,
527 &tag_len);
528 break;
529 case TYPE_INTEGER:
530 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_INTEGER, tag_der,
531 &tag_len);
532 break;
533 case TYPE_ENUMERATED:
534 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_ENUMERATED, tag_der,
535 &tag_len);
536 break;
537 case TYPE_OBJECT_ID:
538 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OBJECT_ID, tag_der,
539 &tag_len);
540 break;
541 case TYPE_TIME:
542 if (node->type & CONST_UTC)
543 {
544 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_UTCTime, tag_der,
545 &tag_len);
546 }
547 else
548 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALIZEDTime,
549 tag_der, &tag_len);
550 break;
551 case TYPE_OCTET_STRING:
552 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OCTET_STRING, tag_der,
553 &tag_len);
554 break;
555 case TYPE_GENERALSTRING:
556 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALSTRING,
557 tag_der, &tag_len);
558 break;
559 case TYPE_BIT_STRING:
560 _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BIT_STRING, tag_der,
561 &tag_len);
562 break;
563 case TYPE_SEQUENCE:
564 case TYPE_SEQUENCE_OF:
565 _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
566 ASN1_TAG_SEQUENCE, tag_der, &tag_len);
567 break;
568 case TYPE_SET:
569 case TYPE_SET_OF:
570 _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
571 ASN1_TAG_SET, tag_der, &tag_len);
572 break;
573 case TYPE_TAG:
574 tag_len = 0;
575 break;
576 case TYPE_CHOICE:
577 tag_len = 0;
578 break;
579 case TYPE_ANY:
580 tag_len = 0;
581 break;
582 default:
583 return ASN1_GENERIC_ERROR;
584 }
585 }
586
587 *max_len -= tag_len;
588 if (*max_len >= 0)
589 memcpy (der + *counter, tag_der, tag_len);
590 *counter += tag_len;
591
592 if (*max_len < 0)
593 return ASN1_MEM_ERROR;
594
595 return ASN1_SUCCESS;
596}
597
598/******************************************************/
599/* Function : _asn1_ordering_set */
600/* Description: puts the elements of a SET type in */
601/* the correct order according to DER rules. */
602/* Parameters: */
603/* der: string with the DER coding. */
604/* node: pointer to the SET element. */
605/* Return: */
606/******************************************************/
607void
608_asn1_ordering_set (unsigned char *der, int der_len, node_asn * node)
609{
610 struct vet
611 {
612 int end;
613 unsigned long value;
614 struct vet *next, *prev;
615 };
616
617 int counter, len, len2;
618 struct vet *first, *last, *p_vet, *p2_vet;
619 node_asn *p;
620 unsigned char class, *temp;
621 unsigned long tag;
622
623 counter = 0;
624
625 if (type_field (node->type) != TYPE_SET)
626 return;
627
628 p = node->down;
629 while ((type_field (p->type) == TYPE_TAG)
630 || (type_field (p->type) == TYPE_SIZE))
631 p = p->right;
632
633 if ((p == NULL) || (p->right == NULL))
634 return;
635
636 first = last = NULL;
637 while (p)
638 {
639 p_vet = (struct vet *) _asn1_alloca (sizeof (struct vet));
640 if (p_vet == NULL)
641 return;
642
643 p_vet->next = NULL;
644 p_vet->prev = last;
645 if (first == NULL)
646 first = p_vet;
647 else
648 last->next = p_vet;
649 last = p_vet;
650
651 /* tag value calculation */
652 if (asn1_get_tag_der
653 (der + counter, der_len - counter, &class, &len2,
654 &tag) != ASN1_SUCCESS)
655 return;
656 p_vet->value = (class << 24) | tag;
657 counter += len2;
658
659 /* extraction and length */
660 len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
661 if (len2 < 0)
662 return;
663 counter += len + len2;
664
665 p_vet->end = counter;
666 p = p->right;
667 }
668
669 p_vet = first;
670
671 while (p_vet)
672 {
673 p2_vet = p_vet->next;
674 counter = 0;
675 while (p2_vet)
676 {
677 if (p_vet->value > p2_vet->value)
678 {
679 /* change position */
680 temp = (unsigned char *) _asn1_alloca (p_vet->end - counter);
681 if (temp == NULL)
682 return;
683
684 memcpy (temp, der + counter, p_vet->end - counter);
685 memcpy (der + counter, der + p_vet->end,
686 p2_vet->end - p_vet->end);
687 memcpy (der + counter + p2_vet->end - p_vet->end, temp,
688 p_vet->end - counter);
689 _asn1_afree (temp);
690
691 tag = p_vet->value;
692 p_vet->value = p2_vet->value;
693 p2_vet->value = tag;
694
695 p_vet->end = counter + (p2_vet->end - p_vet->end);
696 }
697 counter = p_vet->end;
698
699 p2_vet = p2_vet->next;
700 p_vet = p_vet->next;
701 }
702
703 if (p_vet != first)
704 p_vet->prev->next = NULL;
705 else
706 first = NULL;
707 _asn1_afree (p_vet);
708 p_vet = first;
709 }
710}
711
712/******************************************************/
713/* Function : _asn1_ordering_set_of */
714/* Description: puts the elements of a SET OF type in */
715/* the correct order according to DER rules. */
716/* Parameters: */
717/* der: string with the DER coding. */
718/* node: pointer to the SET OF element. */
719/* Return: */
720/******************************************************/
721void
722_asn1_ordering_set_of (unsigned char *der, int der_len, node_asn * node)
723{
724 struct vet
725 {
726 int end;
727 struct vet *next, *prev;
728 };
729
730 int counter, len, len2, change;
731 struct vet *first, *last, *p_vet, *p2_vet;
732 node_asn *p;
733 unsigned char *temp, class;
734 unsigned long k, max;
735
736 counter = 0;
737
738 if (type_field (node->type) != TYPE_SET_OF)
739 return;
740
741 p = node->down;
742 while ((type_field (p->type) == TYPE_TAG)
743 || (type_field (p->type) == TYPE_SIZE))
744 p = p->right;
745 p = p->right;
746
747 if ((p == NULL) || (p->right == NULL))
748 return;
749
750 first = last = NULL;
751 while (p)
752 {
753 p_vet = (struct vet *) _asn1_alloca (sizeof (struct vet));
754 if (p_vet == NULL)
755 return;
756
757 p_vet->next = NULL;
758 p_vet->prev = last;
759 if (first == NULL)
760 first = p_vet;
761 else
762 last->next = p_vet;
763 last = p_vet;
764
765 /* extraction of tag and length */
766 if (der_len - counter > 0)
767 {
768
769 if (asn1_get_tag_der
770 (der + counter, der_len - counter, &class, &len,
771 NULL) != ASN1_SUCCESS)
772 return;
773 counter += len;
774
775 len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
776 if (len2 < 0)
777 return;
778 counter += len + len2;
779 }
780
781 p_vet->end = counter;
782 p = p->right;
783 }
784
785 p_vet = first;
786
787 while (p_vet)
788 {
789 p2_vet = p_vet->next;
790 counter = 0;
791 while (p2_vet)
792 {
793 if ((p_vet->end - counter) > (p2_vet->end - p_vet->end))
794 max = p_vet->end - counter;
795 else
796 max = p2_vet->end - p_vet->end;
797
798 change = -1;
799 for (k = 0; k < max; k++)
800 if (der[counter + k] > der[p_vet->end + k])
801 {
802 change = 1;
803 break;
804 }
805 else if (der[counter + k] < der[p_vet->end + k])
806 {
807 change = 0;
808 break;
809 }
810
811 if ((change == -1)
812 && ((p_vet->end - counter) > (p2_vet->end - p_vet->end)))
813 change = 1;
814
815 if (change == 1)
816 {
817 /* change position */
818 temp = (unsigned char *) _asn1_alloca (p_vet->end - counter);
819 if (temp == NULL)
820 return;
821
822 memcpy (temp, der + counter, (p_vet->end) - counter);
823 memcpy (der + counter, der + (p_vet->end),
824 (p2_vet->end) - (p_vet->end));
825 memcpy (der + counter + (p2_vet->end) - (p_vet->end), temp,
826 (p_vet->end) - counter);
827 _asn1_afree (temp);
828
829 p_vet->end = counter + (p2_vet->end - p_vet->end);
830 }
831 counter = p_vet->end;
832
833 p2_vet = p2_vet->next;
834 p_vet = p_vet->next;
835 }
836
837 if (p_vet != first)
838 p_vet->prev->next = NULL;
839 else
840 first = NULL;
841 _asn1_afree (p_vet);
842 p_vet = first;
843 }
844}
845
846/**
847 * asn1_der_coding - Creates the DER encoding for the NAME structure
848 * @element: pointer to an ASN1 element
849 * @name: the name of the structure you want to encode (it must be
850 * inside *POINTER).
851 * @ider: vector that will contain the DER encoding. DER must be a
852 * pointer to memory cells already allocated.
853 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1], Initialy
854 * holds the sizeof of der vector.
855 * @errorDescription : return the error description or an empty
856 * string if success.
857 *
858 * Creates the DER encoding for the NAME structure (inside *POINTER
859 * structure).
860 *
861 * Returns:
862 *
863 * ASN1_SUCCESS: DER encoding OK.
864 *
865 * ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
866 *
867 * ASN1_VALUE_NOT_FOUND: There is an element without a value.
868 *
869 * ASN1_MEM_ERROR: @ider vector isn't big enough. Also in this case
870 * LEN will contain the length needed.
871 *
872 **/
873asn1_retCode
874asn1_der_coding (ASN1_TYPE element, const char *name, void *ider, int *len,
875 char *ErrorDescription)
876{
877 node_asn *node, *p, *p2;
878 char temp[SIZEOF_UNSIGNED_LONG_INT * 3 + 1];
879 int counter, counter_old, len2, len3, tlen, move, max_len, max_len_old;
880 asn1_retCode err;
881 unsigned char *der = ider;
882
883 node = asn1_find_node (element, name);
884 if (node == NULL)
885 return ASN1_ELEMENT_NOT_FOUND;
886
887 /* Node is now a locally allocated variable.
888 * That is because in some point we modify the
889 * structure, and I don't know why! --nmav
890 */
891 node = _asn1_copy_structure3 (node);
892 if (node == NULL)
893 return ASN1_ELEMENT_NOT_FOUND;
894
895 max_len = *len;
896
897 counter = 0;
898 move = DOWN;
899 p = node;
900 while (1)
901 {
902
903 counter_old = counter;
904 max_len_old = max_len;
905 if (move != UP)
906 {
907 err = _asn1_insert_tag_der (p, der, &counter, &max_len);
908 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
909 goto error;
910 }
911 switch (type_field (p->type))
912 {
913 case TYPE_NULL:
914 max_len--;
915 if (max_len >= 0)
916 der[counter] = 0;
917 counter++;
918 move = RIGHT;
919 break;
920 case TYPE_BOOLEAN:
921 if ((p->type & CONST_DEFAULT) && (p->value == NULL))
922 {
923 counter = counter_old;
924 max_len = max_len_old;
925 }
926 else
927 {
928 if (p->value == NULL)
929 {
930 _asn1_error_description_value_not_found (p,
931 ErrorDescription);
932 err = ASN1_VALUE_NOT_FOUND;
933 goto error;
934 }
935 max_len -= 2;
936 if (max_len >= 0)
937 {
938 der[counter++] = 1;
939 if (p->value[0] == 'F')
940 der[counter++] = 0;
941 else
942 der[counter++] = 0xFF;
943 }
944 else
945 counter += 2;
946 }
947 move = RIGHT;
948 break;
949 case TYPE_INTEGER:
950 case TYPE_ENUMERATED:
951 if ((p->type & CONST_DEFAULT) && (p->value == NULL))
952 {
953 counter = counter_old;
954 max_len = max_len_old;
955 }
956 else
957 {
958 if (p->value == NULL)
959 {
960 _asn1_error_description_value_not_found (p,
961 ErrorDescription);
962 err = ASN1_VALUE_NOT_FOUND;
963 goto error;
964 }
965 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
966 if (len2 < 0)
967 {
968 err = ASN1_DER_ERROR;
969 goto error;
970 }
971 max_len -= len2 + len3;
972 if (max_len >= 0)
973 memcpy (der + counter, p->value, len3 + len2);
974 counter += len3 + len2;
975 }
976 move = RIGHT;
977 break;
978 case TYPE_OBJECT_ID:
979 if ((p->type & CONST_DEFAULT) && (p->value == NULL))
980 {
981 counter = counter_old;
982 max_len = max_len_old;
983 }
984 else
985 {
986 if (p->value == NULL)
987 {
988 _asn1_error_description_value_not_found (p,
989 ErrorDescription);
990 err = ASN1_VALUE_NOT_FOUND;
991 goto error;
992 }
993 len2 = max_len;
994 err = _asn1_objectid_der (p->value, der + counter, &len2);
995 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
996 goto error;
997
998 max_len -= len2;
999 counter += len2;
1000 }
1001 move = RIGHT;
1002 break;
1003 case TYPE_TIME:
1004 if (p->value == NULL)
1005 {
1006 _asn1_error_description_value_not_found (p, ErrorDescription);
1007 err = ASN1_VALUE_NOT_FOUND;
1008 goto error;
1009 }
1010 len2 = max_len;
1011 err = _asn1_time_der (p->value, der + counter, &len2);
1012 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
1013 goto error;
1014
1015 max_len -= len2;
1016 counter += len2;
1017 move = RIGHT;
1018 break;
1019 case TYPE_OCTET_STRING:
1020 if (p->value == NULL)
1021 {
1022 _asn1_error_description_value_not_found (p, ErrorDescription);
1023 err = ASN1_VALUE_NOT_FOUND;
1024 goto error;
1025 }
1026 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1027 if (len2 < 0)
1028 {
1029 err = ASN1_DER_ERROR;
1030 goto error;
1031 }
1032 max_len -= len2 + len3;
1033 if (max_len >= 0)
1034 memcpy (der + counter, p->value, len3 + len2);
1035 counter += len3 + len2;
1036 move = RIGHT;
1037 break;
1038 case TYPE_GENERALSTRING:
1039 if (p->value == NULL)
1040 {
1041 _asn1_error_description_value_not_found (p, ErrorDescription);
1042 err = ASN1_VALUE_NOT_FOUND;
1043 goto error;
1044 }
1045 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1046 if (len2 < 0)
1047 {
1048 err = ASN1_DER_ERROR;
1049 goto error;
1050 }
1051 max_len -= len2 + len3;
1052 if (max_len >= 0)
1053 memcpy (der + counter, p->value, len3 + len2);
1054 counter += len3 + len2;
1055 move = RIGHT;
1056 break;
1057 case TYPE_BIT_STRING:
1058 if (p->value == NULL)
1059 {
1060 _asn1_error_description_value_not_found (p, ErrorDescription);
1061 err = ASN1_VALUE_NOT_FOUND;
1062 goto error;
1063 }
1064 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1065 if (len2 < 0)
1066 {
1067 err = ASN1_DER_ERROR;
1068 goto error;
1069 }
1070 max_len -= len2 + len3;
1071 if (max_len >= 0)
1072 memcpy (der + counter, p->value, len3 + len2);
1073 counter += len3 + len2;
1074 move = RIGHT;
1075 break;
1076 case TYPE_SEQUENCE:
1077 case TYPE_SET:
1078 if (move != UP)
1079 {
1080 _asn1_ltostr (counter, temp);
1081 tlen = strlen (temp);
1082 if (tlen > 0)
1083 _asn1_set_value (p, temp, tlen + 1);
1084 if (p->down == NULL)
1085 {
1086 move = UP;
1087 continue;
1088 }
1089 else
1090 {
1091 p2 = p->down;
1092 while (p2 && (type_field (p2->type) == TYPE_TAG))
1093 p2 = p2->right;
1094 if (p2)
1095 {
1096 p = p2;
1097 move = RIGHT;
1098 continue;
1099 }
1100 move = UP;
1101 continue;
1102 }
1103 }
1104 else
1105 { /* move==UP */
1106 len2 = strtol (p->value, NULL, 10);
1107 _asn1_set_value (p, NULL, 0);
1108 if ((type_field (p->type) == TYPE_SET) && (max_len >= 0))
1109 _asn1_ordering_set (der + len2, max_len - len2, p);
1110 asn1_length_der (counter - len2, temp, &len3);
1111 max_len -= len3;
1112 if (max_len >= 0)
1113 {
1114 memmove (der + len2 + len3, der + len2, counter - len2);
1115 memcpy (der + len2, temp, len3);
1116 }
1117 counter += len3;
1118 move = RIGHT;
1119 }
1120 break;
1121 case TYPE_SEQUENCE_OF:
1122 case TYPE_SET_OF:
1123 if (move != UP)
1124 {
1125 _asn1_ltostr (counter, temp);
1126 tlen = strlen (temp);
1127
1128 if (tlen > 0)
1129 _asn1_set_value (p, temp, tlen + 1);
1130 p = p->down;
1131 while ((type_field (p->type) == TYPE_TAG)
1132 || (type_field (p->type) == TYPE_SIZE))
1133 p = p->right;
1134 if (p->right)
1135 {
1136 p = p->right;
1137 move = RIGHT;
1138 continue;
1139 }
1140 else
1141 p = _asn1_find_up (p);
1142 move = UP;
1143 }
1144 if (move == UP)
1145 {
1146 len2 = strtol (p->value, NULL, 10);
1147 _asn1_set_value (p, NULL, 0);
1148 if ((type_field (p->type) == TYPE_SET_OF)
1149 && (max_len - len2 > 0))
1150 {
1151 _asn1_ordering_set_of (der + len2, max_len - len2, p);
1152 }
1153 asn1_length_der (counter - len2, temp, &len3);
1154 max_len -= len3;
1155 if (max_len >= 0)
1156 {
1157 memmove (der + len2 + len3, der + len2, counter - len2);
1158 memcpy (der + len2, temp, len3);
1159 }
1160 counter += len3;
1161 move = RIGHT;
1162 }
1163 break;
1164 case TYPE_ANY:
1165 if (p->value == NULL)
1166 {
1167 _asn1_error_description_value_not_found (p, ErrorDescription);
1168 err = ASN1_VALUE_NOT_FOUND;
1169 goto error;
1170 }
1171 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
1172 if (len2 < 0)
1173 {
1174 err = ASN1_DER_ERROR;
1175 goto error;
1176 }
1177 max_len -= len2;
1178 if (max_len >= 0)
1179 memcpy (der + counter, p->value + len3, len2);
1180 counter += len2;
1181 move = RIGHT;
1182 break;
1183 default:
1184 move = (move == UP) ? RIGHT : DOWN;
1185 break;
1186 }
1187
1188 if ((move != DOWN) && (counter != counter_old))
1189 {
1190 err = _asn1_complete_explicit_tag (p, der, &counter, &max_len);
1191 if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
1192 goto error;
1193 }
1194
1195 if (p == node && move != DOWN)
1196 break;
1197
1198 if (move == DOWN)
1199 {
1200 if (p->down)
1201 p = p->down;
1202 else
1203 move = RIGHT;
1204 }
1205 if (move == RIGHT)
1206 {
1207 if (p->right)
1208 p = p->right;
1209 else
1210 move = UP;
1211 }
1212 if (move == UP)
1213 p = _asn1_find_up (p);
1214 }
1215
1216 *len = counter;
1217
1218 if (max_len < 0)
1219 {
1220 err = ASN1_MEM_ERROR;
1221 goto error;
1222 }
1223
1224 err = ASN1_SUCCESS;
1225
1226error:
1227 asn1_delete_structure (&node);
1228 return err;
1229}
diff --git a/src/daemon/https/minitasn1/decoding.c b/src/daemon/https/minitasn1/decoding.c
new file mode 100644
index 00000000..0e00cd92
--- /dev/null
+++ b/src/daemon/https/minitasn1/decoding.c
@@ -0,0 +1,2821 @@
1/*
2 * Copyright (C) 2004, 2006 Free Software Foundation
3 * Copyright (C) 2002 Fabio Fiorina
4 *
5 * This file is part of LIBTASN1.
6 *
7 * The LIBTASN1 library is free software; you can redistribute it
8 * and/or modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 */
22
23
24/*****************************************************/
25/* File: decoding.c */
26/* Description: Functions to manage DER decoding */
27/*****************************************************/
28
29#include <int.h>
30#include <errors.h>
31#include "parser_aux.h"
32#include <gstr.h>
33#include "structure.h"
34#include "element.h"
35
36
37void
38_asn1_error_description_tag_error (node_asn * node, char *ErrorDescription)
39{
40
41 Estrcpy (ErrorDescription, ":: tag error near element '");
42 _asn1_hierarchical_name (node, ErrorDescription + strlen (ErrorDescription),
43 MAX_ERROR_DESCRIPTION_SIZE - 40);
44 Estrcat (ErrorDescription, "'");
45
46}
47
48/**
49 * asn1_get_length_der:
50 * @der: DER data to decode.
51 * @der_len: Length of DER data to decode.
52 * @len: Output variable containing the length of the DER length field.
53 *
54 * Extract a length field from DER data.
55 *
56 * Return value: Return the decoded length value, or -1 on indefinite
57 * length, or -2 when the value was too big.
58 **/
59signed long
60asn1_get_length_der (const unsigned char *der, int der_len, int *len)
61{
62 unsigned long ans;
63 int k, punt;
64
65 *len = 0;
66 if (der_len <= 0)
67 return 0;
68
69 if (!(der[0] & 128))
70 {
71 /* short form */
72 *len = 1;
73 return der[0];
74 }
75 else
76 {
77 /* Long form */
78 k = der[0] & 0x7F;
79 punt = 1;
80 if (k)
81 { /* definite length method */
82 ans = 0;
83 while (punt <= k && punt < der_len)
84 {
85 unsigned long last = ans;
86
87 ans = ans * 256 + der[punt++];
88 if (ans < last)
89 /* we wrapped around, no bignum support... */
90 return -2;
91 }
92 }
93 else
94 { /* indefinite length method */
95 ans = -1;
96 }
97
98 *len = punt;
99 return ans;
100 }
101}
102
103
104
105
106/**
107 * asn1_get_tag_der:
108 * @der: DER data to decode.
109 * @der_len: Length of DER data to decode.
110 * @cls: Output variable containing decoded class.
111 * @len: Output variable containing the length of the DER TAG data.
112 * @tag: Output variable containing the decoded tag.
113 *
114 * Decode the class and TAG from DER code.
115 *
116 * Return value: Returns ASN1_SUCCESS on success, or an error.
117 **/
118int
119asn1_get_tag_der (const unsigned char *der, int der_len,
120 unsigned char *cls, int *len, unsigned long *tag)
121{
122 int punt, ris;
123
124 if (der == NULL || der_len <= 0 || len == NULL)
125 return ASN1_DER_ERROR;
126
127 *cls = der[0] & 0xE0;
128 if ((der[0] & 0x1F) != 0x1F)
129 {
130 /* short form */
131 *len = 1;
132 ris = der[0] & 0x1F;
133 }
134 else
135 {
136 /* Long form */
137 punt = 1;
138 ris = 0;
139 while (punt <= der_len && der[punt] & 128)
140 {
141 int last = ris;
142 ris = ris * 128 + (der[punt++] & 0x7F);
143 if (ris < last)
144 /* wrapper around, and no bignums... */
145 return ASN1_DER_ERROR;
146 }
147 if (punt >= der_len)
148 return ASN1_DER_ERROR;
149 {
150 int last = ris;
151 ris = ris * 128 + (der[punt++] & 0x7F);
152 if (ris < last)
153 /* wrapper around, and no bignums... */
154 return ASN1_DER_ERROR;
155 }
156 *len = punt;
157 }
158 if (tag)
159 *tag = ris;
160 return ASN1_SUCCESS;
161}
162
163
164
165
166/**
167 * asn1_get_octet_der:
168 * @der: DER data to decode containing the OCTET SEQUENCE.
169 * @der_len: Length of DER data to decode.
170 * @ret_len: Output variable containing the length of the DER data.
171 * @str: Pre-allocated output buffer to put decoded OCTET SEQUENCE in.
172 * @str_size: Length of pre-allocated output buffer.
173 * @str_len: Output variable containing the length of the OCTET SEQUENCE.
174 *
175 * Extract an OCTET SEQUENCE from DER data.
176 *
177 * Return value: Returns ASN1_SUCCESS on success, or an error.
178 **/
179int
180asn1_get_octet_der (const unsigned char *der, int der_len,
181 int *ret_len, unsigned char *str, int str_size,
182 int *str_len)
183{
184 int len_len;
185
186 if (der_len <= 0)
187 return ASN1_GENERIC_ERROR;
188
189 /* if(str==NULL) return ASN1_SUCCESS; */
190 *str_len = asn1_get_length_der (der, der_len, &len_len);
191
192 if (*str_len < 0)
193 return ASN1_DER_ERROR;
194
195 *ret_len = *str_len + len_len;
196 if (str_size >= *str_len)
197 memcpy (str, der + len_len, *str_len);
198 else
199 {
200 return ASN1_MEM_ERROR;
201 }
202
203 return ASN1_SUCCESS;
204}
205
206
207
208/* Returns ASN1_SUCCESS on success or an error code on error.
209 */
210int
211_asn1_get_time_der (const unsigned char *der, int der_len, int *ret_len,
212 char *str, int str_size)
213{
214 int len_len, str_len;
215
216 if (der_len <= 0 || str == NULL)
217 return ASN1_DER_ERROR;
218 str_len = asn1_get_length_der (der, der_len, &len_len);
219 if (str_len < 0 || str_size < str_len)
220 return ASN1_DER_ERROR;
221 memcpy (str, der + len_len, str_len);
222 str[str_len] = 0;
223 *ret_len = str_len + len_len;
224
225 return ASN1_SUCCESS;
226}
227
228
229
230void
231_asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len,
232 char *str, int str_size)
233{
234 int len_len, len, k;
235 char temp[20];
236 unsigned long val, val1;
237
238 *ret_len = 0;
239 if (str && str_size > 0)
240 str[0] = 0; /* no oid */
241
242 if (str == NULL || der_len <= 0)
243 return;
244 len = asn1_get_length_der (der, der_len, &len_len);
245
246 if (len < 0 || len > der_len || len_len > der_len)
247 return;
248
249 val1 = der[len_len] / 40;
250 val = der[len_len] - val1 * 40;
251
252 _asn1_str_cpy (str, str_size, _asn1_ltostr (val1, temp));
253 _asn1_str_cat (str, str_size, ".");
254 _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
255
256 val = 0;
257 for (k = 1; k < len; k++)
258 {
259 val = val << 7;
260 val |= der[len_len + k] & 0x7F;
261 if (!(der[len_len + k] & 0x80))
262 {
263 _asn1_str_cat (str, str_size, ".");
264 _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
265 val = 0;
266 }
267 }
268 *ret_len = len + len_len;
269}
270
271
272
273
274/**
275 * asn1_get_bit_der:
276 * @der: DER data to decode containing the BIT SEQUENCE.
277 * @der_len: Length of DER data to decode.
278 * @ret_len: Output variable containing the length of the DER data.
279 * @str: Pre-allocated output buffer to put decoded BIT SEQUENCE in.
280 * @str_size: Length of pre-allocated output buffer.
281 * @bit_len: Output variable containing the size of the BIT SEQUENCE.
282 *
283 * Extract a BIT SEQUENCE from DER data.
284 *
285 * Return value: Return ASN1_SUCCESS on success, or an error.
286 **/
287int
288asn1_get_bit_der (const unsigned char *der, int der_len,
289 int *ret_len, unsigned char *str, int str_size,
290 int *bit_len)
291{
292 int len_len, len_byte;
293
294 if (der_len <= 0)
295 return ASN1_GENERIC_ERROR;
296 len_byte = asn1_get_length_der (der, der_len, &len_len) - 1;
297 if (len_byte < 0)
298 return ASN1_DER_ERROR;
299
300 *ret_len = len_byte + len_len + 1;
301 *bit_len = len_byte * 8 - der[len_len];
302
303 if (str_size >= len_byte)
304 memcpy (str, der + len_len + 1, len_byte);
305 else
306 {
307 return ASN1_MEM_ERROR;
308 }
309
310 return ASN1_SUCCESS;
311}
312
313
314
315
316int
317_asn1_extract_tag_der (node_asn * node, const unsigned char *der, int der_len,
318 int *ret_len)
319{
320 node_asn *p;
321 int counter, len2, len3, is_tag_implicit;
322 unsigned long tag, tag_implicit = 0;
323 unsigned char class, class2, class_implicit = 0;
324
325 if (der_len <= 0)
326 return ASN1_GENERIC_ERROR;
327
328 counter = is_tag_implicit = 0;
329
330 if (node->type & CONST_TAG)
331 {
332 p = node->down;
333 while (p)
334 {
335 if (type_field (p->type) == TYPE_TAG)
336 {
337 if (p->type & CONST_APPLICATION)
338 class2 = ASN1_CLASS_APPLICATION;
339 else if (p->type & CONST_UNIVERSAL)
340 class2 = ASN1_CLASS_UNIVERSAL;
341 else if (p->type & CONST_PRIVATE)
342 class2 = ASN1_CLASS_PRIVATE;
343 else
344 class2 = ASN1_CLASS_CONTEXT_SPECIFIC;
345
346 if (p->type & CONST_EXPLICIT)
347 {
348 if (asn1_get_tag_der
349 (der + counter, der_len - counter, &class, &len2,
350 &tag) != ASN1_SUCCESS)
351 return ASN1_DER_ERROR;
352 if (counter + len2 > der_len)
353 return ASN1_DER_ERROR;
354 counter += len2;
355 len3 =
356 asn1_get_length_der (der + counter, der_len - counter,
357 &len2);
358 if (len3 < 0)
359 return ASN1_DER_ERROR;
360 counter += len2;
361 if (!is_tag_implicit)
362 {
363 if ((class != (class2 | ASN1_CLASS_STRUCTURED)) ||
364 (tag != strtoul ((char *) p->value, NULL, 10)))
365 return ASN1_TAG_ERROR;
366 }
367 else
368 { /* ASN1_TAG_IMPLICIT */
369 if ((class != class_implicit) || (tag != tag_implicit))
370 return ASN1_TAG_ERROR;
371 }
372
373 is_tag_implicit = 0;
374 }
375 else
376 { /* ASN1_TAG_IMPLICIT */
377 if (!is_tag_implicit)
378 {
379 if ((type_field (node->type) == TYPE_SEQUENCE) ||
380 (type_field (node->type) == TYPE_SEQUENCE_OF) ||
381 (type_field (node->type) == TYPE_SET) ||
382 (type_field (node->type) == TYPE_SET_OF))
383 class2 |= ASN1_CLASS_STRUCTURED;
384 class_implicit = class2;
385 tag_implicit = strtoul ((char *) p->value, NULL, 10);
386 is_tag_implicit = 1;
387 }
388 }
389 }
390 p = p->right;
391 }
392 }
393
394 if (is_tag_implicit)
395 {
396 if (asn1_get_tag_der
397 (der + counter, der_len - counter, &class, &len2,
398 &tag) != ASN1_SUCCESS)
399 return ASN1_DER_ERROR;
400 if (counter + len2 > der_len)
401 return ASN1_DER_ERROR;
402
403 if ((class != class_implicit) || (tag != tag_implicit))
404 {
405 if (type_field (node->type) == TYPE_OCTET_STRING)
406 {
407 class_implicit |= ASN1_CLASS_STRUCTURED;
408 if ((class != class_implicit) || (tag != tag_implicit))
409 return ASN1_TAG_ERROR;
410 }
411 else
412 return ASN1_TAG_ERROR;
413 }
414 }
415 else
416 {
417 if (type_field (node->type) == TYPE_TAG)
418 {
419 counter = 0;
420 *ret_len = counter;
421 return ASN1_SUCCESS;
422 }
423
424 if (asn1_get_tag_der
425 (der + counter, der_len - counter, &class, &len2,
426 &tag) != ASN1_SUCCESS)
427 return ASN1_DER_ERROR;
428 if (counter + len2 > der_len)
429 return ASN1_DER_ERROR;
430
431 switch (type_field (node->type))
432 {
433 case TYPE_NULL:
434 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_NULL))
435 return ASN1_DER_ERROR;
436 break;
437 case TYPE_BOOLEAN:
438 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BOOLEAN))
439 return ASN1_DER_ERROR;
440 break;
441 case TYPE_INTEGER:
442 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_INTEGER))
443 return ASN1_DER_ERROR;
444 break;
445 case TYPE_ENUMERATED:
446 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_ENUMERATED))
447 return ASN1_DER_ERROR;
448 break;
449 case TYPE_OBJECT_ID:
450 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_OBJECT_ID))
451 return ASN1_DER_ERROR;
452 break;
453 case TYPE_TIME:
454 if (node->type & CONST_UTC)
455 {
456 if ((class != ASN1_CLASS_UNIVERSAL)
457 || (tag != ASN1_TAG_UTCTime))
458 return ASN1_DER_ERROR;
459 }
460 else
461 {
462 if ((class != ASN1_CLASS_UNIVERSAL)
463 || (tag != ASN1_TAG_GENERALIZEDTime))
464 return ASN1_DER_ERROR;
465 }
466 break;
467 case TYPE_OCTET_STRING:
468 if (((class != ASN1_CLASS_UNIVERSAL)
469 && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)))
470 || (tag != ASN1_TAG_OCTET_STRING))
471 return ASN1_DER_ERROR;
472 break;
473 case TYPE_GENERALSTRING:
474 if ((class != ASN1_CLASS_UNIVERSAL)
475 || (tag != ASN1_TAG_GENERALSTRING))
476 return ASN1_DER_ERROR;
477 break;
478 case TYPE_BIT_STRING:
479 if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BIT_STRING))
480 return ASN1_DER_ERROR;
481 break;
482 case TYPE_SEQUENCE:
483 case TYPE_SEQUENCE_OF:
484 if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
485 || (tag != ASN1_TAG_SEQUENCE))
486 return ASN1_DER_ERROR;
487 break;
488 case TYPE_SET:
489 case TYPE_SET_OF:
490 if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
491 || (tag != ASN1_TAG_SET))
492 return ASN1_DER_ERROR;
493 break;
494 case TYPE_ANY:
495 counter -= len2;
496 break;
497 default:
498 return ASN1_DER_ERROR;
499 break;
500 }
501 }
502
503 counter += len2;
504 *ret_len = counter;
505 return ASN1_SUCCESS;
506}
507
508
509int
510_asn1_delete_not_used (node_asn * node)
511{
512 node_asn *p, *p2;
513
514 if (node == NULL)
515 return ASN1_ELEMENT_NOT_FOUND;
516
517 p = node;
518 while (p)
519 {
520 if (p->type & CONST_NOT_USED)
521 {
522 p2 = NULL;
523 if (p != node)
524 {
525 p2 = _asn1_find_left (p);
526 if (!p2)
527 p2 = _asn1_find_up (p);
528 }
529 asn1_delete_structure (&p);
530 p = p2;
531 }
532
533 if (!p)
534 break; /* reach node */
535
536 if (p->down)
537 {
538 p = p->down;
539 }
540 else
541 {
542 if (p == node)
543 p = NULL;
544 else if (p->right)
545 p = p->right;
546 else
547 {
548 while (1)
549 {
550 p = _asn1_find_up (p);
551 if (p == node)
552 {
553 p = NULL;
554 break;
555 }
556 if (p->right)
557 {
558 p = p->right;
559 break;
560 }
561 }
562 }
563 }
564 }
565 return ASN1_SUCCESS;
566}
567
568
569asn1_retCode
570_asn1_get_octet_string (const unsigned char *der, node_asn * node, int *len)
571{
572 int len2, len3, counter, counter2, counter_end, tot_len, indefinite;
573 unsigned char *temp, *temp2;
574
575 counter = 0;
576
577 if (*(der - 1) & ASN1_CLASS_STRUCTURED)
578 {
579 tot_len = 0;
580 indefinite = asn1_get_length_der (der, *len, &len3);
581 if (indefinite < -1)
582 return ASN1_DER_ERROR;
583
584 counter += len3;
585 if (indefinite >= 0)
586 indefinite += len3;
587
588 while (1)
589 {
590 if (counter > (*len))
591 return ASN1_DER_ERROR;
592
593 if (indefinite == -1)
594 {
595 if ((der[counter] == 0) && (der[counter + 1] == 0))
596 {
597 counter += 2;
598 break;
599 }
600 }
601 else if (counter >= indefinite)
602 break;
603
604 if (der[counter] != ASN1_TAG_OCTET_STRING)
605 return ASN1_DER_ERROR;
606
607 counter++;
608
609 len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
610 if (len2 <= 0)
611 return ASN1_DER_ERROR;
612
613 counter += len3 + len2;
614 tot_len += len2;
615 }
616
617 /* copy */
618 if (node)
619 {
620 asn1_length_der (tot_len, NULL, &len2);
621 temp = _asn1_alloca (len2 + tot_len);
622 if (temp == NULL)
623 {
624 return ASN1_MEM_ALLOC_ERROR;
625 }
626
627 asn1_length_der (tot_len, temp, &len2);
628 tot_len += len2;
629 temp2 = temp + len2;
630 len2 = asn1_get_length_der (der, *len, &len3);
631 if (len2 < -1)
632 return ASN1_DER_ERROR;
633 counter2 = len3 + 1;
634
635 if (indefinite == -1)
636 counter_end = counter - 2;
637 else
638 counter_end = counter;
639
640 while (counter2 < counter_end)
641 {
642 len2 =
643 asn1_get_length_der (der + counter2, *len - counter, &len3);
644 if (len2 < -1)
645 return ASN1_DER_ERROR;
646
647 /* FIXME: to be checked. Is this ok? Has the
648 * size been checked before?
649 */
650 memcpy (temp2, der + counter2 + len3, len2);
651 temp2 += len2;
652 counter2 += len2 + len3 + 1;
653 }
654
655 _asn1_set_value (node, temp, tot_len);
656 _asn1_afree (temp);
657 }
658 }
659 else
660 { /* NOT STRUCTURED */
661 len2 = asn1_get_length_der (der, *len, &len3);
662 if (len2 < 0)
663 return ASN1_DER_ERROR;
664 if (len3 + len2 > *len)
665 return ASN1_DER_ERROR;
666 if (node)
667 _asn1_set_value (node, der, len3 + len2);
668 counter = len3 + len2;
669 }
670
671 *len = counter;
672 return ASN1_SUCCESS;
673
674}
675
676
677asn1_retCode
678_asn1_get_indefinite_length_string (const unsigned char *der, int *len)
679{
680 int len2, len3, counter, indefinite;
681 unsigned long tag;
682 unsigned char class;
683
684 counter = indefinite = 0;
685
686 while (1)
687 {
688 if ((*len) < counter)
689 return ASN1_DER_ERROR;
690
691 if ((der[counter] == 0) && (der[counter + 1] == 0))
692 {
693 counter += 2;
694 indefinite--;
695 if (indefinite <= 0)
696 break;
697 else
698 continue;
699 }
700
701 if (asn1_get_tag_der
702 (der + counter, *len - counter, &class, &len2,
703 &tag) != ASN1_SUCCESS)
704 return ASN1_DER_ERROR;
705 if (counter + len2 > *len)
706 return ASN1_DER_ERROR;
707 counter += len2;
708 len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
709 if (len2 < -1)
710 return ASN1_DER_ERROR;
711 if (len2 == -1)
712 {
713 indefinite++;
714 counter += 1;
715 }
716 else
717 {
718 counter += len2 + len3;
719 }
720 }
721
722 *len = counter;
723 return ASN1_SUCCESS;
724
725}
726
727
728/**
729 * asn1_der_decoding - Fill the structure *ELEMENT with values of a DER encoding string.
730 * @element: pointer to an ASN1 structure.
731 * @ider: vector that contains the DER encoding.
732 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1].
733 * @errorDescription: null-terminated string contains details when an
734 * error occurred.
735 *
736 * Fill the structure *ELEMENT with values of a DER encoding
737 * string. The sructure must just be created with function
738 * 'create_stucture'. If an error occurs during the decoding
739 * procedure, the *ELEMENT is deleted and set equal to
740 * %ASN1_TYPE_EMPTY.
741 *
742 * Returns:
743 *
744 * ASN1_SUCCESS: DER encoding OK.
745 *
746 * ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE_EMPTY.
747 *
748 * ASN1_TAG_ERROR,ASN1_DER_ERROR: The der encoding doesn't match
749 * the structure NAME. *ELEMENT deleted.
750 **/
751
752asn1_retCode
753asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
754 char *errorDescription)
755{
756 node_asn *node, *p, *p2, *p3;
757 char temp[128];
758 int counter, len2, len3, len4, move, ris, tlen;
759 unsigned char class, *temp2;
760 unsigned long tag;
761 int indefinite, result;
762 const unsigned char *der = ider;
763
764 node = *element;
765
766 if (node == ASN1_TYPE_EMPTY)
767 return ASN1_ELEMENT_NOT_FOUND;
768
769 if (node->type & CONST_OPTION)
770 {
771 asn1_delete_structure (element);
772 return ASN1_GENERIC_ERROR;
773 }
774
775 counter = 0;
776 move = DOWN;
777 p = node;
778 while (1)
779 {
780 ris = ASN1_SUCCESS;
781 if (move != UP)
782 {
783 if (p->type & CONST_SET)
784 {
785 p2 = _asn1_find_up (p);
786 len2 = strtol (p2->value, NULL, 10);
787 if (len2 == -1)
788 {
789 if (!der[counter] && !der[counter + 1])
790 {
791 p = p2;
792 move = UP;
793 counter += 2;
794 continue;
795 }
796 }
797 else if (counter == len2)
798 {
799 p = p2;
800 move = UP;
801 continue;
802 }
803 else if (counter > len2)
804 {
805 asn1_delete_structure (element);
806 return ASN1_DER_ERROR;
807 }
808 p2 = p2->down;
809 while (p2)
810 {
811 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
812 {
813 if (type_field (p2->type) != TYPE_CHOICE)
814 ris =
815 _asn1_extract_tag_der (p2, der + counter,
816 len - counter, &len2);
817 else
818 {
819 p3 = p2->down;
820 while (p3)
821 {
822 ris =
823 _asn1_extract_tag_der (p3, der + counter,
824 len - counter, &len2);
825 if (ris == ASN1_SUCCESS)
826 break;
827 p3 = p3->right;
828 }
829 }
830 if (ris == ASN1_SUCCESS)
831 {
832 p2->type &= ~CONST_NOT_USED;
833 p = p2;
834 break;
835 }
836 }
837 p2 = p2->right;
838 }
839 if (p2 == NULL)
840 {
841 asn1_delete_structure (element);
842 return ASN1_DER_ERROR;
843 }
844 }
845
846 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
847 {
848 p2 = _asn1_find_up (p);
849 len2 = strtol (p2->value, NULL, 10);
850 if (counter == len2)
851 {
852 if (p->right)
853 {
854 p2 = p->right;
855 move = RIGHT;
856 }
857 else
858 move = UP;
859
860 if (p->type & CONST_OPTION)
861 asn1_delete_structure (&p);
862
863 p = p2;
864 continue;
865 }
866 }
867
868 if (type_field (p->type) == TYPE_CHOICE)
869 {
870 while (p->down)
871 {
872 if (counter < len)
873 ris =
874 _asn1_extract_tag_der (p->down, der + counter,
875 len - counter, &len2);
876 else
877 ris = ASN1_DER_ERROR;
878 if (ris == ASN1_SUCCESS)
879 {
880 while (p->down->right)
881 {
882 p2 = p->down->right;
883 asn1_delete_structure (&p2);
884 }
885 break;
886 }
887 else if (ris == ASN1_ERROR_TYPE_ANY)
888 {
889 asn1_delete_structure (element);
890 return ASN1_ERROR_TYPE_ANY;
891 }
892 else
893 {
894 p2 = p->down;
895 asn1_delete_structure (&p2);
896 }
897 }
898
899 if (p->down == NULL)
900 {
901 if (!(p->type & CONST_OPTION))
902 {
903 asn1_delete_structure (element);
904 return ASN1_DER_ERROR;
905 }
906 }
907 else
908 p = p->down;
909 }
910
911 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
912 {
913 p2 = _asn1_find_up (p);
914 len2 = strtol (p2->value, NULL, 10);
915 if ((len2 != -1) && (counter > len2))
916 ris = ASN1_TAG_ERROR;
917 }
918
919 if (ris == ASN1_SUCCESS)
920 ris =
921 _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
922 if (ris != ASN1_SUCCESS)
923 {
924 if (p->type & CONST_OPTION)
925 {
926 p->type |= CONST_NOT_USED;
927 move = RIGHT;
928 }
929 else if (p->type & CONST_DEFAULT)
930 {
931 _asn1_set_value (p, NULL, 0);
932 move = RIGHT;
933 }
934 else
935 {
936 if (errorDescription != NULL)
937 _asn1_error_description_tag_error (p, errorDescription);
938
939 asn1_delete_structure (element);
940 return ASN1_TAG_ERROR;
941 }
942 }
943 else
944 counter += len2;
945 }
946
947 if (ris == ASN1_SUCCESS)
948 {
949 switch (type_field (p->type))
950 {
951 case TYPE_NULL:
952 if (der[counter])
953 {
954 asn1_delete_structure (element);
955 return ASN1_DER_ERROR;
956 }
957 counter++;
958 move = RIGHT;
959 break;
960 case TYPE_BOOLEAN:
961 if (der[counter++] != 1)
962 {
963 asn1_delete_structure (element);
964 return ASN1_DER_ERROR;
965 }
966 if (der[counter++] == 0)
967 _asn1_set_value (p, "F", 1);
968 else
969 _asn1_set_value (p, "T", 1);
970 move = RIGHT;
971 break;
972 case TYPE_INTEGER:
973 case TYPE_ENUMERATED:
974 len2 =
975 asn1_get_length_der (der + counter, len - counter, &len3);
976 if (len2 < 0)
977 return ASN1_DER_ERROR;
978 if (len2 + len3 > len - counter)
979 return ASN1_DER_ERROR;
980 _asn1_set_value (p, der + counter, len3 + len2);
981 counter += len3 + len2;
982 move = RIGHT;
983 break;
984 case TYPE_OBJECT_ID:
985 _asn1_get_objectid_der (der + counter, len - counter, &len2,
986 temp, sizeof (temp));
987 tlen = strlen (temp);
988 if (tlen > 0)
989 _asn1_set_value (p, temp, tlen + 1);
990 counter += len2;
991 move = RIGHT;
992 break;
993 case TYPE_TIME:
994 result =
995 _asn1_get_time_der (der + counter, len - counter, &len2, temp,
996 sizeof (temp) - 1);
997 if (result != ASN1_SUCCESS)
998 {
999 asn1_delete_structure (element);
1000 return result;
1001 }
1002 tlen = strlen (temp);
1003 if (tlen > 0)
1004 _asn1_set_value (p, temp, tlen + 1);
1005 counter += len2;
1006 move = RIGHT;
1007 break;
1008 case TYPE_OCTET_STRING:
1009 len3 = len - counter;
1010 ris = _asn1_get_octet_string (der + counter, p, &len3);
1011 if (ris != ASN1_SUCCESS)
1012 return ris;
1013 counter += len3;
1014 move = RIGHT;
1015 break;
1016 case TYPE_GENERALSTRING:
1017 len2 =
1018 asn1_get_length_der (der + counter, len - counter, &len3);
1019 if (len2 < 0)
1020 return ASN1_DER_ERROR;
1021 if (len3 + len2 > len - counter)
1022 return ASN1_DER_ERROR;
1023 _asn1_set_value (p, der + counter, len3 + len2);
1024 counter += len3 + len2;
1025 move = RIGHT;
1026 break;
1027 case TYPE_BIT_STRING:
1028 len2 =
1029 asn1_get_length_der (der + counter, len - counter, &len3);
1030 if (len2 < 0)
1031 return ASN1_DER_ERROR;
1032 if (len3 + len2 > len - counter)
1033 return ASN1_DER_ERROR;
1034 _asn1_set_value (p, der + counter, len3 + len2);
1035 counter += len3 + len2;
1036 move = RIGHT;
1037 break;
1038 case TYPE_SEQUENCE:
1039 case TYPE_SET:
1040 if (move == UP)
1041 {
1042 len2 = strtol (p->value, NULL, 10);
1043 _asn1_set_value (p, NULL, 0);
1044 if (len2 == -1)
1045 { /* indefinite length method */
1046 if (len - counter + 1 > 0)
1047 {
1048 if ((der[counter]) || der[counter + 1])
1049 {
1050 asn1_delete_structure (element);
1051 return ASN1_DER_ERROR;
1052 }
1053 }
1054 else
1055 return ASN1_DER_ERROR;
1056 counter += 2;
1057 }
1058 else
1059 { /* definite length method */
1060 if (len2 != counter)
1061 {
1062 asn1_delete_structure (element);
1063 return ASN1_DER_ERROR;
1064 }
1065 }
1066 move = RIGHT;
1067 }
1068 else
1069 { /* move==DOWN || move==RIGHT */
1070 len3 =
1071 asn1_get_length_der (der + counter, len - counter, &len2);
1072 if (len3 < -1)
1073 return ASN1_DER_ERROR;
1074 counter += len2;
1075 if (len3 > 0)
1076 {
1077 _asn1_ltostr (counter + len3, temp);
1078 tlen = strlen (temp);
1079 if (tlen > 0)
1080 _asn1_set_value (p, temp, tlen + 1);
1081 move = DOWN;
1082 }
1083 else if (len3 == 0)
1084 {
1085 p2 = p->down;
1086 while (p2)
1087 {
1088 if (type_field (p2->type) != TYPE_TAG)
1089 {
1090 p3 = p2->right;
1091 asn1_delete_structure (&p2);
1092 p2 = p3;
1093 }
1094 else
1095 p2 = p2->right;
1096 }
1097 move = RIGHT;
1098 }
1099 else
1100 { /* indefinite length method */
1101 _asn1_set_value (p, "-1", 3);
1102 move = DOWN;
1103 }
1104 }
1105 break;
1106 case TYPE_SEQUENCE_OF:
1107 case TYPE_SET_OF:
1108 if (move == UP)
1109 {
1110 len2 = strtol (p->value, NULL, 10);
1111 if (len2 == -1)
1112 { /* indefinite length method */
1113 if ((counter + 2) > len)
1114 return ASN1_DER_ERROR;
1115 if ((der[counter]) || der[counter + 1])
1116 {
1117 _asn1_append_sequence_set (p);
1118 p = p->down;
1119 while (p->right)
1120 p = p->right;
1121 move = RIGHT;
1122 continue;
1123 }
1124 _asn1_set_value (p, NULL, 0);
1125 counter += 2;
1126 }
1127 else
1128 { /* definite length method */
1129 if (len2 > counter)
1130 {
1131 _asn1_append_sequence_set (p);
1132 p = p->down;
1133 while (p->right)
1134 p = p->right;
1135 move = RIGHT;
1136 continue;
1137 }
1138 _asn1_set_value (p, NULL, 0);
1139 if (len2 != counter)
1140 {
1141 asn1_delete_structure (element);
1142 return ASN1_DER_ERROR;
1143 }
1144 }
1145 }
1146 else
1147 { /* move==DOWN || move==RIGHT */
1148 len3 =
1149 asn1_get_length_der (der + counter, len - counter, &len2);
1150 if (len3 < -1)
1151 return ASN1_DER_ERROR;
1152 counter += len2;
1153 if (len3)
1154 {
1155 if (len3 > 0)
1156 { /* definite length method */
1157 _asn1_ltostr (counter + len3, temp);
1158 tlen = strlen (temp);
1159
1160 if (tlen > 0)
1161 _asn1_set_value (p, temp, tlen + 1);
1162 }
1163 else
1164 { /* indefinite length method */
1165 _asn1_set_value (p, "-1", 3);
1166 }
1167 p2 = p->down;
1168 while ((type_field (p2->type) == TYPE_TAG)
1169 || (type_field (p2->type) == TYPE_SIZE))
1170 p2 = p2->right;
1171 if (p2->right == NULL)
1172 _asn1_append_sequence_set (p);
1173 p = p2;
1174 }
1175 }
1176 move = RIGHT;
1177 break;
1178 case TYPE_ANY:
1179 if (asn1_get_tag_der
1180 (der + counter, len - counter, &class, &len2,
1181 &tag) != ASN1_SUCCESS)
1182 return ASN1_DER_ERROR;
1183 if (counter + len2 > len)
1184 return ASN1_DER_ERROR;
1185 len4 =
1186 asn1_get_length_der (der + counter + len2,
1187 len - counter - len2, &len3);
1188 if (len4 < -1)
1189 return ASN1_DER_ERROR;
1190 if (len4 > len - counter + len2 + len3)
1191 return ASN1_DER_ERROR;
1192 if (len4 != -1)
1193 {
1194 len2 += len4;
1195 asn1_length_der (len2 + len3, NULL, &len4);
1196 temp2 = (unsigned char *) _asn1_alloca (len2 + len3 + len4);
1197 if (temp2 == NULL)
1198 {
1199 asn1_delete_structure (element);
1200 return ASN1_MEM_ALLOC_ERROR;
1201 }
1202
1203 asn1_octet_der (der + counter, len2 + len3, temp2, &len4);
1204 _asn1_set_value (p, temp2, len4);
1205 _asn1_afree (temp2);
1206 counter += len2 + len3;
1207 }
1208 else
1209 { /* indefinite length */
1210 /* Check indefinite lenth method in an EXPLICIT TAG */
1211 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
1212 indefinite = 1;
1213 else
1214 indefinite = 0;
1215
1216 len2 = len - counter;
1217 ris =
1218 _asn1_get_indefinite_length_string (der + counter, &len2);
1219 if (ris != ASN1_SUCCESS)
1220 {
1221 asn1_delete_structure (element);
1222 return ris;
1223 }
1224 asn1_length_der (len2, NULL, &len4);
1225 temp2 = (unsigned char *) _asn1_alloca (len2 + len4);
1226 if (temp2 == NULL)
1227 {
1228 asn1_delete_structure (element);
1229 return ASN1_MEM_ALLOC_ERROR;
1230 }
1231
1232 asn1_octet_der (der + counter, len2, temp2, &len4);
1233 _asn1_set_value (p, temp2, len4);
1234 _asn1_afree (temp2);
1235 counter += len2;
1236
1237 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1238 an indefinite length method. */
1239 if (indefinite)
1240 {
1241 if (!der[counter] && !der[counter + 1])
1242 {
1243 counter += 2;
1244 }
1245 else
1246 {
1247 asn1_delete_structure (element);
1248 return ASN1_DER_ERROR;
1249 }
1250 }
1251 }
1252 move = RIGHT;
1253 break;
1254 default:
1255 move = (move == UP) ? RIGHT : DOWN;
1256 break;
1257 }
1258 }
1259
1260 if (p == node && move != DOWN)
1261 break;
1262
1263 if (move == DOWN)
1264 {
1265 if (p->down)
1266 p = p->down;
1267 else
1268 move = RIGHT;
1269 }
1270 if ((move == RIGHT) && !(p->type & CONST_SET))
1271 {
1272 if (p->right)
1273 p = p->right;
1274 else
1275 move = UP;
1276 }
1277 if (move == UP)
1278 p = _asn1_find_up (p);
1279 }
1280
1281 _asn1_delete_not_used (*element);
1282
1283 if (counter != len)
1284 {
1285 asn1_delete_structure (element);
1286 return ASN1_DER_ERROR;
1287 }
1288
1289 return ASN1_SUCCESS;
1290}
1291
1292
1293#define FOUND 1
1294#define SAME_BRANCH 2
1295#define OTHER_BRANCH 3
1296#define EXIT 4
1297
1298/**
1299 * asn1_der_decoding_element - Fill the element named ELEMENTNAME of the structure STRUCTURE with values of a DER encoding string.
1300 * @structure: pointer to an ASN1 structure
1301 * @elementName: name of the element to fill
1302 * @ider: vector that contains the DER encoding of the whole structure.
1303 * @len: number of bytes of *der: der[0]..der[len-1]
1304 * @errorDescription: null-terminated string contains details when an
1305 * error occurred.
1306 *
1307 * Fill the element named ELEMENTNAME with values of a DER encoding
1308 * string. The sructure must just be created with function
1309 * 'create_stucture'. The DER vector must contain the encoding
1310 * string of the whole STRUCTURE. If an error occurs during the
1311 * decoding procedure, the *STRUCTURE is deleted and set equal to
1312 * %ASN1_TYPE_EMPTY.
1313 *
1314 * Returns:
1315 *
1316 * ASN1_SUCCESS: DER encoding OK.
1317 *
1318 * ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE_EMPTY or
1319 * elementName == NULL.
1320 *
1321 * ASN1_TAG_ERROR,ASN1_DER_ERROR: The der encoding doesn't match
1322 * the structure STRUCTURE. *ELEMENT deleted.
1323 *
1324 **/
1325asn1_retCode
1326asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
1327 const void *ider, int len, char *errorDescription)
1328{
1329 node_asn *node, *p, *p2, *p3, *nodeFound = ASN1_TYPE_EMPTY;
1330 char temp[128], currentName[MAX_NAME_SIZE * 10], *dot_p, *char_p;
1331 int nameLen = MAX_NAME_SIZE * 10 - 1, state;
1332 int counter, len2, len3, len4, move, ris, tlen;
1333 unsigned char class, *temp2;
1334 unsigned long tag;
1335 int indefinite, result;
1336 const unsigned char *der = ider;
1337
1338 node = *structure;
1339
1340 if (node == ASN1_TYPE_EMPTY)
1341 return ASN1_ELEMENT_NOT_FOUND;
1342
1343 if (elementName == NULL)
1344 {
1345 asn1_delete_structure (structure);
1346 return ASN1_ELEMENT_NOT_FOUND;
1347 }
1348
1349 if (node->type & CONST_OPTION)
1350 {
1351 asn1_delete_structure (structure);
1352 return ASN1_GENERIC_ERROR;
1353 }
1354
1355 if ((*structure)->name)
1356 { /* Has *structure got a name? */
1357 nameLen -= strlen ((*structure)->name);
1358 if (nameLen > 0)
1359 strcpy (currentName, (*structure)->name);
1360 else
1361 {
1362 asn1_delete_structure (structure);
1363 return ASN1_MEM_ERROR;
1364 }
1365 if (!(strcmp (currentName, elementName)))
1366 {
1367 state = FOUND;
1368 nodeFound = *structure;
1369 }
1370 else if (!memcmp (currentName, elementName, strlen (currentName)))
1371 state = SAME_BRANCH;
1372 else
1373 state = OTHER_BRANCH;
1374 }
1375 else
1376 { /* *structure doesn't have a name? */
1377 currentName[0] = 0;
1378 if (elementName[0] == 0)
1379 {
1380 state = FOUND;
1381 nodeFound = *structure;
1382 }
1383 else
1384 {
1385 state = SAME_BRANCH;
1386 }
1387 }
1388
1389 counter = 0;
1390 move = DOWN;
1391 p = node;
1392 while (1)
1393 {
1394
1395 ris = ASN1_SUCCESS;
1396
1397 if (move != UP)
1398 {
1399 if (p->type & CONST_SET)
1400 {
1401 p2 = _asn1_find_up (p);
1402 len2 = strtol (p2->value, NULL, 10);
1403 if (counter == len2)
1404 {
1405 p = p2;
1406 move = UP;
1407 continue;
1408 }
1409 else if (counter > len2)
1410 {
1411 asn1_delete_structure (structure);
1412 return ASN1_DER_ERROR;
1413 }
1414 p2 = p2->down;
1415 while (p2)
1416 {
1417 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
1418 {
1419 if (type_field (p2->type) != TYPE_CHOICE)
1420 ris =
1421 _asn1_extract_tag_der (p2, der + counter,
1422 len - counter, &len2);
1423 else
1424 {
1425 p3 = p2->down;
1426 while (p3)
1427 {
1428 ris =
1429 _asn1_extract_tag_der (p3, der + counter,
1430 len - counter, &len2);
1431 if (ris == ASN1_SUCCESS)
1432 break;
1433 p3 = p3->right;
1434 }
1435 }
1436 if (ris == ASN1_SUCCESS)
1437 {
1438 p2->type &= ~CONST_NOT_USED;
1439 p = p2;
1440 break;
1441 }
1442 }
1443 p2 = p2->right;
1444 }
1445 if (p2 == NULL)
1446 {
1447 asn1_delete_structure (structure);
1448 return ASN1_DER_ERROR;
1449 }
1450 }
1451
1452 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
1453 {
1454 p2 = _asn1_find_up (p);
1455 len2 = strtol (p2->value, NULL, 10);
1456 if (counter == len2)
1457 {
1458 if (p->right)
1459 {
1460 p2 = p->right;
1461 move = RIGHT;
1462 }
1463 else
1464 move = UP;
1465
1466 if (p->type & CONST_OPTION)
1467 asn1_delete_structure (&p);
1468
1469 p = p2;
1470 continue;
1471 }
1472 }
1473
1474 if (type_field (p->type) == TYPE_CHOICE)
1475 {
1476 while (p->down)
1477 {
1478 if (counter < len)
1479 ris =
1480 _asn1_extract_tag_der (p->down, der + counter,
1481 len - counter, &len2);
1482 else
1483 ris = ASN1_DER_ERROR;
1484 if (ris == ASN1_SUCCESS)
1485 {
1486 while (p->down->right)
1487 {
1488 p2 = p->down->right;
1489 asn1_delete_structure (&p2);
1490 }
1491 break;
1492 }
1493 else if (ris == ASN1_ERROR_TYPE_ANY)
1494 {
1495 asn1_delete_structure (structure);
1496 return ASN1_ERROR_TYPE_ANY;
1497 }
1498 else
1499 {
1500 p2 = p->down;
1501 asn1_delete_structure (&p2);
1502 }
1503 }
1504
1505 if (p->down == NULL)
1506 {
1507 if (!(p->type & CONST_OPTION))
1508 {
1509 asn1_delete_structure (structure);
1510 return ASN1_DER_ERROR;
1511 }
1512 }
1513 else
1514 p = p->down;
1515 }
1516
1517 if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
1518 {
1519 p2 = _asn1_find_up (p);
1520 len2 = strtol (p2->value, NULL, 10);
1521 if (counter > len2)
1522 ris = ASN1_TAG_ERROR;
1523 }
1524
1525 if (ris == ASN1_SUCCESS)
1526 ris =
1527 _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
1528 if (ris != ASN1_SUCCESS)
1529 {
1530 if (p->type & CONST_OPTION)
1531 {
1532 p->type |= CONST_NOT_USED;
1533 move = RIGHT;
1534 }
1535 else if (p->type & CONST_DEFAULT)
1536 {
1537 _asn1_set_value (p, NULL, 0);
1538 move = RIGHT;
1539 }
1540 else
1541 {
1542 if (errorDescription != NULL)
1543 _asn1_error_description_tag_error (p, errorDescription);
1544
1545 asn1_delete_structure (structure);
1546 return ASN1_TAG_ERROR;
1547 }
1548 }
1549 else
1550 counter += len2;
1551 }
1552
1553 if (ris == ASN1_SUCCESS)
1554 {
1555 switch (type_field (p->type))
1556 {
1557 case TYPE_NULL:
1558 if (der[counter])
1559 {
1560 asn1_delete_structure (structure);
1561 return ASN1_DER_ERROR;
1562 }
1563
1564 if (p == nodeFound)
1565 state = EXIT;
1566
1567 counter++;
1568 move = RIGHT;
1569 break;
1570 case TYPE_BOOLEAN:
1571 if (der[counter++] != 1)
1572 {
1573 asn1_delete_structure (structure);
1574 return ASN1_DER_ERROR;
1575 }
1576
1577 if (state == FOUND)
1578 {
1579 if (der[counter++] == 0)
1580 _asn1_set_value (p, "F", 1);
1581 else
1582 _asn1_set_value (p, "T", 1);
1583
1584 if (p == nodeFound)
1585 state = EXIT;
1586
1587 }
1588 else
1589 counter++;
1590
1591 move = RIGHT;
1592 break;
1593 case TYPE_INTEGER:
1594 case TYPE_ENUMERATED:
1595 len2 =
1596 asn1_get_length_der (der + counter, len - counter, &len3);
1597 if (len2 < 0)
1598 return ASN1_DER_ERROR;
1599 if (state == FOUND)
1600 {
1601 if (len3 + len2 > len - counter)
1602 return ASN1_DER_ERROR;
1603 _asn1_set_value (p, der + counter, len3 + len2);
1604
1605 if (p == nodeFound)
1606 state = EXIT;
1607 }
1608 counter += len3 + len2;
1609 move = RIGHT;
1610 break;
1611 case TYPE_OBJECT_ID:
1612 if (state == FOUND)
1613 {
1614 _asn1_get_objectid_der (der + counter, len - counter, &len2,
1615 temp, sizeof (temp));
1616 tlen = strlen (temp);
1617
1618 if (tlen > 0)
1619 _asn1_set_value (p, temp, tlen + 1);
1620
1621 if (p == nodeFound)
1622 state = EXIT;
1623 }
1624 else
1625 {
1626 len2 =
1627 asn1_get_length_der (der + counter, len - counter, &len3);
1628 if (len2 < 0)
1629 return ASN1_DER_ERROR;
1630 len2 += len3;
1631 }
1632
1633 counter += len2;
1634 move = RIGHT;
1635 break;
1636 case TYPE_TIME:
1637 if (state == FOUND)
1638 {
1639 result =
1640 _asn1_get_time_der (der + counter, len - counter, &len2,
1641 temp, sizeof (temp) - 1);
1642 if (result != ASN1_SUCCESS)
1643 {
1644 asn1_delete_structure (structure);
1645 return result;
1646 }
1647
1648 tlen = strlen (temp);
1649 if (tlen > 0)
1650 _asn1_set_value (p, temp, tlen + 1);
1651
1652 if (p == nodeFound)
1653 state = EXIT;
1654 }
1655 else
1656 {
1657 len2 =
1658 asn1_get_length_der (der + counter, len - counter, &len3);
1659 if (len2 < 0)
1660 return ASN1_DER_ERROR;
1661 len2 += len3;
1662 }
1663
1664 counter += len2;
1665 move = RIGHT;
1666 break;
1667 case TYPE_OCTET_STRING:
1668 len3 = len - counter;
1669 if (state == FOUND)
1670 {
1671 ris = _asn1_get_octet_string (der + counter, p, &len3);
1672 if (p == nodeFound)
1673 state = EXIT;
1674 }
1675 else
1676 ris = _asn1_get_octet_string (der + counter, NULL, &len3);
1677
1678 if (ris != ASN1_SUCCESS)
1679 return ris;
1680 counter += len3;
1681 move = RIGHT;
1682 break;
1683 case TYPE_GENERALSTRING:
1684 len2 =
1685 asn1_get_length_der (der + counter, len - counter, &len3);
1686 if (len2 < 0)
1687 return ASN1_DER_ERROR;
1688 if (state == FOUND)
1689 {
1690 if (len3 + len2 > len - counter)
1691 return ASN1_DER_ERROR;
1692 _asn1_set_value (p, der + counter, len3 + len2);
1693
1694 if (p == nodeFound)
1695 state = EXIT;
1696 }
1697 counter += len3 + len2;
1698 move = RIGHT;
1699 break;
1700 case TYPE_BIT_STRING:
1701 len2 =
1702 asn1_get_length_der (der + counter, len - counter, &len3);
1703 if (len2 < 0)
1704 return ASN1_DER_ERROR;
1705 if (state == FOUND)
1706 {
1707 if (len3 + len2 > len - counter)
1708 return ASN1_DER_ERROR;
1709 _asn1_set_value (p, der + counter, len3 + len2);
1710
1711 if (p == nodeFound)
1712 state = EXIT;
1713 }
1714 counter += len3 + len2;
1715 move = RIGHT;
1716 break;
1717 case TYPE_SEQUENCE:
1718 case TYPE_SET:
1719 if (move == UP)
1720 {
1721 len2 = strtol (p->value, NULL, 10);
1722 _asn1_set_value (p, NULL, 0);
1723 if (len2 == -1)
1724 { /* indefinite length method */
1725 if ((der[counter]) || der[counter + 1])
1726 {
1727 asn1_delete_structure (structure);
1728 return ASN1_DER_ERROR;
1729 }
1730 counter += 2;
1731 }
1732 else
1733 { /* definite length method */
1734 if (len2 != counter)
1735 {
1736 asn1_delete_structure (structure);
1737 return ASN1_DER_ERROR;
1738 }
1739 }
1740 if (p == nodeFound)
1741 state = EXIT;
1742 move = RIGHT;
1743 }
1744 else
1745 { /* move==DOWN || move==RIGHT */
1746 if (state == OTHER_BRANCH)
1747 {
1748 len3 =
1749 asn1_get_length_der (der + counter, len - counter,
1750 &len2);
1751 if (len3 < 0)
1752 return ASN1_DER_ERROR;
1753 counter += len2 + len3;
1754 move = RIGHT;
1755 }
1756 else
1757 { /* state==SAME_BRANCH or state==FOUND */
1758 len3 =
1759 asn1_get_length_der (der + counter, len - counter,
1760 &len2);
1761 if (len3 < 0)
1762 return ASN1_DER_ERROR;
1763 counter += len2;
1764 if (len3 > 0)
1765 {
1766 _asn1_ltostr (counter + len3, temp);
1767 tlen = strlen (temp);
1768
1769 if (tlen > 0)
1770 _asn1_set_value (p, temp, tlen + 1);
1771 move = DOWN;
1772 }
1773 else if (len3 == 0)
1774 {
1775 p2 = p->down;
1776 while (p2)
1777 {
1778 if (type_field (p2->type) != TYPE_TAG)
1779 {
1780 p3 = p2->right;
1781 asn1_delete_structure (&p2);
1782 p2 = p3;
1783 }
1784 else
1785 p2 = p2->right;
1786 }
1787 move = RIGHT;
1788 }
1789 else
1790 { /* indefinite length method */
1791 _asn1_set_value (p, "-1", 3);
1792 move = DOWN;
1793 }
1794 }
1795 }
1796 break;
1797 case TYPE_SEQUENCE_OF:
1798 case TYPE_SET_OF:
1799 if (move == UP)
1800 {
1801 len2 = strtol (p->value, NULL, 10);
1802 if (len2 > counter)
1803 {
1804 _asn1_append_sequence_set (p);
1805 p = p->down;
1806 while (p->right)
1807 p = p->right;
1808 move = RIGHT;
1809 continue;
1810 }
1811 _asn1_set_value (p, NULL, 0);
1812 if (len2 != counter)
1813 {
1814 asn1_delete_structure (structure);
1815 return ASN1_DER_ERROR;
1816 }
1817
1818 if (p == nodeFound)
1819 state = EXIT;
1820 }
1821 else
1822 { /* move==DOWN || move==RIGHT */
1823 if (state == OTHER_BRANCH)
1824 {
1825 len3 =
1826 asn1_get_length_der (der + counter, len - counter,
1827 &len2);
1828 if (len3 < 0)
1829 return ASN1_DER_ERROR;
1830 counter += len2 + len3;
1831 move = RIGHT;
1832 }
1833 else
1834 { /* state==FOUND or state==SAME_BRANCH */
1835 len3 =
1836 asn1_get_length_der (der + counter, len - counter,
1837 &len2);
1838 if (len3 < 0)
1839 return ASN1_DER_ERROR;
1840 counter += len2;
1841 if (len3)
1842 {
1843 _asn1_ltostr (counter + len3, temp);
1844 tlen = strlen (temp);
1845
1846 if (tlen > 0)
1847 _asn1_set_value (p, temp, tlen + 1);
1848 p2 = p->down;
1849 while ((type_field (p2->type) == TYPE_TAG)
1850 || (type_field (p2->type) == TYPE_SIZE))
1851 p2 = p2->right;
1852 if (p2->right == NULL)
1853 _asn1_append_sequence_set (p);
1854 p = p2;
1855 state = FOUND;
1856 }
1857 }
1858 }
1859
1860 break;
1861 case TYPE_ANY:
1862 if (asn1_get_tag_der
1863 (der + counter, len - counter, &class, &len2,
1864 &tag) != ASN1_SUCCESS)
1865 return ASN1_DER_ERROR;
1866 if (counter + len2 > len)
1867 return ASN1_DER_ERROR;
1868
1869 len4 =
1870 asn1_get_length_der (der + counter + len2,
1871 len - counter - len2, &len3);
1872 if (len4 < -1)
1873 return ASN1_DER_ERROR;
1874
1875 if (len4 != -1)
1876 {
1877 len2 += len4;
1878 if (state == FOUND)
1879 {
1880 asn1_length_der (len2 + len3, NULL, &len4);
1881 temp2 =
1882 (unsigned char *) _asn1_alloca (len2 + len3 + len4);
1883 if (temp2 == NULL)
1884 {
1885 asn1_delete_structure (structure);
1886 return ASN1_MEM_ALLOC_ERROR;
1887 }
1888
1889 asn1_octet_der (der + counter, len2 + len3, temp2,
1890 &len4);
1891 _asn1_set_value (p, temp2, len4);
1892 _asn1_afree (temp2);
1893
1894 if (p == nodeFound)
1895 state = EXIT;
1896 }
1897 counter += len2 + len3;
1898 }
1899 else
1900 { /* indefinite length */
1901 /* Check indefinite lenth method in an EXPLICIT TAG */
1902 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
1903 indefinite = 1;
1904 else
1905 indefinite = 0;
1906
1907 len2 = len - counter;
1908 ris =
1909 _asn1_get_indefinite_length_string (der + counter, &len2);
1910 if (ris != ASN1_SUCCESS)
1911 {
1912 asn1_delete_structure (structure);
1913 return ris;
1914 }
1915
1916 if (state == FOUND)
1917 {
1918 asn1_length_der (len2, NULL, &len4);
1919 temp2 = (unsigned char *) _asn1_alloca (len2 + len4);
1920 if (temp2 == NULL)
1921 {
1922 asn1_delete_structure (structure);
1923 return ASN1_MEM_ALLOC_ERROR;
1924 }
1925
1926 asn1_octet_der (der + counter, len2, temp2, &len4);
1927 _asn1_set_value (p, temp2, len4);
1928 _asn1_afree (temp2);
1929
1930 if (p == nodeFound)
1931 state = EXIT;
1932 }
1933
1934 counter += len2;
1935
1936 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
1937 an indefinite length method. */
1938 if (indefinite)
1939 {
1940 if (!der[counter] && !der[counter + 1])
1941 {
1942 counter += 2;
1943 }
1944 else
1945 {
1946 asn1_delete_structure (structure);
1947 return ASN1_DER_ERROR;
1948 }
1949 }
1950 }
1951 move = RIGHT;
1952 break;
1953
1954 default:
1955 move = (move == UP) ? RIGHT : DOWN;
1956 break;
1957 }
1958 }
1959
1960 if ((p == node && move != DOWN) || (state == EXIT))
1961 break;
1962
1963 if (move == DOWN)
1964 {
1965 if (p->down)
1966 {
1967 p = p->down;
1968
1969 if (state != FOUND)
1970 {
1971 nameLen -= strlen (p->name) + 1;
1972 if (nameLen > 0)
1973 {
1974 if (currentName[0])
1975 strcat (currentName, ".");
1976 strcat (currentName, p->name);
1977 }
1978 else
1979 {
1980 asn1_delete_structure (structure);
1981 return ASN1_MEM_ERROR;
1982 }
1983 if (!(strcmp (currentName, elementName)))
1984 {
1985 state = FOUND;
1986 nodeFound = p;
1987 }
1988 else
1989 if (!memcmp
1990 (currentName, elementName, strlen (currentName)))
1991 state = SAME_BRANCH;
1992 else
1993 state = OTHER_BRANCH;
1994 }
1995 }
1996 else
1997 move = RIGHT;
1998 }
1999
2000 if ((move == RIGHT) && !(p->type & CONST_SET))
2001 {
2002 if (p->right)
2003 {
2004 p = p->right;
2005
2006 if (state != FOUND)
2007 {
2008 dot_p = char_p = currentName;
2009 while ((char_p = strchr (char_p, '.')))
2010 {
2011 dot_p = char_p++;
2012 dot_p++;
2013 }
2014
2015 nameLen += strlen (currentName) - (dot_p - currentName);
2016 *dot_p = 0;
2017
2018 nameLen -= strlen (p->name);
2019 if (nameLen > 0)
2020 strcat (currentName, p->name);
2021 else
2022 {
2023 asn1_delete_structure (structure);
2024 return ASN1_MEM_ERROR;
2025 }
2026
2027 if (!(strcmp (currentName, elementName)))
2028 {
2029 state = FOUND;
2030 nodeFound = p;
2031 }
2032 else
2033 if (!memcmp
2034 (currentName, elementName, strlen (currentName)))
2035 state = SAME_BRANCH;
2036 else
2037 state = OTHER_BRANCH;
2038 }
2039 }
2040 else
2041 move = UP;
2042 }
2043
2044 if (move == UP)
2045 {
2046 p = _asn1_find_up (p);
2047
2048 if (state != FOUND)
2049 {
2050 dot_p = char_p = currentName;
2051 while ((char_p = strchr (char_p, '.')))
2052 {
2053 dot_p = char_p++;
2054 dot_p++;
2055 }
2056
2057 nameLen += strlen (currentName) - (dot_p - currentName);
2058 *dot_p = 0;
2059
2060 if (!(strcmp (currentName, elementName)))
2061 {
2062 state = FOUND;
2063 nodeFound = p;
2064 }
2065 else
2066 if (!memcmp (currentName, elementName, strlen (currentName)))
2067 state = SAME_BRANCH;
2068 else
2069 state = OTHER_BRANCH;
2070 }
2071 }
2072 }
2073
2074 _asn1_delete_not_used (*structure);
2075
2076 if (counter > len)
2077 {
2078 asn1_delete_structure (structure);
2079 return ASN1_DER_ERROR;
2080 }
2081
2082 return ASN1_SUCCESS;
2083}
2084
2085
2086
2087/**
2088 * asn1_der_decoding_startEnd - Find the start and end point of an element in a DER encoding string.
2089 * @element: pointer to an ASN1 element
2090 * @ider: vector that contains the DER encoding.
2091 * @len: number of bytes of *@ider: @ider[0]..@ider[len-1]
2092 * @name_element: an element of NAME structure.
2093 * @start: the position of the first byte of NAME_ELEMENT decoding
2094 * (@ider[*start])
2095 * @end: the position of the last byte of NAME_ELEMENT decoding
2096 * (@ider[*end])
2097 *
2098 * Find the start and end point of an element in a DER encoding
2099 * string. I mean that if you have a der encoding and you have
2100 * already used the function "asn1_der_decoding" to fill a structure,
2101 * it may happen that you want to find the piece of string concerning
2102 * an element of the structure.
2103 *
2104 * Example: the sequence "tbsCertificate" inside an X509 certificate.
2105 *
2106 * Returns:
2107 *
2108 * ASN1_SUCCESS: DER encoding OK.
2109 *
2110 * ASN1_ELEMENT_NOT_FOUND: ELEMENT is ASN1_TYPE EMPTY or
2111 * NAME_ELEMENT is not a valid element.
2112 *
2113 * ASN1_TAG_ERROR,ASN1_DER_ERROR: the der encoding doesn't match
2114 * the structure ELEMENT.
2115 *
2116 **/
2117asn1_retCode
2118asn1_der_decoding_startEnd (ASN1_TYPE element, const void *ider, int len,
2119 const char *name_element, int *start, int *end)
2120{
2121 node_asn *node, *node_to_find, *p, *p2, *p3;
2122 int counter, len2, len3, len4, move, ris;
2123 unsigned char class;
2124 unsigned long tag;
2125 int indefinite;
2126 const unsigned char *der = ider;
2127
2128 node = element;
2129
2130 if (node == ASN1_TYPE_EMPTY)
2131 return ASN1_ELEMENT_NOT_FOUND;
2132
2133 node_to_find = asn1_find_node (node, name_element);
2134
2135 if (node_to_find == NULL)
2136 return ASN1_ELEMENT_NOT_FOUND;
2137
2138 if (node_to_find == node)
2139 {
2140 *start = 0;
2141 *end = len - 1;
2142 return ASN1_SUCCESS;
2143 }
2144
2145 if (node->type & CONST_OPTION)
2146 return ASN1_GENERIC_ERROR;
2147
2148 counter = 0;
2149 move = DOWN;
2150 p = node;
2151 while (1)
2152 {
2153 ris = ASN1_SUCCESS;
2154
2155 if (move != UP)
2156 {
2157 if (p->type & CONST_SET)
2158 {
2159 p2 = _asn1_find_up (p);
2160 len2 = strtol (p2->value, NULL, 10);
2161 if (len2 == -1)
2162 {
2163 if (!der[counter] && !der[counter + 1])
2164 {
2165 p = p2;
2166 move = UP;
2167 counter += 2;
2168 continue;
2169 }
2170 }
2171 else if (counter == len2)
2172 {
2173 p = p2;
2174 move = UP;
2175 continue;
2176 }
2177 else if (counter > len2)
2178 return ASN1_DER_ERROR;
2179 p2 = p2->down;
2180 while (p2)
2181 {
2182 if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
2183 { /* CONTROLLARE */
2184 if (type_field (p2->type) != TYPE_CHOICE)
2185 ris =
2186 _asn1_extract_tag_der (p2, der + counter,
2187 len - counter, &len2);
2188 else
2189 {
2190 p3 = p2->down;
2191 ris =
2192 _asn1_extract_tag_der (p3, der + counter,
2193 len - counter, &len2);
2194 }
2195 if (ris == ASN1_SUCCESS)
2196 {
2197 p2->type &= ~CONST_NOT_USED;
2198 p = p2;
2199 break;
2200 }
2201 }
2202 p2 = p2->right;
2203 }
2204 if (p2 == NULL)
2205 return ASN1_DER_ERROR;
2206 }
2207
2208 if (p == node_to_find)
2209 *start = counter;
2210
2211 if (type_field (p->type) == TYPE_CHOICE)
2212 {
2213 p = p->down;
2214 ris =
2215 _asn1_extract_tag_der (p, der + counter, len - counter,
2216 &len2);
2217 if (p == node_to_find)
2218 *start = counter;
2219 }
2220
2221 if (ris == ASN1_SUCCESS)
2222 ris =
2223 _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
2224 if (ris != ASN1_SUCCESS)
2225 {
2226 if (p->type & CONST_OPTION)
2227 {
2228 p->type |= CONST_NOT_USED;
2229 move = RIGHT;
2230 }
2231 else if (p->type & CONST_DEFAULT)
2232 {
2233 move = RIGHT;
2234 }
2235 else
2236 {
2237 return ASN1_TAG_ERROR;
2238 }
2239 }
2240 else
2241 counter += len2;
2242 }
2243
2244 if (ris == ASN1_SUCCESS)
2245 {
2246 switch (type_field (p->type))
2247 {
2248 case TYPE_NULL:
2249 if (der[counter])
2250 return ASN1_DER_ERROR;
2251 counter++;
2252 move = RIGHT;
2253 break;
2254 case TYPE_BOOLEAN:
2255 if (der[counter++] != 1)
2256 return ASN1_DER_ERROR;
2257 counter++;
2258 move = RIGHT;
2259 break;
2260 case TYPE_INTEGER:
2261 case TYPE_ENUMERATED:
2262 len2 =
2263 asn1_get_length_der (der + counter, len - counter, &len3);
2264 if (len2 < 0)
2265 return ASN1_DER_ERROR;
2266 counter += len3 + len2;
2267 move = RIGHT;
2268 break;
2269 case TYPE_OBJECT_ID:
2270 len2 =
2271 asn1_get_length_der (der + counter, len - counter, &len3);
2272 if (len2 < 0)
2273 return ASN1_DER_ERROR;
2274 counter += len2 + len3;
2275 move = RIGHT;
2276 break;
2277 case TYPE_TIME:
2278 len2 =
2279 asn1_get_length_der (der + counter, len - counter, &len3);
2280 if (len2 < 0)
2281 return ASN1_DER_ERROR;
2282 counter += len2 + len3;
2283 move = RIGHT;
2284 break;
2285 case TYPE_OCTET_STRING:
2286 len3 = len - counter;
2287 ris = _asn1_get_octet_string (der + counter, NULL, &len3);
2288 if (ris != ASN1_SUCCESS)
2289 return ris;
2290 counter += len3;
2291 move = RIGHT;
2292 break;
2293 case TYPE_GENERALSTRING:
2294 len2 =
2295 asn1_get_length_der (der + counter, len - counter, &len3);
2296 if (len2 < 0)
2297 return ASN1_DER_ERROR;
2298 counter += len3 + len2;
2299 move = RIGHT;
2300 break;
2301 case TYPE_BIT_STRING:
2302 len2 =
2303 asn1_get_length_der (der + counter, len - counter, &len3);
2304 if (len2 < 0)
2305 return ASN1_DER_ERROR;
2306 counter += len3 + len2;
2307 move = RIGHT;
2308 break;
2309 case TYPE_SEQUENCE:
2310 case TYPE_SET:
2311 if (move != UP)
2312 {
2313 len3 =
2314 asn1_get_length_der (der + counter, len - counter, &len2);
2315 if (len3 < -1)
2316 return ASN1_DER_ERROR;
2317 counter += len2;
2318 if (len3 == 0)
2319 move = RIGHT;
2320 else
2321 move = DOWN;
2322 }
2323 else
2324 {
2325 if (!der[counter] && !der[counter + 1]) /* indefinite length method */
2326 counter += 2;
2327 move = RIGHT;
2328 }
2329 break;
2330 case TYPE_SEQUENCE_OF:
2331 case TYPE_SET_OF:
2332 if (move != UP)
2333 {
2334 len3 =
2335 asn1_get_length_der (der + counter, len - counter, &len2);
2336 if (len3 < -1)
2337 return ASN1_DER_ERROR;
2338 counter += len2;
2339 if ((len3 == -1) && !der[counter] && !der[counter + 1])
2340 counter += 2;
2341 else if (len3)
2342 {
2343 p2 = p->down;
2344 while ((type_field (p2->type) == TYPE_TAG) ||
2345 (type_field (p2->type) == TYPE_SIZE))
2346 p2 = p2->right;
2347 p = p2;
2348 }
2349 }
2350 else
2351 {
2352 if (!der[counter] && !der[counter + 1]) /* indefinite length method */
2353 counter += 2;
2354 }
2355 move = RIGHT;
2356 break;
2357 case TYPE_ANY:
2358 if (asn1_get_tag_der
2359 (der + counter, len - counter, &class, &len2,
2360 &tag) != ASN1_SUCCESS)
2361 return ASN1_DER_ERROR;
2362 if (counter + len2 > len)
2363 return ASN1_DER_ERROR;
2364
2365 len4 =
2366 asn1_get_length_der (der + counter + len2,
2367 len - counter - len2, &len3);
2368 if (len4 < -1)
2369 return ASN1_DER_ERROR;
2370
2371 if (len4 != -1)
2372 {
2373 counter += len2 + len4 + len3;
2374 }
2375 else
2376 { /* indefinite length */
2377 /* Check indefinite lenth method in an EXPLICIT TAG */
2378 if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
2379 indefinite = 1;
2380 else
2381 indefinite = 0;
2382
2383 len2 = len - counter;
2384 ris =
2385 _asn1_get_indefinite_length_string (der + counter, &len2);
2386 if (ris != ASN1_SUCCESS)
2387 return ris;
2388 counter += len2;
2389
2390 /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
2391 an indefinite length method. */
2392 if (indefinite)
2393 {
2394 if (!der[counter] && !der[counter + 1])
2395 counter += 2;
2396 else
2397 return ASN1_DER_ERROR;
2398 }
2399 }
2400 move = RIGHT;
2401 break;
2402 default:
2403 move = (move == UP) ? RIGHT : DOWN;
2404 break;
2405 }
2406 }
2407
2408 if ((p == node_to_find) && (move == RIGHT))
2409 {
2410 *end = counter - 1;
2411 return ASN1_SUCCESS;
2412 }
2413
2414 if (p == node && move != DOWN)
2415 break;
2416
2417 if (move == DOWN)
2418 {
2419 if (p->down)
2420 p = p->down;
2421 else
2422 move = RIGHT;
2423 }
2424 if ((move == RIGHT) && !(p->type & CONST_SET))
2425 {
2426 if (p->right)
2427 p = p->right;
2428 else
2429 move = UP;
2430 }
2431 if (move == UP)
2432 p = _asn1_find_up (p);
2433 }
2434
2435 return ASN1_ELEMENT_NOT_FOUND;
2436}
2437
2438
2439/**
2440 * asn1_expand_any_defined_by - Expand "ANY DEFINED BY" fields in structure.
2441 * @definitions: ASN1 definitions
2442 * @element: pointer to an ASN1 structure
2443 *
2444 * Expands every "ANY DEFINED BY" element of a structure created from
2445 * a DER decoding process (asn1_der_decoding function). The element ANY
2446 * must be defined by an OBJECT IDENTIFIER. The type used to expand
2447 * the element ANY is the first one following the definition of
2448 * the actual value of the OBJECT IDENTIFIER.
2449 *
2450 *
2451 * Returns:
2452 *
2453 * ASN1_SUCCESS: Substitution OK.
2454 *
2455 * ASN1_ERROR_TYPE_ANY: Some "ANY DEFINED BY" element couldn't be
2456 * expanded due to a problem in OBJECT_ID -> TYPE association.
2457 *
2458 * other errors: Result of der decoding process.
2459 **/
2460
2461asn1_retCode
2462asn1_expand_any_defined_by (ASN1_TYPE definitions, ASN1_TYPE * element)
2463{
2464 char definitionsName[MAX_NAME_SIZE], name[2 * MAX_NAME_SIZE + 1],
2465 value[MAX_NAME_SIZE];
2466 asn1_retCode retCode = ASN1_SUCCESS, result;
2467 int len, len2, len3;
2468 ASN1_TYPE p, p2, p3, aux = ASN1_TYPE_EMPTY;
2469 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
2470
2471 if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY))
2472 return ASN1_ELEMENT_NOT_FOUND;
2473
2474 strcpy (definitionsName, definitions->name);
2475 strcat (definitionsName, ".");
2476
2477 p = *element;
2478 while (p)
2479 {
2480
2481 switch (type_field (p->type))
2482 {
2483 case TYPE_ANY:
2484 if ((p->type & CONST_DEFINED_BY) && (p->value))
2485 {
2486 /* search the "DEF_BY" element */
2487 p2 = p->down;
2488 while ((p2) && (type_field (p2->type) != TYPE_CONSTANT))
2489 p2 = p2->right;
2490
2491 if (!p2)
2492 {
2493 retCode = ASN1_ERROR_TYPE_ANY;
2494 break;
2495 }
2496
2497 p3 = _asn1_find_up (p);
2498
2499 if (!p3)
2500 {
2501 retCode = ASN1_ERROR_TYPE_ANY;
2502 break;
2503 }
2504
2505 p3 = p3->down;
2506 while (p3)
2507 {
2508 if ((p3->name) && !(strcmp (p3->name, p2->name)))
2509 break;
2510 p3 = p3->right;
2511 }
2512
2513 if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
2514 (p3->value == NULL))
2515 {
2516
2517 p3 = _asn1_find_up (p);
2518 p3 = _asn1_find_up (p3);
2519
2520 if (!p3)
2521 {
2522 retCode = ASN1_ERROR_TYPE_ANY;
2523 break;
2524 }
2525
2526 p3 = p3->down;
2527
2528 while (p3)
2529 {
2530 if ((p3->name) && !(strcmp (p3->name, p2->name)))
2531 break;
2532 p3 = p3->right;
2533 }
2534
2535 if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
2536 (p3->value == NULL))
2537 {
2538 retCode = ASN1_ERROR_TYPE_ANY;
2539 break;
2540 }
2541 }
2542
2543 /* search the OBJECT_ID into definitions */
2544 p2 = definitions->down;
2545 while (p2)
2546 {
2547 if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
2548 (p2->type & CONST_ASSIGN))
2549 {
2550 strcpy (name, definitionsName);
2551 strcat (name, p2->name);
2552
2553 len = MAX_NAME_SIZE;
2554 result =
2555 asn1_read_value (definitions, name, value, &len);
2556
2557 if ((result == ASN1_SUCCESS)
2558 && (!strcmp (p3->value, value)))
2559 {
2560 p2 = p2->right; /* pointer to the structure to
2561 use for expansion */
2562 while ((p2) && (p2->type & CONST_ASSIGN))
2563 p2 = p2->right;
2564
2565 if (p2)
2566 {
2567 strcpy (name, definitionsName);
2568 strcat (name, p2->name);
2569
2570 result =
2571 asn1_create_element (definitions, name, &aux);
2572 if (result == ASN1_SUCCESS)
2573 {
2574 _asn1_set_name (aux, p->name);
2575 len2 =
2576 asn1_get_length_der (p->value,
2577 p->value_len, &len3);
2578 if (len2 < 0)
2579 return ASN1_DER_ERROR;
2580
2581 result =
2582 asn1_der_decoding (&aux, p->value + len3,
2583 len2,
2584 errorDescription);
2585 if (result == ASN1_SUCCESS)
2586 {
2587
2588 _asn1_set_right (aux, p->right);
2589 _asn1_set_right (p, aux);
2590
2591 result = asn1_delete_structure (&p);
2592 if (result == ASN1_SUCCESS)
2593 {
2594 p = aux;
2595 aux = ASN1_TYPE_EMPTY;
2596 break;
2597 }
2598 else
2599 { /* error with asn1_delete_structure */
2600 asn1_delete_structure (&aux);
2601 retCode = result;
2602 break;
2603 }
2604 }
2605 else
2606 { /* error with asn1_der_decoding */
2607 retCode = result;
2608 break;
2609 }
2610 }
2611 else
2612 { /* error with asn1_create_element */
2613 retCode = result;
2614 break;
2615 }
2616 }
2617 else
2618 { /* error with the pointer to the structure to exapand */
2619 retCode = ASN1_ERROR_TYPE_ANY;
2620 break;
2621 }
2622 }
2623 }
2624 p2 = p2->right;
2625 } /* end while */
2626
2627 if (!p2)
2628 {
2629 retCode = ASN1_ERROR_TYPE_ANY;
2630 break;
2631 }
2632
2633 }
2634 break;
2635 default:
2636 break;
2637 }
2638
2639
2640 if (p->down)
2641 {
2642 p = p->down;
2643 }
2644 else if (p == *element)
2645 {
2646 p = NULL;
2647 break;
2648 }
2649 else if (p->right)
2650 p = p->right;
2651 else
2652 {
2653 while (1)
2654 {
2655 p = _asn1_find_up (p);
2656 if (p == *element)
2657 {
2658 p = NULL;
2659 break;
2660 }
2661 if (p->right)
2662 {
2663 p = p->right;
2664 break;
2665 }
2666 }
2667 }
2668 }
2669
2670 return retCode;
2671}
2672
2673
2674
2675/**
2676 * asn1_expand_octet_string - Expand "OCTET STRING" fields in structure.
2677 * @definitions: ASN1 definitions
2678 * @element: pointer to an ASN1 structure
2679 * @octetName: name of the OCTECT STRING field to expand.
2680 * @objectName: name of the OBJECT IDENTIFIER field to use to define
2681 * the type for expansion.
2682 *
2683 * Expands an "OCTET STRING" element of a structure created from a
2684 * DER decoding process (asn1_der_decoding function). The type used
2685 * for expansion is the first one following the definition of the
2686 * actual value of the OBJECT IDENTIFIER indicated by OBJECTNAME.
2687 *
2688 * Returns:
2689 *
2690 * ASN1_SUCCESS: Substitution OK.
2691 *
2692 * ASN1_ELEMENT_NOT_FOUND: OBJECTNAME or OCTETNAME are not correct.
2693 *
2694 * ASN1_VALUE_NOT_VALID: Wasn't possible to find the type to use
2695 * for expansion.
2696 *
2697 * other errors: result of der decoding process.
2698 **/
2699asn1_retCode
2700asn1_expand_octet_string (ASN1_TYPE definitions, ASN1_TYPE * element,
2701 const char *octetName, const char *objectName)
2702{
2703 char name[2 * MAX_NAME_SIZE + 1], value[MAX_NAME_SIZE];
2704 asn1_retCode retCode = ASN1_SUCCESS, result;
2705 int len, len2, len3;
2706 ASN1_TYPE p2, aux = ASN1_TYPE_EMPTY;
2707 ASN1_TYPE octetNode = ASN1_TYPE_EMPTY, objectNode = ASN1_TYPE_EMPTY;
2708 char errorDescription[MAX_ERROR_DESCRIPTION_SIZE];
2709
2710 if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY))
2711 return ASN1_ELEMENT_NOT_FOUND;
2712
2713 octetNode = asn1_find_node (*element, octetName);
2714 if (octetNode == ASN1_TYPE_EMPTY)
2715 return ASN1_ELEMENT_NOT_FOUND;
2716 if (type_field (octetNode->type) != TYPE_OCTET_STRING)
2717 return ASN1_ELEMENT_NOT_FOUND;
2718 if (octetNode->value == NULL)
2719 return ASN1_VALUE_NOT_FOUND;
2720
2721 objectNode = asn1_find_node (*element, objectName);
2722 if (objectNode == ASN1_TYPE_EMPTY)
2723 return ASN1_ELEMENT_NOT_FOUND;
2724
2725 if (type_field (objectNode->type) != TYPE_OBJECT_ID)
2726 return ASN1_ELEMENT_NOT_FOUND;
2727
2728 if (objectNode->value == NULL)
2729 return ASN1_VALUE_NOT_FOUND;
2730
2731
2732 /* search the OBJECT_ID into definitions */
2733 p2 = definitions->down;
2734 while (p2)
2735 {
2736 if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
2737 (p2->type & CONST_ASSIGN))
2738 {
2739 strcpy (name, definitions->name);
2740 strcat (name, ".");
2741 strcat (name, p2->name);
2742
2743 len = sizeof (value);
2744 result = asn1_read_value (definitions, name, value, &len);
2745
2746 if ((result == ASN1_SUCCESS)
2747 && (!strcmp (objectNode->value, value)))
2748 {
2749
2750 p2 = p2->right; /* pointer to the structure to
2751 use for expansion */
2752 while ((p2) && (p2->type & CONST_ASSIGN))
2753 p2 = p2->right;
2754
2755 if (p2)
2756 {
2757 strcpy (name, definitions->name);
2758 strcat (name, ".");
2759 strcat (name, p2->name);
2760
2761 result = asn1_create_element (definitions, name, &aux);
2762 if (result == ASN1_SUCCESS)
2763 {
2764 _asn1_set_name (aux, octetNode->name);
2765 len2 =
2766 asn1_get_length_der (octetNode->value,
2767 octetNode->value_len, &len3);
2768 if (len2 < 0)
2769 return ASN1_DER_ERROR;
2770
2771 result =
2772 asn1_der_decoding (&aux, octetNode->value + len3,
2773 len2, errorDescription);
2774 if (result == ASN1_SUCCESS)
2775 {
2776
2777 _asn1_set_right (aux, octetNode->right);
2778 _asn1_set_right (octetNode, aux);
2779
2780 result = asn1_delete_structure (&octetNode);
2781 if (result == ASN1_SUCCESS)
2782 {
2783 aux = ASN1_TYPE_EMPTY;
2784 break;
2785 }
2786 else
2787 { /* error with asn1_delete_structure */
2788 asn1_delete_structure (&aux);
2789 retCode = result;
2790 break;
2791 }
2792 }
2793 else
2794 { /* error with asn1_der_decoding */
2795 retCode = result;
2796 break;
2797 }
2798 }
2799 else
2800 { /* error with asn1_create_element */
2801 retCode = result;
2802 break;
2803 }
2804 }
2805 else
2806 { /* error with the pointer to the structure to exapand */
2807 retCode = ASN1_VALUE_NOT_VALID;
2808 break;
2809 }
2810 }
2811 }
2812
2813 p2 = p2->right;
2814
2815 }
2816
2817 if (!p2)
2818 retCode = ASN1_VALUE_NOT_VALID;
2819
2820 return retCode;
2821}
diff --git a/src/daemon/https/minitasn1/element.c b/src/daemon/https/minitasn1/element.c
new file mode 100644
index 00000000..25b4975a
--- /dev/null
+++ b/src/daemon/https/minitasn1/element.c
@@ -0,0 +1,1013 @@
1/*
2 * Copyright (C) 2004, 2006 Free Software Foundation
3 * Copyright (C) 2000, 2001, 2002, 2003 Fabio Fiorina
4 *
5 * This file is part of LIBTASN1.
6 *
7 * The LIBTASN1 library is free software; you can redistribute it
8 * and/or modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 */
22
23/*****************************************************/
24/* File: element.c */
25/* Description: Functions with the read and write */
26/* functions. */
27/*****************************************************/
28
29
30#include <int.h>
31#include <errors.h>
32#include "parser_aux.h"
33#include <gstr.h>
34#include "structure.h"
35
36void
37_asn1_hierarchical_name (node_asn * node, char *name, int name_size)
38{
39 node_asn *p;
40 char tmp_name[64];
41
42 p = node;
43
44 name[0] = 0;
45
46 while (p != NULL)
47 {
48 if (p->name != NULL)
49 {
50 _asn1_str_cpy (tmp_name, sizeof (tmp_name), name),
51 _asn1_str_cpy (name, name_size, p->name);
52 _asn1_str_cat (name, name_size, ".");
53 _asn1_str_cat (name, name_size, tmp_name);
54 }
55 p = _asn1_find_up (p);
56 }
57
58 if (name[0] == 0)
59 _asn1_str_cpy (name, name_size, "ROOT");
60}
61
62
63/******************************************************************/
64/* Function : _asn1_convert_integer */
65/* Description: converts an integer from a null terminated string */
66/* to der decoding. The convertion from a null */
67/* terminated string to an integer is made with */
68/* the 'strtol' function. */
69/* Parameters: */
70/* value: null terminated string to convert. */
71/* value_out: convertion result (memory must be already */
72/* allocated). */
73/* value_out_size: number of bytes of value_out. */
74/* len: number of significant byte of value_out. */
75/* Return: ASN1_MEM_ERROR or ASN1_SUCCESS */
76/******************************************************************/
77asn1_retCode
78_asn1_convert_integer (const char *value, unsigned char *value_out,
79 int value_out_size, int *len)
80{
81 char negative;
82 unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
83 long valtmp;
84 int k, k2;
85
86 valtmp = strtol (value, NULL, 10);
87
88 for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
89 {
90 val[SIZEOF_UNSIGNED_LONG_INT - k - 1] = (valtmp >> (8 * k)) & 0xFF;
91 }
92
93 if (val[0] & 0x80)
94 negative = 1;
95 else
96 negative = 0;
97
98 for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT - 1; k++)
99 {
100 if (negative && (val[k] != 0xFF))
101 break;
102 else if (!negative && val[k])
103 break;
104 }
105
106 if ((negative && !(val[k] & 0x80)) || (!negative && (val[k] & 0x80)))
107 k--;
108
109 *len = SIZEOF_UNSIGNED_LONG_INT - k;
110
111 if (SIZEOF_UNSIGNED_LONG_INT - k > value_out_size)
112 /* VALUE_OUT is too short to contain the value conversion */
113 return ASN1_MEM_ERROR;
114
115 for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++)
116 value_out[k2 - k] = val[k2];
117
118
119#ifdef LIBTASN1_DEBUG_INTEGER
120 _libtasn1_log ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len);
121 for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
122 _libtasn1_log (", vOut[%d]=%d", k, value_out[k]);
123 _libtasn1_log ("\n");
124#endif
125
126
127 return ASN1_SUCCESS;
128}
129
130
131int
132_asn1_append_sequence_set (node_asn * node)
133{
134 node_asn *p, *p2;
135 char temp[10];
136 long n;
137
138 if (!node || !(node->down))
139 return ASN1_GENERIC_ERROR;
140
141 p = node->down;
142 while ((type_field (p->type) == TYPE_TAG)
143 || (type_field (p->type) == TYPE_SIZE))
144 p = p->right;
145 p2 = _asn1_copy_structure3 (p);
146 while (p->right)
147 p = p->right;
148 _asn1_set_right (p, p2);
149
150 if (p->name == NULL)
151 _asn1_str_cpy (temp, sizeof (temp), "?1");
152 else
153 {
154 n = strtol (p->name + 1, NULL, 0);
155 n++;
156 temp[0] = '?';
157 _asn1_ltostr (n, temp + 1);
158 }
159 _asn1_set_name (p2, temp);
160 /* p2->type |= CONST_OPTION; */
161
162 return ASN1_SUCCESS;
163}
164
165
166/**
167 * asn1_write_value - Set the value of one element inside a structure.
168 * @node_root: pointer to a structure
169 * @name: the name of the element inside the structure that you want to set.
170 * @ivalue: vector used to specify the value to set. If len is >0,
171 * VALUE must be a two's complement form integer. if len=0 *VALUE
172 * must be a null terminated string with an integer value.
173 * @len: number of bytes of *value to use to set the value:
174 * value[0]..value[len-1] or 0 if value is a null terminated string
175 *
176 * Set the value of one element inside a structure.
177 *
178 * If an element is OPTIONAL and you want to delete it, you must use
179 * the value=NULL and len=0. Using "pkix.asn":
180 *
181 * result=asn1_write_value(cert, "tbsCertificate.issuerUniqueID",
182 * NULL, 0);
183 *
184 * Description for each type:
185 *
186 * INTEGER: VALUE must contain a two's complement form integer.
187 *
188 * value[0]=0xFF , len=1 -> integer=-1.
189 * value[0]=0xFF value[1]=0xFF , len=2 -> integer=-1.
190 * value[0]=0x01 , len=1 -> integer= 1.
191 * value[0]=0x00 value[1]=0x01 , len=2 -> integer= 1.
192 * value="123" , len=0 -> integer= 123.
193 *
194 * ENUMERATED: As INTEGER (but only with not negative numbers).
195 *
196 * BOOLEAN: VALUE must be the null terminated string "TRUE" or
197 * "FALSE" and LEN != 0.
198 *
199 * value="TRUE" , len=1 -> boolean=TRUE.
200 * value="FALSE" , len=1 -> boolean=FALSE.
201 *
202 * OBJECT IDENTIFIER: VALUE must be a null terminated string with
203 * each number separated by a dot (e.g. "1.2.3.543.1"). LEN != 0.
204 *
205 * value="1 2 840 10040 4 3" , len=1 -> OID=dsa-with-sha.
206 *
207 * UTCTime: VALUE must be a null terminated string in one of these
208 * formats: "YYMMDDhhmmssZ", "YYMMDDhhmmssZ",
209 * "YYMMDDhhmmss+hh'mm'", "YYMMDDhhmmss-hh'mm'",
210 * "YYMMDDhhmm+hh'mm'", or "YYMMDDhhmm-hh'mm'". LEN != 0.
211 *
212 * value="9801011200Z" , len=1 -> time=Jannuary 1st, 1998
213 * at 12h 00m Greenwich Mean Time
214 *
215 * GeneralizedTime: VALUE must be in one of this format:
216 * "YYYYMMDDhhmmss.sZ", "YYYYMMDDhhmmss.sZ",
217 * "YYYYMMDDhhmmss.s+hh'mm'", "YYYYMMDDhhmmss.s-hh'mm'",
218 * "YYYYMMDDhhmm+hh'mm'", or "YYYYMMDDhhmm-hh'mm'" where ss.s
219 * indicates the seconds with any precision like "10.1" or "01.02".
220 * LEN != 0
221 *
222 * value="2001010112001.12-0700" , len=1 -> time=Jannuary
223 * 1st, 2001 at 12h 00m 01.12s Pacific Daylight Time
224 *
225 * OCTET STRING: VALUE contains the octet string and LEN is the
226 * number of octets.
227 *
228 * value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
229 * len=3 -> three bytes octet string
230 *
231 * GeneralString: VALUE contains the generalstring and LEN is the
232 * number of octets.
233 *
234 * value="$\backslash$x01$\backslash$x02$\backslash$x03" ,
235 * len=3 -> three bytes generalstring
236 *
237 * BIT STRING: VALUE contains the bit string organized by bytes and
238 * LEN is the number of bits.
239 *
240 * value="$\backslash$xCF" , len=6 -> bit string="110011" (six
241 * bits)
242 *
243 * CHOICE: if NAME indicates a choice type, VALUE must specify one of
244 * the alternatives with a null terminated string. LEN != 0. Using
245 * "pkix.asn"\:
246 *
247 * result=asn1_write_value(cert,
248 * "certificate1.tbsCertificate.subject", "rdnSequence",
249 * 1);
250 *
251 * ANY: VALUE indicates the der encoding of a structure. LEN != 0.
252 *
253 * SEQUENCE OF: VALUE must be the null terminated string "NEW" and
254 * LEN != 0. With this instruction another element is appended in
255 * the sequence. The name of this element will be "?1" if it's the
256 * first one, "?2" for the second and so on.
257 *
258 * Using "pkix.asn"\:
259 *
260 * result=asn1_write_value(cert,
261 * "certificate1.tbsCertificate.subject.rdnSequence", "NEW", 1);
262 *
263 * SET OF: the same as SEQUENCE OF. Using "pkix.asn":
264 *
265 * result=asn1_write_value(cert,
266 * "tbsCertificate.subject.rdnSequence.?LAST", "NEW", 1);
267 *
268 * Returns:
269 *
270 * ASN1_SUCCESS: Set value OK.
271 *
272 * ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
273 *
274 * ASN1_VALUE_NOT_VALID: VALUE has a wrong format.
275 *
276 **/
277asn1_retCode
278asn1_write_value (ASN1_TYPE node_root, const char *name,
279 const void *ivalue, int len)
280{
281 node_asn *node, *p, *p2;
282 unsigned char *temp, *value_temp = NULL, *default_temp = NULL;
283 int len2, k, k2, negative;
284 const unsigned char *value = ivalue;
285
286 node = asn1_find_node (node_root, name);
287 if (node == NULL)
288 return ASN1_ELEMENT_NOT_FOUND;
289
290 if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0))
291 {
292 asn1_delete_structure (&node);
293 return ASN1_SUCCESS;
294 }
295
296 if ((type_field (node->type) == TYPE_SEQUENCE_OF) && (value == NULL)
297 && (len == 0))
298 {
299 p = node->down;
300 while ((type_field (p->type) == TYPE_TAG)
301 || (type_field (p->type) == TYPE_SIZE))
302 p = p->right;
303
304 while (p->right)
305 asn1_delete_structure (&p->right);
306
307 return ASN1_SUCCESS;
308 }
309
310 switch (type_field (node->type))
311 {
312 case TYPE_BOOLEAN:
313 if (!strcmp (value, "TRUE"))
314 {
315 if (node->type & CONST_DEFAULT)
316 {
317 p = node->down;
318 while (type_field (p->type) != TYPE_DEFAULT)
319 p = p->right;
320 if (p->type & CONST_TRUE)
321 _asn1_set_value (node, NULL, 0);
322 else
323 _asn1_set_value (node, "T", 1);
324 }
325 else
326 _asn1_set_value (node, "T", 1);
327 }
328 else if (!strcmp (value, "FALSE"))
329 {
330 if (node->type & CONST_DEFAULT)
331 {
332 p = node->down;
333 while (type_field (p->type) != TYPE_DEFAULT)
334 p = p->right;
335 if (p->type & CONST_FALSE)
336 _asn1_set_value (node, NULL, 0);
337 else
338 _asn1_set_value (node, "F", 1);
339 }
340 else
341 _asn1_set_value (node, "F", 1);
342 }
343 else
344 return ASN1_VALUE_NOT_VALID;
345 break;
346 case TYPE_INTEGER:
347 case TYPE_ENUMERATED:
348 if (len == 0)
349 {
350 if ((isdigit (value[0])) || (value[0] == '-'))
351 {
352 value_temp =
353 (unsigned char *) _asn1_alloca (SIZEOF_UNSIGNED_LONG_INT);
354 if (value_temp == NULL)
355 return ASN1_MEM_ALLOC_ERROR;
356
357 _asn1_convert_integer (value, value_temp,
358 SIZEOF_UNSIGNED_LONG_INT, &len);
359 }
360 else
361 { /* is an identifier like v1 */
362 if (!(node->type & CONST_LIST))
363 return ASN1_VALUE_NOT_VALID;
364 p = node->down;
365 while (p)
366 {
367 if (type_field (p->type) == TYPE_CONSTANT)
368 {
369 if ((p->name) && (!strcmp (p->name, value)))
370 {
371 value_temp =
372 (unsigned char *)
373 _asn1_alloca (SIZEOF_UNSIGNED_LONG_INT);
374 if (value_temp == NULL)
375 return ASN1_MEM_ALLOC_ERROR;
376
377 _asn1_convert_integer (p->value,
378 value_temp,
379 SIZEOF_UNSIGNED_LONG_INT,
380 &len);
381 break;
382 }
383 }
384 p = p->right;
385 }
386 if (p == NULL)
387 return ASN1_VALUE_NOT_VALID;
388 }
389 }
390 else
391 { /* len != 0 */
392 value_temp = (unsigned char *) _asn1_alloca (len);
393 if (value_temp == NULL)
394 return ASN1_MEM_ALLOC_ERROR;
395 memcpy (value_temp, value, len);
396 }
397
398
399 if (value_temp[0] & 0x80)
400 negative = 1;
401 else
402 negative = 0;
403
404 if (negative && (type_field (node->type) == TYPE_ENUMERATED))
405 {
406 _asn1_afree (value_temp);
407 return ASN1_VALUE_NOT_VALID;
408 }
409
410 for (k = 0; k < len - 1; k++)
411 if (negative && (value_temp[k] != 0xFF))
412 break;
413 else if (!negative && value_temp[k])
414 break;
415
416 if ((negative && !(value_temp[k] & 0x80)) ||
417 (!negative && (value_temp[k] & 0x80)))
418 k--;
419
420 asn1_length_der (len - k, NULL, &len2);
421 temp = (unsigned char *) _asn1_alloca (len - k + len2);
422 if (temp == NULL)
423 return ASN1_MEM_ALLOC_ERROR;
424
425 asn1_octet_der (value_temp + k, len - k, temp, &len2);
426 _asn1_set_value (node, temp, len2);
427
428 _asn1_afree (temp);
429
430
431 if (node->type & CONST_DEFAULT)
432 {
433 p = node->down;
434 while (type_field (p->type) != TYPE_DEFAULT)
435 p = p->right;
436 if ((isdigit (p->value[0])) || (p->value[0] == '-'))
437 {
438 default_temp =
439 (unsigned char *) _asn1_alloca (SIZEOF_UNSIGNED_LONG_INT);
440 if (default_temp == NULL)
441 return ASN1_MEM_ALLOC_ERROR;
442
443 _asn1_convert_integer (p->value, default_temp,
444 SIZEOF_UNSIGNED_LONG_INT, &len2);
445 }
446 else
447 { /* is an identifier like v1 */
448 if (!(node->type & CONST_LIST))
449 return ASN1_VALUE_NOT_VALID;
450 p2 = node->down;
451 while (p2)
452 {
453 if (type_field (p2->type) == TYPE_CONSTANT)
454 {
455 if ((p2->name) && (!strcmp (p2->name, p->value)))
456 {
457 default_temp =
458 (unsigned char *)
459 _asn1_alloca (SIZEOF_UNSIGNED_LONG_INT);
460 if (default_temp == NULL)
461 return ASN1_MEM_ALLOC_ERROR;
462
463 _asn1_convert_integer (p2->value,
464 default_temp,
465 SIZEOF_UNSIGNED_LONG_INT,
466 &len2);
467 break;
468 }
469 }
470 p2 = p2->right;
471 }
472 if (p2 == NULL)
473 return ASN1_VALUE_NOT_VALID;
474 }
475
476
477 if ((len - k) == len2)
478 {
479 for (k2 = 0; k2 < len2; k2++)
480 if (value_temp[k + k2] != default_temp[k2])
481 {
482 break;
483 }
484 if (k2 == len2)
485 _asn1_set_value (node, NULL, 0);
486 }
487 _asn1_afree (default_temp);
488 }
489 _asn1_afree (value_temp);
490 break;
491 case TYPE_OBJECT_ID:
492 for (k = 0; k < strlen (value); k++)
493 if ((!isdigit (value[k])) && (value[k] != '.') && (value[k] != '+'))
494 return ASN1_VALUE_NOT_VALID;
495 if (node->type & CONST_DEFAULT)
496 {
497 p = node->down;
498 while (type_field (p->type) != TYPE_DEFAULT)
499 p = p->right;
500 if (!strcmp (value, p->value))
501 {
502 _asn1_set_value (node, NULL, 0);
503 break;
504 }
505 }
506 _asn1_set_value (node, value, strlen (value) + 1);
507 break;
508 case TYPE_TIME:
509 if (node->type & CONST_UTC)
510 {
511 if (strlen (value) < 11)
512 return ASN1_VALUE_NOT_VALID;
513 for (k = 0; k < 10; k++)
514 if (!isdigit (value[k]))
515 return ASN1_VALUE_NOT_VALID;
516 switch (strlen (value))
517 {
518 case 11:
519 if (value[10] != 'Z')
520 return ASN1_VALUE_NOT_VALID;
521 break;
522 case 13:
523 if ((!isdigit (value[10])) || (!isdigit (value[11])) ||
524 (value[12] != 'Z'))
525 return ASN1_VALUE_NOT_VALID;
526 break;
527 case 15:
528 if ((value[10] != '+') && (value[10] != '-'))
529 return ASN1_VALUE_NOT_VALID;
530 for (k = 11; k < 15; k++)
531 if (!isdigit (value[k]))
532 return ASN1_VALUE_NOT_VALID;
533 break;
534 case 17:
535 if ((!isdigit (value[10])) || (!isdigit (value[11])))
536 return ASN1_VALUE_NOT_VALID;
537 if ((value[12] != '+') && (value[12] != '-'))
538 return ASN1_VALUE_NOT_VALID;
539 for (k = 13; k < 17; k++)
540 if (!isdigit (value[k]))
541 return ASN1_VALUE_NOT_VALID;
542 break;
543 default:
544 return ASN1_VALUE_NOT_FOUND;
545 }
546 _asn1_set_value (node, value, strlen (value) + 1);
547 }
548 else
549 { /* GENERALIZED TIME */
550 if (value)
551 _asn1_set_value (node, value, strlen (value) + 1);
552 }
553 break;
554 case TYPE_OCTET_STRING:
555 if (len == 0)
556 len = strlen (value);
557 asn1_length_der (len, NULL, &len2);
558 temp = (unsigned char *) _asn1_alloca (len + len2);
559 if (temp == NULL)
560 return ASN1_MEM_ALLOC_ERROR;
561
562 asn1_octet_der (value, len, temp, &len2);
563 _asn1_set_value (node, temp, len2);
564 _asn1_afree (temp);
565 break;
566 case TYPE_GENERALSTRING:
567 if (len == 0)
568 len = strlen (value);
569 asn1_length_der (len, NULL, &len2);
570 temp = (unsigned char *) _asn1_alloca (len + len2);
571 if (temp == NULL)
572 return ASN1_MEM_ALLOC_ERROR;
573
574 asn1_octet_der (value, len, temp, &len2);
575 _asn1_set_value (node, temp, len2);
576 _asn1_afree (temp);
577 break;
578 case TYPE_BIT_STRING:
579 if (len == 0)
580 len = strlen (value);
581 asn1_length_der ((len >> 3) + 2, NULL, &len2);
582 temp = (unsigned char *) _asn1_alloca ((len >> 3) + 2 + len2);
583 if (temp == NULL)
584 return ASN1_MEM_ALLOC_ERROR;
585
586 asn1_bit_der (value, len, temp, &len2);
587 _asn1_set_value (node, temp, len2);
588 _asn1_afree (temp);
589 break;
590 case TYPE_CHOICE:
591 p = node->down;
592 while (p)
593 {
594 if (!strcmp (p->name, value))
595 {
596 p2 = node->down;
597 while (p2)
598 {
599 if (p2 != p)
600 {
601 asn1_delete_structure (&p2);
602 p2 = node->down;
603 }
604 else
605 p2 = p2->right;
606 }
607 break;
608 }
609 p = p->right;
610 }
611 if (!p)
612 return ASN1_ELEMENT_NOT_FOUND;
613 break;
614 case TYPE_ANY:
615 asn1_length_der (len, NULL, &len2);
616 temp = (unsigned char *) _asn1_alloca (len + len2);
617 if (temp == NULL)
618 return ASN1_MEM_ALLOC_ERROR;
619
620 asn1_octet_der (value, len, temp, &len2);
621 _asn1_set_value (node, temp, len2);
622 _asn1_afree (temp);
623 break;
624 case TYPE_SEQUENCE_OF:
625 case TYPE_SET_OF:
626 if (strcmp (value, "NEW"))
627 return ASN1_VALUE_NOT_VALID;
628 _asn1_append_sequence_set (node);
629 break;
630 default:
631 return ASN1_ELEMENT_NOT_FOUND;
632 break;
633 }
634
635 return ASN1_SUCCESS;
636}
637
638
639#define PUT_VALUE( ptr, ptr_size, data, data_size) \
640 *len = data_size; \
641 if (ptr_size < data_size) { \
642 return ASN1_MEM_ERROR; \
643 } else { \
644 memcpy( ptr, data, data_size); \
645 }
646
647#define PUT_STR_VALUE( ptr, ptr_size, data) \
648 *len = strlen(data) + 1; \
649 if (ptr_size < *len) { \
650 return ASN1_MEM_ERROR; \
651 } else { \
652 /* this strcpy is checked */ \
653 strcpy(ptr, data); \
654 }
655
656#define ADD_STR_VALUE( ptr, ptr_size, data) \
657 *len = strlen(data) + 1; \
658 if (ptr_size < strlen(ptr)+(*len)) { \
659 return ASN1_MEM_ERROR; \
660 } else { \
661 /* this strcat is checked */ \
662 strcat(ptr, data); \
663 }
664
665/**
666 * asn1_read_value - Returns the value of one element inside a structure
667 * @root: pointer to a structure.
668 * @name: the name of the element inside a structure that you want to read.
669 * @ivalue: vector that will contain the element's content, must be a
670 * pointer to memory cells already allocated.
671 * @len: number of bytes of *value: value[0]..value[len-1]. Initialy
672 * holds the sizeof value.
673 *
674 * Returns the value of one element inside a structure.
675 *
676 * If an element is OPTIONAL and the function "read_value" returns
677 * %ASN1_ELEMENT_NOT_FOUND, it means that this element wasn't present
678 * in the der encoding that created the structure. The first element
679 * of a SEQUENCE_OF or SET_OF is named "?1". The second one "?2" and
680 * so on.
681 *
682 * INTEGER: VALUE will contain a two's complement form integer.
683 *
684 * integer=-1 -> value[0]=0xFF , len=1.
685 * integer=1 -> value[0]=0x01 , len=1.
686 *
687 * ENUMERATED: As INTEGER (but only with not negative numbers).
688 *
689 * BOOLEAN: VALUE will be the null terminated string "TRUE" or
690 * "FALSE" and LEN=5 or LEN=6.
691 *
692 * OBJECT IDENTIFIER: VALUE will be a null terminated string with
693 * each number separated by a dot (i.e. "1.2.3.543.1").
694 *
695 * LEN = strlen(VALUE)+1
696 *
697 * UTCTime: VALUE will be a null terminated string in one of these
698 * formats: "YYMMDDhhmmss+hh'mm'" or "YYMMDDhhmmss-hh'mm'".
699 * LEN=strlen(VALUE)+1.
700 *
701 * GeneralizedTime: VALUE will be a null terminated string in the
702 * same format used to set the value.
703 *
704 * OCTET STRING: VALUE will contain the octet string and LEN will be
705 * the number of octets.
706 *
707 * GeneralString: VALUE will contain the generalstring and LEN will
708 * be the number of octets.
709 *
710 * BIT STRING: VALUE will contain the bit string organized by bytes
711 * and LEN will be the number of bits.
712 *
713 * CHOICE: If NAME indicates a choice type, VALUE will specify the
714 * alternative selected.
715 *
716 * ANY: If NAME indicates an any type, VALUE will indicate the DER
717 * encoding of the structure actually used.
718 *
719 * Returns:
720 *
721 * ASN1_SUCCESS: Set value OK.
722 *
723 * ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
724 *
725 * ASN1_VALUE_NOT_FOUND: There isn't any value for the element selected.
726 *
727 * ASN1_MEM_ERROR: The value vector isn't big enough to store the result.
728 * In this case LEN will contain the number of bytes needed.
729 *
730 **/
731asn1_retCode
732asn1_read_value (ASN1_TYPE root, const char *name, void *ivalue, int *len)
733{
734 node_asn *node, *p, *p2;
735 int len2, len3;
736 int value_size = *len;
737 unsigned char *value = ivalue;
738
739 node = asn1_find_node (root, name);
740 if (node == NULL)
741 return ASN1_ELEMENT_NOT_FOUND;
742
743 if ((type_field (node->type) != TYPE_NULL) &&
744 (type_field (node->type) != TYPE_CHOICE) &&
745 !(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN) &&
746 (node->value == NULL))
747 return ASN1_VALUE_NOT_FOUND;
748
749 switch (type_field (node->type))
750 {
751 case TYPE_NULL:
752 PUT_STR_VALUE (value, value_size, "NULL");
753 break;
754 case TYPE_BOOLEAN:
755 if ((node->type & CONST_DEFAULT) && (node->value == NULL))
756 {
757 p = node->down;
758 while (type_field (p->type) != TYPE_DEFAULT)
759 p = p->right;
760 if (p->type & CONST_TRUE)
761 {
762 PUT_STR_VALUE (value, value_size, "TRUE");
763 }
764 else
765 {
766 PUT_STR_VALUE (value, value_size, "FALSE");
767 }
768 }
769 else if (node->value[0] == 'T')
770 {
771 PUT_STR_VALUE (value, value_size, "TRUE");
772 }
773 else
774 {
775 PUT_STR_VALUE (value, value_size, "FALSE");
776 }
777 break;
778 case TYPE_INTEGER:
779 case TYPE_ENUMERATED:
780 if ((node->type & CONST_DEFAULT) && (node->value == NULL))
781 {
782 p = node->down;
783 while (type_field (p->type) != TYPE_DEFAULT)
784 p = p->right;
785 if ((isdigit (p->value[0])) || (p->value[0] == '-')
786 || (p->value[0] == '+'))
787 {
788 if (_asn1_convert_integer
789 (p->value, value, value_size, len) != ASN1_SUCCESS)
790 return ASN1_MEM_ERROR;
791 }
792 else
793 { /* is an identifier like v1 */
794 p2 = node->down;
795 while (p2)
796 {
797 if (type_field (p2->type) == TYPE_CONSTANT)
798 {
799 if ((p2->name) && (!strcmp (p2->name, p->value)))
800 {
801 if (_asn1_convert_integer
802 (p2->value, value, value_size,
803 len) != ASN1_SUCCESS)
804 return ASN1_MEM_ERROR;
805 break;
806 }
807 }
808 p2 = p2->right;
809 }
810 }
811 }
812 else
813 {
814 len2 = -1;
815 if (asn1_get_octet_der
816 (node->value, node->value_len, &len2, value, value_size,
817 len) != ASN1_SUCCESS)
818 return ASN1_MEM_ERROR;
819 }
820 break;
821 case TYPE_OBJECT_ID:
822 if (node->type & CONST_ASSIGN)
823 {
824 value[0] = 0;
825 p = node->down;
826 while (p)
827 {
828 if (type_field (p->type) == TYPE_CONSTANT)
829 {
830 ADD_STR_VALUE (value, value_size, p->value);
831 if (p->right)
832 {
833 ADD_STR_VALUE (value, value_size, ".");
834 }
835 }
836 p = p->right;
837 }
838 *len = strlen (value) + 1;
839 }
840 else if ((node->type & CONST_DEFAULT) && (node->value == NULL))
841 {
842 p = node->down;
843 while (type_field (p->type) != TYPE_DEFAULT)
844 p = p->right;
845 PUT_STR_VALUE (value, value_size, p->value);
846 }
847 else
848 {
849 PUT_STR_VALUE (value, value_size, node->value);
850 }
851 break;
852 case TYPE_TIME:
853 PUT_STR_VALUE (value, value_size, node->value);
854 break;
855 case TYPE_OCTET_STRING:
856 len2 = -1;
857 if (asn1_get_octet_der
858 (node->value, node->value_len, &len2, value, value_size,
859 len) != ASN1_SUCCESS)
860 return ASN1_MEM_ERROR;
861 break;
862 case TYPE_GENERALSTRING:
863 len2 = -1;
864 if (asn1_get_octet_der
865 (node->value, node->value_len, &len2, value, value_size,
866 len) != ASN1_SUCCESS)
867 return ASN1_MEM_ERROR;
868 break;
869 case TYPE_BIT_STRING:
870 len2 = -1;
871 if (asn1_get_bit_der
872 (node->value, node->value_len, &len2, value, value_size,
873 len) != ASN1_SUCCESS)
874 return ASN1_MEM_ERROR;
875 break;
876 case TYPE_CHOICE:
877 PUT_STR_VALUE (value, value_size, node->down->name);
878 break;
879 case TYPE_ANY:
880 len3 = -1;
881 len2 = asn1_get_length_der (node->value, node->value_len, &len3);
882 if (len2 < 0)
883 return ASN1_DER_ERROR;
884 PUT_VALUE (value, value_size, node->value + len3, len2);
885 break;
886 default:
887 return ASN1_ELEMENT_NOT_FOUND;
888 break;
889 }
890 return ASN1_SUCCESS;
891}
892
893
894/**
895 * asn1_read_tag - Returns the TAG of one element inside a structure
896 * @root: pointer to a structure
897 * @name: the name of the element inside a structure.
898 * @tagValue: variable that will contain the TAG value.
899 * @classValue: variable that will specify the TAG type.
900 *
901 * Returns the TAG and the CLASS of one element inside a structure.
902 * CLASS can have one of these constants: %ASN1_CLASS_APPLICATION,
903 * %ASN1_CLASS_UNIVERSAL, %ASN1_CLASS_PRIVATE or
904 * %ASN1_CLASS_CONTEXT_SPECIFIC.
905 *
906 * Returns:
907 *
908 * ASN1_SUCCESS: Set value OK.
909 *
910 * ASN1_ELEMENT_NOT_FOUND: NAME is not a valid element.
911 *
912 **/
913asn1_retCode
914asn1_read_tag (node_asn * root, const char *name, int *tagValue,
915 int *classValue)
916{
917 node_asn *node, *p, *pTag;
918
919 node = asn1_find_node (root, name);
920 if (node == NULL)
921 return ASN1_ELEMENT_NOT_FOUND;
922
923 p = node->down;
924
925 /* pTag will points to the IMPLICIT TAG */
926 pTag = NULL;
927 if (node->type & CONST_TAG)
928 {
929 while (p)
930 {
931 if (type_field (p->type) == TYPE_TAG)
932 {
933 if ((p->type & CONST_IMPLICIT) && (pTag == NULL))
934 pTag = p;
935 else if (p->type & CONST_EXPLICIT)
936 pTag = NULL;
937 }
938 p = p->right;
939 }
940 }
941
942 if (pTag)
943 {
944 *tagValue = strtoul (pTag->value, NULL, 10);
945
946 if (pTag->type & CONST_APPLICATION)
947 *classValue = ASN1_CLASS_APPLICATION;
948 else if (pTag->type & CONST_UNIVERSAL)
949 *classValue = ASN1_CLASS_UNIVERSAL;
950 else if (pTag->type & CONST_PRIVATE)
951 *classValue = ASN1_CLASS_PRIVATE;
952 else
953 *classValue = ASN1_CLASS_CONTEXT_SPECIFIC;
954 }
955 else
956 {
957 *classValue = ASN1_CLASS_UNIVERSAL;
958
959 switch (type_field (node->type))
960 {
961 case TYPE_NULL:
962 *tagValue = ASN1_TAG_NULL;
963 break;
964 case TYPE_BOOLEAN:
965 *tagValue = ASN1_TAG_BOOLEAN;
966 break;
967 case TYPE_INTEGER:
968 *tagValue = ASN1_TAG_INTEGER;
969 break;
970 case TYPE_ENUMERATED:
971 *tagValue = ASN1_TAG_ENUMERATED;
972 break;
973 case TYPE_OBJECT_ID:
974 *tagValue = ASN1_TAG_OBJECT_ID;
975 break;
976 case TYPE_TIME:
977 if (node->type & CONST_UTC)
978 {
979 *tagValue = ASN1_TAG_UTCTime;
980 }
981 else
982 *tagValue = ASN1_TAG_GENERALIZEDTime;
983 break;
984 case TYPE_OCTET_STRING:
985 *tagValue = ASN1_TAG_OCTET_STRING;
986 break;
987 case TYPE_GENERALSTRING:
988 *tagValue = ASN1_TAG_GENERALSTRING;
989 break;
990 case TYPE_BIT_STRING:
991 *tagValue = ASN1_TAG_BIT_STRING;
992 break;
993 case TYPE_SEQUENCE:
994 case TYPE_SEQUENCE_OF:
995 *tagValue = ASN1_TAG_SEQUENCE;
996 break;
997 case TYPE_SET:
998 case TYPE_SET_OF:
999 *tagValue = ASN1_TAG_SET;
1000 break;
1001 case TYPE_TAG:
1002 case TYPE_CHOICE:
1003 case TYPE_ANY:
1004 break;
1005 default:
1006 break;
1007 }
1008 }
1009
1010
1011 return ASN1_SUCCESS;
1012
1013}
diff --git a/src/daemon/https/minitasn1/element.h b/src/daemon/https/minitasn1/element.h
new file mode 100644
index 00000000..3db95295
--- /dev/null
+++ b/src/daemon/https/minitasn1/element.h
@@ -0,0 +1,13 @@
1
2#ifndef _ELEMENT_H
3#define _ELEMENT_H
4
5
6asn1_retCode _asn1_append_sequence_set(node_asn *node);
7
8asn1_retCode _asn1_convert_integer(const char *value,unsigned char *value_out,
9 int value_out_size, int *len);
10
11void _asn1_hierarchical_name(node_asn *node,char *name,int name_size);
12
13#endif
diff --git a/src/daemon/https/minitasn1/errors.c b/src/daemon/https/minitasn1/errors.c
new file mode 100644
index 00000000..544b3f01
--- /dev/null
+++ b/src/daemon/https/minitasn1/errors.c
@@ -0,0 +1,135 @@
1/*
2 * Copyright (C) 2006 Free Software Foundation, Inc.
3 * Copyright (C) 2002, 2005 Fabio Fiorina
4 *
5 * This file is part of LIBTASN1.
6 *
7 * The LIBTASN1 library is free software; you can redistribute it
8 * and/or modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 */
22
23#include <int.h>
24#include "errors.h"
25#ifdef STDC_HEADERS
26# include <stdarg.h>
27#endif
28
29
30#define LIBTASN1_ERROR_ENTRY(name) \
31 { #name, name }
32
33struct libtasn1_error_entry
34{
35 const char *name;
36 int number;
37};
38typedef struct libtasn1_error_entry libtasn1_error_entry;
39
40static const libtasn1_error_entry error_algorithms[] = {
41 LIBTASN1_ERROR_ENTRY (ASN1_SUCCESS),
42 LIBTASN1_ERROR_ENTRY (ASN1_FILE_NOT_FOUND),
43 LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_FOUND),
44 LIBTASN1_ERROR_ENTRY (ASN1_IDENTIFIER_NOT_FOUND),
45 LIBTASN1_ERROR_ENTRY (ASN1_DER_ERROR),
46 LIBTASN1_ERROR_ENTRY (ASN1_VALUE_NOT_FOUND),
47 LIBTASN1_ERROR_ENTRY (ASN1_GENERIC_ERROR),
48 LIBTASN1_ERROR_ENTRY (ASN1_VALUE_NOT_VALID),
49 LIBTASN1_ERROR_ENTRY (ASN1_TAG_ERROR),
50 LIBTASN1_ERROR_ENTRY (ASN1_TAG_IMPLICIT),
51 LIBTASN1_ERROR_ENTRY (ASN1_ERROR_TYPE_ANY),
52 LIBTASN1_ERROR_ENTRY (ASN1_SYNTAX_ERROR),
53 LIBTASN1_ERROR_ENTRY (ASN1_MEM_ERROR),
54 LIBTASN1_ERROR_ENTRY (ASN1_MEM_ALLOC_ERROR),
55 LIBTASN1_ERROR_ENTRY (ASN1_DER_OVERFLOW),
56 LIBTASN1_ERROR_ENTRY (ASN1_NAME_TOO_LONG),
57 LIBTASN1_ERROR_ENTRY (ASN1_ARRAY_ERROR),
58 LIBTASN1_ERROR_ENTRY (ASN1_ELEMENT_NOT_EMPTY),
59 {0}
60};
61
62#define LIBTASN1_ERROR_LOOP(b) \
63 const libtasn1_error_entry *p; \
64 for(p = error_algorithms; p->name != NULL; p++) { b ; }
65
66#define LIBTASN1_ERROR_ALG_LOOP(a) \
67 LIBTASN1_ERROR_LOOP( if(p->number == error) { a; break; } )
68
69
70
71/**
72 * libtasn1_perror - prints a string to stderr with a description of an error
73 * @error: is an error returned by a libtasn1 function.
74 *
75 * This function is like perror(). The only difference is that it
76 * accepts an error returned by a libtasn1 function.
77 **/
78void
79libtasn1_perror (asn1_retCode error)
80{
81 const char *ret = NULL;
82
83 /* avoid prefix */
84 LIBTASN1_ERROR_ALG_LOOP (ret = p->name + sizeof ("ASN1_") - 1);
85
86 fprintf (stderr, "LIBTASN1 ERROR: %s\n", ret);
87
88}
89
90
91/**
92 * libtasn1_strerror - Returns a string with a description of an error
93 * @error: is an error returned by a libtasn1 function.
94 *
95 * This function is similar to strerror(). The only difference is
96 * that it accepts an error (number) returned by a libtasn1 function.
97 *
98 * Returns: Pointer to static zero-terminated string describing error
99 * code.
100 **/
101const char *
102libtasn1_strerror (asn1_retCode error)
103{
104 const char *ret = NULL;
105
106 /* avoid prefix */
107 LIBTASN1_ERROR_ALG_LOOP (ret = p->name + sizeof ("ASN1_") - 1);
108
109 return ret;
110}
111
112/* this function will output a message.
113 */
114#ifdef LIBTASN1_DEBUG
115void
116_libtasn1_log (const char *fmt, ...)
117{
118 va_list args;
119 char str[MAX_LOG_SIZE];
120
121 va_start (args, fmt);
122 vsprintf (str, fmt, args); /* Flawfinder: ignore */
123 va_end (args);
124
125 fprintf (stderr, str);
126
127 return;
128}
129#else /* not DEBUG */
130void
131_libtasn1_log (const char *fmt, ...)
132{
133 return;
134}
135#endif /* DEBUG */
diff --git a/src/daemon/https/minitasn1/errors.h b/src/daemon/https/minitasn1/errors.h
new file mode 100644
index 00000000..f8bf2242
--- /dev/null
+++ b/src/daemon/https/minitasn1/errors.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright (C) 2004, 2006 Free Software Foundation, Inc.
3 * Copyright (C) 2002 Fabio Fiorina
4 *
5 * This file is part of LIBTASN1.
6 *
7 * The LIBTASN1 library is free software; you can redistribute it
8 * and/or modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 */
22
23#ifndef ERRORS_H
24#define ERRORS_H
25
26#include "int.h"
27
28void _libtasn1_log( const char *fmt, ...);
29
30#endif /* ERRORS_H */
diff --git a/src/daemon/https/minitasn1/gstr.c b/src/daemon/https/minitasn1/gstr.c
new file mode 100644
index 00000000..0430ee1a
--- /dev/null
+++ b/src/daemon/https/minitasn1/gstr.c
@@ -0,0 +1,68 @@
1/*
2 * Copyright (C) 2006 Free Software Foundation
3 * Copyright (C) 2002 Nikos Mavroyanopoulos
4 *
5 * This file is part of LIBTASN1.
6 *
7 * The LIBTASN1 library is free software; you can redistribute it
8 * and/or modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 */
22
23#include <int.h>
24
25/* These function are like strcat, strcpy. They only
26 * do bounds checking (they shouldn't cause buffer overruns),
27 * and they always produce null terminated strings.
28 *
29 * They should be used only with null terminated strings.
30 */
31void
32_asn1_str_cat (char *dest, size_t dest_tot_size, const char *src)
33{
34 size_t str_size = strlen (src);
35 size_t dest_size = strlen (dest);
36
37 if (dest_tot_size - dest_size > str_size)
38 {
39 strcat (dest, src);
40 }
41 else
42 {
43 if (dest_tot_size - dest_size > 0)
44 {
45 strncat (dest, src, (dest_tot_size - dest_size) - 1);
46 dest[dest_tot_size - 1] = 0;
47 }
48 }
49}
50
51void
52_asn1_str_cpy (char *dest, size_t dest_tot_size, const char *src)
53{
54 size_t str_size = strlen (src);
55
56 if (dest_tot_size > str_size)
57 {
58 strcpy (dest, src);
59 }
60 else
61 {
62 if (dest_tot_size > 0)
63 {
64 strncpy (dest, src, (dest_tot_size) - 1);
65 dest[dest_tot_size - 1] = 0;
66 }
67 }
68}
diff --git a/src/daemon/https/minitasn1/gstr.h b/src/daemon/https/minitasn1/gstr.h
new file mode 100644
index 00000000..5508d26e
--- /dev/null
+++ b/src/daemon/https/minitasn1/gstr.h
@@ -0,0 +1,5 @@
1void _asn1_str_cpy( char* dest, size_t dest_tot_size, const char* src);
2void _asn1_str_cat( char* dest, size_t dest_tot_size, const char* src);
3
4#define Estrcpy(x,y) _asn1_str_cpy(x,MAX_ERROR_DESCRIPTION_SIZE,y)
5#define Estrcat(x,y) _asn1_str_cat(x,MAX_ERROR_DESCRIPTION_SIZE,y)
diff --git a/src/daemon/https/minitasn1/int.h b/src/daemon/https/minitasn1/int.h
new file mode 100644
index 00000000..d9d18c77
--- /dev/null
+++ b/src/daemon/https/minitasn1/int.h
@@ -0,0 +1,112 @@
1/*
2 * Copyright (C) 2004, 2006 Free Software Foundation, Inc.
3 * Copyright (C) 2002 Fabio Fiorina
4 *
5 * This file is part of LIBTASN1.
6 *
7 * The LIBTASN1 library is free software; you can redistribute it
8 * and/or modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 */
22
23#ifndef INT_H
24#define INT_H
25
26#include <libtasn1.h>
27#include <defines.h>
28
29/*
30#define LIBTASN1_DEBUG
31#define LIBTASN1_DEBUG_PARSER
32#define LIBTASN1_DEBUG_INTEGER
33*/
34
35#include <mem.h>
36
37#define MAX_LOG_SIZE 1024 /* maximum number of characters of a log message */
38
39/* Define used for visiting trees. */
40#define UP 1
41#define RIGHT 2
42#define DOWN 3
43
44/****************************************/
45/* Returns the first 8 bits. */
46/* Used with the field type of node_asn */
47/****************************************/
48#define type_field(x) (x&0xFF)
49
50/* List of constants for field type of typedef node_asn */
51#define TYPE_CONSTANT 1
52#define TYPE_IDENTIFIER 2
53#define TYPE_INTEGER 3
54#define TYPE_BOOLEAN 4
55#define TYPE_SEQUENCE 5
56#define TYPE_BIT_STRING 6
57#define TYPE_OCTET_STRING 7
58#define TYPE_TAG 8
59#define TYPE_DEFAULT 9
60#define TYPE_SIZE 10
61#define TYPE_SEQUENCE_OF 11
62#define TYPE_OBJECT_ID 12
63#define TYPE_ANY 13
64#define TYPE_SET 14
65#define TYPE_SET_OF 15
66#define TYPE_DEFINITIONS 16
67#define TYPE_TIME 17
68#define TYPE_CHOICE 18
69#define TYPE_IMPORTS 19
70#define TYPE_NULL 20
71#define TYPE_ENUMERATED 21
72#define TYPE_GENERALSTRING 27
73
74
75/***********************************************************************/
76/* List of constants to better specify the type of typedef node_asn. */
77/***********************************************************************/
78/* Used with TYPE_TAG */
79#define CONST_UNIVERSAL (1<<8)
80#define CONST_PRIVATE (1<<9)
81#define CONST_APPLICATION (1<<10)
82#define CONST_EXPLICIT (1<<11)
83#define CONST_IMPLICIT (1<<12)
84
85#define CONST_TAG (1<<13) /* Used in ASN.1 assignement */
86#define CONST_OPTION (1<<14)
87#define CONST_DEFAULT (1<<15)
88#define CONST_TRUE (1<<16)
89#define CONST_FALSE (1<<17)
90
91#define CONST_LIST (1<<18) /* Used with TYPE_INTEGER and TYPE_BIT_STRING */
92#define CONST_MIN_MAX (1<<19)
93
94#define CONST_1_PARAM (1<<20)
95
96#define CONST_SIZE (1<<21)
97
98#define CONST_DEFINED_BY (1<<22)
99
100#define CONST_GENERALIZED (1<<23)
101#define CONST_UTC (1<<24)
102
103/* #define CONST_IMPORTS (1<<25) */
104
105#define CONST_NOT_USED (1<<26)
106#define CONST_SET (1<<27)
107#define CONST_ASSIGN (1<<28)
108
109#define CONST_DOWN (1<<29)
110#define CONST_RIGHT (1<<30)
111
112#endif /* INT_H */
diff --git a/src/daemon/https/minitasn1/libtasn1.h b/src/daemon/https/minitasn1/libtasn1.h
new file mode 100644
index 00000000..0b48c305
--- /dev/null
+++ b/src/daemon/https/minitasn1/libtasn1.h
@@ -0,0 +1,246 @@
1/*
2 * Copyright (C) 2004, 2005, 2006 Free Software Foundation
3 * Copyright (C) 2002 Fabio Fiorina
4 *
5 * This file is part of LIBTASN1.
6 *
7 * LIBTASN1 is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * LIBTASN1 is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with LIBTASN1; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 *
22 */
23
24#ifndef LIBTASN1_H
25# define LIBTASN1_H
26
27#include <stdio.h> /* for FILE* */
28
29#ifdef __cplusplus
30extern "C"
31{
32#endif
33
34#define LIBTASN1_VERSION "1.2"
35
36#include <sys/types.h>
37#include <time.h>
38
39#define MAX_NAME_SIZE 128 /* maximum number of characters of a name */
40 /* inside a file with ASN1 definitons */
41#define MAX_ERROR_DESCRIPTION_SIZE 128 /* maximum number of characters */
42 /* of a description message */
43 /* (null character included) */
44
45
46 typedef int asn1_retCode; /* type returned by libtasn1 functions */
47
48 /*****************************************/
49 /* Errors returned by libtasn1 functions */
50 /*****************************************/
51#define ASN1_SUCCESS 0
52#define ASN1_FILE_NOT_FOUND 1
53#define ASN1_ELEMENT_NOT_FOUND 2
54#define ASN1_IDENTIFIER_NOT_FOUND 3
55#define ASN1_DER_ERROR 4
56#define ASN1_VALUE_NOT_FOUND 5
57#define ASN1_GENERIC_ERROR 6
58#define ASN1_VALUE_NOT_VALID 7
59#define ASN1_TAG_ERROR 8
60#define ASN1_TAG_IMPLICIT 9
61#define ASN1_ERROR_TYPE_ANY 10
62#define ASN1_SYNTAX_ERROR 11
63#define ASN1_MEM_ERROR 12
64#define ASN1_MEM_ALLOC_ERROR 13
65#define ASN1_DER_OVERFLOW 14
66#define ASN1_NAME_TOO_LONG 15
67#define ASN1_ARRAY_ERROR 16
68#define ASN1_ELEMENT_NOT_EMPTY 17
69
70/*************************************/
71/* Constants used in asn1_visit_tree */
72/*************************************/
73#define ASN1_PRINT_NAME 1
74#define ASN1_PRINT_NAME_TYPE 2
75#define ASN1_PRINT_NAME_TYPE_VALUE 3
76#define ASN1_PRINT_ALL 4
77
78/*****************************************/
79/* Constants returned by asn1_read_tag */
80/*****************************************/
81#define ASN1_CLASS_UNIVERSAL 0x00 /* old: 1 */
82#define ASN1_CLASS_APPLICATION 0x40 /* old: 2 */
83#define ASN1_CLASS_CONTEXT_SPECIFIC 0x80 /* old: 3 */
84#define ASN1_CLASS_PRIVATE 0xC0 /* old: 4 */
85#define ASN1_CLASS_STRUCTURED 0x20
86
87/*****************************************/
88/* Constants returned by asn1_read_tag */
89/*****************************************/
90#define ASN1_TAG_BOOLEAN 0x01
91#define ASN1_TAG_INTEGER 0x02
92#define ASN1_TAG_SEQUENCE 0x10
93#define ASN1_TAG_SET 0x11
94#define ASN1_TAG_OCTET_STRING 0x04
95#define ASN1_TAG_BIT_STRING 0x03
96#define ASN1_TAG_UTCTime 0x17
97#define ASN1_TAG_GENERALIZEDTime 0x18
98#define ASN1_TAG_OBJECT_ID 0x06
99#define ASN1_TAG_ENUMERATED 0x0A
100#define ASN1_TAG_NULL 0x05
101#define ASN1_TAG_GENERALSTRING 0x1B
102
103/******************************************************/
104/* Structure definition used for the node of the tree */
105/* that represent an ASN.1 DEFINITION. */
106/******************************************************/
107
108 struct node_asn_struct
109 {
110 char *name; /* Node name */
111 unsigned int type; /* Node type */
112 unsigned char *value; /* Node value */
113 int value_len;
114 struct node_asn_struct *down; /* Pointer to the son node */
115 struct node_asn_struct *right; /* Pointer to the brother node */
116 struct node_asn_struct *left; /* Pointer to the next list element */
117 };
118
119 typedef struct node_asn_struct node_asn;
120
121 typedef node_asn *ASN1_TYPE;
122
123#define ASN1_TYPE_EMPTY NULL
124
125 struct static_struct_asn
126 {
127 const char *name; /* Node name */
128 unsigned int type; /* Node type */
129 const void *value; /* Node value */
130 };
131
132 typedef struct static_struct_asn ASN1_ARRAY_TYPE;
133
134
135
136 /***********************************/
137 /* Functions definitions */
138 /***********************************/
139
140 asn1_retCode asn1_parser2tree (const char *file_name,
141 ASN1_TYPE * definitions,
142 char *errorDescription);
143
144 asn1_retCode asn1_parser2array (const char *inputFileName,
145 const char *outputFileName,
146 const char *vectorName,
147 char *errorDescription);
148
149 asn1_retCode asn1_array2tree (const ASN1_ARRAY_TYPE * array,
150 ASN1_TYPE * definitions,
151 char *errorDescription);
152
153 void asn1_print_structure (FILE *out, ASN1_TYPE structure, const char *name,
154 int mode);
155
156 asn1_retCode asn1_create_element (ASN1_TYPE definitions,
157 const char *source_name,
158 ASN1_TYPE * element);
159
160 asn1_retCode asn1_delete_structure (ASN1_TYPE * structure);
161
162 asn1_retCode asn1_delete_element (ASN1_TYPE structure,
163 const char *element_name);
164
165 asn1_retCode asn1_write_value (ASN1_TYPE node_root, const char *name,
166 const void *ivalue, int len);
167
168 asn1_retCode asn1_read_value (ASN1_TYPE root, const char *name,
169 void *ivalue, int *len);
170
171 asn1_retCode asn1_number_of_elements (ASN1_TYPE element, const char *name,
172 int *num);
173
174 asn1_retCode asn1_der_coding (ASN1_TYPE element, const char *name,
175 void *ider, int *len, char *ErrorDescription);
176
177 asn1_retCode asn1_der_decoding (ASN1_TYPE * element, const void *ider,
178 int len, char *errorDescription);
179
180 asn1_retCode asn1_der_decoding_element (ASN1_TYPE * structure,
181 const char *elementName,
182 const void *ider, int len,
183 char *errorDescription);
184
185 asn1_retCode asn1_der_decoding_startEnd (ASN1_TYPE element,
186 const void *ider, int len,
187 const char *name_element,
188 int *start, int *end);
189
190 asn1_retCode asn1_expand_any_defined_by (ASN1_TYPE definitions,
191 ASN1_TYPE * element);
192
193 asn1_retCode asn1_expand_octet_string (ASN1_TYPE definitions,
194 ASN1_TYPE * element,
195 const char *octetName,
196 const char *objectName);
197
198 asn1_retCode asn1_read_tag (node_asn * root, const char *name,
199 int *tagValue, int *classValue);
200
201 const char *asn1_find_structure_from_oid (ASN1_TYPE definitions,
202 const char *oidValue);
203
204 const char *asn1_check_version (const char *req_version);
205
206 const char *libtasn1_strerror (asn1_retCode error);
207
208 void libtasn1_perror (asn1_retCode error);
209
210 /* DER utility functions. */
211
212 int asn1_get_tag_der (const unsigned char *der, int der_len,
213 unsigned char *cls, int *len, unsigned long *tag);
214
215 void asn1_octet_der (const unsigned char *str, int str_len,
216 unsigned char *der, int *der_len);
217
218 asn1_retCode asn1_get_octet_der (const unsigned char *der, int der_len,
219 int *ret_len, unsigned char *str,
220 int str_size, int *str_len);
221
222 void asn1_bit_der (const unsigned char *str, int bit_len,
223 unsigned char *der, int *der_len);
224
225 asn1_retCode asn1_get_bit_der (const unsigned char *der, int der_len,
226 int *ret_len, unsigned char *str,
227 int str_size, int *bit_len);
228
229 signed long asn1_get_length_der (const unsigned char *der, int der_len,
230 int *len);
231
232 void asn1_length_der (unsigned long int len, unsigned char *ans,
233 int *ans_len);
234
235 /* Other utility functions. */
236
237 ASN1_TYPE asn1_find_node (ASN1_TYPE pointer, const char *name);
238
239 asn1_retCode asn1_copy_node (ASN1_TYPE dst, const char *dst_name,
240 ASN1_TYPE src, const char *src_name);
241
242#ifdef __cplusplus
243}
244#endif
245
246#endif /* LIBTASN1_H */
diff --git a/src/daemon/https/minitasn1/mem.h b/src/daemon/https/minitasn1/mem.h
new file mode 100644
index 00000000..267f62f3
--- /dev/null
+++ b/src/daemon/https/minitasn1/mem.h
@@ -0,0 +1,27 @@
1#ifndef MEM_H
2# define MEM_H
3
4/* Use _asn1_afree() when calling alloca, or
5 * memory leaks may occur in systems which do not
6 * support alloca.
7 */
8#ifdef HAVE_ALLOCA
9# ifdef HAVE_ALLOCA_H
10# include <alloca.h>
11# endif
12# define _asn1_alloca alloca
13# define _asn1_afree(x)
14#else
15# define _asn1_alloca _asn1_malloc
16# define _asn1_afree _asn1_free
17#endif /* HAVE_ALLOCA */
18
19#define _asn1_malloc malloc
20#define _asn1_free free
21#define _asn1_calloc calloc
22#define _asn1_realloc realloc
23#define _asn1_strdup strdup
24
25#endif /* MEM_H */
26
27
diff --git a/src/daemon/https/minitasn1/parser_aux.c b/src/daemon/https/minitasn1/parser_aux.c
new file mode 100644
index 00000000..7d975b3d
--- /dev/null
+++ b/src/daemon/https/minitasn1/parser_aux.c
@@ -0,0 +1,1072 @@
1/*
2 * Copyright (C) 2004, 2006, 2007 Free Software Foundation
3 * Copyright (C) 2000,2001 Fabio Fiorina
4 *
5 * This file is part of LIBTASN1.
6 *
7 * The LIBTASN1 library is free software; you can redistribute it
8 * and/or modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 */
22
23#include <int.h>
24#include <errors.h>
25#include "parser_aux.h"
26#include "gstr.h"
27#include "structure.h"
28#include "element.h"
29
30char _asn1_identifierMissing[MAX_NAME_SIZE + 1]; /* identifier name not found */
31
32/***********************************************/
33/* Type: list_type */
34/* Description: type used in the list during */
35/* the structure creation. */
36/***********************************************/
37typedef struct list_struct
38{
39 node_asn *node;
40 struct list_struct *next;
41} list_type;
42
43
44/* Pointer to the first element of the list */
45list_type *firstElement = NULL;
46
47/******************************************************/
48/* Function : _asn1_add_node */
49/* Description: creates a new NODE_ASN element and */
50/* puts it in the list pointed by firstElement. */
51/* Parameters: */
52/* type: type of the new element (see TYPE_ */
53/* and CONST_ constants). */
54/* Return: pointer to the new element. */
55/******************************************************/
56node_asn *
57_asn1_add_node (unsigned int type)
58{
59 list_type *listElement;
60 node_asn *punt;
61
62 punt = (node_asn *) _asn1_calloc (1, sizeof (node_asn));
63 if (punt == NULL)
64 return NULL;
65
66 listElement = (list_type *) _asn1_malloc (sizeof (list_type));
67 if (listElement == NULL)
68 {
69 _asn1_free (punt);
70 return NULL;
71 }
72
73 listElement->node = punt;
74 listElement->next = firstElement;
75 firstElement = listElement;
76
77 punt->type = type;
78
79 return punt;
80}
81
82/**
83 * asn1_find_node:
84 * @pointer: NODE_ASN element pointer.
85 * @name: null terminated string with the element's name to find.
86 *
87 * Searches for an element called NAME starting from POINTER. The
88 * name is composed by differents identifiers separated by dots. When
89 * *POINTER has a name, the first identifier must be the name of
90 * *POINTER, otherwise it must be the name of one child of *POINTER.
91 *
92 * Return value: the searching result. NULL if not found.
93 **/
94ASN1_TYPE
95asn1_find_node (ASN1_TYPE pointer, const char *name)
96{
97 node_asn *p;
98 char *n_end, n[MAX_NAME_SIZE + 1];
99 const char *n_start;
100
101 if (pointer == NULL)
102 return NULL;
103
104 if (name == NULL)
105 return NULL;
106
107 p = pointer;
108 n_start = name;
109
110 if (p->name != NULL)
111 { /* has *pointer got a name ? */
112 n_end = strchr (n_start, '.'); /* search the first dot */
113 if (n_end)
114 {
115 memcpy (n, n_start, n_end - n_start);
116 n[n_end - n_start] = 0;
117 n_start = n_end;
118 n_start++;
119 }
120 else
121 {
122 _asn1_str_cpy (n, sizeof (n), n_start);
123 n_start = NULL;
124 }
125
126 while (p)
127 {
128 if ((p->name) && (!strcmp (p->name, n)))
129 break;
130 else
131 p = p->right;
132 } /* while */
133
134 if (p == NULL)
135 return NULL;
136 }
137 else
138 { /* *pointer doesn't have a name */
139 if (n_start[0] == 0)
140 return p;
141 }
142
143 while (n_start)
144 { /* Has the end of NAME been reached? */
145 n_end = strchr (n_start, '.'); /* search the next dot */
146 if (n_end)
147 {
148 memcpy (n, n_start, n_end - n_start);
149 n[n_end - n_start] = 0;
150 n_start = n_end;
151 n_start++;
152 }
153 else
154 {
155 _asn1_str_cpy (n, sizeof (n), n_start);
156 n_start = NULL;
157 }
158
159 if (p->down == NULL)
160 return NULL;
161
162 p = p->down;
163
164 /* The identifier "?LAST" indicates the last element
165 in the right chain. */
166 if (!strcmp (n, "?LAST"))
167 {
168 if (p == NULL)
169 return NULL;
170 while (p->right)
171 p = p->right;
172 }
173 else
174 { /* no "?LAST" */
175 while (p)
176 {
177 if ((p->name) && (!strcmp (p->name, n)))
178 break;
179 else
180 p = p->right;
181 }
182 if (p == NULL)
183 return NULL;
184 }
185 } /* while */
186
187 return p;
188}
189
190
191/******************************************************************/
192/* Function : _asn1_set_value */
193/* Description: sets the field VALUE in a NODE_ASN element. The */
194/* previous value (if exist) will be lost */
195/* Parameters: */
196/* node: element pointer. */
197/* value: pointer to the value that you want to set. */
198/* len: character number of value. */
199/* Return: pointer to the NODE_ASN element. */
200/******************************************************************/
201node_asn *
202_asn1_set_value (node_asn * node, const void *_value, unsigned int len)
203{
204 const unsigned char *value = _value;
205
206 if (node == NULL)
207 return node;
208 if (node->value)
209 {
210 _asn1_free (node->value);
211 node->value = NULL;
212 node->value_len = 0;
213 }
214 if (!len)
215 return node;
216 node->value = (unsigned char *) _asn1_malloc (len);
217 if (node->value == NULL)
218 return NULL;
219 node->value_len = len;
220
221 memcpy (node->value, value, len);
222 return node;
223}
224
225/******************************************************************/
226/* Function : _asn1_set_name */
227/* Description: sets the field NAME in a NODE_ASN element. The */
228/* previous value (if exist) will be lost */
229/* Parameters: */
230/* node: element pointer. */
231/* name: a null terminated string with the name that you want */
232/* to set. */
233/* Return: pointer to the NODE_ASN element. */
234/******************************************************************/
235node_asn *
236_asn1_set_name (node_asn * node, const char *name)
237{
238 if (node == NULL)
239 return node;
240
241 if (node->name)
242 {
243 _asn1_free (node->name);
244 node->name = NULL;
245 }
246
247 if (name == NULL)
248 return node;
249
250 if (strlen (name))
251 {
252 node->name = (char *) _asn1_strdup (name);
253 if (node->name == NULL)
254 return NULL;
255 }
256 else
257 node->name = NULL;
258 return node;
259}
260
261/******************************************************************/
262/* Function : _asn1_set_right */
263/* Description: sets the field RIGHT in a NODE_ASN element. */
264/* Parameters: */
265/* node: element pointer. */
266/* right: pointer to a NODE_ASN element that you want be pointed*/
267/* by NODE. */
268/* Return: pointer to *NODE. */
269/******************************************************************/
270node_asn *
271_asn1_set_right (node_asn * node, node_asn * right)
272{
273 if (node == NULL)
274 return node;
275 node->right = right;
276 if (right)
277 right->left = node;
278 return node;
279}
280
281/******************************************************************/
282/* Function : _asn1_get_right */
283/* Description: returns the element pointed by the RIGHT field of */
284/* a NODE_ASN element. */
285/* Parameters: */
286/* node: NODE_ASN element pointer. */
287/* Return: field RIGHT of NODE. */
288/******************************************************************/
289node_asn *
290_asn1_get_right (node_asn * node)
291{
292 if (node == NULL)
293 return NULL;
294 return node->right;
295}
296
297/******************************************************************/
298/* Function : _asn1_get_last_right */
299/* Description: return the last element along the right chain. */
300/* Parameters: */
301/* node: starting element pointer. */
302/* Return: pointer to the last element along the right chain. */
303/******************************************************************/
304node_asn *
305_asn1_get_last_right (node_asn * node)
306{
307 node_asn *p;
308
309 if (node == NULL)
310 return NULL;
311 p = node;
312 while (p->right)
313 p = p->right;
314 return p;
315}
316
317/******************************************************************/
318/* Function : _asn1_set_down */
319/* Description: sets the field DOWN in a NODE_ASN element. */
320/* Parameters: */
321/* node: element pointer. */
322/* down: pointer to a NODE_ASN element that you want be pointed */
323/* by NODE. */
324/* Return: pointer to *NODE. */
325/******************************************************************/
326node_asn *
327_asn1_set_down (node_asn * node, node_asn * down)
328{
329 if (node == NULL)
330 return node;
331 node->down = down;
332 if (down)
333 down->left = node;
334 return node;
335}
336
337/******************************************************************/
338/* Function : _asn1_get_down */
339/* Description: returns the element pointed by the DOWN field of */
340/* a NODE_ASN element. */
341/* Parameters: */
342/* node: NODE_ASN element pointer. */
343/* Return: field DOWN of NODE. */
344/******************************************************************/
345node_asn *
346_asn1_get_down (node_asn * node)
347{
348 if (node == NULL)
349 return NULL;
350 return node->down;
351}
352
353/******************************************************************/
354/* Function : _asn1_get_name */
355/* Description: returns the name of a NODE_ASN element. */
356/* Parameters: */
357/* node: NODE_ASN element pointer. */
358/* Return: a null terminated string. */
359/******************************************************************/
360char *
361_asn1_get_name (node_asn * node)
362{
363 if (node == NULL)
364 return NULL;
365 return node->name;
366}
367
368/******************************************************************/
369/* Function : _asn1_mod_type */
370/* Description: change the field TYPE of an NODE_ASN element. */
371/* The new value is the old one | (bitwise or) the */
372/* paramener VALUE. */
373/* Parameters: */
374/* node: NODE_ASN element pointer. */
375/* value: the integer value that must be or-ed with the current */
376/* value of field TYPE. */
377/* Return: NODE pointer. */
378/******************************************************************/
379node_asn *
380_asn1_mod_type (node_asn * node, unsigned int value)
381{
382 if (node == NULL)
383 return node;
384 node->type |= value;
385 return node;
386}
387
388
389/******************************************************************/
390/* Function : _asn1_remove_node */
391/* Description: gets free the memory allocated for an NODE_ASN */
392/* element (not the elements pointed by it). */
393/* Parameters: */
394/* node: NODE_ASN element pointer. */
395/******************************************************************/
396void
397_asn1_remove_node (node_asn * node)
398{
399 if (node == NULL)
400 return;
401
402 if (node->name != NULL)
403 _asn1_free (node->name);
404 if (node->value != NULL)
405 _asn1_free (node->value);
406 _asn1_free (node);
407}
408
409/******************************************************************/
410/* Function : _asn1_find_up */
411/* Description: return the father of the NODE_ASN element. */
412/* Parameters: */
413/* node: NODE_ASN element pointer. */
414/* Return: Null if not found. */
415/******************************************************************/
416node_asn *
417_asn1_find_up (node_asn * node)
418{
419 node_asn *p;
420
421 if (node == NULL)
422 return NULL;
423
424 p = node;
425
426 while ((p->left != NULL) && (p->left->right == p))
427 p = p->left;
428
429 return p->left;
430}
431
432/******************************************************************/
433/* Function : _asn1_delete_list */
434/* Description: deletes the list elements (not the elements */
435/* pointed by them). */
436/******************************************************************/
437void
438_asn1_delete_list (void)
439{
440 list_type *listElement;
441
442 while (firstElement)
443 {
444 listElement = firstElement;
445 firstElement = firstElement->next;
446 _asn1_free (listElement);
447 }
448}
449
450/******************************************************************/
451/* Function : _asn1_delete_list_and nodes */
452/* Description: deletes the list elements and the elements */
453/* pointed by them. */
454/******************************************************************/
455void
456_asn1_delete_list_and_nodes (void)
457{
458 list_type *listElement;
459
460 while (firstElement)
461 {
462 listElement = firstElement;
463 firstElement = firstElement->next;
464 _asn1_remove_node (listElement->node);
465 _asn1_free (listElement);
466 }
467}
468
469
470char *
471_asn1_ltostr (long v, char *str)
472{
473 long d, r;
474 char temp[20];
475 int count, k, start;
476
477 if (v < 0)
478 {
479 str[0] = '-';
480 start = 1;
481 v = -v;
482 }
483 else
484 start = 0;
485
486 count = 0;
487 do
488 {
489 d = v / 10;
490 r = v - d * 10;
491 temp[start + count] = '0' + (char) r;
492 count++;
493 v = d;
494 }
495 while (v);
496
497 for (k = 0; k < count; k++)
498 str[k + start] = temp[start + count - k - 1];
499 str[count + start] = 0;
500 return str;
501}
502
503
504/******************************************************************/
505/* Function : _asn1_change_integer_value */
506/* Description: converts into DER coding the value assign to an */
507/* INTEGER constant. */
508/* Parameters: */
509/* node: root of an ASN1element. */
510/* Return: */
511/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
512/* otherwise ASN1_SUCCESS */
513/******************************************************************/
514asn1_retCode
515_asn1_change_integer_value (ASN1_TYPE node)
516{
517 node_asn *p;
518 unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
519 unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1];
520 int len;
521
522 if (node == NULL)
523 return ASN1_ELEMENT_NOT_FOUND;
524
525 p = node;
526 while (p)
527 {
528 if ((type_field (p->type) == TYPE_INTEGER) && (p->type & CONST_ASSIGN))
529 {
530 if (p->value)
531 {
532 _asn1_convert_integer (p->value, val, sizeof (val), &len);
533 asn1_octet_der (val, len, val2, &len);
534 _asn1_set_value (p, val2, len);
535 }
536 }
537
538 if (p->down)
539 {
540 p = p->down;
541 }
542 else
543 {
544 if (p == node)
545 p = NULL;
546 else if (p->right)
547 p = p->right;
548 else
549 {
550 while (1)
551 {
552 p = _asn1_find_up (p);
553 if (p == node)
554 {
555 p = NULL;
556 break;
557 }
558 if (p->right)
559 {
560 p = p->right;
561 break;
562 }
563 }
564 }
565 }
566 }
567
568 return ASN1_SUCCESS;
569}
570
571
572/******************************************************************/
573/* Function : _asn1_expand_object_id */
574/* Description: expand the IDs of an OBJECT IDENTIFIER constant. */
575/* Parameters: */
576/* node: root of an ASN1 element. */
577/* Return: */
578/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
579/* otherwise ASN1_SUCCESS */
580/******************************************************************/
581asn1_retCode
582_asn1_expand_object_id (ASN1_TYPE node)
583{
584 node_asn *p, *p2, *p3, *p4, *p5;
585 char name_root[MAX_NAME_SIZE], name2[2 * MAX_NAME_SIZE + 1];
586 int move, tlen;
587
588 if (node == NULL)
589 return ASN1_ELEMENT_NOT_FOUND;
590
591 _asn1_str_cpy (name_root, sizeof (name_root), node->name);
592
593 p = node;
594 move = DOWN;
595
596 while (!((p == node) && (move == UP)))
597 {
598 if (move != UP)
599 {
600 if ((type_field (p->type) == TYPE_OBJECT_ID)
601 && (p->type & CONST_ASSIGN))
602 {
603 p2 = p->down;
604 if (p2 && (type_field (p2->type) == TYPE_CONSTANT))
605 {
606 if (p2->value && !isdigit (p2->value[0]))
607 {
608 _asn1_str_cpy (name2, sizeof (name2), name_root);
609 _asn1_str_cat (name2, sizeof (name2), ".");
610 _asn1_str_cat (name2, sizeof (name2), p2->value);
611 p3 = asn1_find_node (node, name2);
612 if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) ||
613 !(p3->type & CONST_ASSIGN))
614 return ASN1_ELEMENT_NOT_FOUND;
615 _asn1_set_down (p, p2->right);
616 _asn1_remove_node (p2);
617 p2 = p;
618 p4 = p3->down;
619 while (p4)
620 {
621 if (type_field (p4->type) == TYPE_CONSTANT)
622 {
623 p5 = _asn1_add_node_only (TYPE_CONSTANT);
624 _asn1_set_name (p5, p4->name);
625 tlen = strlen (p4->value);
626 if (tlen > 0)
627 _asn1_set_value (p5, p4->value, tlen + 1);
628 if (p2 == p)
629 {
630 _asn1_set_right (p5, p->down);
631 _asn1_set_down (p, p5);
632 }
633 else
634 {
635 _asn1_set_right (p5, p2->right);
636 _asn1_set_right (p2, p5);
637 }
638 p2 = p5;
639 }
640 p4 = p4->right;
641 }
642 move = DOWN;
643 continue;
644 }
645 }
646 }
647 move = DOWN;
648 }
649 else
650 move = RIGHT;
651
652 if (move == DOWN)
653 {
654 if (p->down)
655 p = p->down;
656 else
657 move = RIGHT;
658 }
659
660 if (p == node)
661 {
662 move = UP;
663 continue;
664 }
665
666 if (move == RIGHT)
667 {
668 if (p->right)
669 p = p->right;
670 else
671 move = UP;
672 }
673 if (move == UP)
674 p = _asn1_find_up (p);
675 }
676
677
678 /*******************************/
679 /* expand DEFAULT */
680 /*******************************/
681 p = node;
682 move = DOWN;
683
684 while (!((p == node) && (move == UP)))
685 {
686 if (move != UP)
687 {
688 if ((type_field (p->type) == TYPE_OBJECT_ID) &&
689 (p->type & CONST_DEFAULT))
690 {
691 p2 = p->down;
692 if (p2 && (type_field (p2->type) == TYPE_DEFAULT))
693 {
694 _asn1_str_cpy (name2, sizeof (name2), name_root);
695 _asn1_str_cat (name2, sizeof (name2), ".");
696 _asn1_str_cat (name2, sizeof (name2), p2->value);
697 p3 = asn1_find_node (node, name2);
698 if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) ||
699 !(p3->type & CONST_ASSIGN))
700 return ASN1_ELEMENT_NOT_FOUND;
701 p4 = p3->down;
702 name2[0] = 0;
703 while (p4)
704 {
705 if (type_field (p4->type) == TYPE_CONSTANT)
706 {
707 if (name2[0])
708 _asn1_str_cat (name2, sizeof (name2), ".");
709 _asn1_str_cat (name2, sizeof (name2), p4->value);
710 }
711 p4 = p4->right;
712 }
713 tlen = strlen (name2);
714 if (tlen > 0)
715 _asn1_set_value (p2, name2, tlen + 1);
716 }
717 }
718 move = DOWN;
719 }
720 else
721 move = RIGHT;
722
723 if (move == DOWN)
724 {
725 if (p->down)
726 p = p->down;
727 else
728 move = RIGHT;
729 }
730
731 if (p == node)
732 {
733 move = UP;
734 continue;
735 }
736
737 if (move == RIGHT)
738 {
739 if (p->right)
740 p = p->right;
741 else
742 move = UP;
743 }
744 if (move == UP)
745 p = _asn1_find_up (p);
746 }
747
748 return ASN1_SUCCESS;
749}
750
751
752/******************************************************************/
753/* Function : _asn1_type_set_config */
754/* Description: sets the CONST_SET and CONST_NOT_USED properties */
755/* in the fields of the SET elements. */
756/* Parameters: */
757/* node: root of an ASN1 element. */
758/* Return: */
759/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
760/* otherwise ASN1_SUCCESS */
761/******************************************************************/
762asn1_retCode
763_asn1_type_set_config (ASN1_TYPE node)
764{
765 node_asn *p, *p2;
766 int move;
767
768 if (node == NULL)
769 return ASN1_ELEMENT_NOT_FOUND;
770
771 p = node;
772 move = DOWN;
773
774 while (!((p == node) && (move == UP)))
775 {
776 if (move != UP)
777 {
778 if (type_field (p->type) == TYPE_SET)
779 {
780 p2 = p->down;
781 while (p2)
782 {
783 if (type_field (p2->type) != TYPE_TAG)
784 p2->type |= CONST_SET | CONST_NOT_USED;
785 p2 = p2->right;
786 }
787 }
788 move = DOWN;
789 }
790 else
791 move = RIGHT;
792
793 if (move == DOWN)
794 {
795 if (p->down)
796 p = p->down;
797 else
798 move = RIGHT;
799 }
800
801 if (p == node)
802 {
803 move = UP;
804 continue;
805 }
806
807 if (move == RIGHT)
808 {
809 if (p->right)
810 p = p->right;
811 else
812 move = UP;
813 }
814 if (move == UP)
815 p = _asn1_find_up (p);
816 }
817
818 return ASN1_SUCCESS;
819}
820
821
822/******************************************************************/
823/* Function : _asn1_check_identifier */
824/* Description: checks the definitions of all the identifiers */
825/* and the first element of an OBJECT_ID (e.g. {pkix 0 4}). */
826/* The _asn1_identifierMissing global variable is filled if */
827/* necessary. */
828/* Parameters: */
829/* node: root of an ASN1 element. */
830/* Return: */
831/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL, */
832/* ASN1_IDENTIFIER_NOT_FOUND if an identifier is not defined, */
833/* otherwise ASN1_SUCCESS */
834/******************************************************************/
835asn1_retCode
836_asn1_check_identifier (ASN1_TYPE node)
837{
838 node_asn *p, *p2;
839 char name2[MAX_NAME_SIZE * 2 + 2];
840
841 if (node == NULL)
842 return ASN1_ELEMENT_NOT_FOUND;
843
844 p = node;
845 while (p)
846 {
847 if (type_field (p->type) == TYPE_IDENTIFIER)
848 {
849 _asn1_str_cpy (name2, sizeof (name2), node->name);
850 _asn1_str_cat (name2, sizeof (name2), ".");
851 _asn1_str_cat (name2, sizeof (name2), p->value);
852 p2 = asn1_find_node (node, name2);
853 if (p2 == NULL)
854 {
855 strcpy (_asn1_identifierMissing, p->value);
856 return ASN1_IDENTIFIER_NOT_FOUND;
857 }
858 }
859 else if ((type_field (p->type) == TYPE_OBJECT_ID) &&
860 (p->type & CONST_DEFAULT))
861 {
862 p2 = p->down;
863 if (p2 && (type_field (p2->type) == TYPE_DEFAULT))
864 {
865 _asn1_str_cpy (name2, sizeof (name2), node->name);
866 _asn1_str_cat (name2, sizeof (name2), ".");
867 _asn1_str_cat (name2, sizeof (name2), p2->value);
868 strcpy (_asn1_identifierMissing, p2->value);
869 p2 = asn1_find_node (node, name2);
870 if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) ||
871 !(p2->type & CONST_ASSIGN))
872 return ASN1_IDENTIFIER_NOT_FOUND;
873 else
874 _asn1_identifierMissing[0] = 0;
875 }
876 }
877 else if ((type_field (p->type) == TYPE_OBJECT_ID) &&
878 (p->type & CONST_ASSIGN))
879 {
880 p2 = p->down;
881 if (p2 && (type_field (p2->type) == TYPE_CONSTANT))
882 {
883 if (p2->value && !isdigit (p2->value[0]))
884 {
885 _asn1_str_cpy (name2, sizeof (name2), node->name);
886 _asn1_str_cat (name2, sizeof (name2), ".");
887 _asn1_str_cat (name2, sizeof (name2), p2->value);
888 strcpy (_asn1_identifierMissing, p2->value);
889 p2 = asn1_find_node (node, name2);
890 if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) ||
891 !(p2->type & CONST_ASSIGN))
892 return ASN1_IDENTIFIER_NOT_FOUND;
893 else
894 _asn1_identifierMissing[0] = 0;
895 }
896 }
897 }
898
899 if (p->down)
900 {
901 p = p->down;
902 }
903 else if (p->right)
904 p = p->right;
905 else
906 {
907 while (1)
908 {
909 p = _asn1_find_up (p);
910 if (p == node)
911 {
912 p = NULL;
913 break;
914 }
915 if (p->right)
916 {
917 p = p->right;
918 break;
919 }
920 }
921 }
922 }
923
924 return ASN1_SUCCESS;
925}
926
927
928/******************************************************************/
929/* Function : _asn1_set_default_tag */
930/* Description: sets the default IMPLICIT or EXPLICIT property in */
931/* the tagged elements that don't have this declaration. */
932/* Parameters: */
933/* node: pointer to a DEFINITIONS element. */
934/* Return: */
935/* ASN1_ELEMENT_NOT_FOUND if NODE is NULL or not a pointer to */
936/* a DEFINITIONS element, */
937/* otherwise ASN1_SUCCESS */
938/******************************************************************/
939asn1_retCode
940_asn1_set_default_tag (ASN1_TYPE node)
941{
942 node_asn *p;
943
944 if ((node == NULL) || (type_field (node->type) != TYPE_DEFINITIONS))
945 return ASN1_ELEMENT_NOT_FOUND;
946
947 p = node;
948 while (p)
949 {
950 if ((type_field (p->type) == TYPE_TAG) &&
951 !(p->type & CONST_EXPLICIT) && !(p->type & CONST_IMPLICIT))
952 {
953 if (node->type & CONST_EXPLICIT)
954 p->type |= CONST_EXPLICIT;
955 else
956 p->type |= CONST_IMPLICIT;
957 }
958
959 if (p->down)
960 {
961 p = p->down;
962 }
963 else if (p->right)
964 p = p->right;
965 else
966 {
967 while (1)
968 {
969 p = _asn1_find_up (p);
970 if (p == node)
971 {
972 p = NULL;
973 break;
974 }
975 if (p->right)
976 {
977 p = p->right;
978 break;
979 }
980 }
981 }
982 }
983
984 return ASN1_SUCCESS;
985}
986
987
988
989static const char *
990parse_version_number (const char *s, int *number)
991{
992 int val = 0;
993
994 if (*s == '0' && isdigit (s[1]))
995 return NULL; /* leading zeros are not allowed */
996 for (; isdigit (*s); s++)
997 {
998 val *= 10;
999 val += *s - '0';
1000 }
1001 *number = val;
1002 return val < 0 ? NULL : s;
1003}
1004
1005/* The parse version functions were copied from libgcrypt.
1006 */
1007static const char *
1008parse_version_string (const char *s, int *major, int *minor, int *micro)
1009{
1010 s = parse_version_number (s, major);
1011 if (!s || *s != '.')
1012 return NULL;
1013 s++;
1014 s = parse_version_number (s, minor);
1015 if (!s)
1016 return NULL;
1017 if (*s != '.')
1018 {
1019 *micro = 0;
1020 return s;
1021 }
1022 s++;
1023 s = parse_version_number (s, micro);
1024 if (!s)
1025 return NULL;
1026 return s; /* patchlevel */
1027}
1028
1029/**
1030 * asn1_check_version - check for library version
1031 * @req_version: Required version number, or NULL.
1032 *
1033 * Check that the the version of the library is at minimum the
1034 * requested one and return the version string; return %NULL if the
1035 * condition is not satisfied. If a %NULL is passed to this function,
1036 * no check is done, but the version string is simply returned.
1037 *
1038 * See %LIBTASN1_VERSION for a suitable @req_version string.
1039 *
1040 * Return value: Version string of run-time library, or %NULL if the
1041 * run-time library does not meet the required version number.
1042 */
1043const char *
1044asn1_check_version (const char *req_version)
1045{
1046 const char *ver = LIBTASN1_VERSION;
1047 int my_major, my_minor, my_micro;
1048 int rq_major, rq_minor, rq_micro;
1049 const char *my_plvl, *rq_plvl;
1050
1051 if (!req_version)
1052 return ver;
1053
1054 my_plvl = parse_version_string (ver, &my_major, &my_minor, &my_micro);
1055 if (!my_plvl)
1056 return NULL; /* very strange our own version is bogus */
1057 rq_plvl = parse_version_string (req_version, &rq_major, &rq_minor,
1058 &rq_micro);
1059 if (!rq_plvl)
1060 return NULL; /* req version string is invalid */
1061
1062 if (my_major > rq_major
1063 || (my_major == rq_major && my_minor > rq_minor)
1064 || (my_major == rq_major && my_minor == rq_minor
1065 && my_micro > rq_micro)
1066 || (my_major == rq_major && my_minor == rq_minor
1067 && my_micro == rq_micro && strcmp (my_plvl, rq_plvl) >= 0))
1068 {
1069 return ver;
1070 }
1071 return NULL;
1072}
diff --git a/src/daemon/https/minitasn1/parser_aux.h b/src/daemon/https/minitasn1/parser_aux.h
new file mode 100644
index 00000000..3055510c
--- /dev/null
+++ b/src/daemon/https/minitasn1/parser_aux.h
@@ -0,0 +1,63 @@
1
2#ifndef _PARSER_AUX_H
3#define _PARSER_AUX_H
4
5
6/***************************************/
7/* Functions used by ASN.1 parser */
8/***************************************/
9node_asn *
10_asn1_add_node(unsigned int type);
11
12node_asn *
13_asn1_set_value(node_asn *node,const void *value,unsigned int len);
14
15node_asn *
16_asn1_set_name(node_asn *node,const char *name);
17
18node_asn *
19_asn1_set_right(node_asn *node,node_asn *right);
20
21node_asn *
22_asn1_get_right(node_asn *node);
23
24node_asn *
25_asn1_get_last_right(node_asn *node);
26
27node_asn *
28_asn1_set_down(node_asn *node,node_asn *down);
29
30char *
31_asn1_get_name(node_asn *node);
32
33node_asn *
34_asn1_get_down(node_asn *node);
35
36node_asn *
37_asn1_mod_type(node_asn *node,unsigned int value);
38
39void
40_asn1_remove_node(node_asn *node);
41
42void _asn1_delete_list(void);
43
44void _asn1_delete_list_and_nodes(void);
45
46char * _asn1_ltostr(long v,char *str);
47
48node_asn * _asn1_find_up(node_asn *node);
49
50asn1_retCode _asn1_change_integer_value(ASN1_TYPE node);
51
52asn1_retCode _asn1_expand_object_id(ASN1_TYPE node);
53
54asn1_retCode _asn1_type_set_config(ASN1_TYPE node);
55
56asn1_retCode _asn1_check_identifier(ASN1_TYPE node);
57
58asn1_retCode _asn1_set_default_tag(ASN1_TYPE node);
59
60#endif
61
62
63
diff --git a/src/daemon/https/minitasn1/structure.c b/src/daemon/https/minitasn1/structure.c
new file mode 100644
index 00000000..264793c1
--- /dev/null
+++ b/src/daemon/https/minitasn1/structure.c
@@ -0,0 +1,1221 @@
1/*
2 * Copyright (C) 2004, 2006, 2007 Free Software Foundation
3 * Copyright (C) 2002 Fabio Fiorina
4 *
5 * This file is part of LIBTASN1.
6 *
7 * The LIBTASN1 library is free software; you can redistribute it
8 * and/or modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA
21 */
22
23
24/*****************************************************/
25/* File: structure.c */
26/* Description: Functions to create and delete an */
27/* ASN1 tree. */
28/*****************************************************/
29
30
31#include <int.h>
32#include <errors.h>
33#include <structure.h>
34#include "parser_aux.h"
35#include <gstr.h>
36
37
38extern char _asn1_identifierMissing[];
39
40
41/******************************************************/
42/* Function : _asn1_add_node_only */
43/* Description: creates a new NODE_ASN element. */
44/* Parameters: */
45/* type: type of the new element (see TYPE_ */
46/* and CONST_ constants). */
47/* Return: pointer to the new element. */
48/******************************************************/
49node_asn *
50_asn1_add_node_only (unsigned int type)
51{
52 node_asn *punt;
53
54 punt = (node_asn *) _asn1_calloc (1, sizeof (node_asn));
55 if (punt == NULL)
56 return NULL;
57
58 punt->type = type;
59
60 return punt;
61}
62
63
64/******************************************************************/
65/* Function : _asn1_find_left */
66/* Description: returns the NODE_ASN element with RIGHT field that*/
67/* points the element NODE. */
68/* Parameters: */
69/* node: NODE_ASN element pointer. */
70/* Return: NULL if not found. */
71/******************************************************************/
72node_asn *
73_asn1_find_left (node_asn * node)
74{
75 if ((node == NULL) || (node->left == NULL) || (node->left->down == node))
76 return NULL;
77
78 return node->left;
79}
80
81
82asn1_retCode
83_asn1_create_static_structure (ASN1_TYPE pointer, char *output_file_name,
84 char *vector_name)
85{
86 FILE *file;
87 node_asn *p;
88 unsigned long t;
89
90 file = fopen (output_file_name, "w");
91
92 if (file == NULL)
93 return ASN1_FILE_NOT_FOUND;
94
95 fprintf (file, "#if HAVE_CONFIG_H\n");
96 fprintf (file, "# include \"config.h\"\n");
97 fprintf (file, "#endif\n\n");
98
99 fprintf (file, "#include <libtasn1.h>\n\n");
100
101 fprintf (file, "extern const ASN1_ARRAY_TYPE %s[]={\n", vector_name);
102
103 p = pointer;
104
105 while (p)
106 {
107 fprintf (file, " {");
108
109 if (p->name)
110 fprintf (file, "\"%s\",", p->name);
111 else
112 fprintf (file, "0,");
113
114 t = p->type;
115 if (p->down)
116 t |= CONST_DOWN;
117 if (p->right)
118 t |= CONST_RIGHT;
119
120 fprintf (file, "%lu,", t);
121
122 if (p->value)
123 fprintf (file, "\"%s\"},\n", p->value);
124 else
125 fprintf (file, "0},\n");
126
127 if (p->down)
128 {
129 p = p->down;
130 }
131 else if (p->right)
132 {
133 p = p->right;
134 }
135 else
136 {
137 while (1)
138 {
139 p = _asn1_find_up (p);
140 if (p == pointer)
141 {
142 p = NULL;
143 break;
144 }
145 if (p->right)
146 {
147 p = p->right;
148 break;
149 }
150 }
151 }
152 }
153
154 fprintf (file, " {0,0,0}\n};\n");
155
156 fclose (file);
157
158 return ASN1_SUCCESS;
159}
160
161
162/**
163 * asn1_array2tree - Creates the structures needed to manage the ASN1 definitions.
164 * @array: specify the array that contains ASN.1 declarations
165 * @definitions: return the pointer to the structure created by
166 * *ARRAY ASN.1 declarations
167 * @errorDescription: return the error description.
168 *
169 * Creates the structures needed to manage the ASN.1 definitions.
170 * @array is a vector created by asn1_parser2array().
171 *
172 * Returns:
173 *
174 * ASN1_SUCCESS: Structure created correctly.
175 *
176 * ASN1_ELEMENT_NOT_EMPTY: *@definitions not ASN1_TYPE_EMPTY.
177 *
178 * ASN1_IDENTIFIER_NOT_FOUND: In the file there is an identifier that
179 * is not defined (see @errorDescription for more information).
180 *
181 * ASN1_ARRAY_ERROR: The array pointed by @array is wrong.
182 **/
183asn1_retCode
184asn1_array2tree (const ASN1_ARRAY_TYPE * array, ASN1_TYPE * definitions,
185 char *errorDescription)
186{
187 node_asn *p, *p_last = NULL;
188 unsigned long k;
189 int move;
190 asn1_retCode result;
191
192
193 if (*definitions != ASN1_TYPE_EMPTY)
194 return ASN1_ELEMENT_NOT_EMPTY;
195
196 move = UP;
197
198 k = 0;
199 while (array[k].value || array[k].type || array[k].name)
200 {
201 p = _asn1_add_node (array[k].type & (~CONST_DOWN));
202 if (array[k].name)
203 _asn1_set_name (p, array[k].name);
204 if (array[k].value)
205 _asn1_set_value (p, array[k].value, strlen (array[k].value) + 1);
206
207 if (*definitions == NULL)
208 *definitions = p;
209
210 if (move == DOWN)
211 _asn1_set_down (p_last, p);
212 else if (move == RIGHT)
213 _asn1_set_right (p_last, p);
214
215 p_last = p;
216
217 if (array[k].type & CONST_DOWN)
218 move = DOWN;
219 else if (array[k].type & CONST_RIGHT)
220 move = RIGHT;
221 else
222 {
223 while (1)
224 {
225 if (p_last == *definitions)
226 break;
227
228 p_last = _asn1_find_up (p_last);
229
230 if (p_last == NULL)
231 break;
232
233 if (p_last->type & CONST_RIGHT)
234 {
235 p_last->type &= ~CONST_RIGHT;
236 move = RIGHT;
237 break;
238 }
239 } /* while */
240 }
241 k++;
242 } /* while */
243
244 if (p_last == *definitions)
245 {
246 result = _asn1_check_identifier (*definitions);
247 if (result == ASN1_SUCCESS)
248 {
249 _asn1_change_integer_value (*definitions);
250 _asn1_expand_object_id (*definitions);
251 }
252 }
253 else
254 {
255 result = ASN1_ARRAY_ERROR;
256 }
257
258 if (errorDescription != NULL)
259 {
260 if (result == ASN1_IDENTIFIER_NOT_FOUND)
261 {
262 Estrcpy (errorDescription, ":: identifier '");
263 Estrcat (errorDescription, _asn1_identifierMissing);
264 Estrcat (errorDescription, "' not found");
265 }
266 else
267 errorDescription[0] = 0;
268 }
269
270 if (result != ASN1_SUCCESS)
271 {
272 _asn1_delete_list_and_nodes ();
273 *definitions = ASN1_TYPE_EMPTY;
274 }
275 else
276 _asn1_delete_list ();
277
278 return result;
279}
280
281/**
282 * asn1_delete_structure - Deletes the structure pointed by *ROOT.
283 * @structure: pointer to the structure that you want to delete.
284 *
285 * Deletes the structure *@structure. At the end, *@structure is set
286 * to ASN1_TYPE_EMPTY.
287 *
288 * Returns:
289 *
290 * ASN1_SUCCESS: Everything OK.
291 *
292 * ASN1_ELEMENT_NOT_FOUND: *@structure was ASN1_TYPE_EMPTY.
293 *
294 **/
295asn1_retCode
296asn1_delete_structure (ASN1_TYPE * structure)
297{
298 node_asn *p, *p2, *p3;
299
300 if (*structure == ASN1_TYPE_EMPTY)
301 return ASN1_ELEMENT_NOT_FOUND;
302
303 p = *structure;
304 while (p)
305 {
306 if (p->down)
307 {
308 p = p->down;
309 }
310 else
311 { /* no down */
312 p2 = p->right;
313 if (p != *structure)
314 {
315 p3 = _asn1_find_up (p);
316 _asn1_set_down (p3, p2);
317 _asn1_remove_node (p);
318 p = p3;
319 }
320 else
321 { /* p==root */
322 p3 = _asn1_find_left (p);
323 if (!p3)
324 {
325 p3 = _asn1_find_up (p);
326 if (p3)
327 _asn1_set_down (p3, p2);
328 else
329 {
330 if (p->right)
331 p->right->left = NULL;
332 }
333 }
334 else
335 _asn1_set_right (p3, p2);
336 _asn1_remove_node (p);
337 p = NULL;
338 }
339 }
340 }
341
342 *structure = ASN1_TYPE_EMPTY;
343 return ASN1_SUCCESS;
344}
345
346
347
348/**
349 * asn1_delete_element - Deletes the element of a structure.
350 * @structure: pointer to the structure that contains the element you
351 * want to delete.
352 * @element_name: element's name you want to delete.
353 *
354 * Deletes the element named *@element_name inside *@structure.
355 *
356 * Returns:
357 *
358 * ASN1_SUCCESS: Everything OK.
359 *
360 * ASN1_ELEMENT_NOT_FOUND: The name element was not found.
361 *
362 **/
363asn1_retCode
364asn1_delete_element (ASN1_TYPE structure, const char *element_name)
365{
366 node_asn *p2, *p3, *source_node;
367
368 source_node = asn1_find_node (structure, element_name);
369
370 if (source_node == ASN1_TYPE_EMPTY)
371 return ASN1_ELEMENT_NOT_FOUND;
372
373 p2 = source_node->right;
374 p3 = _asn1_find_left (source_node);
375 if (!p3)
376 {
377 p3 = _asn1_find_up (source_node);
378 if (p3)
379 _asn1_set_down (p3, p2);
380 else if (source_node->right)
381 source_node->right->left = NULL;
382 }
383 else
384 _asn1_set_right (p3, p2);
385
386 return asn1_delete_structure (&source_node);
387}
388
389node_asn *
390_asn1_copy_structure3 (node_asn * source_node)
391{
392 node_asn *dest_node, *p_s, *p_d, *p_d_prev;
393 int move;
394
395 if (source_node == NULL)
396 return NULL;
397
398 dest_node = _asn1_add_node_only (source_node->type);
399
400 p_s = source_node;
401 p_d = dest_node;
402
403 move = DOWN;
404
405 do
406 {
407 if (move != UP)
408 {
409 if (p_s->name)
410 _asn1_set_name (p_d, p_s->name);
411 if (p_s->value)
412 _asn1_set_value (p_d, p_s->value, p_s->value_len);
413 move = DOWN;
414 }
415 else
416 move = RIGHT;
417
418 if (move == DOWN)
419 {
420 if (p_s->down)
421 {
422 p_s = p_s->down;
423 p_d_prev = p_d;
424 p_d = _asn1_add_node_only (p_s->type);
425 _asn1_set_down (p_d_prev, p_d);
426 }
427 else
428 move = RIGHT;
429 }
430
431 if (p_s == source_node)
432 break;
433
434 if (move == RIGHT)
435 {
436 if (p_s->right)
437 {
438 p_s = p_s->right;
439 p_d_prev = p_d;
440 p_d = _asn1_add_node_only (p_s->type);
441 _asn1_set_right (p_d_prev, p_d);
442 }
443 else
444 move = UP;
445 }
446 if (move == UP)
447 {
448 p_s = _asn1_find_up (p_s);
449 p_d = _asn1_find_up (p_d);
450 }
451 }
452 while (p_s != source_node);
453
454 return dest_node;
455}
456
457
458node_asn *
459_asn1_copy_structure2 (node_asn * root, const char *source_name)
460{
461 node_asn *source_node;
462
463 source_node = asn1_find_node (root, source_name);
464
465 return _asn1_copy_structure3 (source_node);
466
467}
468
469
470asn1_retCode
471_asn1_type_choice_config (node_asn * node)
472{
473 node_asn *p, *p2, *p3, *p4;
474 int move, tlen;
475
476 if (node == NULL)
477 return ASN1_ELEMENT_NOT_FOUND;
478
479 p = node;
480 move = DOWN;
481
482 while (!((p == node) && (move == UP)))
483 {
484 if (move != UP)
485 {
486 if ((type_field (p->type) == TYPE_CHOICE) && (p->type & CONST_TAG))
487 {
488 p2 = p->down;
489 while (p2)
490 {
491 if (type_field (p2->type) != TYPE_TAG)
492 {
493 p2->type |= CONST_TAG;
494 p3 = _asn1_find_left (p2);
495 while (p3)
496 {
497 if (type_field (p3->type) == TYPE_TAG)
498 {
499 p4 = _asn1_add_node_only (p3->type);
500 tlen = strlen (p3->value);
501 if (tlen > 0)
502 _asn1_set_value (p4, p3->value, tlen + 1);
503 _asn1_set_right (p4, p2->down);
504 _asn1_set_down (p2, p4);
505 }
506 p3 = _asn1_find_left (p3);
507 }
508 }
509 p2 = p2->right;
510 }
511 p->type &= ~(CONST_TAG);
512 p2 = p->down;
513 while (p2)
514 {
515 p3 = p2->right;
516 if (type_field (p2->type) == TYPE_TAG)
517 asn1_delete_structure (&p2);
518 p2 = p3;
519 }
520 }
521 move = DOWN;
522 }
523 else
524 move = RIGHT;
525
526 if (move == DOWN)
527 {
528 if (p->down)
529 p = p->down;
530 else
531 move = RIGHT;
532 }
533
534 if (p == node)
535 {
536 move = UP;
537 continue;
538 }
539
540 if (move == RIGHT)
541 {
542 if (p->right)
543 p = p->right;
544 else
545 move = UP;
546 }
547 if (move == UP)
548 p = _asn1_find_up (p);
549 }
550
551 return ASN1_SUCCESS;
552}
553
554
555asn1_retCode
556_asn1_expand_identifier (node_asn ** node, node_asn * root)
557{
558 node_asn *p, *p2, *p3;
559 char name2[MAX_NAME_SIZE + 2];
560 int move;
561
562 if (node == NULL)
563 return ASN1_ELEMENT_NOT_FOUND;
564
565 p = *node;
566 move = DOWN;
567
568 while (!((p == *node) && (move == UP)))
569 {
570 if (move != UP)
571 {
572 if (type_field (p->type) == TYPE_IDENTIFIER)
573 {
574 _asn1_str_cpy (name2, sizeof (name2), root->name);
575 _asn1_str_cat (name2, sizeof (name2), ".");
576 _asn1_str_cat (name2, sizeof (name2), p->value);
577 p2 = _asn1_copy_structure2 (root, name2);
578 if (p2 == NULL)
579 {
580 return ASN1_IDENTIFIER_NOT_FOUND;
581 }
582 _asn1_set_name (p2, p->name);
583 p2->right = p->right;
584 p2->left = p->left;
585 if (p->right)
586 p->right->left = p2;
587 p3 = p->down;
588 if (p3)
589 {
590 while (p3->right)
591 p3 = p3->right;
592 _asn1_set_right (p3, p2->down);
593 _asn1_set_down (p2, p->down);
594 }
595
596 p3 = _asn1_find_left (p);
597 if (p3)
598 _asn1_set_right (p3, p2);
599 else
600 {
601 p3 = _asn1_find_up (p);
602 if (p3)
603 _asn1_set_down (p3, p2);
604 else
605 {
606 p2->left = NULL;
607 }
608 }
609
610 if (p->type & CONST_SIZE)
611 p2->type |= CONST_SIZE;
612 if (p->type & CONST_TAG)
613 p2->type |= CONST_TAG;
614 if (p->type & CONST_OPTION)
615 p2->type |= CONST_OPTION;
616 if (p->type & CONST_DEFAULT)
617 p2->type |= CONST_DEFAULT;
618 if (p->type & CONST_SET)
619 p2->type |= CONST_SET;
620 if (p->type & CONST_NOT_USED)
621 p2->type |= CONST_NOT_USED;
622
623 if (p == *node)
624 *node = p2;
625 _asn1_remove_node (p);
626 p = p2;
627 move = DOWN;
628 continue;
629 }
630 move = DOWN;
631 }
632 else
633 move = RIGHT;
634
635 if (move == DOWN)
636 {
637 if (p->down)
638 p = p->down;
639 else
640 move = RIGHT;
641 }
642
643 if (p == *node)
644 {
645 move = UP;
646 continue;
647 }
648
649 if (move == RIGHT)
650 {
651 if (p->right)
652 p = p->right;
653 else
654 move = UP;
655 }
656 if (move == UP)
657 p = _asn1_find_up (p);
658 }
659
660 return ASN1_SUCCESS;
661}
662
663
664/**
665 * asn1_create_element - Creates a structure of type SOURCE_NAME.
666 * @definitions: pointer to the structure returned by "parser_asn1" function
667 * @source_name: the name of the type of the new structure (must be
668 * inside p_structure).
669 * @element: pointer to the structure created.
670 *
671 * Creates a structure of type @source_name. Example using
672 * "pkix.asn":
673 *
674 * rc = asn1_create_structure(cert_def, "PKIX1.Certificate",
675 * certptr);
676 *
677 * Returns:
678 *
679 * ASN1_SUCCESS: Creation OK.
680 *
681 * ASN1_ELEMENT_NOT_FOUND: SOURCE_NAME isn't known
682 **/
683asn1_retCode
684asn1_create_element (ASN1_TYPE definitions, const char *source_name,
685 ASN1_TYPE * element)
686{
687 node_asn *dest_node;
688 int res;
689
690 dest_node = _asn1_copy_structure2 (definitions, source_name);
691
692 if (dest_node == NULL)
693 return ASN1_ELEMENT_NOT_FOUND;
694
695 _asn1_set_name (dest_node, "");
696
697 res = _asn1_expand_identifier (&dest_node, definitions);
698 _asn1_type_choice_config (dest_node);
699
700 *element = dest_node;
701
702 return res;
703}
704
705
706/**
707 * asn1_print_structure - Prints on the standard output the structure's tree
708 * @out: pointer to the output file (e.g. stdout).
709 * @structure: pointer to the structure that you want to visit.
710 * @name: an element of the structure
711 * @mode: specify how much of the structure to print, can be
712 * %ASN1_PRINT_NAME, %ASN1_PRINT_NAME_TYPE,
713 * %ASN1_PRINT_NAME_TYPE_VALUE, or %ASN1_PRINT_ALL.
714 *
715 * Prints on the @out file descriptor the structure's tree starting
716 * from the @name element inside the structure @structure.
717 **/
718void
719asn1_print_structure (FILE * out, ASN1_TYPE structure, const char *name,
720 int mode)
721{
722 node_asn *p, *root;
723 int k, indent = 0, len, len2, len3;
724
725 if (out == NULL)
726 return;
727
728 root = asn1_find_node (structure, name);
729
730 if (root == NULL)
731 return;
732
733 p = root;
734 while (p)
735 {
736 if (mode == ASN1_PRINT_ALL)
737 {
738 for (k = 0; k < indent; k++)
739 fprintf (out, " ");
740 fprintf (out, "name:");
741 if (p->name)
742 fprintf (out, "%s ", p->name);
743 else
744 fprintf (out, "NULL ");
745 }
746 else
747 {
748 switch (type_field (p->type))
749 {
750 case TYPE_CONSTANT:
751 case TYPE_TAG:
752 case TYPE_SIZE:
753 break;
754 default:
755 for (k = 0; k < indent; k++)
756 fprintf (out, " ");
757 fprintf (out, "name:");
758 if (p->name)
759 fprintf (out, "%s ", p->name);
760 else
761 fprintf (out, "NULL ");
762 }
763 }
764
765 if (mode != ASN1_PRINT_NAME)
766 {
767 switch (type_field (p->type))
768 {
769 case TYPE_CONSTANT:
770 if (mode == ASN1_PRINT_ALL)
771 fprintf (out, "type:CONST");
772 break;
773 case TYPE_TAG:
774 if (mode == ASN1_PRINT_ALL)
775 fprintf (out, "type:TAG");
776 break;
777 case TYPE_SIZE:
778 if (mode == ASN1_PRINT_ALL)
779 fprintf (out, "type:SIZE");
780 break;
781 case TYPE_DEFAULT:
782 fprintf (out, "type:DEFAULT");
783 break;
784 case TYPE_NULL:
785 fprintf (out, "type:NULL");
786 break;
787 case TYPE_IDENTIFIER:
788 fprintf (out, "type:IDENTIFIER");
789 break;
790 case TYPE_INTEGER:
791 fprintf (out, "type:INTEGER");
792 break;
793 case TYPE_ENUMERATED:
794 fprintf (out, "type:ENUMERATED");
795 break;
796 case TYPE_TIME:
797 fprintf (out, "type:TIME");
798 break;
799 case TYPE_BOOLEAN:
800 fprintf (out, "type:BOOLEAN");
801 break;
802 case TYPE_SEQUENCE:
803 fprintf (out, "type:SEQUENCE");
804 break;
805 case TYPE_BIT_STRING:
806 fprintf (out, "type:BIT_STR");
807 break;
808 case TYPE_OCTET_STRING:
809 fprintf (out, "type:OCT_STR");
810 break;
811 case TYPE_GENERALSTRING:
812 fprintf (out, "type:GENERALSTRING");
813 break;
814 case TYPE_SEQUENCE_OF:
815 fprintf (out, "type:SEQ_OF");
816 break;
817 case TYPE_OBJECT_ID:
818 fprintf (out, "type:OBJ_ID");
819 break;
820 case TYPE_ANY:
821 fprintf (out, "type:ANY");
822 break;
823 case TYPE_SET:
824 fprintf (out, "type:SET");
825 break;
826 case TYPE_SET_OF:
827 fprintf (out, "type:SET_OF");
828 break;
829 case TYPE_CHOICE:
830 fprintf (out, "type:CHOICE");
831 break;
832 case TYPE_DEFINITIONS:
833 fprintf (out, "type:DEFINITIONS");
834 break;
835 default:
836 break;
837 }
838 }
839
840 if ((mode == ASN1_PRINT_NAME_TYPE_VALUE) || (mode == ASN1_PRINT_ALL))
841 {
842 switch (type_field (p->type))
843 {
844 case TYPE_CONSTANT:
845 if (mode == ASN1_PRINT_ALL)
846 if (p->value)
847 fprintf (out, " value:%s", p->value);
848 break;
849 case TYPE_TAG:
850 if (mode == ASN1_PRINT_ALL)
851 if (p->value)
852 fprintf (out, " value:%s", p->value);
853 break;
854 case TYPE_SIZE:
855 if (mode == ASN1_PRINT_ALL)
856 if (p->value)
857 fprintf (out, " value:%s", p->value);
858 break;
859 case TYPE_DEFAULT:
860 if (p->value)
861 fprintf (out, " value:%s", p->value);
862 else if (p->type & CONST_TRUE)
863 fprintf (out, " value:TRUE");
864 else if (p->type & CONST_FALSE)
865 fprintf (out, " value:FALSE");
866 break;
867 case TYPE_IDENTIFIER:
868 if (p->value)
869 fprintf (out, " value:%s", p->value);
870 break;
871 case TYPE_INTEGER:
872 if (p->value)
873 {
874 len2 = -1;
875 len = asn1_get_length_der (p->value, p->value_len, &len2);
876 fprintf (out, " value:0x");
877 if (len > 0)
878 for (k = 0; k < len; k++)
879 fprintf (out, "%02x", (p->value)[k + len2]);
880 }
881 break;
882 case TYPE_ENUMERATED:
883 if (p->value)
884 {
885 len2 = -1;
886 len = asn1_get_length_der (p->value, p->value_len, &len2);
887 fprintf (out, " value:0x");
888 if (len > 0)
889 for (k = 0; k < len; k++)
890 fprintf (out, "%02x", (p->value)[k + len2]);
891 }
892 break;
893 case TYPE_TIME:
894 if (p->value)
895 fprintf (out, " value:%s", p->value);
896 break;
897 case TYPE_BOOLEAN:
898 if (p->value)
899 {
900 if (p->value[0] == 'T')
901 fprintf (out, " value:TRUE");
902 else if (p->value[0] == 'F')
903 fprintf (out, " value:FALSE");
904 }
905 break;
906 case TYPE_BIT_STRING:
907 if (p->value)
908 {
909 len2 = -1;
910 len = asn1_get_length_der (p->value, p->value_len, &len2);
911 if (len > 0)
912 {
913 fprintf (out, " value(%i):",
914 (len - 1) * 8 - (p->value[len2]));
915 for (k = 1; k < len; k++)
916 fprintf (out, "%02x", (p->value)[k + len2]);
917 }
918 }
919 break;
920 case TYPE_OCTET_STRING:
921 if (p->value)
922 {
923 len2 = -1;
924 len = asn1_get_length_der (p->value, p->value_len, &len2);
925 fprintf (out, " value:");
926 if (len > 0)
927 for (k = 0; k < len; k++)
928 fprintf (out, "%02x", (p->value)[k + len2]);
929 }
930 break;
931 case TYPE_GENERALSTRING:
932 if (p->value)
933 {
934 len2 = -1;
935 len = asn1_get_length_der (p->value, p->value_len, &len2);
936 fprintf (out, " value:");
937 if (len > 0)
938 for (k = 0; k < len; k++)
939 fprintf (out, "%02x", (p->value)[k + len2]);
940 }
941 break;
942 case TYPE_OBJECT_ID:
943 if (p->value)
944 fprintf (out, " value:%s", p->value);
945 break;
946 case TYPE_ANY:
947 if (p->value)
948 {
949 len3 = -1;
950 len2 = asn1_get_length_der (p->value, p->value_len, &len3);
951 fprintf (out, " value:");
952 if (len2 > 0)
953 for (k = 0; k < len2; k++)
954 fprintf (out, "%02x", (p->value)[k + len3]);
955 }
956 break;
957 case TYPE_SET:
958 case TYPE_SET_OF:
959 case TYPE_CHOICE:
960 case TYPE_DEFINITIONS:
961 case TYPE_SEQUENCE_OF:
962 case TYPE_SEQUENCE:
963 case TYPE_NULL:
964 break;
965 default:
966 break;
967 }
968 }
969
970 if (mode == ASN1_PRINT_ALL)
971 {
972 if (p->type & 0x1FFFFF00)
973 {
974 fprintf (out, " attr:");
975 if (p->type & CONST_UNIVERSAL)
976 fprintf (out, "UNIVERSAL,");
977 if (p->type & CONST_PRIVATE)
978 fprintf (out, "PRIVATE,");
979 if (p->type & CONST_APPLICATION)
980 fprintf (out, "APPLICATION,");
981 if (p->type & CONST_EXPLICIT)
982 fprintf (out, "EXPLICIT,");
983 if (p->type & CONST_IMPLICIT)
984 fprintf (out, "IMPLICIT,");
985 if (p->type & CONST_TAG)
986 fprintf (out, "TAG,");
987 if (p->type & CONST_DEFAULT)
988 fprintf (out, "DEFAULT,");
989 if (p->type & CONST_TRUE)
990 fprintf (out, "TRUE,");
991 if (p->type & CONST_FALSE)
992 fprintf (out, "FALSE,");
993 if (p->type & CONST_LIST)
994 fprintf (out, "LIST,");
995 if (p->type & CONST_MIN_MAX)
996 fprintf (out, "MIN_MAX,");
997 if (p->type & CONST_OPTION)
998 fprintf (out, "OPTION,");
999 if (p->type & CONST_1_PARAM)
1000 fprintf (out, "1_PARAM,");
1001 if (p->type & CONST_SIZE)
1002 fprintf (out, "SIZE,");
1003 if (p->type & CONST_DEFINED_BY)
1004 fprintf (out, "DEF_BY,");
1005 if (p->type & CONST_GENERALIZED)
1006 fprintf (out, "GENERALIZED,");
1007 if (p->type & CONST_UTC)
1008 fprintf (out, "UTC,");
1009 if (p->type & CONST_SET)
1010 fprintf (out, "SET,");
1011 if (p->type & CONST_NOT_USED)
1012 fprintf (out, "NOT_USED,");
1013 if (p->type & CONST_ASSIGN)
1014 fprintf (out, "ASSIGNMENT,");
1015 }
1016 }
1017
1018 if (mode == ASN1_PRINT_ALL)
1019 {
1020 fprintf (out, "\n");
1021 }
1022 else
1023 {
1024 switch (type_field (p->type))
1025 {
1026 case TYPE_CONSTANT:
1027 case TYPE_TAG:
1028 case TYPE_SIZE:
1029 break;
1030 default:
1031 fprintf (out, "\n");
1032 }
1033 }
1034
1035 if (p->down)
1036 {
1037 p = p->down;
1038 indent += 2;
1039 }
1040 else if (p == root)
1041 {
1042 p = NULL;
1043 break;
1044 }
1045 else if (p->right)
1046 p = p->right;
1047 else
1048 {
1049 while (1)
1050 {
1051 p = _asn1_find_up (p);
1052 if (p == root)
1053 {
1054 p = NULL;
1055 break;
1056 }
1057 indent -= 2;
1058 if (p->right)
1059 {
1060 p = p->right;
1061 break;
1062 }
1063 }
1064 }
1065 }
1066}
1067
1068
1069
1070/**
1071 * asn1_number_of_elements - Counts the number of elements of a structure.
1072 * @element: pointer to the root of an ASN1 structure.
1073 * @name: the name of a sub-structure of ROOT.
1074 * @num: pointer to an integer where the result will be stored
1075 *
1076 * Counts the number of elements of a sub-structure called NAME with
1077 * names equal to "?1","?2", ...
1078 *
1079 * Returns:
1080 *
1081 * ASN1_SUCCESS: Creation OK.
1082 *
1083 * ASN1_ELEMENT_NOT_FOUND: NAME isn't known.
1084 *
1085 * ASN1_GENERIC_ERROR: Pointer num equal to NULL.
1086 *
1087 **/
1088asn1_retCode
1089asn1_number_of_elements (ASN1_TYPE element, const char *name, int *num)
1090{
1091 node_asn *node, *p;
1092
1093 if (num == NULL)
1094 return ASN1_GENERIC_ERROR;
1095
1096 *num = 0;
1097
1098 node = asn1_find_node (element, name);
1099 if (node == NULL)
1100 return ASN1_ELEMENT_NOT_FOUND;
1101
1102 p = node->down;
1103
1104 while (p)
1105 {
1106 if ((p->name) && (p->name[0] == '?'))
1107 (*num)++;
1108 p = p->right;
1109 }
1110
1111 return ASN1_SUCCESS;
1112}
1113
1114
1115/**
1116 * asn1_find_structure_from_oid - Locate structure defined by a specific OID.
1117 * @definitions: ASN1 definitions
1118 * @oidValue: value of the OID to search (e.g. "1.2.3.4").
1119 *
1120 * Search the structure that is defined just after an OID definition.
1121 *
1122 * Returns: NULL when OIDVALUE not found, otherwise the pointer to a
1123 * constant string that contains the element name defined just
1124 * after the OID.
1125 *
1126 **/
1127const char *
1128asn1_find_structure_from_oid (ASN1_TYPE definitions, const char *oidValue)
1129{
1130 char definitionsName[MAX_NAME_SIZE], name[2 * MAX_NAME_SIZE + 1];
1131 char value[MAX_NAME_SIZE];
1132 ASN1_TYPE p;
1133 int len;
1134 asn1_retCode result;
1135
1136 if ((definitions == ASN1_TYPE_EMPTY) || (oidValue == NULL))
1137 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1138
1139
1140 strcpy (definitionsName, definitions->name);
1141 strcat (definitionsName, ".");
1142
1143 /* search the OBJECT_ID into definitions */
1144 p = definitions->down;
1145 while (p)
1146 {
1147 if ((type_field (p->type) == TYPE_OBJECT_ID) &&
1148 (p->type & CONST_ASSIGN))
1149 {
1150 strcpy (name, definitionsName);
1151 strcat (name, p->name);
1152
1153 len = MAX_NAME_SIZE;
1154 result = asn1_read_value (definitions, name, value, &len);
1155
1156 if ((result == ASN1_SUCCESS) && (!strcmp (oidValue, value)))
1157 {
1158 p = p->right;
1159 if (p == NULL) /* reach the end of ASN1 definitions */
1160 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1161
1162 return p->name;
1163 }
1164 }
1165 p = p->right;
1166 }
1167
1168 return NULL; /* ASN1_ELEMENT_NOT_FOUND; */
1169}
1170
1171/**
1172 * asn1_copy_node:
1173 * @dst: Destination ASN1_TYPE node.
1174 * @dst_name: Field name in destination node.
1175 * @src: Source ASN1_TYPE node.
1176 * @src_name: Field name in source node.
1177 *
1178 * Create a deep copy of a ASN1_TYPE variable.
1179 *
1180 * Return value: Return ASN1_SUCCESS on success.
1181 **/
1182asn1_retCode
1183asn1_copy_node (ASN1_TYPE dst, const char *dst_name,
1184 ASN1_TYPE src, const char *src_name)
1185{
1186/* FIXME: rewrite using copy_structure().
1187 * It seems quite hard to do.
1188 */
1189 int result;
1190 ASN1_TYPE dst_node;
1191 void *data = NULL;
1192 int size = 0;
1193
1194 result = asn1_der_coding (src, src_name, NULL, &size, NULL);
1195 if (result != ASN1_MEM_ERROR)
1196 return result;
1197
1198 data = _asn1_malloc (size);
1199 if (data == NULL)
1200 return ASN1_MEM_ERROR;
1201
1202 result = asn1_der_coding (src, src_name, data, &size, NULL);
1203 if (result != ASN1_SUCCESS)
1204 {
1205 _asn1_free (data);
1206 return result;
1207 }
1208
1209 dst_node = asn1_find_node (dst, dst_name);
1210 if (dst_node == NULL)
1211 {
1212 _asn1_free (data);
1213 return ASN1_ELEMENT_NOT_FOUND;
1214 }
1215
1216 result = asn1_der_decoding (&dst_node, data, size, NULL);
1217
1218 _asn1_free (data);
1219
1220 return result;
1221}
diff --git a/src/daemon/https/minitasn1/structure.h b/src/daemon/https/minitasn1/structure.h
new file mode 100644
index 00000000..4c78391e
--- /dev/null
+++ b/src/daemon/https/minitasn1/structure.h
@@ -0,0 +1,23 @@
1
2/*************************************************/
3/* File: structure.h */
4/* Description: list of exported object by */
5/* "structure.c" */
6/*************************************************/
7
8#ifndef _STRUCTURE_H
9#define _STRUCTURE_H
10
11asn1_retCode _asn1_create_static_structure(node_asn *pointer,
12 char* output_file_name,char *vector_name);
13
14node_asn* _asn1_copy_structure3(node_asn *source_node);
15
16node_asn* _asn1_copy_structure2(node_asn *root,const char *source_name);
17
18node_asn * _asn1_add_node_only(unsigned int type);
19
20node_asn * _asn1_find_left(node_asn *node);
21
22#endif
23
diff --git a/src/daemon/https/opencdk/Makefile.am b/src/daemon/https/opencdk/Makefile.am
new file mode 100644
index 00000000..b69a151f
--- /dev/null
+++ b/src/daemon/https/opencdk/Makefile.am
@@ -0,0 +1,12 @@
1AM_CPPFLAGS = -I$(top_srcdir)/lib \
2-I$(top_srcdir)/lgl \
3-I$(GCRYPT_CPPFLAGS)
4
5noinst_LTLIBRARIES = libopencdk.la
6
7libopencdk_la_LDFLAGS = -lgcrypt
8
9libopencdk_la_SOURCES = armor.c filters.h main.c seskey.c types.h \
10 cipher.c kbnode.c main.h packet.h dummy.c sig-check.c verify.c \
11 compress.c keydb.c misc.c pubkey.c stream.c write-packet.c \
12 context.h literal.c new-packet.c read-packet.c stream.h opencdk.h
diff --git a/src/daemon/https/opencdk/README b/src/daemon/https/opencdk/README
new file mode 100644
index 00000000..2cf780e0
--- /dev/null
+++ b/src/daemon/https/opencdk/README
@@ -0,0 +1,5 @@
1This is a stripped down mirror of the files in OpenCDK
2src/. To avoid to link proc-packets.c, dummy.c is included.
3
4In Makefile.am libminiopencdk_la_SOURCES contains the list
5of all needed files.
diff --git a/src/daemon/https/opencdk/armor.c b/src/daemon/https/opencdk/armor.c
new file mode 100644
index 00000000..e95f7eb1
--- /dev/null
+++ b/src/daemon/https/opencdk/armor.c
@@ -0,0 +1,763 @@
1/* armor.c - Armor filters
2 * Copyright (C) 2001, 2002, 2003, 2007 Timo Schulz
3 * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4 *
5 * This file is part of OpenCDK.
6 *
7 * OpenCDK is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * OpenCDK is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * ChangeLog for basic BASE64 code (base64_encode, base64_decode):
18 * Original author: Eric S. Raymond (Fetchmail)
19 * Heavily modified by Brendan Cully <brendan@kublai.com> (Mutt)
20 * Modify the code for generic use by Timo Schulz <twoaday@freakmail.de>
21 */
22
23#ifdef HAVE_CONFIG_H
24# include <config.h>
25#endif
26#include <stdio.h>
27#include <string.h>
28#include <assert.h>
29#include <sys/stat.h>
30
31#include "opencdk.h"
32#include "main.h"
33#include "filters.h"
34
35#ifdef __MINGW32__
36# define LF "\r\n"
37#else
38# define LF "\n"
39#endif
40
41#define CRCINIT 0xB704CE
42
43#define BAD -1
44#define b64val(c) index64[(unsigned int)(c)]
45
46static u32 crc_table[] = {
47 0x000000, 0x864CFB, 0x8AD50D, 0x0C99F6, 0x93E6E1, 0x15AA1A, 0x1933EC,
48 0x9F7F17,
49 0xA18139, 0x27CDC2, 0x2B5434, 0xAD18CF, 0x3267D8, 0xB42B23, 0xB8B2D5,
50 0x3EFE2E,
51 0xC54E89, 0x430272, 0x4F9B84, 0xC9D77F, 0x56A868, 0xD0E493, 0xDC7D65,
52 0x5A319E,
53 0x64CFB0, 0xE2834B, 0xEE1ABD, 0x685646, 0xF72951, 0x7165AA, 0x7DFC5C,
54 0xFBB0A7,
55 0x0CD1E9, 0x8A9D12, 0x8604E4, 0x00481F, 0x9F3708, 0x197BF3, 0x15E205,
56 0x93AEFE,
57 0xAD50D0, 0x2B1C2B, 0x2785DD, 0xA1C926, 0x3EB631, 0xB8FACA, 0xB4633C,
58 0x322FC7,
59 0xC99F60, 0x4FD39B, 0x434A6D, 0xC50696, 0x5A7981, 0xDC357A, 0xD0AC8C,
60 0x56E077,
61 0x681E59, 0xEE52A2, 0xE2CB54, 0x6487AF, 0xFBF8B8, 0x7DB443, 0x712DB5,
62 0xF7614E,
63 0x19A3D2, 0x9FEF29, 0x9376DF, 0x153A24, 0x8A4533, 0x0C09C8, 0x00903E,
64 0x86DCC5,
65 0xB822EB, 0x3E6E10, 0x32F7E6, 0xB4BB1D, 0x2BC40A, 0xAD88F1, 0xA11107,
66 0x275DFC,
67 0xDCED5B, 0x5AA1A0, 0x563856, 0xD074AD, 0x4F0BBA, 0xC94741, 0xC5DEB7,
68 0x43924C,
69 0x7D6C62, 0xFB2099, 0xF7B96F, 0x71F594, 0xEE8A83, 0x68C678, 0x645F8E,
70 0xE21375,
71 0x15723B, 0x933EC0, 0x9FA736, 0x19EBCD, 0x8694DA, 0x00D821, 0x0C41D7,
72 0x8A0D2C,
73 0xB4F302, 0x32BFF9, 0x3E260F, 0xB86AF4, 0x2715E3, 0xA15918, 0xADC0EE,
74 0x2B8C15,
75 0xD03CB2, 0x567049, 0x5AE9BF, 0xDCA544, 0x43DA53, 0xC596A8, 0xC90F5E,
76 0x4F43A5,
77 0x71BD8B, 0xF7F170, 0xFB6886, 0x7D247D, 0xE25B6A, 0x641791, 0x688E67,
78 0xEEC29C,
79 0x3347A4, 0xB50B5F, 0xB992A9, 0x3FDE52, 0xA0A145, 0x26EDBE, 0x2A7448,
80 0xAC38B3,
81 0x92C69D, 0x148A66, 0x181390, 0x9E5F6B, 0x01207C, 0x876C87, 0x8BF571,
82 0x0DB98A,
83 0xF6092D, 0x7045D6, 0x7CDC20, 0xFA90DB, 0x65EFCC, 0xE3A337, 0xEF3AC1,
84 0x69763A,
85 0x578814, 0xD1C4EF, 0xDD5D19, 0x5B11E2, 0xC46EF5, 0x42220E, 0x4EBBF8,
86 0xC8F703,
87 0x3F964D, 0xB9DAB6, 0xB54340, 0x330FBB, 0xAC70AC, 0x2A3C57, 0x26A5A1,
88 0xA0E95A,
89 0x9E1774, 0x185B8F, 0x14C279, 0x928E82, 0x0DF195, 0x8BBD6E, 0x872498,
90 0x016863,
91 0xFAD8C4, 0x7C943F, 0x700DC9, 0xF64132, 0x693E25, 0xEF72DE, 0xE3EB28,
92 0x65A7D3,
93 0x5B59FD, 0xDD1506, 0xD18CF0, 0x57C00B, 0xC8BF1C, 0x4EF3E7, 0x426A11,
94 0xC426EA,
95 0x2AE476, 0xACA88D, 0xA0317B, 0x267D80, 0xB90297, 0x3F4E6C, 0x33D79A,
96 0xB59B61,
97 0x8B654F, 0x0D29B4, 0x01B042, 0x87FCB9, 0x1883AE, 0x9ECF55, 0x9256A3,
98 0x141A58,
99 0xEFAAFF, 0x69E604, 0x657FF2, 0xE33309, 0x7C4C1E, 0xFA00E5, 0xF69913,
100 0x70D5E8,
101 0x4E2BC6, 0xC8673D, 0xC4FECB, 0x42B230, 0xDDCD27, 0x5B81DC, 0x57182A,
102 0xD154D1,
103 0x26359F, 0xA07964, 0xACE092, 0x2AAC69, 0xB5D37E, 0x339F85, 0x3F0673,
104 0xB94A88,
105 0x87B4A6, 0x01F85D, 0x0D61AB, 0x8B2D50, 0x145247, 0x921EBC, 0x9E874A,
106 0x18CBB1,
107 0xE37B16, 0x6537ED, 0x69AE1B, 0xEFE2E0, 0x709DF7, 0xF6D10C, 0xFA48FA,
108 0x7C0401,
109 0x42FA2F, 0xC4B6D4, 0xC82F22, 0x4E63D9, 0xD11CCE, 0x575035, 0x5BC9C3,
110 0xDD8538
111};
112
113static const char *armor_begin[] = {
114 "BEGIN PGP MESSAGE",
115 "BEGIN PGP PUBLIC KEY BLOCK",
116 "BEGIN PGP PRIVATE KEY BLOCK",
117 "BEGIN PGP SIGNATURE",
118 NULL
119};
120
121static const char *armor_end[] = {
122 "END PGP MESSAGE",
123 "END PGP PUBLIC KEY BLOCK",
124 "END PGP PRIVATE KEY BLOCK",
125 "END PGP SIGNATURE",
126 NULL
127};
128
129static const char *valid_headers[] = {
130 "Comment",
131 "Version",
132 "MessageID",
133 "Hash",
134 "Charset",
135 NULL
136};
137
138static char b64chars[] =
139 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
140
141static int index64[128] = {
142 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
143 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
144 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
145 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
146 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
147 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
148 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
149 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1
150};
151
152
153/* encode a raw binary buffer to a null-terminated base64 strings */
154static int
155base64_encode (char *out, const byte * in, size_t len, size_t olen)
156{
157 if (!out || !in)
158 return CDK_Inv_Value;
159
160 while (len >= 3 && olen > 10)
161 {
162 *out++ = b64chars[in[0] >> 2];
163 *out++ = b64chars[((in[0] << 4) & 0x30) | (in[1] >> 4)];
164 *out++ = b64chars[((in[1] << 2) & 0x3c) | (in[2] >> 6)];
165 *out++ = b64chars[in[2] & 0x3f];
166 olen -= 4;
167 len -= 3;
168 in += 3;
169 }
170
171 /* clean up remainder */
172 if (len > 0 && olen > 4)
173 {
174 byte fragment = 0;
175 *out++ = b64chars[in[0] >> 2];
176 fragment = (in[0] << 4) & 0x30;
177 if (len > 1)
178 fragment |= in[1] >> 4;
179 *out++ = b64chars[fragment];
180 *out++ = (len < 2) ? '=' : b64chars[(in[1] << 2) & 0x3c];
181 *out++ = '=';
182 }
183 *out = '\0';
184 return 0;
185}
186
187
188/* Convert '\0'-terminated base64 string to raw byte buffer.
189 Returns length of returned buffer, or -1 on error. */
190static int
191base64_decode (byte * out, const char *in)
192{
193 size_t len;
194 byte digit1, digit2, digit3, digit4;
195
196 if (!out || !in)
197 return -1;
198
199 len = 0;
200 do
201 {
202 digit1 = in[0];
203 if (digit1 > 127 || b64val (digit1) == BAD)
204 return -1;
205 digit2 = in[1];
206 if (digit2 > 127 || b64val (digit2) == BAD)
207 return -1;
208 digit3 = in[2];
209 if (digit3 > 127 || ((digit3 != '=') && (b64val (digit3) == BAD)))
210 return -1;
211 digit4 = in[3];
212 if (digit4 > 127 || ((digit4 != '=') && (b64val (digit4) == BAD)))
213 return -1;
214 in += 4;
215
216 /* digits are already sanity-checked */
217 *out++ = (b64val (digit1) << 2) | (b64val (digit2) >> 4);
218 len++;
219 if (digit3 != '=')
220 {
221 *out++ = ((b64val (digit2) << 4) & 0xf0) | (b64val (digit3) >> 2);
222 len++;
223 if (digit4 != '=')
224 {
225 *out++ = ((b64val (digit3) << 6) & 0xc0) | b64val (digit4);
226 len++;
227 }
228 }
229 }
230 while (*in && digit4 != '=');
231
232 return len;
233}
234
235
236/* Return the compression algorithm in @r_zipalgo.
237 If the parameter is not set after execution,
238 the stream is not compressed. */
239static int
240compress_get_algo (cdk_stream_t inp, int *r_zipalgo)
241{
242 byte plain[512];
243 char buf[128];
244 int nread, pkttype;
245
246 *r_zipalgo = 0;
247 cdk_stream_seek (inp, 0);
248 while (!cdk_stream_eof (inp))
249 {
250 nread = _cdk_stream_gets (inp, buf, DIM (buf) - 1);
251 if (!nread || nread == -1)
252 break;
253 if (nread == 1 && !cdk_stream_eof (inp)
254 && (nread = _cdk_stream_gets (inp, buf, DIM (buf) - 1)) > 0)
255 {
256 base64_decode (plain, buf);
257 if (!(*plain & 0x80))
258 break;
259 pkttype = *plain & 0x40 ? (*plain & 0x3f) : ((*plain >> 2) & 0xf);
260 if (pkttype == CDK_PKT_COMPRESSED && r_zipalgo)
261 {
262 _cdk_log_debug ("armor compressed (algo=%d)\n", *(plain + 1));
263 *r_zipalgo = *(plain + 1);
264 }
265 break;
266 }
267 }
268 return 0;
269}
270
271
272static int
273check_armor (cdk_stream_t inp, int *r_zipalgo)
274{
275 char buf[4096];
276 size_t nread;
277 int check;
278
279 check = 0;
280 nread = cdk_stream_read (inp, buf, DIM (buf) - 1);
281 if (nread > 0)
282 {
283 buf[nread] = '\0';
284 if (strstr (buf, "-----BEGIN PGP"))
285 {
286 compress_get_algo (inp, r_zipalgo);
287 check = 1;
288 }
289 cdk_stream_seek (inp, 0);
290 }
291 return check;
292}
293
294
295static int
296is_armored (int ctb)
297{
298 int pkttype = 0;
299
300 if (!(ctb & 0x80))
301 return 1; /* invalid packet: assume it is armored */
302 pkttype = ctb & 0x40 ? (ctb & 0x3f) : ((ctb >> 2) & 0xf);
303 switch (pkttype)
304 {
305 case CDK_PKT_MARKER:
306 case CDK_PKT_SYMKEY_ENC:
307 case CDK_PKT_ONEPASS_SIG:
308 case CDK_PKT_PUBLIC_KEY:
309 case CDK_PKT_SECRET_KEY:
310 case CDK_PKT_PUBKEY_ENC:
311 case CDK_PKT_SIGNATURE:
312 case CDK_PKT_LITERAL:
313 case CDK_PKT_COMPRESSED:
314 case CDK_PKT_ENCRYPTED:
315 return 0; /* seems to be a regular packet: not armored */
316 }
317 return 1;
318}
319
320
321static u32
322update_crc (u32 crc, const byte * buf, size_t buflen)
323{
324 int j;
325
326 if (!crc)
327 crc = CRCINIT;
328
329 for (j = 0; j < buflen; j++)
330 crc = (crc << 8) ^ crc_table[0xff & ((crc >> 16) ^ buf[j])];
331 crc &= 0xffffff;
332 return crc;
333}
334
335
336static cdk_error_t
337armor_encode (void *opaque, FILE * in, FILE * out)
338{
339 armor_filter_t *afx = opaque;
340 struct stat statbuf;
341 char crcbuf[5], buf[128], raw[49];
342 byte crcbuf2[3];
343 size_t nread = 0;
344 const char *lf;
345
346 if (!afx)
347 return CDK_Inv_Value;
348 if (afx->idx < 0 || afx->idx > DIM (armor_begin) ||
349 afx->idx2 < 0 || afx->idx2 > DIM (armor_end))
350 return CDK_Inv_Value;
351
352 _cdk_log_debug ("armor filter: encode\n");
353
354 memset (crcbuf, 0, sizeof (crcbuf));
355
356 lf = afx->le ? afx->le : LF;
357 fprintf (out, "-----%s-----%s", armor_begin[afx->idx], lf);
358 fprintf (out, "Version: OpenPrivacy " PACKAGE_VERSION "%s", lf);
359 if (afx->hdrlines)
360 fwrite (afx->hdrlines, 1, strlen (afx->hdrlines), out);
361 fprintf (out, "%s", lf);
362
363 if (fstat (fileno (in), &statbuf))
364 return CDK_General_Error;
365
366 while (!feof (in))
367 {
368 nread = fread (raw, 1, DIM (raw) - 1, in);
369 if (!nread)
370 break;
371 if (ferror (in))
372 return CDK_File_Error;
373 afx->crc = update_crc (afx->crc, (byte *) raw, nread);
374 base64_encode (buf, (byte *) raw, nread, DIM (buf) - 1);
375 fprintf (out, "%s%s", buf, lf);
376 }
377
378 crcbuf2[0] = afx->crc >> 16;
379 crcbuf2[1] = afx->crc >> 8;
380 crcbuf2[2] = afx->crc;
381 crcbuf[0] = b64chars[crcbuf2[0] >> 2];
382 crcbuf[1] = b64chars[((crcbuf2[0] << 4) & 0x30) | (crcbuf2[1] >> 4)];
383 crcbuf[2] = b64chars[((crcbuf2[1] << 2) & 0x3c) | (crcbuf2[2] >> 6)];
384 crcbuf[3] = b64chars[crcbuf2[2] & 0x3f];
385 fprintf (out, "=%s%s", crcbuf, lf);
386 fprintf (out, "-----%s-----%s", armor_end[afx->idx2], lf);
387
388 return 0;
389}
390
391
392/**
393 * cdk_armor_filter_use:
394 * @inp: the stream to check
395 *
396 * Check if the stream contains armored data.
397 **/
398int
399cdk_armor_filter_use (cdk_stream_t inp)
400{
401 int c, check;
402 int zipalgo;
403
404 zipalgo = 0;
405 c = cdk_stream_getc (inp);
406 if (c == EOF)
407 return 0; /* EOF, doesn't matter whether armored or not */
408 cdk_stream_seek (inp, 0);
409 check = is_armored (c);
410 if (check)
411 {
412 check = check_armor (inp, &zipalgo);
413 if (zipalgo)
414 _cdk_stream_set_compress_algo (inp, zipalgo);
415 }
416 return check;
417}
418
419
420static int
421search_header (const char *buf, const char **array)
422{
423 const char *s;
424 int i;
425
426 if (strlen (buf) < 5 || strncmp (buf, "-----", 5))
427 return -1;
428 for (i = 0; (s = array[i]); i++)
429 {
430 if (!strncmp (s, buf + 5, strlen (s)))
431 return i;
432 }
433 return -1;
434}
435
436
437const char *
438_cdk_armor_get_lineend (void)
439{
440 return LF;
441}
442
443
444static cdk_error_t
445armor_decode (void *opaque, FILE * in, FILE * out)
446{
447 armor_filter_t *afx = opaque;
448 const char *s;
449 char buf[127];
450 byte raw[128], crcbuf[4];
451 u32 crc2 = 0;
452 size_t nread = 0;
453 int i, pgp_data = 0;
454 cdk_error_t rc = 0;
455
456 if (!afx)
457 return CDK_Inv_Value;
458
459 _cdk_log_debug ("armor filter: decode\n");
460
461 fseek (in, 0, SEEK_SET);
462 /* Search the begin of the message */
463 while (!feof (in) && !pgp_data)
464 {
465 s = fgets (buf, DIM (buf) - 1, in);
466 if (!s)
467 break;
468 afx->idx = search_header (buf, armor_begin);
469 if (afx->idx >= 0)
470 pgp_data = 1;
471 }
472
473 if (feof (in) || !pgp_data)
474 return CDK_Armor_Error; /* no data found */
475
476 /* Parse header until the empty line is reached */
477 while (!feof (in))
478 {
479 s = fgets (buf, DIM (buf) - 1, in);
480 if (!s)
481 return CDK_EOF;
482 if (strlen (s) == strlen (LF))
483 {
484 rc = 0;
485 break; /* empty line */
486 }
487 /* From RFC2440: OpenPGP should consider improperly formatted Armor
488 Headers to be corruption of the ASCII Armor. A colon and a single
489 space separate the key and value. */
490 if (!strstr (buf, ": "))
491 return CDK_Armor_Error;
492 rc = CDK_General_Error;
493 for (i = 0; (s = valid_headers[i]); i++)
494 {
495 if (!strncmp (s, buf, strlen (s)))
496 rc = 0;
497 }
498 if (rc)
499 {
500 /* From RFC2440: Unknown keys should be reported to the user,
501 but OpenPGP should continue to process the message. */
502 _cdk_log_info ("unknown header: `%s'\n", buf);
503 rc = 0;
504 }
505 }
506
507 /* Read the data body */
508 while (!feof (in))
509 {
510 s = fgets (buf, DIM (buf) - 1, in);
511 if (!s)
512 break;
513 buf[strlen (buf) - strlen (LF)] = '\0';
514 if (buf[0] == '=' && strlen (s) == 5)
515 { /* CRC */
516 memset (crcbuf, 0, sizeof (crcbuf));
517 base64_decode (crcbuf, buf + 1);
518 crc2 = (crcbuf[0] << 16) | (crcbuf[1] << 8) | crcbuf[2];
519 break; /* stop here */
520 }
521 else
522 {
523 nread = base64_decode (raw, buf);
524 if (nread == -1 || nread == 0)
525 break;
526 afx->crc = update_crc (afx->crc, raw, nread);
527 fwrite (raw, 1, nread, out);
528 }
529 }
530
531 /* Search the tail of the message */
532 s = fgets (buf, DIM (buf) - 1, in);
533 if (s)
534 {
535 buf[strlen (buf) - strlen (LF)] = '\0';
536 rc = CDK_General_Error;
537 afx->idx2 = search_header (buf, armor_end);
538 if (afx->idx2 >= 0)
539 rc = 0;
540 }
541
542 /* This catches error when no tail was found or the header is
543 different then the tail line. */
544 if (rc || afx->idx != afx->idx2)
545 rc = CDK_Armor_Error;
546
547 afx->crc_okay = (afx->crc == crc2) ? 1 : 0;
548 if (!afx->crc_okay && !rc)
549 {
550 _cdk_log_debug ("file crc=%08lX afx_crc=%08lX\n", crc2, afx->crc);
551 rc = CDK_Armor_CRC_Error;
552 }
553
554 return rc;
555}
556
557
558/**
559 * cdk_file_armor:
560 * @hd: Handle
561 * @file: Name of the file to protect.
562 * @output: Output filename.
563 *
564 * Protect a file with ASCII armor.
565 **/
566cdk_error_t
567cdk_file_armor (cdk_ctx_t hd, const char *file, const char *output)
568{
569 cdk_stream_t inp, out;
570 cdk_error_t rc;
571
572 rc = _cdk_check_args (hd->opt.overwrite, file, output);
573 if (rc)
574 return rc;
575
576 rc = cdk_stream_open (file, &inp);
577 if (rc)
578 return rc;
579
580 rc = cdk_stream_new (output, &out);
581 if (rc)
582 {
583 cdk_stream_close (inp);
584 return rc;
585 }
586
587 cdk_stream_set_armor_flag (out, CDK_ARMOR_MESSAGE);
588 if (hd->opt.compress)
589 rc = cdk_stream_set_compress_flag (out, hd->compress.algo,
590 hd->compress.level);
591 if (!rc)
592 rc = cdk_stream_set_literal_flag (out, 0, file);
593 if (!rc)
594 rc = cdk_stream_kick_off (inp, out);
595 if (!rc)
596 rc = _cdk_stream_get_errno (out);
597
598 cdk_stream_close (out);
599 cdk_stream_close (inp);
600 return rc;
601}
602
603
604/**
605 * cdk_file_dearmor:
606 * @file: Name of the file to unprotect.
607 * @output: Output filename.
608 *
609 * Remove ASCII armor from a file.
610 **/
611cdk_error_t
612cdk_file_dearmor (const char *file, const char *output)
613{
614 cdk_stream_t inp, out;
615 cdk_error_t rc;
616 int zipalgo;
617
618 rc = _cdk_check_args (1, file, output);
619 if (rc)
620 return rc;
621
622 rc = cdk_stream_open (file, &inp);
623 if (rc)
624 return rc;
625
626 rc = cdk_stream_create (output, &out);
627 if (rc)
628 {
629 cdk_stream_close (inp);
630 return rc;
631 }
632
633 if (cdk_armor_filter_use (inp))
634 {
635 rc = cdk_stream_set_literal_flag (inp, 0, NULL);
636 zipalgo = cdk_stream_is_compressed (inp);
637 if (zipalgo)
638 rc = cdk_stream_set_compress_flag (inp, zipalgo, 0);
639 if (!rc)
640 rc = cdk_stream_set_armor_flag (inp, 0);
641 if (!rc)
642 rc = cdk_stream_kick_off (inp, out);
643 if (!rc)
644 rc = _cdk_stream_get_errno (inp);
645 }
646
647 cdk_stream_close (inp);
648 cdk_stream_close (out);
649 return rc;
650}
651
652
653int
654_cdk_filter_armor (void *opaque, int ctl, FILE * in, FILE * out)
655{
656 if (ctl == STREAMCTL_READ)
657 return armor_decode (opaque, in, out);
658 else if (ctl == STREAMCTL_WRITE)
659 return armor_encode (opaque, in, out);
660 else if (ctl == STREAMCTL_FREE)
661 {
662 armor_filter_t *afx = opaque;
663 if (afx)
664 {
665 _cdk_log_debug ("free armor filter\n");
666 afx->idx = afx->idx2 = 0;
667 afx->crc = afx->crc_okay = 0;
668 return 0;
669 }
670 }
671 return CDK_Inv_Mode;
672}
673
674
675/**
676 * cdk_armor_encode_buffer:
677 * @inbuf: the raw input buffer
678 * @inlen: raw buffer len
679 * @outbuf: the destination buffer for the base64 output
680 * @outlen: destination buffer len
681 * @nwritten: actual length of the base64 data
682 * @type: the base64 file type.
683 *
684 * Encode the given buffer into base64 format.
685 **/
686cdk_error_t
687cdk_armor_encode_buffer (const byte * inbuf, size_t inlen,
688 char *outbuf, size_t outlen,
689 size_t * nwritten, int type)
690{
691 const char *head, *tail, *le;
692 byte tempbuf[48];
693 char tempout[128];
694 size_t pos, off, len, rest;
695
696 if (!inbuf || !nwritten)
697 return CDK_Inv_Value;
698 if (type > CDK_ARMOR_SIGNATURE)
699 return CDK_Inv_Mode;
700
701 head = armor_begin[type];
702 tail = armor_end[type];
703 le = _cdk_armor_get_lineend ();
704 pos = strlen (head) + 10 + 2 + 2 + strlen (tail) + 10 + 2 + 5 + 2;
705 /* The output data is 4/3 times larger, plus a line end for each line. */
706 pos += (4 * inlen / 3) + 2 * (4 * inlen / 3 / 64);
707
708 if (outbuf && outlen < pos)
709 return CDK_Too_Short;
710
711 /* Only return the size of the output. */
712 if (!outbuf)
713 {
714 *nwritten = pos;
715 return 0;
716 }
717
718 pos = 0;
719 memset (outbuf, 0, outlen);
720 memcpy (outbuf + pos, "-----", 5);
721 pos += 5;
722 memcpy (outbuf + pos, head, strlen (head));
723 pos += strlen (head);
724 memcpy (outbuf + pos, "-----", 5);
725 pos += 5;
726 memcpy (outbuf + pos, le, strlen (le));
727 pos += strlen (le);
728 memcpy (outbuf + pos, le, strlen (le));
729 pos += strlen (le);
730 rest = inlen;
731 for (off = 0; off < inlen;)
732 {
733 if (rest > 48)
734 {
735 memcpy (tempbuf, inbuf + off, 48);
736 off += 48;
737 len = 48;
738 }
739 else
740 {
741 memcpy (tempbuf, inbuf + off, rest);
742 off += rest;
743 len = rest;
744 }
745 rest -= len;
746 base64_encode (tempout, tempbuf, len, DIM (tempout) - 1);
747 memcpy (outbuf + pos, tempout, strlen (tempout));
748 pos += strlen (tempout);
749 memcpy (outbuf + pos, le, strlen (le));
750 pos += strlen (le);
751 }
752
753 memcpy (outbuf + pos, "-----", 5);
754 pos += 5;
755 memcpy (outbuf + pos, tail, strlen (tail));
756 pos += strlen (tail);
757 memcpy (outbuf + pos, "-----", 5);
758 pos += 5;
759 memcpy (outbuf + pos, le, strlen (le));
760 pos += strlen (le);
761 *nwritten = pos;
762 return 0;
763}
diff --git a/src/daemon/https/opencdk/cipher.c b/src/daemon/https/opencdk/cipher.c
new file mode 100644
index 00000000..2ce22eb3
--- /dev/null
+++ b/src/daemon/https/opencdk/cipher.c
@@ -0,0 +1,528 @@
1/* cipher.c - Cipher filters
2 * Copyright (C) 2002, 2003, 2007 Timo Schulz
3 * Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation
4 *
5 * This file is part of OpenCDK.
6 *
7 * OpenCDK is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * OpenCDK is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17#ifdef HAVE_CONFIG_H
18# include <config.h>
19#endif
20#include <stdio.h>
21#include <assert.h>
22#include <sys/stat.h>
23
24#include "opencdk.h"
25#include "main.h"
26#include "filters.h"
27
28
29/* The maximal cipher block size in octets. */
30#define MAX_CIPHER_BLKSIZE 16
31
32
33static off_t
34fp_get_length (FILE * fp)
35{
36 struct stat statbuf;
37
38 if (fstat (fileno (fp), &statbuf))
39 return (off_t) - 1;
40 return statbuf.st_size;
41}
42
43
44static cdk_error_t
45hash_encode (void *opaque, FILE * in, FILE * out)
46{
47 md_filter_t *mfx = opaque;
48 byte buf[BUFSIZE];
49 gcry_error_t err;
50 int nread;
51
52 if (!mfx)
53 return CDK_Inv_Value;
54
55 _cdk_log_debug ("hash filter: encode algo=%d\n", mfx->digest_algo);
56
57 if (!mfx->md)
58 {
59 err = gcry_md_open (&mfx->md, mfx->digest_algo, 0);
60 if (err)
61 return map_gcry_error (err);
62 }
63
64 while (!feof (in))
65 {
66 nread = fread (buf, 1, BUFSIZE, in);
67 if (!nread)
68 break;
69 gcry_md_write (mfx->md, buf, nread);
70 }
71
72 wipemem (buf, sizeof (buf));
73 return 0;
74}
75
76
77cdk_error_t
78_cdk_filter_hash (void *opaque, int ctl, FILE * in, FILE * out)
79{
80 if (ctl == STREAMCTL_READ)
81 return hash_encode (opaque, in, out);
82 else if (ctl == STREAMCTL_FREE)
83 {
84 md_filter_t *mfx = opaque;
85 if (mfx)
86 {
87 _cdk_log_debug ("free hash filter\n");
88 gcry_md_close (mfx->md);
89 mfx->md = NULL;
90 return 0;
91 }
92 }
93 return CDK_Inv_Mode;
94}
95
96
97static cdk_error_t
98write_header (cipher_filter_t * cfx, FILE * out)
99{
100 cdk_pkt_encrypted_t ed;
101 cdk_packet_t pkt;
102 cdk_error_t rc;
103 cdk_dek_t dek = cfx->dek;
104 byte temp[MAX_CIPHER_BLKSIZE + 2];
105 size_t blocksize;
106 int use_mdc, nprefix;
107 gcry_error_t err;
108
109 blocksize = gcry_cipher_get_algo_blklen (dek->algo);
110 if (blocksize < 8 || blocksize > 16)
111 return CDK_Inv_Algo;
112
113 /* It might be possible the receiver does not understand the MDC
114 output and thus we offer to supress the MDC packet. */
115 use_mdc = dek->use_mdc;
116 if (blocksize == 8)
117 use_mdc = 0;
118
119 /* We need to increase the data length because the MDC packet will
120 be also included. It has a fixed length of 22 octets. */
121 if (use_mdc && cfx->datalen)
122 cfx->datalen += 22;
123
124 cdk_pkt_alloc (&pkt, CDK_PKT_ENCRYPTED_MDC);
125 ed = pkt->pkt.encrypted;
126 if (!cfx->blkmode.on)
127 {
128 ed->len = cfx->datalen;
129 ed->extralen = blocksize + 2;
130 }
131 else
132 cfx->blkmode.nleft = DEF_BLOCKSIZE;
133
134 if (use_mdc)
135 {
136 ed->mdc_method = GCRY_MD_SHA1;
137 err = gcry_md_open (&cfx->mdc, GCRY_MD_SHA1, 0);
138 if (err)
139 return map_gcry_error (err);
140 }
141
142 /* When we use partial bodies, the MDC feature or a blocksize
143 larger than 8, we force the use of the new packet format. */
144 if (cfx->blkmode.on || use_mdc || blocksize != 8)
145 pkt->old_ctb = 0;
146 else
147 pkt->old_ctb = 1;
148 pkt->pkttype = use_mdc ? CDK_PKT_ENCRYPTED_MDC : CDK_PKT_ENCRYPTED;
149 rc = _cdk_pkt_write_fp (out, pkt);
150 cdk_pkt_release (pkt);
151 if (rc)
152 return rc;
153
154 nprefix = blocksize;
155 gcry_randomize (temp, nprefix, GCRY_STRONG_RANDOM);
156 temp[nprefix] = temp[nprefix - 2];
157 temp[nprefix + 1] = temp[nprefix - 1];
158 err = gcry_cipher_open (&cfx->hd, dek->algo, GCRY_CIPHER_MODE_CFB,
159 use_mdc ? 0 : GCRY_CIPHER_ENABLE_SYNC);
160 if (err)
161 return map_gcry_error (err);
162 err = gcry_cipher_setiv (cfx->hd, NULL, 0);
163 if (err)
164 return map_gcry_error (err);
165 err = gcry_cipher_setkey (cfx->hd, dek->key, dek->keylen);
166 if (err)
167 return map_gcry_error (err);
168 if (cfx->mdc)
169 gcry_md_write (cfx->mdc, temp, nprefix + 2);
170 gcry_cipher_encrypt (cfx->hd, temp, nprefix + 2, NULL, 0);
171 gcry_cipher_sync (cfx->hd);
172 fwrite (temp, 1, nprefix + 2, out);
173 if (cfx->blkmode.on)
174 {
175 cfx->blkmode.nleft -= (nprefix + 2);
176 if (use_mdc)
177 cfx->blkmode.nleft--; /* 1 byte version */
178 }
179 return rc;
180}
181
182
183static cdk_error_t
184write_mdc_packet (FILE * out, cipher_filter_t * cfx)
185{
186 byte pktdata[22];
187 int dlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
188
189 if (!out || !cfx)
190 return CDK_Inv_Value;
191 if (dlen != 20)
192 return CDK_Inv_Algo;
193
194 /* We must hash the prefix of the MDC packet here */
195 pktdata[0] = 0xD3;
196 pktdata[1] = 0x14;
197 gcry_md_write (cfx->mdc, pktdata, 2);
198 gcry_md_final (cfx->mdc);
199 memcpy (pktdata + 2, gcry_md_read (cfx->mdc, GCRY_MD_SHA1), dlen);
200 gcry_cipher_encrypt (cfx->hd, pktdata, dlen + 2, NULL, 0);
201 fwrite (pktdata, 1, dlen + 2, out);
202 wipemem (pktdata, sizeof (pktdata));
203 return 0;
204}
205
206
207static inline int
208num2bits (size_t n)
209{
210 size_t i;
211
212 for (i = 0; n > 1; i++)
213 n >>= 1;
214 return i;
215}
216
217
218static cdk_error_t
219write_partial_block (FILE * in, FILE * out, off_t * r_len,
220 cipher_filter_t * cfx)
221{
222 gcry_error_t err;
223 byte buf[DEF_BLOCKSIZE];
224 size_t n;
225 int nread;
226
227 if (!out || !cfx)
228 return CDK_Inv_Value;
229
230 if (!cfx->blkmode.nleft && *r_len > 0)
231 {
232 if (*r_len > DEF_BLOCKSIZE)
233 {
234 /*_cdk_log_debug ("write_partial_block: size %lu block %d\n",
235 *r_len, DEF_BLOCKSIZE);*/
236 fputc ((0xE0 | DEF_BLOCKBITS), out);
237 cfx->blkmode.nleft = DEF_BLOCKSIZE;
238 (*r_len) -= DEF_BLOCKSIZE;
239 }
240 else if (*r_len > 512)
241 {
242 n = num2bits (*r_len);
243 cfx->blkmode.nleft = (1 << n);
244 /*_cdk_log_debug ("write_partial_block: size %lu bits %d block %d\n",
245 *r_len, n, (1<<n));*/
246 fputc ((0xE0 | n), out);
247 (*r_len) -= cfx->blkmode.nleft;
248 }
249 else
250 {
251 size_t pktlen = *r_len;
252
253 /* If we use the MDC mode, we need to increase the final
254 partial body length to hold the mdc packet itself. */
255 if (cfx->mdc)
256 pktlen += 22;
257
258 if (pktlen < 192)
259 fputc (pktlen, out);
260 else if (pktlen < 8384)
261 {
262 pktlen -= 192;
263 fputc ((pktlen / 256) + 192, out);
264 fputc ((pktlen % 256), out);
265 }
266 cfx->blkmode.nleft = pktlen;
267 /*_cdk_log_debug ("write_partial_block: end %d block\n", pktlen);*/
268 (*r_len) -= pktlen;
269 }
270 }
271 else
272 (*r_len) -= cfx->blkmode.nleft;
273
274 n = cfx->blkmode.nleft < DIM (buf) ? cfx->blkmode.nleft : DIM (buf);
275 nread = fread (buf, 1, n, in);
276 if (!nread)
277 return CDK_EOF;
278 if (cfx->mdc)
279 gcry_md_write (cfx->mdc, buf, nread);
280 err = gcry_cipher_encrypt (cfx->hd, buf, nread, NULL, 0);
281 if (err)
282 return map_gcry_error (err);
283 fwrite (buf, 1, nread, out);
284 cfx->blkmode.nleft -= nread;
285 return 0;
286}
287
288
289static cdk_error_t
290cipher_encode_file (void *opaque, FILE * in, FILE * out)
291{
292 cipher_filter_t *cfx = opaque;
293 byte buf[BUFSIZE];
294 off_t len, len2;
295 int nread;
296 cdk_error_t rc;
297
298 if (!cfx || !in || !out)
299 return CDK_Inv_Value;
300
301 len = len2 = fp_get_length (in);
302 if (len == (off_t) - 1)
303 return CDK_File_Error;
304 while (!feof (in))
305 {
306 if (cfx->blkmode.on)
307 {
308 rc = write_partial_block (in, out, &len2, cfx);
309 if (rc == CDK_EOF)
310 break;
311 if (rc)
312 {
313 wipemem (buf, sizeof (buf));
314 return rc;
315 }
316 continue;
317 }
318 nread = fread (buf, 1, DIM (buf), in);
319 if (!nread)
320 break;
321 if (cfx->mdc)
322 gcry_md_write (cfx->mdc, buf, nread);
323 gcry_cipher_encrypt (cfx->hd, buf, nread, NULL, 0);
324 fwrite (buf, 1, nread, out);
325 }
326 if (cfx->mdc)
327 rc = write_mdc_packet (out, cfx);
328 else
329 rc = 0;
330
331 wipemem (buf, sizeof (buf));
332 return rc;
333}
334
335
336static cdk_error_t
337read_header (cipher_filter_t * cfx, FILE * in)
338{
339 cdk_dek_t dek;
340 byte temp[32];
341 int blocksize, nprefix;
342 int i, c;
343 gcry_error_t err;
344
345 if (!cfx || !in)
346 return CDK_Inv_Value;
347
348 dek = cfx->dek;
349 blocksize = gcry_cipher_get_algo_blklen (dek->algo);
350 if (blocksize < 8 || blocksize > 16)
351 return CDK_Inv_Algo;
352
353 nprefix = blocksize;
354 if (cfx->datalen > 0 && cfx->datalen < (nprefix + 2))
355 return CDK_Inv_Value;
356 if (cfx->mdc_method)
357 {
358 err = gcry_md_open (&cfx->mdc, cfx->mdc_method, 0);
359 if (err)
360 return map_gcry_error (err);
361 }
362 err = gcry_cipher_open (&cfx->hd, dek->algo, GCRY_CIPHER_MODE_CFB,
363 cfx->mdc_method ? 0 : GCRY_CIPHER_ENABLE_SYNC);
364 if (err)
365 return map_gcry_error (err);
366 err = gcry_cipher_setiv (cfx->hd, NULL, 0);
367 if (err)
368 return map_gcry_error (err);
369 err = gcry_cipher_setkey (cfx->hd, dek->key, dek->keylen);
370 if (err)
371 return map_gcry_error (err);
372
373 for (i = 0; i < (nprefix + 2); i++)
374 {
375 c = fgetc (in);
376 if (c == EOF)
377 return CDK_File_Error;
378 temp[i] = c;
379 }
380 gcry_cipher_decrypt (cfx->hd, temp, nprefix + 2, NULL, 0);
381 gcry_cipher_sync (cfx->hd);
382 i = nprefix;
383 if (temp[i - 2] != temp[i] || temp[i - 1] != temp[i + 1])
384 return CDK_Chksum_Error;
385 if (cfx->mdc)
386 gcry_md_write (cfx->mdc, temp, nprefix + 2);
387 if (cfx->blkmode.on)
388 cfx->blkmode.size -= (nprefix + 2);
389 return 0;
390}
391
392
393static cdk_error_t
394finalize_mdc (gcry_md_hd_t md, const byte * buf, size_t nread)
395{
396 byte mdcbuf[20];
397 int dlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
398 cdk_error_t rc;
399
400 if (dlen != 20)
401 return CDK_Inv_Algo;
402
403 if (buf[nread - dlen - 2] == 0xD3 && buf[nread - dlen - 1] == 0x14)
404 {
405 gcry_md_write (md, buf, nread - dlen);
406 gcry_md_final (md);
407 memcpy (mdcbuf, gcry_md_read (md, GCRY_MD_SHA1), dlen);
408 if (memcmp (mdcbuf, buf + nread - dlen, dlen))
409 rc = CDK_Bad_MDC;
410 else
411 rc = CDK_Success;
412 wipemem (mdcbuf, sizeof (mdcbuf));
413 return rc;
414 }
415
416 return CDK_Inv_Packet;
417}
418
419
420static cdk_error_t
421cipher_decode_file (void *opaque, FILE * in, FILE * out)
422{
423 cipher_filter_t *cfx = opaque;
424 cdk_error_t rc;
425 byte buf[BUFSIZE];
426 int nread, nreq;
427
428 if (!cfx || !in || !out)
429 return CDK_Inv_Value;
430
431 while (!feof (in))
432 {
433 /*_cdk_log_debug ("partial on=%d size=%lu\n",
434 cfx->blkmode.on, cfx->blkmode.size);*/
435 nreq = cfx->blkmode.on ? cfx->blkmode.size : DIM (buf);
436 nread = fread (buf, 1, nreq, in);
437 if (!nread)
438 break;
439 gcry_cipher_decrypt (cfx->hd, buf, nread, NULL, 0);
440 if (feof (in) && cfx->mdc)
441 {
442 rc = finalize_mdc (cfx->mdc, buf, nread);
443 if (rc)
444 {
445 wipemem (buf, sizeof (buf));
446 return rc;
447 }
448 /* We need to correct the size here to avoid the MDC
449 packet will be written to the output. */
450 nread -= 22;
451 }
452 else if (cfx->mdc)
453 gcry_md_write (cfx->mdc, buf, nread);
454 fwrite (buf, 1, nread, out);
455 if (cfx->blkmode.on)
456 {
457 cfx->blkmode.size = _cdk_pkt_read_len (in, &cfx->blkmode.on);
458 if (cfx->blkmode.size == (size_t) EOF)
459 return CDK_Inv_Packet;
460 }
461 }
462
463 wipemem (buf, sizeof (buf));
464 return 0;
465}
466
467
468static cdk_error_t
469cipher_decode (void *opaque, FILE * in, FILE * out)
470{
471 cipher_filter_t *cfx = opaque;
472 cdk_error_t rc;
473
474 _cdk_log_debug ("cipher filter: decode\n");
475
476 if (!cfx || !in || !out)
477 return CDK_Inv_Value;
478
479 rc = read_header (cfx, in);
480 if (!rc)
481 rc = cipher_decode_file (cfx, in, out);
482 return rc;
483}
484
485
486static cdk_error_t
487cipher_encode (void *opaque, FILE * in, FILE * out)
488{
489 cipher_filter_t *cfx = opaque;
490 cdk_error_t rc;
491
492 _cdk_log_debug ("cipher filter: encode\n");
493
494 if (!cfx || !in || !out)
495 return CDK_Inv_Value;
496
497 cfx->datalen = fp_get_length (in);
498 if (cfx->datalen < BUFSIZE && cfx->blkmode.on)
499 cfx->blkmode.on = 0;
500 rc = write_header (cfx, out);
501 if (!rc)
502 rc = cipher_encode_file (cfx, in, out);
503 return rc;
504}
505
506
507cdk_error_t
508_cdk_filter_cipher (void *opaque, int ctl, FILE * in, FILE * out)
509{
510 if (ctl == STREAMCTL_READ)
511 return cipher_decode (opaque, in, out);
512 else if (ctl == STREAMCTL_WRITE)
513 return cipher_encode (opaque, in, out);
514 else if (ctl == STREAMCTL_FREE)
515 {
516 cipher_filter_t *cfx = opaque;
517 if (cfx)
518 {
519 _cdk_log_debug ("free cipher filter\n");
520 gcry_md_close (cfx->mdc);
521 cfx->mdc = NULL;
522 gcry_cipher_close (cfx->hd);
523 cfx->hd = NULL;
524 return 0;
525 }
526 }
527 return CDK_Inv_Mode;
528}
diff --git a/src/daemon/https/opencdk/compress.c b/src/daemon/https/opencdk/compress.c
new file mode 100644
index 00000000..a984f38d
--- /dev/null
+++ b/src/daemon/https/opencdk/compress.c
@@ -0,0 +1,238 @@
1/* compress.c - Compression filters
2 * Copyright (C) 2002, 2003 Timo Schulz
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation
4 *
5 * This file is part of OpenCDK.
6 *
7 * OpenCDK is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * OpenCDK is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17#ifdef HAVE_CONFIG_H
18# include <config.h>
19#endif
20#include <stdio.h>
21#include <time.h>
22#ifdef HAVE_LIBZ
23# include <zlib.h>
24#endif
25
26#include "opencdk.h"
27#include "main.h"
28#include "filters.h"
29
30#ifdef HAVE_LIBZ
31static int
32compress_data (z_stream * zs, int flush, byte * inbuf, size_t insize,
33 FILE * out)
34{
35 int nbytes, zrc;
36 byte buf[4096];
37
38 zs->next_in = inbuf;
39 zs->avail_in = insize;
40
41 do
42 {
43 zs->next_out = buf;
44 zs->avail_out = DIM (buf);
45
46 zrc = deflate (zs, flush);
47 if (zrc == Z_STREAM_END && flush == Z_FINISH)
48 ;
49 else if (zrc != Z_OK)
50 break;
51 nbytes = DIM (buf) - zs->avail_out;
52 fwrite (buf, 1, nbytes, out);
53 }
54 while (zs->avail_out == 0 || (flush == Z_FINISH && zrc != Z_STREAM_END));
55 return zrc;
56}
57
58
59static int
60decompress_data (compress_filter_t * zfx, z_stream * zs,
61 FILE * in, size_t * ret_len)
62{
63 int nread, nold;
64 int rc, zrc;
65
66 rc = 0;
67 nread = 0;
68 while (zs->avail_out != 0)
69 {
70 if (!zs->avail_in)
71 {
72 nread = fread (zfx->inbuf, 1, zfx->inbufsize, in);
73 zs->next_in = zfx->inbuf;
74 zs->avail_in = nread;
75 }
76 nold = zs->avail_out;
77 zrc = inflate (zs, Z_SYNC_FLUSH);
78 if (zrc != Z_OK && zrc != Z_STREAM_END)
79 {
80 rc = CDK_Zlib_Error;
81 break;
82 }
83 *ret_len = zfx->outbufsize - zs->avail_out;
84 if (nold == zs->avail_out)
85 break;
86 if (zrc == Z_STREAM_END)
87 {
88 rc = EOF; /* eof */
89 break;
90 }
91 }
92 if (!nread && feof (in))
93 rc = -1;
94 return rc;
95}
96
97
98static cdk_error_t
99compress_decode (void *opaque, FILE * in, FILE * out)
100{
101 compress_filter_t *zfx = opaque;
102 z_stream *zs;
103 size_t nbytes;
104 int zrc;
105 cdk_error_t rc = 0;
106
107 _cdk_log_debug ("compress filter: decode (algo=%d)\n", zfx->algo);
108
109 if (!zfx || !in || !out)
110 return CDK_Inv_Value;
111
112 zs = cdk_calloc (1, sizeof *zs);
113 if (!zs)
114 return CDK_Out_Of_Core;
115 if (zfx->algo == CDK_COMPRESS_ZIP)
116 zrc = inflateInit2 (zs, -13);
117 else
118 zrc = inflateInit (zs);
119 if (zrc != Z_OK)
120 return CDK_Zlib_Error;
121
122 zfx->outbufsize = 8192;
123 zfx->inbufsize = 2048;
124 memset (zfx->inbuf, 0, sizeof zfx->inbuf);
125 zs->avail_in = 0;
126
127 nbytes = 0;
128 while (rc != -1)
129 {
130 zs->next_out = zfx->outbuf;
131 zs->avail_out = 8192;
132 rc = decompress_data (zfx, zs, in, &nbytes);
133 fwrite (zfx->outbuf, 1, nbytes, out);
134 }
135 inflateEnd (zs);
136 cdk_free (zs);
137 if (rc == CDK_EOF)
138 rc = 0;
139 return rc;
140}
141
142
143static cdk_error_t
144compress_encode (void *opaque, FILE * in, FILE * out)
145{
146 compress_filter_t *zfx = opaque;
147 z_stream *zs;
148 struct cdk_pkt_compressed_s cd;
149 struct cdk_packet_s pkt;
150 int zrc, nread;
151 cdk_error_t rc;
152
153 _cdk_log_debug ("compress filter: encode\n");
154
155 if (!zfx || !in || !out)
156 return CDK_Inv_Value;
157
158 if (!zfx->algo)
159 zfx->algo = CDK_COMPRESS_ZIP;
160
161 memset (&cd, 0, sizeof (cd));
162 cd.len = 0;
163 cd.algorithm = zfx->algo;
164 pkt.pkttype = CDK_PKT_COMPRESSED;
165 pkt.pkt.compressed = &cd;
166 rc = _cdk_pkt_write_fp (out, &pkt);
167 if (rc)
168 return rc;
169
170 zs = cdk_calloc (1, sizeof *zs);
171 if (!zs)
172 return CDK_Out_Of_Core;
173 if (zfx->algo == CDK_COMPRESS_ZIP)
174 rc = deflateInit2 (zs, zfx->level, Z_DEFLATED, -13, 8,
175 Z_DEFAULT_STRATEGY);
176 else
177 rc = deflateInit (zs, zfx->level);
178 if (rc != Z_OK)
179 {
180 cdk_free (zs);
181 return CDK_Zlib_Error;
182 }
183 zfx->outbufsize = 8192;
184 memset (zfx->outbuf, 0, sizeof zfx->outbuf);
185
186 while (!feof (in))
187 {
188 nread = fread (zfx->outbuf, 1, zfx->outbufsize, in);
189 if (!nread)
190 break;
191 zrc = compress_data (zs, Z_NO_FLUSH, zfx->outbuf, nread, out);
192 if (zrc)
193 {
194 rc = CDK_Zlib_Error;
195 break;
196 }
197 }
198 if (!rc)
199 {
200 nread = 0;
201 zrc = compress_data (zs, Z_FINISH, zfx->outbuf, nread, out);
202 if (zrc != Z_STREAM_END)
203 rc = CDK_Zlib_Error;
204 }
205 deflateEnd (zs);
206 cdk_free (zs);
207 return rc;
208}
209
210
211cdk_error_t
212_cdk_filter_compress (void *opaque, int ctl, FILE * in, FILE * out)
213{
214 if (ctl == STREAMCTL_READ)
215 return compress_decode (opaque, in, out);
216 else if (ctl == STREAMCTL_WRITE)
217 return compress_encode (opaque, in, out);
218 else if (ctl == STREAMCTL_FREE)
219 {
220 compress_filter_t *zfx = opaque;
221 if (zfx)
222 {
223 _cdk_log_debug ("free compress filter\n");
224 zfx->level = 0;
225 zfx->algo = 0;
226 return 0;
227 }
228 }
229 return CDK_Inv_Mode;
230}
231
232#else
233cdk_error_t
234_cdk_filter_compress (void *opaque, int ctl, FILE * in, FILE * out)
235{
236 return CDK_Not_Implemented;
237}
238#endif /* HAVE_LIBZ */
diff --git a/src/daemon/https/opencdk/context.h b/src/daemon/https/opencdk/context.h
new file mode 100644
index 00000000..e6569523
--- /dev/null
+++ b/src/daemon/https/opencdk/context.h
@@ -0,0 +1,120 @@
1/* context.h
2 * Copyright (C) 2002, 2003, 2007 Timo Schulz
3 *
4 * This file is part of OpenCDK.
5 *
6 * OpenCDK is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * OpenCDK is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16#ifndef CDK_CONTEXT_H
17#define CDK_CONTEXT_H
18
19#include "types.h"
20
21struct cdk_listkey_s {
22 unsigned init:1;
23 cdk_stream_t inp;
24 cdk_keydb_hd_t db;
25 int type;
26 union {
27 char *patt;
28 cdk_strlist_t fpatt;
29 } u;
30 cdk_strlist_t t;
31};
32
33
34struct cdk_s2k_s {
35 int mode;
36 byte hash_algo;
37 byte salt[8];
38 u32 count;
39};
40
41
42struct cdk_ctx_s {
43 int cipher_algo;
44 int digest_algo;
45 struct {
46 int algo;
47 int level;
48 } compress;
49 struct {
50 int mode;
51 int digest_algo;
52 } _s2k;
53 struct {
54 unsigned blockmode:1;
55 unsigned armor:1;
56 unsigned textmode:1;
57 unsigned compress:1;
58 unsigned mdc:1;
59 unsigned overwrite;
60 unsigned force_digest:1;
61 } opt;
62 struct {
63 cdk_verify_result_t verify;
64 } result;
65 struct {
66 cdk_pkt_seckey_t sk;
67 unsigned on:1;
68 } cache;
69 cdk_dek_t dek;
70 struct {
71 cdk_keydb_hd_t sec;
72 cdk_keydb_hd_t pub;
73 unsigned int close_db:1;
74 } db;
75 char *(*passphrase_cb) (void *opaque, const char *prompt);
76 void * passphrase_cb_value;
77};
78
79struct cdk_prefitem_s {
80 byte type;
81 byte value;
82};
83
84struct cdk_desig_revoker_s {
85 struct cdk_desig_revoker_s * next;
86 byte r_class;
87 byte algid;
88 byte fpr[KEY_FPR_LEN];
89};
90
91struct cdk_subpkt_s {
92 struct cdk_subpkt_s * next;
93 u32 size;
94 byte type;
95 byte d[1];
96};
97
98struct cdk_keylist_s {
99 struct cdk_keylist_s * next;
100 union {
101 cdk_pkt_pubkey_t pk;
102 cdk_pkt_seckey_t sk;
103 } key;
104 int version;
105 int type;
106};
107
108struct cdk_dek_s {
109 int algo;
110 int keylen;
111 int use_mdc;
112 byte key[32]; /* 256-bit */
113};
114
115struct cdk_strlist_s {
116 struct cdk_strlist_s * next;
117 char d[1];
118};
119
120#endif /* CDK_CONTEXT_H */
diff --git a/src/daemon/https/opencdk/dummy.c b/src/daemon/https/opencdk/dummy.c
new file mode 100644
index 00000000..2132f2d9
--- /dev/null
+++ b/src/daemon/https/opencdk/dummy.c
@@ -0,0 +1,15 @@
1#include <stdio.h>
2#include <string.h>
3
4#include "opencdk.h"
5#include "main.h"
6#include "filters.h"
7#include "packet.h"
8
9cdk_error_t
10_cdk_proc_packets (cdk_ctx_t hd, cdk_stream_t inp, cdk_stream_t data,
11 const char *output, cdk_stream_t outstream,
12 gcry_md_hd_t md)
13{
14 return 0;
15}
diff --git a/src/daemon/https/opencdk/filters.h b/src/daemon/https/opencdk/filters.h
new file mode 100644
index 00000000..a60881ed
--- /dev/null
+++ b/src/daemon/https/opencdk/filters.h
@@ -0,0 +1,95 @@
1/* filters.h - Filter structs
2 * Copyright (C) 2002, 2003 Timo Schulz
3 *
4 * This file is part of OpenCDK.
5 *
6 * OpenCDK is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * OpenCDK is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16#ifndef CDK_FILTERS_H
17#define CDK_FILTERS_H
18
19enum {
20 STREAMCTL_READ = 0,
21 STREAMCTL_WRITE = 1,
22 STREAMCTL_FREE = 2
23};
24
25typedef struct {
26 gcry_cipher_hd_t hd;
27 gcry_md_hd_t mdc;
28 int mdc_method;
29 cdk_dek_t dek;
30 u32 datalen;
31 struct {
32 size_t on;
33 off_t size;
34 off_t nleft;
35 } blkmode;
36 cdk_stream_t s;
37} cipher_filter_t;
38
39typedef struct {
40 int digest_algo;
41 gcry_md_hd_t md;
42} md_filter_t;
43
44typedef struct {
45 const char *le; /* line endings */
46 const char *hdrlines;
47 u32 crc;
48 int crc_okay;
49 int idx, idx2;
50} armor_filter_t;
51
52typedef struct {
53 cdk_lit_format_t mode;
54 char *orig_filename; /* This original name of the input file. */
55 char *filename;
56 gcry_md_hd_t md;
57 struct {
58 size_t on;
59 off_t size;
60 } blkmode;
61} literal_filter_t;
62
63typedef struct {
64 size_t inbufsize;
65 byte inbuf[8192];
66 size_t outbufsize;
67 byte outbuf[8192];
68 int algo; /* compress algo */
69 int level;
70} compress_filter_t;
71
72typedef struct {
73 const char * lf;
74} text_filter_t;
75
76
77/*-- armor.c -*/
78int _cdk_filter_armor( void * opaque, int ctl, FILE * in, FILE * out );
79
80/*-- cipher.c --*/
81cdk_error_t _cdk_filter_hash( void * opaque, int ctl, FILE * in, FILE * out );
82cdk_error_t _cdk_filter_cipher( void * opaque, int ctl,
83 FILE * in, FILE * out );
84
85/*-- literal.c --*/
86int _cdk_filter_literal( void * opaque, int ctl, FILE * in, FILE * out );
87int _cdk_filter_text( void * opaque, int ctl, FILE * in, FILE * out );
88
89/*-- compress.c --*/
90cdk_error_t _cdk_filter_compress( void * opaque, int ctl,
91 FILE * in, FILE * out );
92
93#endif /* CDK_FILTERS_H */
94
95
diff --git a/src/daemon/https/opencdk/kbnode.c b/src/daemon/https/opencdk/kbnode.c
new file mode 100644
index 00000000..9028c24b
--- /dev/null
+++ b/src/daemon/https/opencdk/kbnode.c
@@ -0,0 +1,581 @@
1/* kbnode.c - keyblock node utility functions
2 * Copyright (C) 1998-2001 Free Software Foundation, Inc.
3 * Copyright (C) 2002, 2003, 2007 Timo Schulz
4 *
5 * This file is part of OpenCDK.
6 *
7 * OpenCDK is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * OpenCDK is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17#ifdef HAVE_CONFIG_H
18# include <config.h>
19#endif
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23#include <assert.h>
24
25#include "opencdk.h"
26#include "main.h"
27#include "packet.h"
28
29
30/**
31 * cdk_kbnode_new:
32 * @pkt: the packet to add
33 *
34 * Allocate a new key node and add the packet.
35 **/
36cdk_kbnode_t
37cdk_kbnode_new (cdk_packet_t pkt)
38{
39 cdk_kbnode_t n;
40
41 n = cdk_calloc (1, sizeof *n);
42 if (!n)
43 return NULL;
44 n->pkt = pkt;
45 return n;
46}
47
48
49void
50_cdk_kbnode_clone (cdk_kbnode_t node)
51{
52 /* Mark the node as clone which means that the packet
53 will not be freed, just the node itself. */
54 if (node)
55 node->is_cloned = 1;
56}
57
58
59/**
60 * cdk_kbnode_release:
61 * @n: the key node
62 *
63 * Release the memory of the node.
64 **/
65void
66cdk_kbnode_release (cdk_kbnode_t node)
67{
68 cdk_kbnode_t n2;
69
70 while (node)
71 {
72 n2 = node->next;
73 if (!node->is_cloned)
74 cdk_pkt_release (node->pkt);
75 cdk_free (node);
76 node = n2;
77 }
78}
79
80
81/**
82 * cdk_kbnode_delete:
83 * @node: the key node
84 *
85 * Mark the given node as deleted.
86 **/
87void
88cdk_kbnode_delete (cdk_kbnode_t node)
89{
90 if (node)
91 node->is_deleted = 1;
92}
93
94
95/* Append NODE to ROOT. ROOT must exist! */
96void
97_cdk_kbnode_add (cdk_kbnode_t root, cdk_kbnode_t node)
98{
99 cdk_kbnode_t n1;
100
101 for (n1 = root; n1->next; n1 = n1->next)
102 ;
103 n1->next = node;
104}
105
106
107/**
108 * cdk_kbnode_insert:
109 * @root: the root key node
110 * @node: the node to add
111 * @pkttype: packet type
112 *
113 * Insert @node into the list after @root but before a packet which is not of
114 * type @pkttype (only if @pkttype != 0).
115 **/
116void
117cdk_kbnode_insert (cdk_kbnode_t root, cdk_kbnode_t node, int pkttype)
118{
119 if (!pkttype)
120 {
121 node->next = root->next;
122 root->next = node;
123 }
124 else
125 {
126 cdk_kbnode_t n1;
127
128 for (n1 = root; n1->next; n1 = n1->next)
129 if (pkttype != n1->next->pkt->pkttype)
130 {
131 node->next = n1->next;
132 n1->next = node;
133 return;
134 }
135 /* No such packet, append */
136 node->next = NULL;
137 n1->next = node;
138 }
139}
140
141
142/**
143 * cdk_kbnode_find_prev:
144 * @root: the root key node
145 * @node: the key node
146 * @pkttype: packet type
147 *
148 * Find the previous node (if @pkttype = 0) or the previous node
149 * with pkttype @pkttype in the list starting with @root of @node.
150 **/
151cdk_kbnode_t
152cdk_kbnode_find_prev (cdk_kbnode_t root, cdk_kbnode_t node, int pkttype)
153{
154 cdk_kbnode_t n1;
155
156 for (n1 = NULL; root && root != node; root = root->next)
157 {
158 if (!pkttype || root->pkt->pkttype == pkttype)
159 n1 = root;
160 }
161 return n1;
162}
163
164
165/**
166 * cdk_kbnode_find_next:
167 * @node: the key node
168 * @pkttype: packet type
169 *
170 * Ditto, but find the next packet. The behaviour is trivial if
171 * @pkttype is 0 but if it is specified, the next node with a packet
172 * of this type is returned. The function has some knowledge about
173 * the valid ordering of packets: e.g. if the next signature packet
174 * is requested, the function will not return one if it encounters
175 * a user-id.
176 **/
177cdk_kbnode_t
178cdk_kbnode_find_next (cdk_kbnode_t node, int pkttype)
179{
180 for (node = node->next; node; node = node->next)
181 {
182 if (!pkttype)
183 return node;
184 else if (pkttype == CDK_PKT_USER_ID &&
185 (node->pkt->pkttype == CDK_PKT_PUBLIC_KEY ||
186 node->pkt->pkttype == CDK_PKT_SECRET_KEY))
187 return NULL;
188 else if (pkttype == CDK_PKT_SIGNATURE &&
189 (node->pkt->pkttype == CDK_PKT_USER_ID ||
190 node->pkt->pkttype == CDK_PKT_PUBLIC_KEY ||
191 node->pkt->pkttype == CDK_PKT_SECRET_KEY))
192 return NULL;
193 else if (node->pkt->pkttype == pkttype)
194 return node;
195 }
196 return NULL;
197}
198
199
200/**
201 * cdk_kbnode_find:
202 * @node: the key node
203 * @pkttype: packet type
204 *
205 * Try to find the next node with the packettype @pkttype.
206 **/
207cdk_kbnode_t
208cdk_kbnode_find (cdk_kbnode_t node, int pkttype)
209{
210 for (; node; node = node->next)
211 {
212 if (node->pkt->pkttype == pkttype)
213 return node;
214 }
215 return NULL;
216}
217
218
219/**
220 * cdk_kbnode_find_packet:
221 * @node: the key node
222 * @pkttype: packet type
223 *
224 * Same as cdk_kbnode_find but it returns the packet instead of the node.
225 **/
226cdk_packet_t
227cdk_kbnode_find_packet (cdk_kbnode_t node, int pkttype)
228{
229 cdk_kbnode_t res;
230
231 res = cdk_kbnode_find (node, pkttype);
232 return res ? res->pkt : NULL;
233}
234
235
236/****************
237 * Walk through a list of kbnodes. This function returns
238 * the next kbnode for each call; before using the function the first
239 * time, the caller must set CONTEXT to NULL (This has simply the effect
240 * to start with ROOT).
241 */
242cdk_kbnode_t
243cdk_kbnode_walk (cdk_kbnode_t root, cdk_kbnode_t * context, int all)
244{
245 cdk_kbnode_t n;
246
247 do
248 {
249 if (!*context)
250 {
251 *context = root;
252 n = root;
253 }
254 else
255 {
256 n = (*context)->next;
257 *context = n;
258 }
259 }
260 while (!all && n && n->is_deleted);
261 return n;
262}
263
264
265/**
266 * cdk_kbnode_commit:
267 * @root: the nodes
268 *
269 * Commit changes made to the kblist at ROOT. Note that ROOT my change,
270 * and it is therefore passed by reference.
271 * The function has the effect of removing all nodes marked as deleted.
272 * returns true if any node has been changed
273 */
274int
275cdk_kbnode_commit (cdk_kbnode_t * root)
276{
277 cdk_kbnode_t n, nl;
278 int changed = 0;
279
280 for (n = *root, nl = NULL; n; n = nl->next)
281 {
282 if (n->is_deleted)
283 {
284 if (n == *root)
285 *root = nl = n->next;
286 else
287 nl->next = n->next;
288 if (!n->is_cloned)
289 cdk_pkt_release (n->pkt);
290 cdk_free (n);
291 changed = 1;
292 }
293 else
294 nl = n;
295 }
296 return changed;
297}
298
299
300/**
301 * cdk_kbnode_remove:
302 * @root: the root node
303 * @node: the node to delete
304 *
305 * Remove a node from the root node.
306 */
307void
308cdk_kbnode_remove (cdk_kbnode_t * root, cdk_kbnode_t node)
309{
310 cdk_kbnode_t n, nl;
311
312 for (n = *root, nl = NULL; n; n = nl->next)
313 {
314 if (n == node)
315 {
316 if (n == *root)
317 *root = nl = n->next;
318 else
319 nl->next = n->next;
320 if (!n->is_cloned)
321 cdk_pkt_release (n->pkt);
322 cdk_free (n);
323 }
324 else
325 nl = n;
326 }
327}
328
329
330
331/**
332 * cdk_cdknode_move:
333 * @root: root node
334 * @node: the node to move
335 * @where: destination place where to move the node.
336 *
337 * Move NODE behind right after WHERE or to the beginning if WHERE is NULL.
338 */
339void
340cdk_kbnode_move (cdk_kbnode_t * root, cdk_kbnode_t node, cdk_kbnode_t where)
341{
342 cdk_kbnode_t tmp, prev;
343
344 if (!root || !*root || !node)
345 return;
346 for (prev = *root; prev && prev->next != node; prev = prev->next)
347 ;
348 if (!prev)
349 return; /* Node is not in the list */
350
351 if (!where)
352 { /* Move node before root */
353 if (node == *root)
354 return;
355 prev->next = node->next;
356 node->next = *root;
357 *root = node;
358 return;
359 }
360 if (node == where) /* Move it after where. */
361 return;
362 tmp = node->next;
363 node->next = where->next;
364 where->next = node;
365 prev->next = tmp;
366}
367
368
369/**
370 * cdk_kbnode_get_packet:
371 * @node: the key node
372 *
373 * Return the packet which is stored inside the node in @node.
374 **/
375cdk_packet_t
376cdk_kbnode_get_packet (cdk_kbnode_t node)
377{
378 if (node)
379 return node->pkt;
380 return NULL;
381}
382
383
384/**
385 * cdk_kbnode_read_from_mem:
386 * @ret_node: the new key node
387 * @buf: the buffer which stores the key sequence
388 * @buflen: the length of the buffer
389 *
390 * Try to read a key node from the memory buffer @buf.
391 **/
392cdk_error_t
393cdk_kbnode_read_from_mem (cdk_kbnode_t * ret_node,
394 const byte * buf, size_t buflen)
395{
396 cdk_stream_t inp;
397 cdk_error_t rc;
398
399 if (!buflen || !ret_node || !buf)
400 return CDK_Inv_Value;
401
402 *ret_node = NULL;
403 rc = cdk_stream_tmp_from_mem (buf, buflen, &inp);
404 if (rc)
405 return rc;
406 rc = cdk_keydb_get_keyblock (inp, ret_node);
407 cdk_stream_close (inp);
408 return rc;
409}
410
411/**
412 * cdk_kbnode_write_to_mem_alloc:
413 * @node: the key node
414 * @r_buf: buffer to hold the raw data
415 * @r_buflen: buffer length of the allocated raw data.
416 *
417 * The function acts similar to cdk_kbnode_write_to_mem but
418 * it allocates the buffer to avoid the lengthy second run.
419 */
420cdk_error_t
421cdk_kbnode_write_to_mem_alloc (cdk_kbnode_t node,
422 byte ** r_buf, size_t * r_buflen)
423{
424 cdk_kbnode_t n;
425 cdk_stream_t s;
426 cdk_error_t rc;
427 size_t len;
428
429 if (!node)
430 return CDK_Inv_Value;
431
432 *r_buf = NULL;
433 *r_buflen = 0;
434
435 rc = cdk_stream_tmp_new (&s);
436 if (rc)
437 return rc;
438
439 for (n = node; n; n = n->next)
440 {
441 /* Skip all packets which cannot occur in a key composition. */
442 if (n->pkt->pkttype != CDK_PKT_PUBLIC_KEY &&
443 n->pkt->pkttype != CDK_PKT_PUBLIC_SUBKEY &&
444 n->pkt->pkttype != CDK_PKT_SECRET_KEY &&
445 n->pkt->pkttype != CDK_PKT_SECRET_SUBKEY &&
446 n->pkt->pkttype != CDK_PKT_SIGNATURE &&
447 n->pkt->pkttype != CDK_PKT_USER_ID &&
448 n->pkt->pkttype != CDK_PKT_ATTRIBUTE)
449 continue;
450 rc = cdk_pkt_write (s, n->pkt);
451 if (rc)
452 {
453 cdk_stream_close (s);
454 return rc;
455 }
456 }
457
458 cdk_stream_seek (s, 0);
459 len = cdk_stream_get_length (s);
460 *r_buf = cdk_calloc (1, len);
461 *r_buflen = cdk_stream_read (s, *r_buf, len);
462 cdk_stream_close (s);
463 return 0;
464}
465
466
467/**
468 * cdk_kbnode_write_to_mem:
469 * @node: the key node
470 * @buf: the buffer to store the node data
471 * @r_nbytes: the new length of the buffer.
472 *
473 * Try to write the contents of the key node to the buffer @buf and
474 * return the length of it in @r_nbytes. If buf is zero, only the
475 * length of the node is calculated and returned in @r_nbytes.
476 * Whenever it is possible, the cdk_kbnode_write_to_mem_alloc should be used.
477 **/
478cdk_error_t
479cdk_kbnode_write_to_mem (cdk_kbnode_t node, byte * buf, size_t * r_nbytes)
480{
481 cdk_kbnode_t n;
482 cdk_stream_t s;
483 size_t len;
484 cdk_error_t rc;
485
486 if (!node)
487 return CDK_Inv_Value;
488
489 rc = cdk_stream_tmp_new (&s);
490 if (rc)
491 return rc;
492
493 for (n = node; n; n = n->next)
494 {
495 /* Skip all packets which cannot occur in a key composition. */
496 if (n->pkt->pkttype != CDK_PKT_PUBLIC_KEY &&
497 n->pkt->pkttype != CDK_PKT_PUBLIC_SUBKEY &&
498 n->pkt->pkttype != CDK_PKT_SECRET_KEY &&
499 n->pkt->pkttype != CDK_PKT_SECRET_SUBKEY &&
500 n->pkt->pkttype != CDK_PKT_SIGNATURE &&
501 n->pkt->pkttype != CDK_PKT_USER_ID &&
502 n->pkt->pkttype != CDK_PKT_ATTRIBUTE)
503 continue;
504 rc = cdk_pkt_write (s, n->pkt);
505 if (rc)
506 {
507 cdk_stream_close (s);
508 return rc;
509 }
510 }
511
512 cdk_stream_seek (s, 0);
513 len = cdk_stream_get_length (s);
514 if (!buf)
515 {
516 *r_nbytes = len; /* Only return the length of the buffer */
517 cdk_stream_close (s);
518 return 0;
519 }
520 if (*r_nbytes < len)
521 rc = CDK_Too_Short;
522 if (!rc)
523 *r_nbytes = cdk_stream_read (s, buf, len);
524 cdk_stream_close (s);
525 return rc;
526}
527
528
529/**
530 * cdk_kbnode_hash:
531 * @node: the key node
532 * @hashctx: opaque pointer to the hash context
533 * @is_v4: OpenPGP signature (yes=1, no=0)
534 * @pkttype: packet type to hash (if zero use the packet type from the node)
535 * @flags: flags which depend on the operation
536 *
537 * Hash the key node contents. Two modes are supported. If the packet
538 * type is used (!= 0) then the function searches the first node with
539 * this type. Otherwise the node is seen as a single node and the type
540 * is extracted from it.
541 **/
542cdk_error_t
543cdk_kbnode_hash (cdk_kbnode_t node, gcry_md_hd_t md, int is_v4,
544 int pkttype, int flags)
545{
546 cdk_packet_t pkt;
547
548 if (!node || !md)
549 return CDK_Inv_Value;
550 if (!pkttype)
551 {
552 pkt = cdk_kbnode_get_packet (node);
553 pkttype = pkt->pkttype;
554 }
555 else
556 {
557 pkt = cdk_kbnode_find_packet (node, pkttype);
558 if (!pkt)
559 return CDK_Inv_Packet;
560 }
561
562 switch (pkttype)
563 {
564 case CDK_PKT_PUBLIC_KEY:
565 case CDK_PKT_PUBLIC_SUBKEY:
566 _cdk_hash_pubkey (pkt->pkt.public_key, md, flags & 1);
567 break;
568
569 case CDK_PKT_USER_ID:
570 _cdk_hash_userid (pkt->pkt.user_id, is_v4, md);
571 break;
572
573 case CDK_PKT_SIGNATURE:
574 _cdk_hash_sig_data (pkt->pkt.signature, md);
575 break;
576
577 default:
578 return CDK_Inv_Mode;
579 }
580 return 0;
581}
diff --git a/src/daemon/https/opencdk/keydb.c b/src/daemon/https/opencdk/keydb.c
new file mode 100644
index 00000000..0553d3c3
--- /dev/null
+++ b/src/daemon/https/opencdk/keydb.c
@@ -0,0 +1,2303 @@
1/* keydb.c - Key database routines
2 * Copyright (C) 2002, 2003, 2007 Timo Schulz
3 *
4 * This file is part of OpenCDK.
5 *
6 * OpenCDK is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * OpenCDK is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16#ifdef HAVE_CONFIG_H
17# include <config.h>
18#endif
19#include <sys/stat.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23#include <time.h>
24#include <ctype.h>
25
26#include "opencdk.h"
27#include "main.h"
28#include "packet.h"
29#include "filters.h"
30#include "stream.h"
31
32
33#define KEYID_CMP(a, b) ((a[0]) == (b[0]) && (a[1]) == (b[1]))
34#define KEYDB_CACHE_ENTRIES 8
35
36
37/* Internal key index structure. */
38struct key_idx_s
39{
40 off_t offset;
41 u32 keyid[2];
42 byte fpr[KEY_FPR_LEN];
43};
44typedef struct key_idx_s *key_idx_t;
45
46
47/* Internal handle for the search operation. */
48struct cdk_dbsearch_s
49{
50 union
51 {
52 char *pattern; /* A search is performed by pattern. */
53 u32 keyid[2]; /* A search by keyid. */
54 byte fpr[KEY_FPR_LEN]; /* A search by fingerprint. */
55 } u;
56 int type;
57};
58typedef struct cdk_dbsearch_s *cdk_dbsearch_t;
59
60/* Internal key cache to associate a key with an file offset. */
61struct key_table_s
62{
63 struct key_table_s *next;
64 off_t offset;
65 cdk_dbsearch_t desc;
66};
67typedef struct key_table_s *key_table_t;
68
69/* Internal key database handle. */
70struct cdk_keydb_hd_s
71{
72 int type; /* type of the key db handle. */
73 int fp_ref; /* 1=means it is a reference and shall not be closed. */
74 cdk_stream_t fp;
75 cdk_stream_t idx;
76 cdk_dbsearch_t dbs;
77 char *name; /* name of the underlying file or NULL. */
78 char *idx_name; /* name of the index file or NULL. */
79 struct key_table_s *cache;
80 size_t ncache;
81 unsigned int secret:1; /* contain secret keys. */
82 unsigned int isopen:1; /* the underlying stream is opened. */
83 unsigned int no_cache:1; /* disable the index cache. */
84 unsigned int search:1; /* handle is in search mode. */
85
86 /* structure to store some stats about the keydb. */
87 struct
88 {
89 size_t new_keys; /* amount of new keys that were imported. */
90 } stats;
91};
92
93
94static void keydb_cache_free (key_table_t cache);
95static int keydb_search_copy (cdk_dbsearch_t * r_dst, cdk_dbsearch_t src);
96static void keydb_search_free (cdk_dbsearch_t dbs);
97static int classify_data (const byte * buf, size_t len);
98static cdk_kbnode_t find_selfsig_node (cdk_kbnode_t key, cdk_pkt_pubkey_t pk);
99
100
101static char *
102keydb_idx_mkname (const char *file)
103{
104 char *fname, *fmt;
105
106 fmt = "%s.idx";
107 fname = cdk_calloc (1, strlen (file) + strlen (fmt) + 1);
108 if (!fname)
109 return NULL;
110 sprintf (fname, fmt, file);
111 return fname;
112}
113
114
115/* This functions builds an index of the keyring into a separate file
116 with the name keyring.ext.idx. It contains the offset of all public-
117 and public subkeys. The format of the file is:
118 --------
119 4 octets offset of the packet
120 8 octets keyid
121 20 octets fingerprint
122 --------
123 We store the keyid and the fingerprint due to the fact we can't get
124 the keyid from a v3 fingerprint directly.
125*/
126static cdk_error_t
127keydb_idx_build (const char *file)
128{
129 cdk_packet_t pkt;
130 cdk_stream_t inp, out = NULL;
131 byte buf[4 + 8 + KEY_FPR_LEN];
132 char *idx_name;
133 u32 keyid[2];
134 cdk_error_t rc;
135
136 if (!file)
137 return CDK_Inv_Value;
138
139 rc = cdk_stream_open (file, &inp);
140 if (rc)
141 return rc;
142
143 idx_name = keydb_idx_mkname (file);
144 if (!idx_name)
145 {
146 cdk_stream_close (inp);
147 return CDK_Out_Of_Core;
148 }
149 rc = cdk_stream_create (idx_name, &out);
150 cdk_free (idx_name);
151 if (rc)
152 {
153 cdk_stream_close (inp);
154 return rc;
155 }
156
157 cdk_pkt_new (&pkt);
158 while (!cdk_stream_eof (inp))
159 {
160 off_t pos = cdk_stream_tell (inp);
161
162 rc = cdk_pkt_read (inp, pkt);
163 if (rc)
164 {
165 _cdk_log_debug ("index build failed packet off=%lu\n", pos);
166 /* FIXME: The index is incomplete */
167 break;
168 }
169 if (pkt->pkttype == CDK_PKT_PUBLIC_KEY ||
170 pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY)
171 {
172 _cdk_u32tobuf (pos, buf);
173 cdk_pk_get_keyid (pkt->pkt.public_key, keyid);
174 _cdk_u32tobuf (keyid[0], buf + 4);
175 _cdk_u32tobuf (keyid[1], buf + 8);
176 cdk_pk_get_fingerprint (pkt->pkt.public_key, buf + 12);
177 cdk_stream_write (out, buf, 4 + 8 + KEY_FPR_LEN);
178 }
179 cdk_pkt_free (pkt);
180 }
181
182 cdk_pkt_release (pkt);
183
184 cdk_stream_close (out);
185 cdk_stream_close (inp);
186 return rc;
187}
188
189
190/**
191 * cdk_keydb_idx_rebuild:
192 * @hd: key database handle
193 *
194 * Rebuild the key index files for the given key database.
195 **/
196cdk_error_t
197cdk_keydb_idx_rebuild (cdk_keydb_hd_t db)
198{
199 struct stat stbuf;
200 char *tmp_idx_name;
201 cdk_error_t rc;
202 int err;
203
204 if (!db || !db->name)
205 return CDK_Inv_Value;
206 if (db->secret)
207 return 0;
208
209 tmp_idx_name = keydb_idx_mkname (db->name);
210 if (!tmp_idx_name)
211 return CDK_Out_Of_Core;
212 err = stat (tmp_idx_name, &stbuf);
213 cdk_free (tmp_idx_name);
214 /* This function expects an existing index which can be rebuild,
215 if no index exists we do not build one and just return. */
216 if (err)
217 return 0;
218
219 cdk_stream_close (db->idx);
220 db->idx = NULL;
221 if (!db->idx_name)
222 {
223 db->idx_name = keydb_idx_mkname (db->name);
224 if (!db->idx_name)
225 return CDK_Out_Of_Core;
226 }
227 rc = keydb_idx_build (db->name);
228 if (!rc)
229 rc = cdk_stream_open (db->idx_name, &db->idx);
230 return rc;
231}
232
233
234static cdk_error_t
235keydb_idx_parse (cdk_stream_t inp, key_idx_t * r_idx)
236{
237 key_idx_t idx;
238 byte buf[4];
239
240 if (!inp || !r_idx)
241 return CDK_Inv_Value;
242
243 idx = cdk_calloc (1, sizeof *idx);
244 if (!idx)
245 return CDK_Out_Of_Core;
246
247 while (!cdk_stream_eof (inp))
248 {
249 if (cdk_stream_read (inp, buf, 4) == CDK_EOF)
250 break;
251 idx->offset = _cdk_buftou32 (buf);
252 cdk_stream_read (inp, buf, 4);
253 idx->keyid[0] = _cdk_buftou32 (buf);
254 cdk_stream_read (inp, buf, 4);
255 idx->keyid[1] = _cdk_buftou32 (buf);
256 cdk_stream_read (inp, idx->fpr, KEY_FPR_LEN);
257 break;
258 }
259 *r_idx = idx;
260 return cdk_stream_eof (inp) ? CDK_EOF : 0;
261}
262
263
264static cdk_error_t
265keydb_idx_search (cdk_stream_t inp, u32 * keyid, const byte * fpr,
266 off_t * r_off)
267{
268 key_idx_t idx;
269
270 if (!inp || !r_off)
271 return CDK_Inv_Value;
272 if ((keyid && fpr) || (!keyid && !fpr))
273 return CDK_Inv_Mode;
274
275 /* We need an initialize the offset var with a value
276 because it might be possible the returned offset will
277 be 0 and then we cannot differ between the begin and an EOF. */
278 *r_off = 0xFFFFFFFF;
279 cdk_stream_seek (inp, 0);
280 while (keydb_idx_parse (inp, &idx) != CDK_EOF)
281 {
282 if (keyid && KEYID_CMP (keyid, idx->keyid))
283 {
284 *r_off = idx->offset;
285 break;
286 }
287 else if (fpr && !memcmp (idx->fpr, fpr, KEY_FPR_LEN))
288 {
289 *r_off = idx->offset;
290 break;
291 }
292 cdk_free (idx);
293 idx = NULL;
294 }
295 cdk_free (idx);
296 return *r_off != 0xFFFFFFFF ? 0 : CDK_EOF;
297}
298
299
300/**
301 * cdk_keydb_new_from_mem:
302 * @r_hd: The keydb output handle.
303 * @data: The raw key data.
304 * @datlen: The length of the raw data.
305 *
306 * Create a new keyring db handle from the contents of a buffer.
307 */
308cdk_error_t
309cdk_keydb_new_from_mem (cdk_keydb_hd_t * r_db, int secret,
310 const void *data, size_t datlen)
311{
312 cdk_keydb_hd_t db;
313 cdk_error_t rc;
314
315 if (!r_db)
316 return CDK_Inv_Value;
317 *r_db = NULL;
318 db = calloc (1, sizeof *db);
319 rc = cdk_stream_tmp_from_mem (data, datlen, &db->fp);
320 if (!db->fp)
321 {
322 cdk_free (db);
323 return rc;
324 }
325 if (cdk_armor_filter_use (db->fp))
326 cdk_stream_set_armor_flag (db->fp, 0);
327 db->type = CDK_DBTYPE_DATA;
328 db->secret = secret;
329 *r_db = db;
330 return 0;
331}
332
333
334/**
335 * cdk_keydb_new_from_stream:
336 * @r_hd: the output keydb handle
337 * @secret: does the stream contain secret key data
338 * @in: the input stream to use
339 *
340 * This function creates a new keydb handle based on the given
341 * stream. The stream is not closed in cdk_keydb_free() and it
342 * is up to the caller to close it. No decoding is done.
343 */
344cdk_error_t
345cdk_keydb_new_from_stream (cdk_keydb_hd_t * r_hd, int secret, cdk_stream_t in)
346{
347 cdk_keydb_hd_t hd;
348
349 if (!r_hd)
350 return CDK_Inv_Value;
351 *r_hd = NULL;
352
353 hd = calloc (1, sizeof *hd);
354 hd->fp = in;
355 hd->fp_ref = 1;
356 hd->type = CDK_DBTYPE_STREAM;
357 hd->secret = secret;
358 *r_hd = hd;
359
360 /* We do not push any filters and thus we expect that the format
361 of the stream has the format the user wanted. */
362
363 return 0;
364}
365
366
367cdk_error_t
368cdk_keydb_new_from_file (cdk_keydb_hd_t * r_hd, int secret, const char *fname)
369{
370 cdk_keydb_hd_t hd;
371
372 if (!r_hd)
373 return CDK_Inv_Value;
374 *r_hd = NULL;
375 hd = calloc (1, sizeof *hd);
376 hd->name = cdk_strdup (fname);
377 if (!hd->name)
378 {
379 cdk_free (hd);
380 return CDK_Out_Of_Core;
381 }
382 hd->type = secret ? CDK_DBTYPE_SK_KEYRING : CDK_DBTYPE_PK_KEYRING;
383 hd->secret = secret;
384 *r_hd = hd;
385 return 0;
386}
387
388
389
390/**
391 * cdk_keydb_new:
392 * @r_hd: handle to store the new keydb object
393 * @type: type of the keyring
394 * @data: data which depends on the keyring type
395 * @count: length of the data
396 *
397 * Create a new keydb object
398 **/
399cdk_error_t
400cdk_keydb_new (cdk_keydb_hd_t * r_hd, int type, void *data, size_t count)
401{
402 switch (type)
403 {
404 case CDK_DBTYPE_PK_KEYRING:
405 case CDK_DBTYPE_SK_KEYRING:
406 return cdk_keydb_new_from_file (r_hd, type == CDK_DBTYPE_SK_KEYRING,
407 (const char *) data);
408
409 case CDK_DBTYPE_DATA:
410 return cdk_keydb_new_from_mem (r_hd, 0, data, count);
411
412 case CDK_DBTYPE_STREAM:
413 return cdk_keydb_new_from_stream (r_hd, 0, (cdk_stream_t) data);
414
415 default:
416 return CDK_Inv_Mode;
417 }
418 return CDK_Inv_Mode;
419}
420
421
422/**
423 * cdk_keydb_free:
424 * @hd: the keydb object
425 *
426 * Free the keydb object.
427 **/
428void
429cdk_keydb_free (cdk_keydb_hd_t hd)
430{
431 if (!hd)
432 return;
433
434 if (hd->name)
435 {
436 cdk_free (hd->name);
437 hd->name = NULL;
438 }
439
440 if (hd->fp && !hd->fp_ref)
441 {
442 cdk_stream_close (hd->fp);
443 hd->fp = NULL;
444 }
445
446 if (hd->idx)
447 {
448 cdk_stream_close (hd->idx);
449 hd->idx = NULL;
450 }
451
452 hd->isopen = 0;
453 hd->no_cache = 0;
454 hd->secret = 0;
455 keydb_cache_free (hd->cache);
456 hd->cache = NULL;
457 keydb_search_free (hd->dbs);
458 hd->dbs = NULL;
459 cdk_free (hd);
460}
461
462
463cdk_error_t
464_cdk_keydb_open (cdk_keydb_hd_t hd, cdk_stream_t * ret_kr)
465{
466 cdk_error_t rc, ec;
467
468 if (!hd || !ret_kr)
469 return CDK_Inv_Value;
470
471 rc = 0;
472 if ((hd->type == CDK_DBTYPE_DATA || hd->type == CDK_DBTYPE_STREAM)
473 && hd->fp)
474 cdk_stream_seek (hd->fp, 0);
475 else if (hd->type == CDK_DBTYPE_PK_KEYRING ||
476 hd->type == CDK_DBTYPE_SK_KEYRING)
477 {
478 if (!hd->isopen && hd->name)
479 {
480 rc = cdk_stream_open (hd->name, &hd->fp);
481 if (rc)
482 goto leave;
483 if (cdk_armor_filter_use (hd->fp))
484 cdk_stream_set_armor_flag (hd->fp, 0);
485 hd->isopen = 1;
486 /* We disable the index cache for smaller keyrings. */
487 if (cdk_stream_get_length (hd->fp) < 524288)
488 {
489 hd->no_cache = 1;
490 goto leave;
491 }
492 cdk_free (hd->idx_name);
493 hd->idx_name = keydb_idx_mkname (hd->name);
494 if (!hd->idx_name)
495 {
496 rc = CDK_Out_Of_Core;
497 goto leave;
498 }
499 ec = cdk_stream_open (hd->idx_name, &hd->idx);
500 if (ec && !hd->secret)
501 {
502 rc = keydb_idx_build (hd->name);
503 if (!rc)
504 rc = cdk_stream_open (hd->idx_name, &hd->idx);
505 if (!rc)
506 _cdk_log_debug ("create key index table\n");
507 else
508 {
509 /* This is no real error, it just means we can't create
510 the index at the given directory. maybe we've no write
511 access. in this case, we simply disable the index. */
512 _cdk_log_debug ("disable key index table err=%d\n", rc);
513 rc = 0;
514 hd->no_cache = 1;
515 }
516 }
517 }
518 else
519 {
520 /* We use the cache to search keys, so we always rewind the
521 STREAM. Except when the _NEXT search mode is used because
522 this mode is an enumeration and no seeking is needed. */
523 if (!hd->search ||
524 (hd->search && hd->dbs->type != CDK_DBSEARCH_NEXT))
525 cdk_stream_seek (hd->fp, 0);
526 }
527 }
528 else
529 return CDK_Inv_Mode;
530
531leave:
532 if (rc)
533 {
534 cdk_stream_close (hd->fp);
535 hd->fp = NULL;
536 }
537 *ret_kr = hd->fp;
538 return rc;
539}
540
541
542static int
543find_by_keyid (cdk_kbnode_t knode, cdk_dbsearch_t ks)
544{
545 cdk_kbnode_t node;
546 u32 keyid[2];
547
548 for (node = knode; node; node = node->next)
549 {
550 if (node->pkt->pkttype == CDK_PKT_PUBLIC_KEY ||
551 node->pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY ||
552 node->pkt->pkttype == CDK_PKT_SECRET_KEY ||
553 node->pkt->pkttype == CDK_PKT_SECRET_SUBKEY)
554 {
555 _cdk_pkt_get_keyid (node->pkt, keyid);
556 switch (ks->type)
557 {
558 case CDK_DBSEARCH_SHORT_KEYID:
559 if (keyid[1] == ks->u.keyid[1])
560 return 1;
561 break;
562
563 case CDK_DBSEARCH_KEYID:
564 if (KEYID_CMP (keyid, ks->u.keyid))
565 return 1;
566 break;
567
568 default:
569 _cdk_log_debug ("find_by_keyid: invalid mode = %d\n", ks->type);
570 return 0;
571 }
572 }
573 }
574 return 0;
575}
576
577
578static int
579find_by_fpr (cdk_kbnode_t knode, cdk_dbsearch_t ks)
580{
581 cdk_kbnode_t node;
582 byte fpr[KEY_FPR_LEN];
583
584 if (ks->type != CDK_DBSEARCH_FPR)
585 return 0;
586
587 for (node = knode; node; node = node->next)
588 {
589 if (node->pkt->pkttype == CDK_PKT_PUBLIC_KEY ||
590 node->pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY ||
591 node->pkt->pkttype == CDK_PKT_SECRET_KEY ||
592 node->pkt->pkttype == CDK_PKT_SECRET_SUBKEY)
593 {
594 _cdk_pkt_get_fingerprint (node->pkt, fpr);
595 if (!memcmp (ks->u.fpr, fpr, KEY_FPR_LEN))
596 return 1;
597 break;
598 }
599 }
600
601 return 0;
602}
603
604
605static int
606find_by_pattern (cdk_kbnode_t knode, cdk_dbsearch_t ks)
607{
608 cdk_kbnode_t node;
609 size_t uidlen;
610 char *name;
611
612 for (node = knode; node; node = node->next)
613 {
614 if (node->pkt->pkttype != CDK_PKT_USER_ID)
615 continue;
616 if (node->pkt->pkt.user_id->attrib_img != NULL)
617 continue; /* Skip attribute packets. */
618 uidlen = node->pkt->pkt.user_id->len;
619 name = node->pkt->pkt.user_id->name;
620 switch (ks->type)
621 {
622 case CDK_DBSEARCH_EXACT:
623 if (name &&
624 (strlen (ks->u.pattern) == uidlen &&
625 !strncmp (ks->u.pattern, name, uidlen)))
626 return 1;
627 break;
628
629 case CDK_DBSEARCH_SUBSTR:
630 if (uidlen > 65536)
631 break;
632 if (name && strlen (ks->u.pattern) > uidlen)
633 break;
634 if (name && _cdk_memistr (name, uidlen, ks->u.pattern))
635 return 1;
636 break;
637
638 default: /* Invalid mode */
639 return 0;
640 }
641 }
642 return 0;
643}
644
645
646static void
647keydb_search_free (cdk_dbsearch_t dbs)
648{
649 if (!dbs)
650 return;
651 if (dbs->type == CDK_DBSEARCH_EXACT || dbs->type == CDK_DBSEARCH_SUBSTR)
652 cdk_free (dbs->u.pattern);
653 dbs->type = 0;
654 cdk_free (dbs);
655}
656
657
658static void
659keydb_cache_free (key_table_t cache)
660{
661 key_table_t c2;
662
663 while (cache)
664 {
665 c2 = cache->next;
666 cache->offset = 0;
667 keydb_search_free (cache->desc);
668 cdk_free (cache);
669 cache = c2;
670 }
671}
672
673
674static key_table_t
675keydb_cache_find (key_table_t cache, cdk_dbsearch_t desc)
676{
677 key_table_t t;
678
679 for (t = cache; t; t = t->next)
680 {
681 if (t->desc->type != desc->type)
682 continue;
683 switch (t->desc->type)
684 {
685 case CDK_DBSEARCH_SHORT_KEYID:
686 case CDK_DBSEARCH_KEYID:
687 if (KEYID_CMP (t->desc->u.keyid, desc->u.keyid))
688 return t;
689 break;
690
691 case CDK_DBSEARCH_EXACT:
692 if (strlen (t->desc->u.pattern) == strlen (desc->u.pattern) &&
693 !strcmp (t->desc->u.pattern, desc->u.pattern))
694 return t;
695 break;
696
697 case CDK_DBSEARCH_SUBSTR:
698 if (strstr (t->desc->u.pattern, desc->u.pattern))
699 return t;
700 break;
701
702 case CDK_DBSEARCH_FPR:
703 if (!memcmp (t->desc->u.fpr, desc->u.fpr, KEY_FPR_LEN))
704 return t;
705 break;
706 }
707 }
708
709 return NULL;
710}
711
712
713static cdk_error_t
714keydb_cache_add (cdk_keydb_hd_t hd, cdk_dbsearch_t dbs, off_t offset)
715{
716 key_table_t k;
717
718 if (!hd)
719 return CDK_Inv_Value;
720
721 if (hd->ncache > KEYDB_CACHE_ENTRIES)
722 return 0; /* FIXME: we should replace the last entry. */
723 k = cdk_calloc (1, sizeof *k);
724 if (!k)
725 return CDK_Out_Of_Core;
726 k->offset = offset;
727 keydb_search_copy (&k->desc, dbs);
728 k->next = hd->cache;
729 hd->cache = k;
730 hd->ncache++;
731 _cdk_log_debug ("cache: add entry off=%d type=%d\n", offset, dbs->type);
732 return 0;
733}
734
735
736static cdk_error_t
737keydb_search_copy (cdk_dbsearch_t * r_dst, cdk_dbsearch_t src)
738{
739 cdk_dbsearch_t dst;
740
741 if (!r_dst || !src)
742 return CDK_Inv_Value;
743
744 *r_dst = NULL;
745 dst = cdk_calloc (1, sizeof *dst);
746 if (!dst)
747 return CDK_Out_Of_Core;
748 dst->type = src->type;
749 switch (src->type)
750 {
751 case CDK_DBSEARCH_EXACT:
752 case CDK_DBSEARCH_SUBSTR:
753 dst->u.pattern = cdk_strdup (src->u.pattern);
754 if (!dst->u.pattern)
755 return CDK_Out_Of_Core;
756 break;
757
758 case CDK_DBSEARCH_SHORT_KEYID:
759 case CDK_DBSEARCH_KEYID:
760 dst->u.keyid[0] = src->u.keyid[0];
761 dst->u.keyid[1] = src->u.keyid[1];
762 break;
763
764 case CDK_DBSEARCH_FPR:
765 memcpy (dst->u.fpr, src->u.fpr, KEY_FPR_LEN);
766 break;
767 }
768 *r_dst = dst;
769 return 0;
770}
771
772
773/**
774 * cdk_keydb_search_start:
775 * @db: key database handle
776 * @type: specifies the search type
777 * @desc: description which depends on the type
778 *
779 * Create a new keydb search object.
780 **/
781cdk_error_t
782cdk_keydb_search_start (cdk_keydb_hd_t db, int type, void *desc)
783{
784 cdk_dbsearch_t dbs;
785 u32 *keyid;
786 char *p, tmp[3];
787 int i;
788
789 if (!db)
790 return CDK_Inv_Value;
791 if (type != CDK_DBSEARCH_NEXT && !desc)
792 return CDK_Inv_Mode;
793
794 dbs = cdk_calloc (1, sizeof *dbs);
795 if (!dbs)
796 return CDK_Out_Of_Core;
797 dbs->type = type;
798 switch (type)
799 {
800 case CDK_DBSEARCH_EXACT:
801 case CDK_DBSEARCH_SUBSTR:
802 cdk_free (dbs->u.pattern);
803 dbs->u.pattern = cdk_strdup (desc);
804 if (!dbs->u.pattern)
805 {
806 cdk_free (dbs);
807 return CDK_Out_Of_Core;
808 }
809 break;
810
811 case CDK_DBSEARCH_SHORT_KEYID:
812 keyid = desc;
813 dbs->u.keyid[1] = keyid[0];
814 break;
815
816 case CDK_DBSEARCH_KEYID:
817 keyid = desc;
818 dbs->u.keyid[0] = keyid[0];
819 dbs->u.keyid[1] = keyid[1];
820 break;
821
822 case CDK_DBSEARCH_FPR:
823 memcpy (dbs->u.fpr, desc, KEY_FPR_LEN);
824 break;
825
826 case CDK_DBSEARCH_NEXT:
827 break;
828
829 case CDK_DBSEARCH_AUTO:
830 /* Override the type with the actual db search type. */
831 dbs->type = classify_data (desc, strlen (desc));
832 switch (dbs->type)
833 {
834 case CDK_DBSEARCH_SUBSTR:
835 case CDK_DBSEARCH_EXACT:
836 cdk_free (dbs->u.pattern);
837 p = dbs->u.pattern = cdk_strdup (desc);
838 if (!p)
839 {
840 cdk_free (dbs);
841 return CDK_Out_Of_Core;
842 }
843 break;
844
845 case CDK_DBSEARCH_SHORT_KEYID:
846 case CDK_DBSEARCH_KEYID:
847 p = desc;
848 if (!strncmp (p, "0x", 2))
849 p += 2;
850 if (strlen (p) == 8)
851 {
852 dbs->u.keyid[0] = 0;
853 dbs->u.keyid[1] = strtoul (p, NULL, 16);
854 }
855 else if (strlen (p) == 16)
856 {
857 dbs->u.keyid[0] = strtoul (p, NULL, 16);
858 dbs->u.keyid[1] = strtoul (p + 8, NULL, 16);
859 }
860 else
861 { /* Invalid key ID object. */
862 cdk_free (dbs);
863 return CDK_Inv_Mode;
864 }
865 break;
866
867 case CDK_DBSEARCH_FPR:
868 p = desc;
869 if (strlen (p) != 2 * KEY_FPR_LEN)
870 {
871 cdk_free (dbs);
872 return CDK_Inv_Mode;
873 }
874 for (i = 0; i < KEY_FPR_LEN; i++)
875 {
876 tmp[0] = p[2 * i];
877 tmp[1] = p[2 * i + 1];
878 tmp[2] = 0x00;
879 dbs->u.fpr[i] = strtoul (tmp, NULL, 16);
880 }
881 break;
882 }
883 break;
884
885 default:
886 cdk_free (dbs);
887 _cdk_log_debug ("cdk_keydb_search_start: invalid mode = %d\n", type);
888 return CDK_Inv_Mode;
889 }
890
891 keydb_search_free (db->dbs);
892 db->dbs = dbs;
893 return 0;
894}
895
896
897static cdk_error_t
898keydb_pos_from_cache (cdk_keydb_hd_t hd, cdk_dbsearch_t ks,
899 int *r_cache_hit, off_t * r_off)
900{
901 key_table_t c;
902
903 if (!hd || !r_cache_hit || !r_off)
904 return CDK_Inv_Value;
905
906 /* Reset the values. */
907 *r_cache_hit = 0;
908 *r_off = 0;
909
910 c = keydb_cache_find (hd->cache, ks);
911 if (c != NULL)
912 {
913 _cdk_log_debug ("cache: found entry in cache.\n");
914 *r_cache_hit = 1;
915 *r_off = c->offset;
916 return 0;
917 }
918
919 /* No index cache available so we just return here. */
920 if (!hd->idx)
921 return 0;
922
923 if (hd->idx)
924 {
925 if (ks->type == CDK_DBSEARCH_KEYID)
926 {
927 if (keydb_idx_search (hd->idx, ks->u.keyid, NULL, r_off))
928 return CDK_Error_No_Key;
929 _cdk_log_debug ("cache: found keyid entry in idx table.\n");
930 *r_cache_hit = 1;
931 }
932 else if (ks->type == CDK_DBSEARCH_FPR)
933 {
934 if (keydb_idx_search (hd->idx, NULL, ks->u.fpr, r_off))
935 return CDK_Error_No_Key;
936 _cdk_log_debug ("cache: found fpr entry in idx table.\n");
937 *r_cache_hit = 1;
938 }
939 }
940
941 return 0;
942}
943
944
945/**
946 * cdk_keydb_search:
947 * @hd: the keydb object
948 * @ks: the keydb search object
949 * @ret_key: kbnode object to store the key
950 *
951 * Search for a key in the given keyring. The search mode is handled
952 * via @ks. If the key was found, @ret_key contains the key data.
953 **/
954cdk_error_t
955cdk_keydb_search (cdk_keydb_hd_t hd, cdk_kbnode_t * ret_key)
956{
957 cdk_stream_t kr;
958 cdk_kbnode_t knode;
959 cdk_dbsearch_t ks;
960 cdk_error_t rc = 0;
961 off_t pos = 0, off = 0;
962 int key_found = 0, cache_hit = 0;
963
964 if (!hd || !ret_key)
965 return CDK_Inv_Value;
966
967 *ret_key = NULL;
968 kr = NULL;
969 hd->search = 1;
970 rc = _cdk_keydb_open (hd, &kr);
971 if (rc)
972 return rc;
973
974 if (!hd->no_cache)
975 {
976 /* It is possible the index is not up-to-date and thus we do
977 not find the requesed key. In this case, we reset cache hit
978 and continue our normal search procedure. */
979 rc = keydb_pos_from_cache (hd, hd->dbs, &cache_hit, &off);
980 if (rc)
981 cache_hit = 0;
982 }
983
984 knode = NULL;
985 ks = hd->dbs;
986 while (!key_found && !rc)
987 {
988 if (cache_hit && ks->type != CDK_DBSEARCH_NEXT)
989 cdk_stream_seek (kr, off);
990 pos = cdk_stream_tell (kr);
991 rc = cdk_keydb_get_keyblock (kr, &knode);
992 if (rc)
993 {
994 if (rc == CDK_EOF)
995 break;
996 else
997 return rc;
998 }
999
1000 switch (ks->type)
1001 {
1002 case CDK_DBSEARCH_SHORT_KEYID:
1003 case CDK_DBSEARCH_KEYID:
1004 key_found = find_by_keyid (knode, ks);
1005 break;
1006
1007 case CDK_DBSEARCH_FPR:
1008 key_found = find_by_fpr (knode, ks);
1009 break;
1010
1011 case CDK_DBSEARCH_EXACT:
1012 case CDK_DBSEARCH_SUBSTR:
1013 key_found = find_by_pattern (knode, ks);
1014 break;
1015
1016 case CDK_DBSEARCH_NEXT:
1017 key_found = knode ? 1 : 0;
1018 break;
1019 }
1020
1021 if (key_found)
1022 {
1023 if (!keydb_cache_find (hd->cache, ks))
1024 keydb_cache_add (hd, ks, pos);
1025 break;
1026 }
1027
1028 cdk_kbnode_release (knode);
1029 knode = NULL;
1030 }
1031
1032 hd->search = 0;
1033 if (key_found && rc == CDK_EOF)
1034 rc = 0;
1035 else if (rc == CDK_EOF && !key_found)
1036 rc = CDK_Error_No_Key;
1037 *ret_key = key_found ? knode : NULL;
1038 return rc;
1039}
1040
1041
1042cdk_error_t
1043cdk_keydb_get_bykeyid (cdk_keydb_hd_t hd, u32 * keyid, cdk_kbnode_t * ret_key)
1044{
1045 cdk_error_t rc;
1046
1047 if (!hd || !keyid || !ret_key)
1048 return CDK_Inv_Value;
1049
1050 rc = cdk_keydb_search_start (hd, CDK_DBSEARCH_KEYID, keyid);
1051 if (!rc)
1052 rc = cdk_keydb_search (hd, ret_key);
1053 return rc;
1054}
1055
1056
1057cdk_error_t
1058cdk_keydb_get_byfpr (cdk_keydb_hd_t hd, const byte * fpr,
1059 cdk_kbnode_t * r_key)
1060{
1061 cdk_error_t rc;
1062
1063 if (!hd || !fpr || !r_key)
1064 return CDK_Inv_Value;
1065
1066 rc = cdk_keydb_search_start (hd, CDK_DBSEARCH_FPR, (byte *) fpr);
1067 if (!rc)
1068 rc = cdk_keydb_search (hd, r_key);
1069 return rc;
1070}
1071
1072
1073cdk_error_t
1074cdk_keydb_get_bypattern (cdk_keydb_hd_t hd, const char *patt,
1075 cdk_kbnode_t * ret_key)
1076{
1077 cdk_error_t rc;
1078
1079 if (!hd || !patt || !ret_key)
1080 return CDK_Inv_Value;
1081
1082 rc = cdk_keydb_search_start (hd, CDK_DBSEARCH_SUBSTR, (char *) patt);
1083 if (!rc)
1084 rc = cdk_keydb_search (hd, ret_key);
1085 return rc;
1086}
1087
1088
1089static int
1090keydb_check_key (cdk_packet_t pkt)
1091{
1092 cdk_pkt_pubkey_t pk;
1093 int is_sk, valid;
1094
1095 if (pkt->pkttype == CDK_PKT_PUBLIC_KEY ||
1096 pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY)
1097 {
1098 pk = pkt->pkt.public_key;
1099 is_sk = 0;
1100 }
1101 else if (pkt->pkttype == CDK_PKT_SECRET_KEY ||
1102 pkt->pkttype == CDK_PKT_SECRET_SUBKEY)
1103 {
1104 pk = pkt->pkt.secret_key->pk;
1105 is_sk = 1;
1106 }
1107 else /* No key object. */
1108 return 0;
1109 valid = !pk->is_revoked && !pk->has_expired;
1110 if (is_sk)
1111 return valid;
1112 return valid && !pk->is_invalid;
1113}
1114
1115
1116/* Find the first kbnode with the requested packet type
1117 that represents a valid key. */
1118static cdk_kbnode_t
1119kbnode_find_valid (cdk_kbnode_t root, int pkttype)
1120{
1121 cdk_kbnode_t n;
1122
1123 for (n = root; n; n = n->next)
1124 {
1125 if (n->pkt->pkttype != pkttype)
1126 continue;
1127 if (keydb_check_key (n->pkt))
1128 return n;
1129 }
1130
1131 return NULL;
1132}
1133
1134
1135static cdk_kbnode_t
1136keydb_find_byusage (cdk_kbnode_t root, int req_usage, int is_pk)
1137{
1138 cdk_kbnode_t node, key;
1139 int req_type;
1140 long timestamp;
1141
1142 req_type = is_pk ? CDK_PKT_PUBLIC_KEY : CDK_PKT_SECRET_KEY;
1143 if (!req_usage)
1144 return kbnode_find_valid (root, req_type);
1145
1146 node = cdk_kbnode_find (root, req_type);
1147 if (node && !keydb_check_key (node->pkt))
1148 return NULL;
1149
1150 key = NULL;
1151 timestamp = 0;
1152 /* We iteratre over the all nodes and search for keys or
1153 subkeys which match the usage and which are not invalid.
1154 A timestamp is used to figure out the newest valid key. */
1155 for (node = root; node; node = node->next)
1156 {
1157 if (is_pk && (node->pkt->pkttype == CDK_PKT_PUBLIC_KEY ||
1158 node->pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY)
1159 && keydb_check_key (node->pkt)
1160 && (node->pkt->pkt.public_key->pubkey_usage & req_usage))
1161 {
1162 if (node->pkt->pkt.public_key->timestamp > timestamp)
1163 key = node;
1164 }
1165 if (!is_pk && (node->pkt->pkttype == CDK_PKT_SECRET_KEY ||
1166 node->pkt->pkttype == CDK_PKT_SECRET_SUBKEY)
1167 && keydb_check_key (node->pkt)
1168 && (node->pkt->pkt.secret_key->pk->pubkey_usage & req_usage))
1169 {
1170 if (node->pkt->pkt.secret_key->pk->timestamp > timestamp)
1171 key = node;
1172 }
1173
1174 }
1175 return key;
1176}
1177
1178
1179static cdk_kbnode_t
1180keydb_find_bykeyid (cdk_kbnode_t root, const u32 * keyid, int search_mode)
1181{
1182 cdk_kbnode_t node;
1183 u32 kid[2];
1184
1185 for (node = root; node; node = node->next)
1186 {
1187 if (!_cdk_pkt_get_keyid (node->pkt, kid))
1188 continue;
1189 if (search_mode == CDK_DBSEARCH_SHORT_KEYID && kid[1] == keyid[1])
1190 return node;
1191 else if (kid[0] == keyid[0] && kid[1] == keyid[1])
1192 return node;
1193 }
1194 return NULL;
1195}
1196
1197
1198cdk_error_t
1199_cdk_keydb_get_sk_byusage (cdk_keydb_hd_t hd, const char *name,
1200 cdk_seckey_t * ret_sk, int usage)
1201{
1202 cdk_kbnode_t knode = NULL;
1203 cdk_kbnode_t node, sk_node, pk_node;
1204 cdk_pkt_seckey_t sk;
1205 cdk_error_t rc;
1206 const char *s;
1207 int pkttype;
1208
1209 if (!ret_sk || !usage)
1210 return CDK_Inv_Value;
1211 if (!hd)
1212 return CDK_Error_No_Keyring;
1213
1214 *ret_sk = NULL;
1215 rc = cdk_keydb_search_start (hd, CDK_DBSEARCH_AUTO, (char *) name);
1216 if (rc)
1217 return rc;
1218
1219 rc = cdk_keydb_search (hd, &knode);
1220 if (rc)
1221 return rc;
1222
1223 sk_node = keydb_find_byusage (knode, usage, 0);
1224 if (!sk_node)
1225 {
1226 cdk_kbnode_release (knode);
1227 return CDK_Unusable_Key;
1228 }
1229
1230 /* We clone the node with the secret key to avoid that the
1231 packet will be released. */
1232 _cdk_kbnode_clone (sk_node);
1233 sk = sk_node->pkt->pkt.secret_key;
1234
1235 for (node = knode; node; node = node->next)
1236 {
1237 if (node->pkt->pkttype == CDK_PKT_USER_ID)
1238 {
1239 s = node->pkt->pkt.user_id->name;
1240 if (sk && !sk->pk->uid && _cdk_memistr (s, strlen (s), name))
1241 {
1242 _cdk_copy_userid (&sk->pk->uid, node->pkt->pkt.user_id);
1243 break;
1244 }
1245 }
1246 }
1247
1248 /* To find the self signature, we need the primary public key because
1249 the selected secret key might be different from the primary key. */
1250 pk_node = cdk_kbnode_find (knode, CDK_PKT_SECRET_KEY);
1251 if (!pk_node)
1252 {
1253 cdk_kbnode_release (knode);
1254 return CDK_Unusable_Key;
1255 }
1256 node = find_selfsig_node (knode, pk_node->pkt->pkt.secret_key->pk);
1257 if (sk->pk->uid && node)
1258 _cdk_copy_signature (&sk->pk->uid->selfsig, node->pkt->pkt.signature);
1259
1260 /* We only release the outer packet. */
1261 _cdk_pkt_detach_free (sk_node->pkt, &pkttype, (void *) &sk);
1262 cdk_kbnode_release (knode);
1263 *ret_sk = sk;
1264 return rc;
1265}
1266
1267
1268cdk_error_t
1269_cdk_keydb_get_pk_byusage (cdk_keydb_hd_t hd, const char *name,
1270 cdk_pubkey_t * ret_pk, int usage)
1271{
1272 cdk_kbnode_t knode, node, pk_node;
1273 cdk_pkt_pubkey_t pk;
1274 const char *s;
1275 cdk_error_t rc;
1276
1277 if (!ret_pk || !usage)
1278 return CDK_Inv_Value;
1279 if (!hd)
1280 return CDK_Error_No_Keyring;
1281
1282 *ret_pk = NULL;
1283 rc = cdk_keydb_search_start (hd, CDK_DBSEARCH_AUTO, (char *) name);
1284 if (!rc)
1285 rc = cdk_keydb_search (hd, &knode);
1286 if (rc)
1287 return rc;
1288
1289 node = keydb_find_byusage (knode, usage, 1);
1290 if (!node)
1291 {
1292 cdk_kbnode_release (knode);
1293 return CDK_Unusable_Key;
1294 }
1295
1296 pk = NULL;
1297 _cdk_copy_pubkey (&pk, node->pkt->pkt.public_key);
1298 for (node = knode; node; node = node->next)
1299 {
1300 if (node->pkt->pkttype == CDK_PKT_USER_ID)
1301 {
1302 s = node->pkt->pkt.user_id->name;
1303 if (pk && !pk->uid && _cdk_memistr (s, strlen (s), name))
1304 {
1305 _cdk_copy_userid (&pk->uid, node->pkt->pkt.user_id);
1306 break;
1307 }
1308 }
1309 }
1310
1311 /* Same as in the sk code, the selected key can be a sub key
1312 and thus we need the primary key to find the self sig. */
1313 pk_node = cdk_kbnode_find (knode, CDK_PKT_PUBLIC_KEY);
1314 if (!pk_node)
1315 {
1316 cdk_kbnode_release (knode);
1317 return CDK_Unusable_Key;
1318 }
1319 node = find_selfsig_node (knode, pk_node->pkt->pkt.public_key);
1320 if (pk->uid && node)
1321 _cdk_copy_signature (&pk->uid->selfsig, node->pkt->pkt.signature);
1322 cdk_kbnode_release (knode);
1323
1324 *ret_pk = pk;
1325 return rc;
1326}
1327
1328
1329/**
1330 * cdk_keydb_get_pk:
1331 * @hd: key db handle
1332 * @keyid: keyid of the key
1333 * @r_pk: the allocated public key
1334 *
1335 * Perform a key database search by keyid and return the raw public
1336 * key without any signatures or user id's.
1337 **/
1338cdk_error_t
1339cdk_keydb_get_pk (cdk_keydb_hd_t hd, u32 * keyid, cdk_pubkey_t * r_pk)
1340{
1341 cdk_kbnode_t knode = NULL, node;
1342 cdk_pubkey_t pk;
1343 cdk_error_t rc;
1344 size_t s_type;
1345 int pkttype;
1346
1347 if (!keyid || !r_pk)
1348 return CDK_Inv_Value;
1349 if (!hd)
1350 return CDK_Error_No_Keyring;
1351
1352 *r_pk = NULL;
1353 s_type = !keyid[0] ? CDK_DBSEARCH_SHORT_KEYID : CDK_DBSEARCH_KEYID;
1354 rc = cdk_keydb_search_start (hd, s_type, keyid);
1355 if (rc)
1356 return rc;
1357 rc = cdk_keydb_search (hd, &knode);
1358 if (rc)
1359 return rc;
1360
1361 node = keydb_find_bykeyid (knode, keyid, s_type);
1362 if (!node)
1363 {
1364 cdk_kbnode_release (knode);
1365 return CDK_Error_No_Key;
1366 }
1367
1368 /* See comment in cdk_keydb_get_sk() */
1369 _cdk_pkt_detach_free (node->pkt, &pkttype, (void *) &pk);
1370 *r_pk = pk;
1371 _cdk_kbnode_clone (node);
1372 cdk_kbnode_release (knode);
1373
1374 return rc;
1375}
1376
1377
1378/**
1379 * cdk_keydb_get_sk:
1380 * @hd: key db handle
1381 * @keyid: the keyid of the key
1382 * @ret_sk: the allocated secret key
1383 *
1384 * Perform a key database search by keyid and return
1385 * only the raw secret key without the additional nodes,
1386 * like the user id or the signatures.
1387 **/
1388cdk_error_t
1389cdk_keydb_get_sk (cdk_keydb_hd_t hd, u32 * keyid, cdk_seckey_t * ret_sk)
1390{
1391 cdk_kbnode_t snode, node;
1392 cdk_seckey_t sk;
1393 cdk_error_t rc;
1394 int pkttype;
1395
1396 if (!keyid || !ret_sk)
1397 return CDK_Inv_Value;
1398 if (!hd)
1399 return CDK_Error_No_Keyring;
1400
1401 *ret_sk = NULL;
1402 rc = cdk_keydb_get_bykeyid (hd, keyid, &snode);
1403 if (rc)
1404 return rc;
1405
1406 node = keydb_find_bykeyid (snode, keyid, CDK_DBSEARCH_KEYID);
1407 if (!node)
1408 {
1409 cdk_kbnode_release (snode);
1410 return CDK_Error_No_Key;
1411 }
1412
1413 /* We need to release the packet itself but not its contents
1414 and thus we detach the openpgp packet and release the structure. */
1415 _cdk_pkt_detach_free (node->pkt, &pkttype, (void *) &sk);
1416 _cdk_kbnode_clone (node);
1417 cdk_kbnode_release (snode);
1418
1419 *ret_sk = sk;
1420 return 0;
1421}
1422
1423
1424static int
1425is_selfsig (cdk_kbnode_t node, const u32 * keyid)
1426{
1427 cdk_pkt_signature_t sig;
1428
1429 if (node->pkt->pkttype != CDK_PKT_SIGNATURE)
1430 return 0;
1431 sig = node->pkt->pkt.signature;
1432 if ((sig->sig_class >= 0x10 && sig->sig_class <= 0x13) &&
1433 sig->keyid[0] == keyid[0] && sig->keyid[1] == keyid[1])
1434 return 1;
1435
1436 return 0;
1437}
1438
1439
1440/* Find the newest self signature for the public key @pk
1441 and return the signature node. */
1442static cdk_kbnode_t
1443find_selfsig_node (cdk_kbnode_t key, cdk_pkt_pubkey_t pk)
1444{
1445 cdk_kbnode_t n, sig;
1446 unsigned int ts;
1447 u32 keyid[2];
1448
1449 cdk_pk_get_keyid (pk, keyid);
1450 sig = NULL;
1451 ts = 0;
1452 for (n = key; n; n = n->next)
1453 {
1454 if (is_selfsig (n, keyid) && n->pkt->pkt.signature->timestamp > ts)
1455 {
1456 ts = n->pkt->pkt.signature->timestamp;
1457 sig = n;
1458 }
1459 }
1460
1461 return sig;
1462}
1463
1464
1465
1466static cdk_error_t
1467keydb_merge_selfsig (cdk_kbnode_t key, u32 * keyid)
1468{
1469 cdk_kbnode_t node, kbnode, unode;
1470 cdk_subpkt_t s = NULL;
1471 cdk_pkt_signature_t sig = NULL;
1472 cdk_pkt_userid_t uid = NULL;
1473 const byte *symalg = NULL, *hashalg = NULL, *compalg = NULL;
1474 size_t nsymalg = 0, nhashalg = 0, ncompalg = 0, n = 0;
1475 size_t key_usage = 0, key_expire = 0;
1476
1477 if (!key)
1478 return CDK_Inv_Value;
1479
1480 for (node = key; node; node = node->next)
1481 {
1482 if (!is_selfsig (node, keyid))
1483 continue;
1484 unode = cdk_kbnode_find_prev (key, node, CDK_PKT_USER_ID);
1485 if (!unode)
1486 return CDK_Error_No_Key;
1487 uid = unode->pkt->pkt.user_id;
1488 sig = node->pkt->pkt.signature;
1489 s = cdk_subpkt_find (sig->hashed, CDK_SIGSUBPKT_PRIMARY_UID);
1490 if (s)
1491 uid->is_primary = 1;
1492 s = cdk_subpkt_find (sig->hashed, CDK_SIGSUBPKT_FEATURES);
1493 if (s && s->size == 1 && s->d[0] & 0x01)
1494 uid->mdc_feature = 1;
1495 s = cdk_subpkt_find (sig->hashed, CDK_SIGSUBPKT_KEY_EXPIRE);
1496 if (s && s->size == 4)
1497 key_expire = _cdk_buftou32 (s->d);
1498 s = cdk_subpkt_find (sig->hashed, CDK_SIGSUBPKT_KEY_FLAGS);
1499 if (s)
1500 {
1501 if (s->d[0] & 0x03) /* cert + sign data */
1502 key_usage |= CDK_KEY_USG_SIGN;
1503 if (s->d[0] & 0x0C) /* encrypt comm. + storage */
1504 key_usage |= CDK_KEY_USG_ENCR;
1505 if (s->d[0] & 0x20)
1506 key_usage |= CDK_KEY_USG_AUTH;
1507 }
1508 s = cdk_subpkt_find (sig->hashed, CDK_SIGSUBPKT_PREFS_SYM);
1509 if (s)
1510 {
1511 symalg = s->d;
1512 nsymalg = s->size;
1513 n += s->size + 1;
1514 }
1515 s = cdk_subpkt_find (sig->hashed, CDK_SIGSUBPKT_PREFS_HASH);
1516 if (s)
1517 {
1518 hashalg = s->d;
1519 nhashalg = s->size;
1520 n += s->size + 1;
1521 }
1522 s = cdk_subpkt_find (sig->hashed, CDK_SIGSUBPKT_PREFS_ZIP);
1523 if (s)
1524 {
1525 compalg = s->d;
1526 ncompalg = s->size;
1527 n += s->size + 1;
1528 }
1529 if (uid->prefs != NULL)
1530 cdk_free (uid->prefs);
1531 if (!n || !hashalg || !compalg || !symalg)
1532 uid->prefs = NULL;
1533 else
1534 {
1535 uid->prefs = cdk_calloc (1, sizeof (*uid->prefs) * (n + 1));
1536 if (!uid->prefs)
1537 return CDK_Out_Of_Core;
1538 n = 0;
1539 for (; nsymalg; nsymalg--, n++)
1540 {
1541 uid->prefs[n].type = CDK_PREFTYPE_SYM;
1542 uid->prefs[n].value = *symalg++;
1543 }
1544 for (; nhashalg; nhashalg--, n++)
1545 {
1546 uid->prefs[n].type = CDK_PREFTYPE_HASH;
1547 uid->prefs[n].value = *hashalg++;
1548 }
1549 for (; ncompalg; ncompalg--, n++)
1550 {
1551 uid->prefs[n].type = CDK_PREFTYPE_ZIP;
1552 uid->prefs[n].value = *compalg++;
1553 }
1554
1555 uid->prefs[n].type = CDK_PREFTYPE_NONE; /* end of list marker */
1556 uid->prefs[n].value = 0;
1557 uid->prefs_size = n;
1558 }
1559 }
1560
1561 /* Now we add the extracted information to the primary key. */
1562 kbnode = cdk_kbnode_find (key, CDK_PKT_PUBLIC_KEY);
1563 if (kbnode)
1564 {
1565 cdk_pkt_pubkey_t pk = kbnode->pkt->pkt.public_key;
1566 if (uid && uid->prefs && n)
1567 {
1568 if (pk->prefs != NULL)
1569 cdk_free (pk->prefs);
1570 pk->prefs = _cdk_copy_prefs (uid->prefs);
1571 pk->prefs_size = n;
1572 }
1573 if (key_expire)
1574 {
1575 pk->expiredate = pk->timestamp + key_expire;
1576 pk->has_expired = pk->expiredate > (u32) time (NULL) ? 0 : 1;
1577 }
1578
1579 if (key_usage)
1580 pk->pubkey_usage = key_usage;
1581 pk->is_invalid = 0;
1582 }
1583
1584 return 0;
1585}
1586
1587
1588static cdk_error_t
1589keydb_parse_allsigs (cdk_kbnode_t knode, cdk_keydb_hd_t hd, int check)
1590{
1591 cdk_kbnode_t node, kb;
1592 cdk_pkt_signature_t sig;
1593 cdk_pkt_pubkey_t pk;
1594 cdk_subpkt_t s = NULL;
1595 u32 expiredate = 0, curtime = (u32) time (NULL);
1596 u32 keyid[2];
1597
1598 if (!knode)
1599 return CDK_Inv_Value;
1600 if (check && !hd)
1601 return CDK_Inv_Mode;
1602
1603 kb = cdk_kbnode_find (knode, CDK_PKT_SECRET_KEY);
1604 if (kb)
1605 return 0;
1606
1607 /* Reset */
1608 for (node = knode; node; node = node->next)
1609 {
1610 if (node->pkt->pkttype == CDK_PKT_USER_ID)
1611 node->pkt->pkt.user_id->is_revoked = 0;
1612 else if (node->pkt->pkttype == CDK_PKT_PUBLIC_KEY ||
1613 node->pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY)
1614 node->pkt->pkt.public_key->is_revoked = 0;
1615 }
1616
1617 kb = cdk_kbnode_find (knode, CDK_PKT_PUBLIC_KEY);
1618 if (!kb)
1619 return CDK_Wrong_Format;
1620 cdk_pk_get_keyid (kb->pkt->pkt.public_key, keyid);
1621
1622 for (node = knode; node; node = node->next)
1623 {
1624 if (node->pkt->pkttype == CDK_PKT_SIGNATURE)
1625 {
1626 sig = node->pkt->pkt.signature;
1627 /* Revocation certificates for primary keys */
1628 if (sig->sig_class == 0x20)
1629 {
1630 kb = cdk_kbnode_find_prev (knode, node, CDK_PKT_PUBLIC_KEY);
1631 if (kb)
1632 {
1633 kb->pkt->pkt.public_key->is_revoked = 1;
1634 if (check)
1635 _cdk_pk_check_sig (hd, kb, node, NULL);
1636 }
1637 else
1638 return CDK_Error_No_Key;
1639 }
1640 /* Revocation certificates for subkeys */
1641 else if (sig->sig_class == 0x28)
1642 {
1643 kb = cdk_kbnode_find_prev (knode, node, CDK_PKT_PUBLIC_SUBKEY);
1644 if (kb)
1645 {
1646 kb->pkt->pkt.public_key->is_revoked = 1;
1647 if (check)
1648 _cdk_pk_check_sig (hd, kb, node, NULL);
1649 }
1650 else
1651 return CDK_Error_No_Key;
1652 }
1653 /* Revocation certifcates for user ID's */
1654 else if (sig->sig_class == 0x30)
1655 {
1656 if (sig->keyid[0] != keyid[0] || sig->keyid[1] != keyid[1])
1657 continue; /* revokes an earlier signature, no userID. */
1658 kb = cdk_kbnode_find_prev (knode, node, CDK_PKT_USER_ID);
1659 if (kb)
1660 {
1661 kb->pkt->pkt.user_id->is_revoked = 1;
1662 if (check)
1663 _cdk_pk_check_sig (hd, kb, node, NULL);
1664 }
1665 else
1666 return CDK_Error_No_Key;
1667 }
1668 /* Direct certificates for primary keys */
1669 else if (sig->sig_class == 0x1F)
1670 {
1671 kb = cdk_kbnode_find_prev (knode, node, CDK_PKT_PUBLIC_KEY);
1672 if (kb)
1673 {
1674 pk = kb->pkt->pkt.public_key;
1675 pk->is_invalid = 0;
1676 s = cdk_subpkt_find (node->pkt->pkt.signature->hashed,
1677 CDK_SIGSUBPKT_KEY_EXPIRE);
1678 if (s)
1679 {
1680 expiredate = _cdk_buftou32 (s->d);
1681 pk->expiredate = pk->timestamp + expiredate;
1682 pk->has_expired = pk->expiredate > curtime ? 0 : 1;
1683 }
1684 if (check)
1685 _cdk_pk_check_sig (hd, kb, node, NULL);
1686 }
1687 else
1688 return CDK_Error_No_Key;
1689 }
1690 /* Direct certificates for subkeys */
1691 else if (sig->sig_class == 0x18)
1692 {
1693 kb = cdk_kbnode_find_prev (knode, node, CDK_PKT_PUBLIC_SUBKEY);
1694 if (kb)
1695 {
1696 pk = kb->pkt->pkt.public_key;
1697 pk->is_invalid = 0;
1698 s = cdk_subpkt_find (node->pkt->pkt.signature->hashed,
1699 CDK_SIGSUBPKT_KEY_EXPIRE);
1700 if (s)
1701 {
1702 expiredate = _cdk_buftou32 (s->d);
1703 pk->expiredate = pk->timestamp + expiredate;
1704 pk->has_expired = pk->expiredate > curtime ? 0 : 1;
1705 }
1706 if (check)
1707 _cdk_pk_check_sig (hd, kb, node, NULL);
1708 }
1709 else
1710 return CDK_Error_No_Key;
1711 }
1712 }
1713 }
1714 node = cdk_kbnode_find (knode, CDK_PKT_PUBLIC_KEY);
1715 if (node && node->pkt->pkt.public_key->version == 3)
1716 {
1717 /* v3 public keys have no additonal signatures for the key directly.
1718 we say the key is valid when we have at least a self signature. */
1719 pk = node->pkt->pkt.public_key;
1720 for (node = knode; node; node = node->next)
1721 {
1722 if (is_selfsig (node, keyid))
1723 {
1724 pk->is_invalid = 0;
1725 break;
1726 }
1727 }
1728 }
1729 if (node && (node->pkt->pkt.public_key->is_revoked ||
1730 node->pkt->pkt.public_key->has_expired))
1731 {
1732 /* If the primary key has been revoked, mark all subkeys as invalid
1733 because without a primary key they are not useable */
1734 for (node = knode; node; node = node->next)
1735 {
1736 if (node->pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY)
1737 node->pkt->pkt.public_key->is_invalid = 1;
1738 }
1739 }
1740
1741 return 0;
1742}
1743
1744
1745cdk_error_t
1746cdk_keydb_get_keyblock (cdk_stream_t inp, cdk_kbnode_t * r_knode)
1747{
1748 cdk_packet_t pkt;
1749 cdk_kbnode_t knode, node;
1750 cdk_desig_revoker_t revkeys;
1751 cdk_error_t rc;
1752 u32 keyid[2], main_keyid[2];
1753 off_t old_off;
1754 int key_seen, got_key;
1755
1756 if (!inp || !r_knode)
1757 return CDK_Inv_Value;
1758
1759 /* Reset all values. */
1760 keyid[0] = keyid[1] = 0;
1761 main_keyid[0] = main_keyid[1] = 0;
1762 revkeys = NULL;
1763 knode = NULL;
1764 key_seen = got_key = 0;
1765
1766 *r_knode = NULL;
1767 rc = CDK_EOF;
1768 while (!cdk_stream_eof (inp))
1769 {
1770 cdk_pkt_new (&pkt);
1771 old_off = cdk_stream_tell (inp);
1772 rc = cdk_pkt_read (inp, pkt);
1773 if (rc)
1774 {
1775 cdk_pkt_release (pkt);
1776 if (rc == CDK_EOF)
1777 break;
1778 else
1779 { /* Release all packets we reached so far. */
1780 _cdk_log_debug ("keydb_get_keyblock: error %d\n", rc);
1781 cdk_kbnode_release (knode);
1782 return rc;
1783 }
1784 }
1785 if (pkt->pkttype == CDK_PKT_PUBLIC_KEY ||
1786 pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY ||
1787 pkt->pkttype == CDK_PKT_SECRET_KEY ||
1788 pkt->pkttype == CDK_PKT_SECRET_SUBKEY)
1789 {
1790 if (key_seen && (pkt->pkttype == CDK_PKT_PUBLIC_KEY ||
1791 pkt->pkttype == CDK_PKT_SECRET_KEY))
1792 {
1793 /* The next key starts here so set the file pointer
1794 and leave the loop. */
1795 cdk_stream_seek (inp, old_off);
1796 cdk_pkt_release (pkt);
1797 break;
1798 }
1799 if (pkt->pkttype == CDK_PKT_PUBLIC_KEY ||
1800 pkt->pkttype == CDK_PKT_SECRET_KEY)
1801 {
1802 _cdk_pkt_get_keyid (pkt, main_keyid);
1803 key_seen = 1;
1804 }
1805 else if (pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY ||
1806 pkt->pkttype == CDK_PKT_SECRET_SUBKEY)
1807 {
1808 if (pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY)
1809 {
1810 pkt->pkt.public_key->main_keyid[0] = main_keyid[0];
1811 pkt->pkt.public_key->main_keyid[1] = main_keyid[1];
1812 }
1813 else
1814 {
1815 pkt->pkt.secret_key->main_keyid[0] = main_keyid[0];
1816 pkt->pkt.secret_key->main_keyid[1] = main_keyid[1];
1817 }
1818 }
1819 /* We save this for the signature */
1820 _cdk_pkt_get_keyid (pkt, keyid);
1821 got_key = 1;
1822 }
1823 else if (pkt->pkttype == CDK_PKT_USER_ID)
1824 ;
1825 else if (pkt->pkttype == CDK_PKT_SIGNATURE)
1826 {
1827 pkt->pkt.signature->key[0] = keyid[0];
1828 pkt->pkt.signature->key[1] = keyid[1];
1829 if (pkt->pkt.signature->sig_class == 0x1F &&
1830 pkt->pkt.signature->revkeys)
1831 revkeys = pkt->pkt.signature->revkeys;
1832 }
1833 node = cdk_kbnode_new (pkt);
1834 if (!knode)
1835 knode = node;
1836 else
1837 _cdk_kbnode_add (knode, node);
1838 }
1839
1840 if (got_key)
1841 {
1842 keydb_merge_selfsig (knode, main_keyid);
1843 rc = keydb_parse_allsigs (knode, NULL, 0);
1844 if (revkeys)
1845 {
1846 node = cdk_kbnode_find (knode, CDK_PKT_PUBLIC_KEY);
1847 if (node)
1848 node->pkt->pkt.public_key->revkeys = revkeys;
1849 }
1850 }
1851 else
1852 cdk_kbnode_release (knode);
1853 *r_knode = got_key ? knode : NULL;
1854
1855 /* It is possible that we are in an EOF condition after we
1856 successfully read a keyblock. For example if the requested
1857 key is the last in the file. */
1858 if (rc == CDK_EOF && got_key)
1859 rc = 0;
1860 return rc;
1861}
1862
1863
1864/* Return the type of the given data. In case it cannot be classified,
1865 a substring search will be performed. */
1866static int
1867classify_data (const byte * buf, size_t len)
1868{
1869 int type;
1870 int i;
1871
1872 if (buf[0] == '0' && (buf[1] == 'x' || buf[1] == 'X'))
1873 { /* Skip hex prefix. */
1874 buf += 2;
1875 len -= 2;
1876 }
1877
1878 /* The length of the data does not match either a keyid or a fingerprint. */
1879 if (len != 8 && len != 16 && len != 40)
1880 return CDK_DBSEARCH_SUBSTR;
1881
1882 for (i = 0; i < len; i++)
1883 {
1884 if (!isxdigit (buf[i]))
1885 return CDK_DBSEARCH_SUBSTR;
1886 }
1887 if (i != len)
1888 return CDK_DBSEARCH_SUBSTR;
1889 switch (len)
1890 {
1891 case 8:
1892 type = CDK_DBSEARCH_SHORT_KEYID;
1893 break;
1894 case 16:
1895 type = CDK_DBSEARCH_KEYID;
1896 break;
1897 case 40:
1898 type = CDK_DBSEARCH_FPR;
1899 break;
1900 default:
1901 type = CDK_DBSEARCH_SUBSTR;
1902 break;
1903 }
1904
1905 return type;
1906}
1907
1908
1909/**
1910 * cdk_keydb_export:
1911 * @hd: the keydb handle
1912 * @out: the output stream
1913 * @remusr: the list of key pattern to export
1914 *
1915 * Export a list of keys to the given output stream.
1916 * Use string list with names for pattering searching.
1917 * This procedure strips local signatures.
1918 **/
1919cdk_error_t
1920cdk_keydb_export (cdk_keydb_hd_t hd, cdk_stream_t out, cdk_strlist_t remusr)
1921{
1922 cdk_kbnode_t knode, node;
1923 cdk_strlist_t r;
1924 cdk_error_t rc;
1925 int old_ctb;
1926
1927 for (r = remusr; r; r = r->next)
1928 {
1929 rc = cdk_keydb_search_start (hd, CDK_DBSEARCH_AUTO, r->d);
1930 if (rc)
1931 return rc;
1932 rc = cdk_keydb_search (hd, &knode);
1933 if (rc)
1934 return rc;
1935 node = cdk_kbnode_find (knode, CDK_PKT_PUBLIC_KEY);
1936 if (!node)
1937 return CDK_Error_No_Key;
1938
1939 /* If the key is a version 3 key, use the old packet
1940 format for the output. */
1941 if (node->pkt->pkt.public_key->version == 3)
1942 old_ctb = 1;
1943 else
1944 old_ctb = 0;
1945
1946 for (node = knode; node; node = node->next)
1947 {
1948 /* No specified format; skip them */
1949 if (node->pkt->pkttype == CDK_PKT_RING_TRUST)
1950 continue;
1951 /* We never export local signed signatures */
1952 if (node->pkt->pkttype == CDK_PKT_SIGNATURE &&
1953 !node->pkt->pkt.signature->flags.exportable)
1954 continue;
1955 /* Filter out invalid signatures */
1956 if (node->pkt->pkttype == CDK_PKT_SIGNATURE &&
1957 !KEY_CAN_SIGN (node->pkt->pkt.signature->pubkey_algo))
1958 continue;
1959
1960 /* Adjust the ctb flag if needed. */
1961 node->pkt->old_ctb = old_ctb;
1962 rc = cdk_pkt_write (out, node->pkt);
1963 if (rc)
1964 {
1965 cdk_kbnode_release (knode);
1966 return rc;
1967 }
1968 }
1969 cdk_kbnode_release (knode);
1970 knode = NULL;
1971 }
1972 return 0;
1973}
1974
1975
1976static cdk_packet_t
1977find_key_packet (cdk_kbnode_t knode, int *r_is_sk)
1978{
1979 cdk_packet_t pkt;
1980
1981 pkt = cdk_kbnode_find_packet (knode, CDK_PKT_PUBLIC_KEY);
1982 if (!pkt)
1983 {
1984 pkt = cdk_kbnode_find_packet (knode, CDK_PKT_SECRET_KEY);
1985 if (r_is_sk)
1986 *r_is_sk = pkt ? 1 : 0;
1987 }
1988 return pkt;
1989}
1990
1991
1992/* Return 1 if the is allowd in a key node. */
1993static int
1994is_key_node (cdk_kbnode_t node)
1995{
1996 switch (node->pkt->pkttype)
1997 {
1998 case CDK_PKT_SIGNATURE:
1999 case CDK_PKT_SECRET_KEY:
2000 case CDK_PKT_PUBLIC_KEY:
2001 case CDK_PKT_SECRET_SUBKEY:
2002 case CDK_PKT_PUBLIC_SUBKEY:
2003 case CDK_PKT_USER_ID:
2004 case CDK_PKT_ATTRIBUTE:
2005 return 1;
2006
2007 default:
2008 return 0;
2009 }
2010
2011 return 0;
2012}
2013
2014
2015cdk_error_t
2016cdk_keydb_import (cdk_keydb_hd_t hd, cdk_kbnode_t knode)
2017{
2018 cdk_kbnode_t node, chk;
2019 cdk_packet_t pkt;
2020 cdk_stream_t out;
2021 cdk_error_t rc;
2022 u32 keyid[2];
2023
2024 if (!hd || !knode)
2025 return CDK_Inv_Value;
2026
2027 pkt = find_key_packet (knode, NULL);
2028 if (!pkt)
2029 return CDK_Inv_Packet;
2030
2031 _cdk_pkt_get_keyid (pkt, keyid);
2032 chk = NULL;
2033 cdk_keydb_get_bykeyid (hd, keyid, &chk);
2034 if (chk)
2035 { /* FIXME: search for new signatures */
2036 cdk_kbnode_release (chk);
2037 return 0;
2038 }
2039
2040 /* We append data to the stream so we need to close
2041 the stream here to re-open it later. */
2042 if (hd->fp)
2043 {
2044 cdk_stream_close (hd->fp);
2045 hd->fp = NULL;
2046 }
2047
2048 rc = _cdk_stream_append (hd->name, &out);
2049 if (rc)
2050 return rc;
2051
2052 for (node = knode; node; node = node->next)
2053 {
2054 if (node->pkt->pkttype == CDK_PKT_RING_TRUST)
2055 continue; /* No uniformed syntax for this packet */
2056 if (node->pkt->pkttype == CDK_PKT_SIGNATURE &&
2057 !node->pkt->pkt.signature->flags.exportable)
2058 {
2059 _cdk_log_debug ("key db import: skip local signature\n");
2060 continue;
2061 }
2062
2063 if (!is_key_node (node))
2064 {
2065 _cdk_log_debug ("key db import: skip invalid node of type %d\n",
2066 node->pkt->pkttype);
2067 continue;
2068 }
2069
2070 rc = cdk_pkt_write (out, node->pkt);
2071 if (rc)
2072 {
2073 cdk_stream_close (out);
2074 return rc;
2075 }
2076 }
2077
2078 cdk_stream_close (out);
2079 if (!hd->no_cache)
2080 cdk_keydb_idx_rebuild (hd);
2081 hd->stats.new_keys++;
2082
2083 return 0;
2084}
2085
2086
2087cdk_error_t
2088_cdk_keydb_check_userid (cdk_keydb_hd_t hd, u32 * keyid, const char *id)
2089{
2090 cdk_kbnode_t knode = NULL, unode = NULL;
2091 cdk_error_t rc;
2092 int check;
2093
2094 if (!hd)
2095 return CDK_Inv_Value;
2096
2097 rc = cdk_keydb_search_start (hd, CDK_DBSEARCH_KEYID, keyid);
2098 if (rc)
2099 return rc;
2100 rc = cdk_keydb_search (hd, &knode);
2101 if (rc)
2102 return rc;
2103
2104 rc = cdk_keydb_search_start (hd, CDK_DBSEARCH_EXACT, (char *) id);
2105 if (!rc)
2106 rc = cdk_keydb_search (hd, &unode);
2107 if (rc)
2108 {
2109 cdk_kbnode_release (knode);
2110 return rc;
2111 }
2112
2113 check = 0;
2114 cdk_keydb_search_start (hd, CDK_DBSEARCH_KEYID, keyid);
2115 if (unode && find_by_keyid (unode, hd->dbs))
2116 check++;
2117 cdk_kbnode_release (unode);
2118
2119 cdk_keydb_search_start (hd, CDK_DBSEARCH_EXACT, (char *) id);
2120 if (knode && find_by_pattern (knode, hd->dbs))
2121 check++;
2122 cdk_kbnode_release (knode);
2123
2124 return check == 2 ? 0 : CDK_Inv_Value;
2125}
2126
2127
2128/**
2129 * cdk_keydb_check_sk:
2130 * @hd: the key db handle
2131 * @keyid: the 64-bit keyid
2132 *
2133 * Check if a secret key with the given key ID is available
2134 * in the key database.
2135 **/
2136cdk_error_t
2137cdk_keydb_check_sk (cdk_keydb_hd_t hd, u32 * keyid)
2138{
2139 cdk_stream_t db;
2140 cdk_packet_t pkt;
2141 cdk_error_t rc;
2142 u32 kid[2];
2143
2144 if (!hd || !keyid)
2145 return CDK_Inv_Value;
2146 if (!hd->secret)
2147 return CDK_Inv_Mode;
2148
2149 rc = _cdk_keydb_open (hd, &db);
2150 if (rc)
2151 return rc;
2152 cdk_pkt_new (&pkt);
2153 while (!cdk_pkt_read (db, pkt))
2154 {
2155 if (pkt->pkttype != CDK_PKT_SECRET_KEY &&
2156 pkt->pkttype != CDK_PKT_SECRET_SUBKEY)
2157 {
2158 cdk_pkt_free (pkt);
2159 continue;
2160 }
2161 cdk_sk_get_keyid (pkt->pkt.secret_key, kid);
2162 if (KEYID_CMP (kid, keyid))
2163 {
2164 cdk_pkt_release (pkt);
2165 return 0;
2166 }
2167 cdk_pkt_free (pkt);
2168 }
2169 cdk_pkt_release (pkt);
2170 return CDK_Error_No_Key;
2171}
2172
2173
2174/**
2175 * cdk_listkey_start:
2176 * @r_ctx: pointer to store the new context
2177 * @db: the key database handle
2178 * @patt: string pattern
2179 * @fpatt: recipients from a stringlist to show
2180 *
2181 * Prepare a key listing with the given parameters. Two modes are supported.
2182 * The first mode uses string pattern to determine if the key should be
2183 * returned or not. The other mode uses a string list to request the key
2184 * which should be listed.
2185 **/
2186cdk_error_t
2187cdk_listkey_start (cdk_listkey_t * r_ctx, cdk_keydb_hd_t db,
2188 const char *patt, cdk_strlist_t fpatt)
2189{
2190 cdk_listkey_t ctx;
2191 cdk_stream_t inp;
2192 cdk_error_t rc;
2193
2194 if (!r_ctx || !db)
2195 return CDK_Inv_Value;
2196 if ((patt && fpatt) || (!patt && !fpatt))
2197 return CDK_Inv_Mode;
2198 rc = _cdk_keydb_open (db, &inp);
2199 if (rc)
2200 return rc;
2201 ctx = cdk_calloc (1, sizeof *ctx);
2202 if (!ctx)
2203 return CDK_Out_Of_Core;
2204 ctx->db = db;
2205 ctx->inp = inp;
2206 if (patt)
2207 {
2208 ctx->u.patt = cdk_strdup (patt);
2209 if (!ctx->u.patt)
2210 return CDK_Out_Of_Core;
2211 }
2212 else if (fpatt)
2213 {
2214 cdk_strlist_t l;
2215 for (l = fpatt; l; l = l->next)
2216 cdk_strlist_add (&ctx->u.fpatt, l->d);
2217 }
2218 ctx->type = patt ? 1 : 0;
2219 ctx->init = 1;
2220 *r_ctx = ctx;
2221 return 0;
2222}
2223
2224
2225/**
2226 * cdk_listkey_close:
2227 * @ctx: the list key context
2228 *
2229 * Free the list key context.
2230 **/
2231void
2232cdk_listkey_close (cdk_listkey_t ctx)
2233{
2234 if (!ctx)
2235 return;
2236
2237 if (ctx->type)
2238 cdk_free (ctx->u.patt);
2239 else
2240 cdk_strlist_free (ctx->u.fpatt);
2241 cdk_free (ctx);
2242}
2243
2244
2245/**
2246 * cdk_listkey_next:
2247 * @ctx: list key context
2248 * @r_key: the pointer to the new key node object
2249 *
2250 * Retrieve the next key from the pattern of the key list context.
2251 **/
2252cdk_error_t
2253cdk_listkey_next (cdk_listkey_t ctx, cdk_kbnode_t * ret_key)
2254{
2255 if (!ctx || !ret_key)
2256 return CDK_Inv_Value;
2257 if (!ctx->init)
2258 return CDK_Inv_Mode;
2259
2260 if (ctx->type && ctx->u.patt[0] == '*')
2261 return cdk_keydb_get_keyblock (ctx->inp, ret_key);
2262 else if (ctx->type)
2263 {
2264 cdk_kbnode_t node;
2265 struct cdk_dbsearch_s ks;
2266 cdk_error_t rc;
2267
2268 for (;;)
2269 {
2270 rc = cdk_keydb_get_keyblock (ctx->inp, &node);
2271 if (rc)
2272 return rc;
2273 memset (&ks, 0, sizeof (ks));
2274 ks.type = CDK_DBSEARCH_SUBSTR;
2275 ks.u.pattern = ctx->u.patt;
2276 if (find_by_pattern (node, &ks))
2277 {
2278 *ret_key = node;
2279 return 0;
2280 }
2281 cdk_kbnode_release (node);
2282 node = NULL;
2283 }
2284 }
2285 else
2286 {
2287 if (!ctx->t)
2288 ctx->t = ctx->u.fpatt;
2289 else if (ctx->t->next)
2290 ctx->t = ctx->t->next;
2291 else
2292 return CDK_EOF;
2293 return cdk_keydb_get_bypattern (ctx->db, ctx->t->d, ret_key);
2294 }
2295 return CDK_General_Error;
2296}
2297
2298
2299int
2300_cdk_keydb_is_secret (cdk_keydb_hd_t db)
2301{
2302 return db->secret;
2303}
diff --git a/src/daemon/https/opencdk/literal.c b/src/daemon/https/opencdk/literal.c
new file mode 100644
index 00000000..4ccba6b2
--- /dev/null
+++ b/src/daemon/https/opencdk/literal.c
@@ -0,0 +1,307 @@
1/* Literal.c - Literal packet filters
2 * Copyright (C) 2002, 2003 Timo Schulz
3 *
4 * This file is part of OpenCDK.
5 *
6 * OpenCDK is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * OpenCDK is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16#ifdef HAVE_CONFIG_H
17# include <config.h>
18#endif
19#include <stdio.h>
20#include <time.h>
21
22#include "opencdk.h"
23#include "main.h"
24#include "filters.h"
25
26
27/* Duplicate the string @s but strip of possible
28 relative folder names of it. */
29static char *
30dup_trim_filename (const char *s)
31{
32 char *p = NULL;
33
34 p = strrchr (s, '/');
35 if (!p)
36 p = strrchr (s, '\\');
37 if (!p)
38 return cdk_strdup (s);
39 return cdk_strdup (p + 1);
40}
41
42
43static cdk_error_t
44literal_decode (void *opaque, FILE * in, FILE * out)
45{
46 literal_filter_t *pfx = opaque;
47 cdk_stream_t si, so;
48 cdk_packet_t pkt;
49 cdk_pkt_literal_t pt;
50 byte buf[BUFSIZE];
51 size_t nread;
52 int bufsize;
53 cdk_error_t rc;
54
55 _cdk_log_debug ("literal filter: decode\n");
56
57 if (!pfx || !in || !out)
58 return CDK_Inv_Value;
59
60 rc = _cdk_stream_fpopen (in, STREAMCTL_READ, &si);
61 if (rc)
62 return rc;
63
64 cdk_pkt_new (&pkt);
65 rc = cdk_pkt_read (si, pkt);
66 if (rc || pkt->pkttype != CDK_PKT_LITERAL)
67 {
68 cdk_pkt_release (pkt);
69 cdk_stream_close (si);
70 return !rc ? CDK_Inv_Packet : rc;
71 }
72
73 rc = _cdk_stream_fpopen (out, STREAMCTL_WRITE, &so);
74 if (rc)
75 {
76 cdk_pkt_release (pkt);
77 cdk_stream_close (si);
78 return rc;
79 }
80
81 pt = pkt->pkt.literal;
82 pfx->mode = pt->mode;
83
84 if (pfx->filename && pt->namelen > 0)
85 {
86 /* The name in the literal packet is more authorative. */
87 cdk_free (pfx->filename);
88 pfx->filename = dup_trim_filename (pt->name);
89 }
90 else if (!pfx->filename && pt->namelen > 0)
91 pfx->filename = dup_trim_filename (pt->name);
92 else if (!pt->namelen && !pfx->filename && pfx->orig_filename)
93 {
94 /* In this case, we need to derrive the output file name
95 from the original name and cut off the OpenPGP extension.
96 If this is not possible, we return an error. */
97 if (!stristr (pfx->orig_filename, ".gpg") &&
98 !stristr (pfx->orig_filename, ".pgp") &&
99 !stristr (pfx->orig_filename, ".asc"))
100 {
101 cdk_pkt_release (pkt);
102 cdk_stream_close (si);
103 cdk_stream_close (so);
104 _cdk_log_debug
105 ("literal filter: no file name and no PGP extension\n");
106 return CDK_Inv_Mode;
107 }
108 _cdk_log_debug ("literal filter: derrive file name from original\n");
109 pfx->filename = dup_trim_filename (pfx->orig_filename);
110 pfx->filename[strlen (pfx->filename) - 4] = '\0';
111 }
112
113 while (!feof (in))
114 {
115 _cdk_log_debug ("literal_decode: part on %d size %lu\n",
116 pfx->blkmode.on, pfx->blkmode.size);
117 if (pfx->blkmode.on)
118 bufsize = pfx->blkmode.size;
119 else
120 bufsize = pt->len < DIM (buf) ? pt->len : DIM (buf);
121 nread = cdk_stream_read (pt->buf, buf, bufsize);
122 if (nread == EOF)
123 {
124 rc = CDK_File_Error;
125 break;
126 }
127 if (pfx->md)
128 gcry_md_write (pfx->md, buf, nread);
129 cdk_stream_write (so, buf, nread);
130 pt->len -= nread;
131 if (pfx->blkmode.on)
132 {
133 pfx->blkmode.size = _cdk_pkt_read_len (in, &pfx->blkmode.on);
134 if (pfx->blkmode.size == (size_t) EOF)
135 return CDK_Inv_Packet;
136 }
137 if (pt->len <= 0 && !pfx->blkmode.on)
138 break;
139 }
140
141 cdk_stream_close (si);
142 cdk_stream_close (so);
143 cdk_pkt_release (pkt);
144 return rc;
145}
146
147
148static char
149intmode_to_char (int mode)
150{
151 switch (mode)
152 {
153 case CDK_LITFMT_BINARY:
154 return 'b';
155 case CDK_LITFMT_TEXT:
156 return 't';
157 case CDK_LITFMT_UNICODE:
158 return 'u';
159 default:
160 return 'b';
161 }
162
163 return 'b';
164}
165
166
167static cdk_error_t
168literal_encode (void *opaque, FILE * in, FILE * out)
169{
170 literal_filter_t *pfx = opaque;
171 cdk_pkt_literal_t pt;
172 cdk_stream_t si;
173 cdk_packet_t pkt;
174 size_t filelen;
175 cdk_error_t rc;
176
177 _cdk_log_debug ("literal filter: encode\n");
178
179 if (!pfx || !in || !out)
180 return CDK_Inv_Value;
181 if (!pfx->filename)
182 {
183 pfx->filename = cdk_strdup ("_CONSOLE");
184 if (!pfx->filename)
185 return CDK_Out_Of_Core;
186 }
187
188 rc = _cdk_stream_fpopen (in, STREAMCTL_READ, &si);
189 if (rc)
190 return rc;
191
192 filelen = strlen (pfx->filename);
193 cdk_pkt_new (&pkt);
194 pt = pkt->pkt.literal = cdk_calloc (1, sizeof *pt + filelen - 1);
195 if (!pt)
196 {
197 cdk_pkt_release (pkt);
198 cdk_stream_close (si);
199 return CDK_Out_Of_Core;
200 }
201 memcpy (pt->name, pfx->filename, filelen);
202 pt->namelen = filelen;
203 pt->name[pt->namelen] = '\0';
204 pt->timestamp = (u32) time (NULL);
205 pt->mode = intmode_to_char (pfx->mode);
206 pt->len = cdk_stream_get_length (si);
207 pt->buf = si;
208 pkt->old_ctb = 1;
209 pkt->pkttype = CDK_PKT_LITERAL;
210 pkt->pkt.literal = pt;
211 rc = _cdk_pkt_write_fp (out, pkt);
212
213 cdk_pkt_release (pkt);
214 cdk_stream_close (si);
215 return rc;
216}
217
218
219int
220_cdk_filter_literal (void *opaque, int ctl, FILE * in, FILE * out)
221{
222 if (ctl == STREAMCTL_READ)
223 return literal_decode (opaque, in, out);
224 else if (ctl == STREAMCTL_WRITE)
225 return literal_encode (opaque, in, out);
226 else if (ctl == STREAMCTL_FREE)
227 {
228 literal_filter_t *pfx = opaque;
229 if (pfx)
230 {
231 _cdk_log_debug ("free literal filter\n");
232 cdk_free (pfx->filename);
233 pfx->filename = NULL;
234 cdk_free (pfx->orig_filename);
235 pfx->orig_filename = NULL;
236 return 0;
237 }
238 }
239 return CDK_Inv_Mode;
240}
241
242
243static int
244text_encode (void *opaque, FILE * in, FILE * out)
245{
246 const char *s;
247 char buf[2048];
248
249 if (!in || !out)
250 return CDK_Inv_Value;
251
252 /* FIXME: This code does not work for very long lines. */
253 while (!feof (in))
254 {
255 s = fgets (buf, DIM (buf) - 1, in);
256 if (!s)
257 break;
258 _cdk_trim_string (buf, 1);
259 fwrite (buf, 1, strlen (buf), out);
260 }
261
262 return 0;
263}
264
265
266static int
267text_decode (void *opaque, FILE * in, FILE * out)
268{
269 text_filter_t *tfx = opaque;
270 const char *s;
271 char buf[2048];
272
273 if (!tfx || !in || !out)
274 return CDK_Inv_Value;
275
276 while (!feof (in))
277 {
278 s = fgets (buf, DIM (buf) - 1, in);
279 if (!s)
280 break;
281 _cdk_trim_string (buf, 0);
282 fwrite (buf, 1, strlen (buf), out);
283 fwrite (tfx->lf, 1, strlen (tfx->lf), out);
284 }
285
286 return 0;
287}
288
289
290int
291_cdk_filter_text (void *opaque, int ctl, FILE * in, FILE * out)
292{
293 if (ctl == STREAMCTL_READ)
294 return text_encode (opaque, in, out);
295 else if (ctl == STREAMCTL_WRITE)
296 return text_decode (opaque, in, out);
297 else if (ctl == STREAMCTL_FREE)
298 {
299 text_filter_t *tfx = opaque;
300 if (tfx)
301 {
302 _cdk_log_debug ("free text filter\n");
303 tfx->lf = NULL;
304 }
305 }
306 return CDK_Inv_Mode;
307}
diff --git a/src/daemon/https/opencdk/main.c b/src/daemon/https/opencdk/main.c
new file mode 100644
index 00000000..be5aec62
--- /dev/null
+++ b/src/daemon/https/opencdk/main.c
@@ -0,0 +1,779 @@
1/* main.c
2 * Copyright (C) 2001, 2002, 2003, 2007 Timo Schulz
3 *
4 * This file is part of OpenCDK.
5 *
6 * OpenCDK is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * OpenCDK is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16#ifdef HAVE_CONFIG_H
17# include <config.h>
18#endif
19#include <stdio.h>
20#include <errno.h>
21#ifdef HAVE_UNISTD_H
22# include <unistd.h>
23#endif
24#ifdef _WIN32
25#include <windows.h>
26#endif
27
28#include "opencdk.h"
29#include "main.h"
30#include "packet.h"
31
32
33/* Set a default cipher algorithm and a digest algorithm.
34 Even if AES and SHA-256 are not 'MUST' in the latest
35 OpenPGP draft, AES seems to be a good choice. */
36#define DEFAULT_CIPHER_ALGO GCRY_CIPHER_AES
37#define DEFAULT_DIGEST_ALGO GCRY_MD_SHA256
38
39/* The site of the secure memory which is allocated in gcrypt. */
40#define SECMEM_SIZE 16384
41
42
43/* Hooks to custom memory allocation functions. */
44static void *(*alloc_func) (size_t n) = gcry_xmalloc;
45static void *(*alloc_secure_func) (size_t n) = gcry_malloc_secure;
46static void *(*realloc_func) (void *p, size_t n) = gcry_realloc;
47static void *(*calloc_func) (size_t m, size_t n) = gcry_calloc;
48static void (*free_func) (void *) = gcry_free;
49static int malloc_hooks = 0;
50static int secmem_init = 0;
51
52/* Global settings for the logging. */
53static cdk_log_fnc_t log_handler = NULL;
54static void *log_handler_value = NULL;
55static int log_level = CDK_LOG_NONE;
56
57
58/**
59 * cdk_strerror:
60 * @ec: the error number
61 *
62 * Return an error text for the given id.
63 **/
64const char *
65cdk_strerror (int ec)
66{
67 static char buf[20];
68
69 switch (ec)
70 {
71 case CDK_EOF:
72 return "End Of File";
73 case CDK_Success:
74 return "No error";
75 case CDK_General_Error:
76 return "General error";
77 case CDK_File_Error:
78 return strerror (errno);
79 case CDK_Bad_Sig:
80 return "Bad signature";
81 case CDK_Inv_Packet:
82 return "Invalid packet";
83 case CDK_Inv_Algo:
84 return "Invalid algorithm";
85 case CDK_Not_Implemented:
86 return "This is not implemented yet";
87 case CDK_Armor_Error:
88 return "ASCII armor error";
89 case CDK_Armor_CRC_Error:
90 return "ASCII armored damaged (CRC error)";
91 case CDK_MPI_Error:
92 return "Invalid or missformed MPI";
93 case CDK_Inv_Value:
94 return "Invalid parameter or value";
95 case CDK_Error_No_Key:
96 return "No key available or not found";
97 case CDK_Chksum_Error:
98 return "Check for key does not match";
99 case CDK_Time_Conflict:
100 return "Time conflict";
101 case CDK_Zlib_Error:
102 return "ZLIB error";
103 case CDK_Weak_Key:
104 return "Weak key was detected";
105 case CDK_Out_Of_Core:
106 return "Out of core!!";
107 case CDK_Wrong_Seckey:
108 return "Wrong secret key";
109 case CDK_Wrong_Format:
110 return "Data has wrong format";
111 case CDK_Bad_MDC:
112 return "Manipulated MDC detected";
113 case CDK_Inv_Mode:
114 return "Invalid mode";
115 case CDK_Error_No_Keyring:
116 return "No keyring available";
117 case CDK_Inv_Packet_Ver:
118 return "Invalid version for packet";
119 case CDK_Too_Short:
120 return "Buffer or object is too short";
121 case CDK_Unusable_Key:
122 return "Unusable public key";
123 case CDK_No_Data:
124 return "No data";
125 case CDK_No_Passphrase:
126 return "No passphrase supplied";
127 case CDK_Network_Error:
128 return "A network error occurred";
129 default:
130 sprintf (buf, "ec=%d", ec);
131 return buf;
132 }
133 return NULL;
134}
135
136
137static void
138out_of_core (size_t n)
139{
140 fprintf (stderr, "\n ** fatal error: out of memory (%d bytes) **\n", n);
141}
142
143
144/**
145 * cdk_set_malloc_hooks:
146 * @new_alloc_func: malloc replacement
147 * @new_alloc_secure_func: secure malloc replacement
148 * @new_realloc_func: realloc replacement
149 * @new_calloc_func: calloc replacement
150 * @new_free_func: free replacement
151 *
152 * Set private memory hooks for the library.
153 */
154void
155cdk_set_malloc_hooks (void *(*new_alloc_func) (size_t n),
156 void *(*new_alloc_secure_func) (size_t n),
157 void *(*new_realloc_func) (void *p, size_t n),
158 void *(*new_calloc_func) (size_t m, size_t n),
159 void (*new_free_func) (void *))
160{
161 alloc_func = new_alloc_func;
162 alloc_secure_func = new_alloc_secure_func;
163 realloc_func = new_realloc_func;
164 calloc_func = new_calloc_func;
165 free_func = new_free_func;
166 malloc_hooks = 1;
167}
168
169
170/**
171 * cdk_malloc_hook_initialized:
172 *
173 * Return if the malloc hooks are already initialized.
174 **/
175int
176cdk_malloc_hook_initialized (void)
177{
178 return malloc_hooks;
179}
180
181
182void *
183cdk_malloc (size_t size)
184{
185 void *p = alloc_func (size);
186 if (!p)
187 out_of_core (size);
188 return p;
189}
190
191
192/**
193 * cdk_calloc:
194 * @n: amount of elements
195 * @m: size of one element
196 *
197 * Safe wrapper around the c-function calloc.
198 **/
199void *
200cdk_calloc (size_t n, size_t m)
201{
202 void *p = calloc_func (n, m);
203 if (!p)
204 out_of_core (m);
205 return p;
206}
207
208
209/* Things which need to be done after the secure memory initialisation. */
210static void
211_secmem_finish (void)
212{
213 gcry_control (GCRYCTL_DROP_PRIVS);
214}
215
216
217/* Initialize the secure memory. */
218static void
219_secmem_init (size_t size)
220{
221 if (secmem_init == 1)
222 return;
223 if (size >= SECMEM_SIZE)
224 size = SECMEM_SIZE;
225
226 /* Check if no other library has already initialized gcrypt. */
227 if (!gcry_control (GCRYCTL_ANY_INITIALIZATION_P))
228 {
229 _cdk_log_debug ("init: libgcrypt initialize.\n");
230 gcry_control (GCRYCTL_INIT_SECMEM, size, 0);
231 gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
232 gcry_control (GCRYCTL_DISABLE_SECMEM_WARN);
233 gcry_control (GCRYCTL_INITIALIZATION_FINISHED, NULL, 0);
234 secmem_init = 1;
235 }
236}
237
238
239/* Things which needs to be done to deinit the secure memory. */
240static void
241_secmem_end (void)
242{
243 gcry_control (GCRYCTL_TERM_SECMEM);
244 secmem_init = 0;
245}
246
247
248/* The Windows system needs to startup the Winsock interface first
249 before we can use any socket related function. */
250#ifdef _WIN32
251static void
252init_sockets (void)
253{
254 static int initialized = 0;
255 WSADATA wsdata;
256
257 if (initialized)
258 return;
259 if (WSAStartup (0x202, &wsdata))
260 _cdk_log_debug ("winsock init failed.\n");
261
262 initialized = 1;
263}
264
265static void
266deinit_sockets (void)
267{
268 WSACleanup ();
269}
270#else
271void
272init_sockets (void)
273{
274}
275void
276deinit_sockets (void)
277{
278}
279#endif
280
281
282/**
283 * cdk_lib_startup:
284 *
285 * Prepare the internal structures of the library.
286 * This function should be called before any other CDK function.
287 */
288void
289cdk_lib_startup (void)
290{
291 _secmem_init (SECMEM_SIZE);
292 _secmem_finish ();
293 init_sockets ();
294}
295
296
297/**
298 * cdk_lib_shutdown:
299 *
300 * Shutdown the library and free all internal and globally used
301 * memory and structures. This function should be called in the
302 * exit handler of the calling program.
303 */
304void
305cdk_lib_shutdown (void)
306{
307 deinit_sockets ();
308 _secmem_end ();
309}
310
311/**
312 * cdk_salloc:
313 * @size: how much bytes should be allocated.
314 * @clear: shall the buffer cleared after the allocation?
315 *
316 * Allocated the requested amount of bytes in 'secure' memory.
317 */
318void *
319cdk_salloc (size_t size, int clear)
320{
321 void *p;
322
323 if (!secmem_init)
324 _secmem_init (SECMEM_SIZE);
325
326 p = alloc_secure_func (size);
327 if (!p)
328 out_of_core (size);
329 if (clear)
330 memset (p, 0, size);
331 return p;
332}
333
334
335void *
336cdk_realloc (void *ptr, size_t size)
337{
338 void *p = realloc_func (ptr, size);
339 if (!p)
340 out_of_core (size);
341 return p;
342}
343
344
345char *
346cdk_strdup (const char *ptr)
347{
348 char *p = cdk_malloc (strlen (ptr) + 1);
349 if (p)
350 strcpy (p, ptr);
351 return p;
352}
353
354
355void
356cdk_free (void *ptr)
357{
358 if (ptr)
359 free_func (ptr);
360}
361
362
363/* Internal logging routine. */
364static void
365_cdk_logv (int level, const char *fmt, va_list arg_ptr)
366{
367
368 if (log_handler)
369 log_handler (log_handler_value, level, fmt, arg_ptr);
370 else
371 {
372 if (level == CDK_LOG_NONE)
373 return;
374 if (level == CDK_LOG_DEBUG)
375 fputs ("DBG: ", stderr);
376 vfprintf (stderr, fmt, arg_ptr);
377 }
378}
379
380
381/**
382 * cdk_set_log_handler:
383 * @logfnc: the function pointer
384 * @opaque: a private values for the function
385 *
386 * Set a custom handler for logging.
387 **/
388void
389cdk_set_log_handler (cdk_log_fnc_t logfnc, void *opaque)
390{
391 log_handler = logfnc;
392 log_handler_value = opaque;
393}
394
395
396/**
397 * cdk_set_log_level:
398 * @lvl: the level
399 *
400 * Set the verbosity level.
401 **/
402void
403cdk_set_log_level (int level)
404{
405 log_level = level;
406}
407
408
409/* Return the current log level of the lib. */
410int
411_cdk_get_log_level (void)
412{
413 return log_level;
414}
415
416
417void
418_cdk_log_info (const char *fmt, ...)
419{
420 va_list arg;
421
422 if (log_level == CDK_LOG_NONE)
423 return;
424 va_start (arg, fmt);
425 _cdk_logv (CDK_LOG_INFO, fmt, arg);
426 va_end (arg);
427}
428
429
430void
431_cdk_log_debug (const char *fmt, ...)
432{
433 va_list arg;
434
435 if (log_level < CDK_LOG_DEBUG)
436 return;
437 va_start (arg, fmt);
438 _cdk_logv (CDK_LOG_DEBUG, fmt, arg);
439 va_end (arg);
440}
441
442
443/* Use the passphrase callback in the handle HD or
444 return NULL if there is no valid callback. */
445char *
446_cdk_passphrase_get (cdk_ctx_t hd, const char *prompt)
447{
448 if (!hd || !hd->passphrase_cb)
449 return NULL;
450 return hd->passphrase_cb (hd->passphrase_cb_value, prompt);
451}
452
453
454static void
455handle_set_cipher (cdk_ctx_t hd, int cipher)
456{
457 if (!hd)
458 return;
459 if (gcry_cipher_test_algo (cipher))
460 cipher = DEFAULT_CIPHER_ALGO;
461 hd->cipher_algo = cipher;
462}
463
464
465static void
466handle_set_digest (cdk_ctx_t hd, int digest)
467{
468 if (!hd)
469 return;
470 if (gcry_md_test_algo (digest))
471 digest = DEFAULT_DIGEST_ALGO;
472 hd->digest_algo = digest;
473}
474
475
476static void
477handle_set_s2k (cdk_ctx_t hd, int mode, int digest, int cipher)
478{
479 if (!hd)
480 return;
481 if (gcry_cipher_test_algo (cipher))
482 cipher = DEFAULT_CIPHER_ALGO;
483 if (gcry_md_test_algo (digest))
484 digest = DEFAULT_DIGEST_ALGO;
485 if (mode != CDK_S2K_SIMPLE &&
486 mode != CDK_S2K_SALTED && mode != CDK_S2K_ITERSALTED)
487 mode = CDK_S2K_ITERSALTED;
488 hd->_s2k.mode = mode;
489 hd->_s2k.digest_algo = digest;
490}
491
492
493static void
494handle_set_compress (cdk_ctx_t hd, int algo, int level)
495{
496 if (!hd)
497 return;
498 if (algo < 0 || algo > 2)
499 algo = 0;
500 hd->compress.algo = algo;
501 if (!algo)
502 hd->opt.compress = 0;
503 else
504 {
505 if (level > 0 && level < 10)
506 hd->compress.level = level;
507 else
508 hd->compress.level = 6;
509 }
510}
511
512
513/**
514 * cdk_handle_control:
515 * @hd: session handle
516 * @action: flag which indicates whether put or get is requested
517 * @cmd: command id
518 *
519 * Perform various control operations for the current session.
520 **/
521int
522cdk_handle_control (cdk_ctx_t hd, int action, int cmd, ...)
523{
524 va_list arg_ptr;
525 int set = action == CDK_CTLF_SET, val = 0;
526
527 if (!hd)
528 return -1;
529
530 if (action != CDK_CTLF_SET && action != CDK_CTLF_GET)
531 return -1;
532 va_start (arg_ptr, cmd);
533 switch (cmd)
534 {
535 case CDK_CTL_ARMOR:
536 if (set)
537 hd->opt.armor = va_arg (arg_ptr, int);
538 else
539 val = hd->opt.armor;
540 break;
541
542 case CDK_CTL_CIPHER:
543 if (set)
544 handle_set_cipher (hd, va_arg (arg_ptr, int));
545 else
546 val = hd->cipher_algo;
547 break;
548
549 case CDK_CTL_DIGEST:
550 if (set)
551 handle_set_digest (hd, va_arg (arg_ptr, int));
552 else
553 val = hd->digest_algo;
554 break;
555
556 case CDK_CTL_OVERWRITE:
557 if (set)
558 hd->opt.overwrite = va_arg (arg_ptr, int);
559 else
560 val = hd->opt.overwrite;
561 break;
562
563 case CDK_CTL_COMPRESS:
564 if (set)
565 {
566 int algo = va_arg (arg_ptr, int);
567 int level = va_arg (arg_ptr, int);
568 handle_set_compress (hd, algo, level);
569 }
570 else
571 val = hd->compress.algo;
572 break;
573
574 case CDK_CTL_S2K:
575 if (set)
576 {
577 int mode = va_arg (arg_ptr, int);
578 int digest = va_arg (arg_ptr, int);
579 int cipher = va_arg (arg_ptr, int);
580 handle_set_s2k (hd, mode, digest, cipher);
581 }
582 else
583 val = hd->_s2k.mode;
584 break;
585
586 case CDK_CTL_FORCE_DIGEST:
587 if (set)
588 hd->opt.force_digest = va_arg (arg_ptr, int);
589 else
590 val = hd->opt.force_digest;
591 break;
592
593 case CDK_CTL_BLOCKMODE_ON:
594 if (set)
595 hd->opt.blockmode = va_arg (arg_ptr, int);
596 else
597 val = hd->opt.blockmode;
598 break;
599
600 default:
601 val = -1;
602 break;
603 }
604 va_end (arg_ptr);
605 return val;
606}
607
608
609
610/**
611 * cdk_handle_new:
612 * @r_ctx: context to store the handle
613 *
614 * create a new session handle.
615 **/
616cdk_error_t
617cdk_handle_new (cdk_ctx_t * r_ctx)
618{
619 cdk_ctx_t c;
620
621 if (!r_ctx)
622 return CDK_Inv_Value;
623
624 c = cdk_calloc (1, sizeof *c);
625 if (!c)
626 return CDK_Out_Of_Core;
627
628 /* For S2K use the iterated and salted mode and use the
629 default digest and cipher algorithms. Because the MDC
630 feature will be used, the default cipher should use a
631 blocksize of 128 bits. */
632 c->_s2k.mode = CDK_S2K_ITERSALTED;
633 c->_s2k.digest_algo = DEFAULT_DIGEST_ALGO;
634
635 c->opt.mdc = 1;
636 c->opt.compress = 1;
637 c->opt.armor = 0;
638 c->opt.textmode = 0;
639
640 c->digest_algo = DEFAULT_DIGEST_ALGO;
641 c->cipher_algo = DEFAULT_CIPHER_ALGO;
642
643 c->compress.algo = CDK_COMPRESS_ZIP;
644 c->compress.level = 6;
645
646 *r_ctx = c;
647 return 0;
648}
649
650
651/**
652 * cdk_handle_set_keyring:
653 * @hd: session handle
654 * @type: public=0 or secret=1 keyring type
655 * @kringname: file name of the keyring which shall be used.
656 *
657 * Convenient function to set the keyring for the current session.
658 */
659cdk_error_t
660cdk_handle_set_keyring (cdk_ctx_t hd, int type, const char *kringname)
661{
662 cdk_keydb_hd_t db;
663 cdk_error_t err;
664
665 err = cdk_keydb_new_from_file (&db, type, kringname);
666 if (err)
667 return err;
668
669 if (!type)
670 hd->db.pub = db;
671 else
672 hd->db.sec = db;
673 hd->db.close_db = 1;
674 return 0;
675}
676
677
678/**
679 * cdk_handle_set_keydb:
680 * @hd: session handle
681 * @db: the database handle
682 *
683 * set the key database handle.
684 * the function automatically detects whether this is a public or
685 * secret keyring and the right handle is set.
686 **/
687void
688cdk_handle_set_keydb (cdk_ctx_t hd, cdk_keydb_hd_t db)
689{
690 if (!hd)
691 return;
692 if (_cdk_keydb_is_secret (db))
693 hd->db.sec = db;
694 else
695 hd->db.pub = db;
696}
697
698
699/**
700 * cdk_handle_get_keydb:
701 * @hd: session handle
702 * @type: type of the keyring
703 *
704 * Return the keydb handle from the session handle.
705 * The caller should not free these handles.
706 **/
707cdk_keydb_hd_t
708cdk_handle_get_keydb (cdk_ctx_t hd, int type)
709{
710 if (!hd)
711 return NULL;
712 if (type == CDK_DBTYPE_PK_KEYRING)
713 return hd->db.pub;
714 else if (type == CDK_DBTYPE_SK_KEYRING)
715 return hd->db.sec;
716 return NULL;
717}
718
719
720/**
721 * cdk_handle_set_passphrase_cb:
722 * @hd: session handle
723 * @cb: callback function
724 * @cb_value: the opaque value for the cb function
725 *
726 * set the passphrase callback.
727 **/
728void
729cdk_handle_set_passphrase_cb (cdk_ctx_t hd,
730 char *(*cb) (void *opa, const char *prompt),
731 void *cb_value)
732{
733 if (!hd)
734 return;
735 hd->passphrase_cb = cb;
736 hd->passphrase_cb_value = cb_value;
737}
738
739
740/**
741 * cdk_handle_verify_get_result:
742 * @hd: the session handle
743 *
744 * Return the verify result for the current session.
745 * Do not free the pointer.
746 **/
747cdk_verify_result_t
748cdk_handle_verify_get_result (cdk_ctx_t hd)
749{
750 return hd->result.verify;
751}
752
753
754/**
755 * cdk_handle_free:
756 * @hd: the handle
757 *
758 * Release the main handle.
759 **/
760void
761cdk_handle_free (cdk_ctx_t hd)
762{
763 if (!hd)
764 return;
765 _cdk_result_verify_free (hd->result.verify);
766
767 /* If cdk_handle_set_keyring() were used, we need to free the key db
768 handles here because the handles are not controlled by the user. */
769 if (hd->db.close_db)
770 {
771 if (hd->db.pub)
772 cdk_keydb_free (hd->db.pub);
773 if (hd->db.sec)
774 cdk_keydb_free (hd->db.sec);
775 hd->db.pub = hd->db.sec = NULL;
776 }
777 cdk_free (hd->dek);
778 cdk_free (hd);
779}
diff --git a/src/daemon/https/opencdk/main.h b/src/daemon/https/opencdk/main.h
new file mode 100644
index 00000000..3e9a443d
--- /dev/null
+++ b/src/daemon/https/opencdk/main.h
@@ -0,0 +1,183 @@
1/* main.h
2 * Copyright (C) 2002, 2003, 2007 Timo Schulz
3 *
4 * This file is part of OpenCDK.
5 *
6 * OpenCDK is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * OpenCDK is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16#ifndef CDK_MAIN_H
17#define CDK_MAIN_H
18
19#include <gcrypt.h>
20#include "types.h"
21
22/* The general size of a buffer for the variou modules. */
23#define BUFSIZE 8192
24
25/* This is the default block size for the partial length packet mode. */
26#define DEF_BLOCKSIZE 8192
27#define DEF_BLOCKBITS 13 /* 2^13 = 8192 */
28
29/* For now SHA-1 is used to create fingerprint for keys.
30 But if this will ever change, it is a good idea to
31 have a constant for it to avoid to change it in all files. */
32#define KEY_FPR_LEN 20
33
34#include "context.h"
35
36/* The maximal amount of bits a multi precsion integer can have. */
37#define MAX_MPI_BITS 16384
38#define MAX_MPI_BYTES (MAX_MPI_BITS/8)
39
40
41/* Because newer DSA variants are not limited to SHA-1, we must consider
42 that SHA-512 is used and increase the buffer size of the digest. */
43#define MAX_DIGEST_LEN 64
44
45/* Helper to find out if the signature were made over a user ID
46 or if the signature revokes a previous user ID. */
47#define IS_UID_SIG(s) (((s)->sig_class & ~3) == 0x10)
48#define IS_UID_REV(s) ((s)->sig_class == 0x30)
49
50#define DEBUG_PKT (_cdk_get_log_level () == (CDK_LOG_DEBUG+1))
51
52/* Helper to find out if a key has the requested capability. */
53#define KEY_CAN_ENCRYPT(a) (_cdk_pk_algo_usage ((a)) & CDK_KEY_USG_ENCR)
54#define KEY_CAN_SIGN(a) (_cdk_pk_algo_usage ((a)) & CDK_KEY_USG_SIGN)
55#define KEY_CAN_AUTH(a) (_cdk_pk_algo_usage ((a)) & CDK_KEY_USG_AUTH)
56
57/* Helper macro to make sure the buffer is overwritten. */
58#define wipemem(_ptr,_len) do { \
59 volatile char *_vptr = (volatile char *)(_ptr); \
60 size_t _vlen = (_len); \
61 while (_vlen) \
62 { \
63 *_vptr = 0; \
64 _vptr++; \
65 _vlen--; \
66 } } while (0)
67
68/*-- armor.c --*/
69const char * _cdk_armor_get_lineend (void);
70
71/*-- main.c --*/
72int _cdk_get_log_level (void);
73void _cdk_log_info (const char * fmt, ...);
74void _cdk_log_debug (const char * fmt, ...);
75char * _cdk_passphrase_get (cdk_ctx_t hd, const char *prompt);
76
77/*-- misc.c --*/
78int _cdk_check_args( int overwrite, const char * in, const char * out );
79u32 _cdk_buftou32 (const byte * buf);
80void _cdk_u32tobuf (u32 u, byte * buf);
81const char *_cdk_memistr (const char * buf, size_t buflen, const char * sub);
82cdk_error_t _cdk_map_gcry_error (gcry_error_t err);
83#define map_gcry_error(err) _cdk_map_gcry_error (err)
84
85/* Helper to provide case insentensive strstr version. */
86#define stristr(haystack, needle) \
87 _cdk_memistr((haystack), strlen (haystack), (needle))
88
89/*-- proc-packet.c --*/
90cdk_error_t _cdk_proc_packets (cdk_ctx_t hd, cdk_stream_t inp,
91 cdk_stream_t data,
92 const char *output, cdk_stream_t outstream,
93 gcry_md_hd_t md);
94cdk_error_t _cdk_pkt_write2 (cdk_stream_t out, int pkttype, void *pktctx);
95
96/*-- pubkey.c --*/
97u32 _cdk_pkt_get_keyid (cdk_packet_t pkt, u32 * keyid);
98cdk_error_t _cdk_pkt_get_fingerprint (cdk_packet_t pkt, byte *fpr);
99int _cdk_pk_algo_usage (int algo);
100int _cdk_pk_test_algo (int algo, unsigned int usage);
101int _cdk_sk_get_csum (cdk_pkt_seckey_t sk);
102
103/*-- new-packet.c --*/
104byte * _cdk_subpkt_get_array (cdk_subpkt_t s, int count, size_t * r_nbytes);
105cdk_error_t _cdk_subpkt_copy (cdk_subpkt_t * r_dst, cdk_subpkt_t src);
106void _cdk_pkt_detach_free (cdk_packet_t pkt, int *r_pkttype, void **ctx);
107
108/*-- sig-check.c --*/
109cdk_error_t _cdk_sig_check (cdk_pkt_pubkey_t pk, cdk_pkt_signature_t sig,
110 gcry_md_hd_t digest, int * r_expired);
111cdk_error_t _cdk_hash_sig_data (cdk_pkt_signature_t sig, gcry_md_hd_t hd);
112cdk_error_t _cdk_hash_userid (cdk_pkt_userid_t uid, int sig_version, gcry_md_hd_t md);
113cdk_error_t _cdk_hash_pubkey (cdk_pkt_pubkey_t pk, gcry_md_hd_t md,
114 int use_fpr);
115cdk_error_t _cdk_pk_check_sig (cdk_keydb_hd_t hd,
116 cdk_kbnode_t knode,
117 cdk_kbnode_t snode, int *is_selfsig);
118
119/*-- kbnode.c --*/
120void _cdk_kbnode_add (cdk_kbnode_t root, cdk_kbnode_t node);
121void _cdk_kbnode_clone (cdk_kbnode_t node);
122
123/*-- sesskey.c --*/
124cdk_error_t _cdk_digest_encode_pkcs1 (byte **r_md, size_t *r_mdlen,
125 int pk_algo,
126 const byte * md,
127 int digest_algo, unsigned nbits);
128cdk_error_t _cdk_sk_unprotect_auto (cdk_ctx_t hd, cdk_pkt_seckey_t sk);
129
130/*-- keydb.c --*/
131int _cdk_keydb_is_secret (cdk_keydb_hd_t db);
132cdk_error_t _cdk_keydb_get_pk_byusage (cdk_keydb_hd_t hd, const char * name,
133 cdk_pkt_pubkey_t * ret_pk, int usage);
134cdk_error_t _cdk_keydb_get_sk_byusage (cdk_keydb_hd_t hd, const char * name,
135 cdk_pkt_seckey_t * ret_sk, int usage);
136cdk_error_t _cdk_keydb_check_userid (cdk_keydb_hd_t hd, u32 * keyid,
137 const char * id);
138
139/*-- sign.c --*/
140int _cdk_sig_hash_for (cdk_pkt_pubkey_t pk);
141void _cdk_trim_string (char * s, int canon);
142cdk_error_t _cdk_sig_create (cdk_pkt_pubkey_t pk, cdk_pkt_signature_t sig);
143cdk_error_t _cdk_sig_complete (cdk_pkt_signature_t sig, cdk_pkt_seckey_t sk,
144 gcry_md_hd_t hd);
145
146/*-- stream.c --*/
147void _cdk_stream_set_compress_algo (cdk_stream_t s, int algo);
148cdk_error_t _cdk_stream_open_mode (const char *file, const char *mode,
149 cdk_stream_t *ret_s);
150void * _cdk_stream_get_opaque( cdk_stream_t s, int fid );
151const char * _cdk_stream_get_fname( cdk_stream_t s );
152FILE * _cdk_stream_get_fp( cdk_stream_t s );
153int _cdk_stream_gets( cdk_stream_t s, char * buf, size_t count );
154cdk_error_t _cdk_stream_append( const char * file, cdk_stream_t * ret_s );
155int _cdk_stream_get_errno( cdk_stream_t s );
156cdk_error_t _cdk_stream_set_blockmode( cdk_stream_t s, size_t nbytes );
157int _cdk_stream_get_blockmode( cdk_stream_t s );
158int _cdk_stream_puts( cdk_stream_t s, const char * buf );
159cdk_error_t _cdk_stream_fpopen (FILE * fp, unsigned write_mode,
160 cdk_stream_t *ret_out);
161
162/*-- verify.c --*/
163void _cdk_result_verify_free (cdk_verify_result_t res);
164cdk_verify_result_t _cdk_result_verify_new (void);
165
166
167/*-- read-packet.c --*/
168size_t _cdk_pkt_read_len (FILE * inp, size_t *ret_partial);
169
170/*-- write-packet.c --*/
171cdk_error_t _cdk_pkt_write_fp( FILE * out, cdk_packet_t pkt );
172
173/*-- seskey.c --*/
174cdk_error_t _cdk_s2k_copy (cdk_s2k_t *r_dst, cdk_s2k_t src);
175
176cdk_error_t cdk_dek_encode_pkcs1 (cdk_dek_t dek, size_t nbits,
177 gcry_mpi_t *r_enc);
178cdk_error_t cdk_dek_decode_pkcs1 (cdk_dek_t * ret_dek, gcry_mpi_t esk);
179cdk_error_t cdk_dek_extract (cdk_dek_t * ret_dek, cdk_ctx_t hd,
180 cdk_pkt_pubkey_enc_t enc,
181 cdk_pkt_seckey_t sk );
182
183#endif /* CDK_MAIN_H */
diff --git a/src/daemon/https/opencdk/misc.c b/src/daemon/https/opencdk/misc.c
new file mode 100644
index 00000000..c296de40
--- /dev/null
+++ b/src/daemon/https/opencdk/misc.c
@@ -0,0 +1,571 @@
1/* misc.c
2 * Copyright (C) 2002, 2003 Timo Schulz
3 * Copyright (C) 1998-2002, 2007 Free Software Foundation, Inc.
4 *
5 * This file is part of OpenCDK.
6 *
7 * OpenCDK is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * OpenCDK is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17#ifdef HAVE_CONFIG_H
18# include <config.h>
19#endif
20#include <stdio.h>
21#include <string.h>
22#include <ctype.h>
23#include <sys/stat.h>
24
25#include "opencdk.h"
26#include "main.h"
27
28
29u32
30_cdk_buftou32 (const byte * buf)
31{
32 u32 u;
33
34 if (!buf)
35 return 0;
36 u = buf[0] << 24;
37 u |= buf[1] << 16;
38 u |= buf[2] << 8;
39 u |= buf[3];
40 return u;
41}
42
43
44void
45_cdk_u32tobuf (u32 u, byte * buf)
46{
47 if (!buf)
48 return;
49 buf[0] = u >> 24;
50 buf[1] = u >> 16;
51 buf[2] = u >> 8;
52 buf[3] = u;
53}
54
55
56static const char *
57parse_version_number (const char *s, int *number)
58{
59 int val = 0;
60
61 if (*s == '0' && isdigit (s[1]))
62 return NULL;
63 /* leading zeros are not allowed */
64 for (; isdigit (*s); s++)
65 {
66 val *= 10;
67 val += *s - '0';
68 }
69 *number = val;
70 return val < 0 ? NULL : s;
71}
72
73
74static const char *
75parse_version_string (const char *s, int *major, int *minor, int *micro)
76{
77 s = parse_version_number (s, major);
78 if (!s || *s != '.')
79 return NULL;
80 s++;
81 s = parse_version_number (s, minor);
82 if (!s || *s != '.')
83 return NULL;
84 s++;
85 s = parse_version_number (s, micro);
86 if (!s)
87 return NULL;
88 return s; /* patchlevel */
89}
90
91
92/**
93 * cdk_check_version:
94 * @req_version: The requested version
95 *
96 * Check that the the version of the library is at minimum the requested
97 * one and return the version string; return NULL if the condition is
98 * not satisfied. If a NULL is passed to this function, no check is done,
99 *but the version string is simply returned.
100 **/
101const char *
102cdk_check_version (const char *req_version)
103{
104 const char *ver = VERSION;
105 int my_major, my_minor, my_micro;
106 int rq_major, rq_minor, rq_micro;
107 const char *my_plvl, *rq_plvl;
108
109 if (!req_version)
110 return ver;
111 my_plvl = parse_version_string (ver, &my_major, &my_minor, &my_micro);
112 if (!my_plvl)
113 return NULL;
114 /* very strange our own version is bogus */
115 rq_plvl = parse_version_string (req_version, &rq_major, &rq_minor,
116 &rq_micro);
117 if (!rq_plvl)
118 return NULL; /* req version string is invalid */
119 if (my_major > rq_major
120 || (my_major == rq_major && my_minor > rq_minor)
121 || (my_major == rq_major && my_minor == rq_minor
122 && my_micro > rq_micro)
123 || (my_major == rq_major && my_minor == rq_minor
124 && my_micro == rq_micro && strcmp (my_plvl, rq_plvl) >= 0))
125 return ver;
126 return NULL;
127}
128
129
130/**
131 * cdk_strlist_free:
132 * @sl: the string list
133 *
134 * Release the string list object.
135 **/
136void
137cdk_strlist_free (cdk_strlist_t sl)
138{
139 cdk_strlist_t sl2;
140
141 for (; sl; sl = sl2)
142 {
143 sl2 = sl->next;
144 cdk_free (sl);
145 }
146}
147
148
149/**
150 * cdk_strlist_add:
151 * @list: destination string list
152 * @string: the string to add
153 *
154 * Add the given list to the string list.
155 **/
156cdk_strlist_t
157cdk_strlist_add (cdk_strlist_t * list, const char *string)
158{
159 cdk_strlist_t sl;
160
161 if (!string)
162 return NULL;
163
164 sl = cdk_calloc (1, sizeof *sl + strlen (string) + 1);
165 if (!sl)
166 return NULL;
167 strcpy (sl->d, string);
168 sl->next = *list;
169 *list = sl;
170 return sl;
171}
172
173
174/**
175 * cdk_strlist_next:
176 * @root: the opaque string list.
177 * @r_str: optional argument to store the string data.
178 *
179 * Return the next string list node from @root. The optional
180 * argument @r_str return the data of the current (!) node.
181 **/
182cdk_strlist_t
183cdk_strlist_next (cdk_strlist_t root, const char **r_str)
184{
185 cdk_strlist_t node;
186
187 if (root && r_str)
188 *r_str = root->d;
189 for (node = root->next; node; node = node->next)
190 return node;
191
192 return NULL;
193}
194
195
196const char *
197_cdk_memistr (const char *buf, size_t buflen, const char *sub)
198{
199 const byte *t, *s;
200 size_t n;
201
202 for (t = (byte *) buf, n = buflen, s = (byte *) sub; n; t++, n--)
203 {
204 if (toupper (*t) == toupper (*s))
205 {
206 for (buf = t++, buflen = n--, s++;
207 n && toupper (*t) == toupper ((byte) * s); t++, s++, n--)
208 ;
209 if (!*s)
210 return buf;
211 t = (byte *) buf;
212 n = buflen;
213 s = (byte *) sub;
214 }
215 }
216
217 return NULL;
218}
219
220
221/**
222 * cdk_utf8_encode:
223 * @string:
224 *
225 * Encode the given string in utf8 and return it.
226 **/
227char *
228cdk_utf8_encode (const char *string)
229{
230 const byte *s;
231 char *buffer;
232 byte *p;
233 size_t length;
234
235 /* FIXME: We should use iconv if possible for utf8 issues. */
236 for (s = (const byte *) string, length = 0; *s; s++)
237 {
238 length++;
239 if (*s & 0x80)
240 length++;
241 }
242
243 buffer = cdk_calloc (1, length + 1);
244 for (p = (byte *) buffer, s = (byte *) string; *s; s++)
245 {
246 if (*s & 0x80)
247 {
248 *p++ = 0xc0 | ((*s >> 6) & 3);
249 *p++ = 0x80 | (*s & 0x3f);
250 }
251 else
252 *p++ = *s;
253 }
254 *p = 0;
255 return buffer;
256}
257
258
259/**
260 * cdk_utf8_decode:
261 * @string: the string to decode
262 * @length: the length of the string
263 * @delim: the delimiter
264 *
265 * Decode the given utf8 string and return the native representation.
266 **/
267char *
268cdk_utf8_decode (const char *string, size_t length, int delim)
269{
270 int nleft;
271 int i;
272 byte encbuf[8];
273 int encidx;
274 const byte *s;
275 size_t n;
276 byte *buffer = NULL, *p = NULL;
277 unsigned long val = 0;
278 size_t slen;
279 int resync = 0;
280
281 /* 1. pass (p==NULL): count the extended utf-8 characters */
282 /* 2. pass (p!=NULL): create string */
283 for (;;)
284 {
285 for (slen = length, nleft = encidx = 0, n = 0, s = (byte *) string;
286 slen; s++, slen--)
287 {
288 if (resync)
289 {
290 if (!(*s < 128 || (*s >= 0xc0 && *s <= 0xfd)))
291 {
292 /* still invalid */
293 if (p)
294 {
295 sprintf ((char *) p, "\\x%02x", *s);
296 p += 4;
297 }
298 n += 4;
299 continue;
300 }
301 resync = 0;
302 }
303 if (!nleft)
304 {
305 if (!(*s & 0x80))
306 { /* plain ascii */
307 if (*s < 0x20 || *s == 0x7f || *s == delim ||
308 (delim && *s == '\\'))
309 {
310 n++;
311 if (p)
312 *p++ = '\\';
313 switch (*s)
314 {
315 case '\n':
316 n++;
317 if (p)
318 *p++ = 'n';
319 break;
320 case '\r':
321 n++;
322 if (p)
323 *p++ = 'r';
324 break;
325 case '\f':
326 n++;
327 if (p)
328 *p++ = 'f';
329 break;
330 case '\v':
331 n++;
332 if (p)
333 *p++ = 'v';
334 break;
335 case '\b':
336 n++;
337 if (p)
338 *p++ = 'b';
339 break;
340 case 0:
341 n++;
342 if (p)
343 *p++ = '0';
344 break;
345 default:
346 n += 3;
347 if (p)
348 {
349 sprintf ((char *) p, "x%02x", *s);
350 p += 3;
351 }
352 break;
353 }
354 }
355 else
356 {
357 if (p)
358 *p++ = *s;
359 n++;
360 }
361 }
362 else if ((*s & 0xe0) == 0xc0)
363 { /* 110x xxxx */
364 val = *s & 0x1f;
365 nleft = 1;
366 encidx = 0;
367 encbuf[encidx++] = *s;
368 }
369 else if ((*s & 0xf0) == 0xe0)
370 { /* 1110 xxxx */
371 val = *s & 0x0f;
372 nleft = 2;
373 encidx = 0;
374 encbuf[encidx++] = *s;
375 }
376 else if ((*s & 0xf8) == 0xf0)
377 { /* 1111 0xxx */
378 val = *s & 0x07;
379 nleft = 3;
380 encidx = 0;
381 encbuf[encidx++] = *s;
382 }
383 else if ((*s & 0xfc) == 0xf8)
384 { /* 1111 10xx */
385 val = *s & 0x03;
386 nleft = 4;
387 encidx = 0;
388 encbuf[encidx++] = *s;
389 }
390 else if ((*s & 0xfe) == 0xfc)
391 { /* 1111 110x */
392 val = *s & 0x01;
393 nleft = 5;
394 encidx = 0;
395 encbuf[encidx++] = *s;
396 }
397 else
398 { /* invalid encoding: print as \xnn */
399 if (p)
400 {
401 sprintf ((char *) p, "\\x%02x", *s);
402 p += 4;
403 }
404 n += 4;
405 resync = 1;
406 }
407 }
408 else if (*s < 0x80 || *s >= 0xc0)
409 { /* invalid */
410 if (p)
411 {
412 for (i = 0; i < encidx; i++)
413 {
414 sprintf ((char *) p, "\\x%02x", encbuf[i]);
415 p += 4;
416 }
417 sprintf ((char *) p, "\\x%02x", *s);
418 p += 4;
419 }
420 n += 4 + 4 * encidx;
421 nleft = 0;
422 encidx = 0;
423 resync = 1;
424 }
425 else
426 {
427 encbuf[encidx++] = *s;
428 val <<= 6;
429 val |= *s & 0x3f;
430 if (!--nleft)
431 { /* ready native set */
432 if (val >= 0x80 && val < 256)
433 {
434 n++; /* we can simply print this character */
435 if (p)
436 *p++ = val;
437 }
438 else
439 { /* we do not have a translation: print utf8 */
440 if (p)
441 {
442 for (i = 0; i < encidx; i++)
443 {
444 sprintf ((char *) p, "\\x%02x", encbuf[i]);
445 p += 4;
446 }
447 }
448 n += encidx * 4;
449 encidx = 0;
450 }
451 }
452 }
453
454 }
455 if (!buffer) /* allocate the buffer after the first pass */
456 buffer = p = cdk_malloc (n + 1);
457 else
458 {
459 *p = 0; /* make a string */
460 return (char *) buffer;
461 }
462 }
463}
464
465
466/* Map the gcrypt error to a valid opencdk error constant. */
467cdk_error_t
468_cdk_map_gcry_error (gcry_error_t err)
469{
470 /* FIXME: We need to catch them all. */
471 switch (gpg_err_code (err))
472 {
473 case GPG_ERR_NO_ERROR:
474 return CDK_Success;
475 case GPG_ERR_INV_VALUE:
476 return CDK_Inv_Value;
477 case GPG_ERR_GENERAL:
478 return CDK_General_Error;
479 case GPG_ERR_INV_PACKET:
480 return CDK_Inv_Packet;
481 case GPG_ERR_TOO_SHORT:
482 return CDK_Too_Short;
483 case GPG_ERR_TOO_LARGE:
484 return CDK_Inv_Value;
485 case GPG_ERR_NO_PUBKEY:
486 case GPG_ERR_NO_SECKEY:
487 return CDK_Error_No_Key;
488 case GPG_ERR_BAD_SIGNATURE:
489 return CDK_Bad_Sig;
490 case GPG_ERR_NO_DATA:
491 return CDK_No_Data;
492 default:
493 break;
494 }
495
496 return (cdk_error_t) err;
497}
498
499
500/* Remove all trailing white spaces from the string. */
501void
502_cdk_trim_string (char *s, int canon)
503{
504 while (s && *s &&
505 (s[strlen (s) - 1] == '\t' ||
506 s[strlen (s) - 1] == '\r' ||
507 s[strlen (s) - 1] == '\n' || s[strlen (s) - 1] == ' '))
508 s[strlen (s) - 1] = '\0';
509 if (canon)
510 strcat (s, "\r\n");
511}
512
513
514int
515_cdk_check_args (int overwrite, const char *in, const char *out)
516{
517 struct stat stbuf;
518
519 if (!in || !out)
520 return CDK_Inv_Value;
521 if (strlen (in) == strlen (out) && strcmp (in, out) == 0)
522 return CDK_Inv_Mode;
523 if (!overwrite && !stat (out, &stbuf))
524 return CDK_Inv_Mode;
525 return 0;
526}
527
528#ifdef _WIN32
529#include <io.h>
530#include <fcntl.h>
531
532FILE *
533my_tmpfile (void)
534{
535 /* Because the tmpfile() version of wine is not really useful,
536 we implement our own version to avoid problems with 'make check'. */
537 static const char *letters = "abcdefghijklmnopqrstuvwxyz";
538 char buf[512], rnd[24];
539 FILE *fp;
540 int fd, i;
541
542 gcry_create_nonce (rnd, DIM (rnd));
543 for (i = 0; i < DIM (rnd) - 1; i++)
544 {
545 char c = letters[(unsigned char) rnd[i] % 26];
546 rnd[i] = c;
547 }
548 rnd[DIM (rnd) - 1] = 0;
549 if (!GetTempPath (464, buf))
550 return NULL;
551 strcat (buf, "_cdk_");
552 strcat (buf, rnd);
553
554 /* We need to make sure the file will be deleted when it is closed. */
555 fd = _open (buf, _O_CREAT | _O_EXCL | _O_TEMPORARY |
556 _O_RDWR | _O_BINARY, _S_IREAD | _S_IWRITE);
557 if (fd == -1)
558 return NULL;
559 fp = fdopen (fd, "w+b");
560 if (fp != NULL)
561 return fp;
562 _close (fd);
563 return NULL;
564}
565#else
566FILE *
567my_tmpfile (void)
568{
569 return tmpfile ();
570}
571#endif
diff --git a/src/daemon/https/opencdk/new-packet.c b/src/daemon/https/opencdk/new-packet.c
new file mode 100644
index 00000000..d6f60690
--- /dev/null
+++ b/src/daemon/https/opencdk/new-packet.c
@@ -0,0 +1,874 @@
1/* new-packet.c - packet handling (freeing, copying, ...)
2 * Copyright (C) 2001, 2002, 2003, 2007 Timo Schulz
3 *
4 * This file is part of OpenCDK.
5 *
6 * OpenCDK is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * OpenCDK is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16#ifdef HAVE_CONFIG_H
17# include <config.h>
18#endif
19#include <string.h>
20#include <stdio.h>
21#include <assert.h>
22
23#include "opencdk.h"
24#include "main.h"
25#include "packet.h"
26
27
28/* Release an array of MPI values. */
29void
30_cdk_free_mpibuf (size_t n, gcry_mpi_t * array)
31{
32 while (n--)
33 {
34 gcry_mpi_release (array[n]);
35 array[n] = NULL;
36 }
37}
38
39
40/**
41 * cdk_pkt_new:
42 * @r_pkt: the new packet
43 *
44 * Allocate a new packet.
45 **/
46cdk_error_t
47cdk_pkt_new (cdk_packet_t * r_pkt)
48{
49 cdk_packet_t pkt;
50
51 if (!r_pkt)
52 return CDK_Inv_Value;
53 pkt = cdk_calloc (1, sizeof *pkt);
54 if (!pkt)
55 return CDK_Out_Of_Core;
56 *r_pkt = pkt;
57 return 0;
58}
59
60
61static void
62free_symkey_enc (cdk_pkt_symkey_enc_t enc)
63{
64 if (!enc)
65 return;
66 cdk_s2k_free (enc->s2k);
67 cdk_free (enc);
68}
69
70
71static void
72free_pubkey_enc (cdk_pkt_pubkey_enc_t enc)
73{
74 size_t nenc;
75
76 if (!enc)
77 return;
78
79 nenc = cdk_pk_get_nenc (enc->pubkey_algo);
80 _cdk_free_mpibuf (nenc, enc->mpi);
81 cdk_free (enc);
82}
83
84
85static void
86free_literal (cdk_pkt_literal_t pt)
87{
88 if (!pt)
89 return;
90 /* The buffer which is referenced in this packet is closed
91 elsewhere. To close it here would cause a double close. */
92 cdk_free (pt);
93}
94
95
96void
97_cdk_free_userid (cdk_pkt_userid_t uid)
98{
99 if (!uid)
100 return;
101
102 cdk_free (uid->prefs);
103 uid->prefs = NULL;
104 cdk_free (uid->attrib_img);
105 uid->attrib_img = NULL;
106 cdk_free (uid);
107}
108
109
110void
111_cdk_free_signature (cdk_pkt_signature_t sig)
112{
113 cdk_desig_revoker_t r;
114 size_t nsig;
115
116 if (!sig)
117 return;
118
119 nsig = cdk_pk_get_nsig (sig->pubkey_algo);
120 _cdk_free_mpibuf (nsig, sig->mpi);
121
122 cdk_subpkt_free (sig->hashed);
123 sig->hashed = NULL;
124 cdk_subpkt_free (sig->unhashed);
125 sig->unhashed = NULL;
126 while (sig->revkeys)
127 {
128 r = sig->revkeys->next;
129 cdk_free (sig->revkeys);
130 sig->revkeys = r;
131 }
132 cdk_free (sig);
133}
134
135
136void
137cdk_pk_release (cdk_pubkey_t pk)
138{
139 size_t npkey;
140
141 if (!pk)
142 return;
143
144 npkey = cdk_pk_get_npkey (pk->pubkey_algo);
145 _cdk_free_userid (pk->uid);
146 pk->uid = NULL;
147 cdk_free (pk->prefs);
148 pk->prefs = NULL;
149 _cdk_free_mpibuf (npkey, pk->mpi);
150 cdk_free (pk);
151}
152
153
154void
155cdk_sk_release (cdk_seckey_t sk)
156{
157 size_t nskey;
158
159 if (!sk)
160 return;
161
162 nskey = cdk_pk_get_nskey (sk->pubkey_algo);
163 _cdk_free_mpibuf (nskey, sk->mpi);
164 cdk_free (sk->encdata);
165 sk->encdata = NULL;
166 cdk_pk_release (sk->pk);
167 sk->pk = NULL;
168 cdk_s2k_free (sk->protect.s2k);
169 sk->protect.s2k = NULL;
170 cdk_free (sk);
171}
172
173
174static void
175free_encrypted (cdk_pkt_encrypted_t enc)
176{
177 if (!enc)
178 return;
179
180 /* This is just a reference for the filters to know where
181 the encrypted data starts and to read from the sream. It
182 us closed elsewhere and to close it here would double close it. */
183 /*cdk_stream_close (enc->buf); */
184 enc->buf = NULL;
185 cdk_free (enc);
186}
187
188
189/* Detach the openpgp packet from the packet structure
190 and release the packet structure itself. */
191void
192_cdk_pkt_detach_free (cdk_packet_t pkt, int *r_pkttype, void **ctx)
193{
194 /* For now we just allow this for keys. */
195 switch (pkt->pkttype)
196 {
197 case CDK_PKT_PUBLIC_KEY:
198 case CDK_PKT_PUBLIC_SUBKEY:
199 *ctx = pkt->pkt.public_key;
200 break;
201
202 case CDK_PKT_SECRET_KEY:
203 case CDK_PKT_SECRET_SUBKEY:
204 *ctx = pkt->pkt.secret_key;
205 break;
206
207 default:
208 *r_pkttype = 0;
209 return;
210 }
211
212 /* The caller might expect a specific packet type and
213 is not interested to store it for later use. */
214 if (r_pkttype)
215 *r_pkttype = pkt->pkttype;
216
217 cdk_free (pkt);
218}
219
220
221void
222cdk_pkt_free (cdk_packet_t pkt)
223{
224 if (!pkt)
225 return;
226
227 switch (pkt->pkttype)
228 {
229 case CDK_PKT_ATTRIBUTE:
230 case CDK_PKT_USER_ID:
231 _cdk_free_userid (pkt->pkt.user_id);
232 break;
233 case CDK_PKT_PUBLIC_KEY:
234 case CDK_PKT_PUBLIC_SUBKEY:
235 cdk_pk_release (pkt->pkt.public_key);
236 break;
237 case CDK_PKT_SECRET_KEY:
238 case CDK_PKT_SECRET_SUBKEY:
239 cdk_sk_release (pkt->pkt.secret_key);
240 break;
241 case CDK_PKT_SIGNATURE:
242 _cdk_free_signature (pkt->pkt.signature);
243 break;
244 case CDK_PKT_PUBKEY_ENC:
245 free_pubkey_enc (pkt->pkt.pubkey_enc);
246 break;
247 case CDK_PKT_SYMKEY_ENC:
248 free_symkey_enc (pkt->pkt.symkey_enc);
249 break;
250 case CDK_PKT_MDC:
251 cdk_free (pkt->pkt.mdc);
252 break;
253 case CDK_PKT_ENCRYPTED:
254 case CDK_PKT_ENCRYPTED_MDC:
255 free_encrypted (pkt->pkt.encrypted);
256 break;
257 case CDK_PKT_ONEPASS_SIG:
258 cdk_free (pkt->pkt.onepass_sig);
259 break;
260 case CDK_PKT_LITERAL:
261 free_literal (pkt->pkt.literal);
262 break;
263 case CDK_PKT_COMPRESSED:
264 cdk_free (pkt->pkt.compressed);
265 break;
266 default:
267 break;
268 }
269
270 /* Reset the packet type to avoid, when cdk_pkt_release() will be
271 used, that the second cdk_pkt_free() call will double free the data. */
272 pkt->pkttype = 0;
273}
274
275
276/**
277 * cdk_pkt_release:
278 * @pkt: the packet
279 *
280 * Free the contents of the given package and
281 * release the memory of the structure.
282 **/
283void
284cdk_pkt_release (cdk_packet_t pkt)
285{
286 if (!pkt)
287 return;
288 cdk_pkt_free (pkt);
289 cdk_free (pkt);
290}
291
292
293/**
294 * cdk_pkt_alloc:
295 * @r_pkt: output is the new packet
296 * @pkttype: the requested packet type
297 *
298 * Allocate a new packet structure with the given packet type.
299 **/
300cdk_error_t
301cdk_pkt_alloc (cdk_packet_t * r_pkt, int pkttype)
302{
303 cdk_packet_t pkt;
304 int rc;
305
306 if (!r_pkt)
307 return CDK_Inv_Value;
308
309 rc = cdk_pkt_new (&pkt);
310 if (rc)
311 return rc;
312
313 switch (pkttype)
314 {
315 case CDK_PKT_USER_ID:
316 pkt->pkt.user_id = cdk_calloc (1, sizeof pkt->pkt.user_id);
317 if (!pkt->pkt.user_id)
318 return CDK_Out_Of_Core;
319 break;
320
321 case CDK_PKT_PUBLIC_KEY:
322 case CDK_PKT_PUBLIC_SUBKEY:
323 pkt->pkt.public_key = cdk_calloc (1, sizeof *pkt->pkt.public_key);
324 if (!pkt->pkt.public_key)
325 return CDK_Out_Of_Core;
326 break;
327
328 case CDK_PKT_SECRET_KEY:
329 case CDK_PKT_SECRET_SUBKEY:
330 pkt->pkt.secret_key = cdk_calloc (1, sizeof *pkt->pkt.secret_key);
331 pkt->pkt.secret_key->pk =
332 cdk_calloc (1, sizeof *pkt->pkt.secret_key->pk);
333 if (!pkt->pkt.secret_key || !pkt->pkt.secret_key->pk)
334 return CDK_Out_Of_Core;
335 break;
336
337 case CDK_PKT_SIGNATURE:
338 pkt->pkt.signature = cdk_calloc (1, sizeof *pkt->pkt.signature);
339 if (!pkt->pkt.signature)
340 return CDK_Out_Of_Core;
341 break;
342
343 case CDK_PKT_SYMKEY_ENC:
344 pkt->pkt.symkey_enc = cdk_calloc (1, sizeof *pkt->pkt.symkey_enc);
345 if (!pkt->pkt.symkey_enc)
346 return CDK_Out_Of_Core;
347 break;
348
349 case CDK_PKT_PUBKEY_ENC:
350 pkt->pkt.pubkey_enc = cdk_calloc (1, sizeof *pkt->pkt.pubkey_enc);
351 if (!pkt->pkt.pubkey_enc)
352 return CDK_Out_Of_Core;
353 break;
354
355 case CDK_PKT_MDC:
356 pkt->pkt.mdc = cdk_calloc (1, sizeof *pkt->pkt.mdc);
357 if (!pkt->pkt.mdc)
358 return CDK_Out_Of_Core;
359 break;
360
361 case CDK_PKT_ENCRYPTED_MDC:
362 case CDK_PKT_ENCRYPTED:
363 pkt->pkt.symkey_enc = cdk_calloc (1, sizeof *pkt->pkt.symkey_enc);
364 if (!pkt->pkt.symkey_enc)
365 return CDK_Out_Of_Core;
366 break;
367
368 case CDK_PKT_ONEPASS_SIG:
369 pkt->pkt.onepass_sig = cdk_calloc (1, sizeof *pkt->pkt.onepass_sig);
370 if (!pkt->pkt.onepass_sig)
371 return CDK_Out_Of_Core;
372 break;
373
374 case CDK_PKT_LITERAL:
375 /* FIXME: We would need the size of the file name to allocate extra
376 bytes, otherwise the result would be useless. */
377 pkt->pkt.literal = cdk_calloc (1, sizeof *pkt->pkt.literal);
378 if (!pkt->pkt.literal)
379 return CDK_Out_Of_Core;
380 break;
381 }
382 pkt->pkttype = pkttype;
383 *r_pkt = pkt;
384 return 0;
385}
386
387
388cdk_prefitem_t
389_cdk_copy_prefs (const cdk_prefitem_t prefs)
390{
391 size_t n = 0;
392 struct cdk_prefitem_s *new_prefs;
393
394 if (!prefs)
395 return NULL;
396
397 for (n = 0; prefs[n].type; n++)
398 ;
399 new_prefs = cdk_calloc (1, sizeof *new_prefs * (n + 1));
400 if (!new_prefs)
401 return NULL;
402 for (n = 0; prefs[n].type; n++)
403 {
404 new_prefs[n].type = prefs[n].type;
405 new_prefs[n].value = prefs[n].value;
406 }
407 new_prefs[n].type = CDK_PREFTYPE_NONE;
408 new_prefs[n].value = 0;
409 return new_prefs;
410}
411
412
413cdk_error_t
414_cdk_copy_userid (cdk_pkt_userid_t * dst, cdk_pkt_userid_t src)
415{
416 cdk_pkt_userid_t u;
417
418 if (!dst || !src)
419 return CDK_Inv_Value;
420
421 *dst = NULL;
422 u = cdk_calloc (1, sizeof *u + strlen (src->name) + 1);
423 if (!u)
424 return CDK_Out_Of_Core;
425 memcpy (u, src, sizeof *u);
426 memcpy (u->name, src->name, strlen (src->name));
427 u->prefs = _cdk_copy_prefs (src->prefs);
428 if (src->selfsig)
429 _cdk_copy_signature (&u->selfsig, src->selfsig);
430 *dst = u;
431
432 return 0;
433}
434
435
436cdk_error_t
437_cdk_copy_pubkey (cdk_pkt_pubkey_t * dst, cdk_pkt_pubkey_t src)
438{
439 cdk_pkt_pubkey_t k;
440 int i;
441
442 if (!dst || !src)
443 return CDK_Inv_Value;
444
445 *dst = NULL;
446 k = cdk_calloc (1, sizeof *k);
447 if (!k)
448 return CDK_Out_Of_Core;
449 memcpy (k, src, sizeof *k);
450 if (src->uid)
451 _cdk_copy_userid (&k->uid, src->uid);
452 if (src->prefs)
453 k->prefs = _cdk_copy_prefs (src->prefs);
454 for (i = 0; i < cdk_pk_get_npkey (src->pubkey_algo); i++)
455 k->mpi[i] = gcry_mpi_copy (src->mpi[i]);
456 *dst = k;
457
458 return 0;
459}
460
461
462cdk_error_t
463_cdk_copy_seckey (cdk_pkt_seckey_t * dst, cdk_pkt_seckey_t src)
464{
465 cdk_pkt_seckey_t k;
466 int i;
467
468 if (!dst || !src)
469 return CDK_Inv_Value;
470
471 *dst = NULL;
472 k = cdk_calloc (1, sizeof *k);
473 if (!k)
474 return CDK_Out_Of_Core;
475 memcpy (k, src, sizeof *k);
476 _cdk_copy_pubkey (&k->pk, src->pk);
477
478 if (src->encdata)
479 {
480 k->encdata = cdk_calloc (1, src->enclen + 1);
481 if (!k->encdata)
482 return CDK_Out_Of_Core;
483 memcpy (k->encdata, src->encdata, src->enclen);
484 }
485
486 _cdk_s2k_copy (&k->protect.s2k, src->protect.s2k);
487
488 for (i = 0; i < cdk_pk_get_nskey (src->pubkey_algo); i++)
489 {
490 k->mpi[i] = gcry_mpi_copy (src->mpi[i]);
491 gcry_mpi_set_flag (k->mpi[i], GCRYMPI_FLAG_SECURE);
492 }
493
494 *dst = k;
495 return 0;
496}
497
498
499cdk_error_t
500_cdk_copy_pk_to_sk (cdk_pkt_pubkey_t pk, cdk_pkt_seckey_t sk)
501{
502 if (!pk || !sk)
503 return CDK_Inv_Value;
504
505 sk->version = pk->version;
506 sk->expiredate = pk->expiredate;
507 sk->pubkey_algo = pk->pubkey_algo;
508 sk->has_expired = pk->has_expired;
509 sk->is_revoked = pk->is_revoked;
510 sk->main_keyid[0] = pk->main_keyid[0];
511 sk->main_keyid[1] = pk->main_keyid[1];
512 sk->keyid[0] = pk->keyid[0];
513 sk->keyid[1] = pk->keyid[1];
514
515 return 0;
516}
517
518
519cdk_error_t
520_cdk_copy_signature (cdk_pkt_signature_t * dst, cdk_pkt_signature_t src)
521{
522 cdk_pkt_signature_t s;
523
524 if (!dst || !src)
525 return CDK_Inv_Value;
526
527 *dst = NULL;
528 s = cdk_calloc (1, sizeof *s);
529 if (!s)
530 return CDK_Out_Of_Core;
531 memcpy (s, src, sizeof *src);
532 _cdk_subpkt_copy (&s->hashed, src->hashed);
533 _cdk_subpkt_copy (&s->unhashed, src->unhashed);
534 /* FIXME: Copy MPI parts */
535 *dst = s;
536
537 return 0;
538}
539
540
541cdk_error_t
542_cdk_pubkey_compare (cdk_pkt_pubkey_t a, cdk_pkt_pubkey_t b)
543{
544 int na, nb, i;
545
546 if (a->timestamp != b->timestamp || a->pubkey_algo != b->pubkey_algo)
547 return -1;
548 if (a->version < 4 && a->expiredate != b->expiredate)
549 return -1;
550 na = cdk_pk_get_npkey (a->pubkey_algo);
551 nb = cdk_pk_get_npkey (b->pubkey_algo);
552 if (na != nb)
553 return -1;
554
555 for (i = 0; i < na; i++)
556 {
557 if (gcry_mpi_cmp (a->mpi[i], b->mpi[i]))
558 return -1;
559 }
560
561 return 0;
562}
563
564
565/**
566 * cdk_subpkt_free:
567 * @ctx: the sub packet node to free
568 *
569 * Release the context.
570 **/
571void
572cdk_subpkt_free (cdk_subpkt_t ctx)
573{
574 cdk_subpkt_t s;
575
576 while (ctx)
577 {
578 s = ctx->next;
579 cdk_free (ctx);
580 ctx = s;
581 }
582}
583
584
585/**
586 * cdk_subpkt_find:
587 * @ctx: the sub packet node
588 * @type: the packet type to find
589 *
590 * Find the given packet type in the node. If no packet with this
591 * type was found, return null otherwise pointer to the node.
592 **/
593cdk_subpkt_t
594cdk_subpkt_find (cdk_subpkt_t ctx, size_t type)
595{
596 return cdk_subpkt_find_nth (ctx, type, 0);
597}
598
599/**
600 * cdk_subpkt_type_count:
601 * @ctx: The sub packet context
602 * @type: The sub packet type.
603 *
604 * Return the amount of sub packets with this type.
605 **/
606size_t
607cdk_subpkt_type_count (cdk_subpkt_t ctx, size_t type)
608{
609 cdk_subpkt_t s;
610 size_t count;
611
612 count = 0;
613 for (s = ctx; s; s = s->next)
614 {
615 if (s->type == type)
616 count++;
617 }
618
619 return count;
620}
621
622
623/**
624 * cdk_subpkt_find_nth:
625 * @ctx: The sub packet context
626 * @type: The sub packet type
627 * @index: The nth packet to retrieve, 0 means the first
628 *
629 * Return the nth sub packet of the given type.
630 **/
631cdk_subpkt_t
632cdk_subpkt_find_nth (cdk_subpkt_t ctx, size_t type, size_t idx)
633{
634 cdk_subpkt_t s;
635 size_t pos;
636
637 pos = 0;
638 for (s = ctx; s; s = s->next)
639 {
640 if (s->type == type && pos++ == idx)
641 return s;
642 }
643
644 return NULL;
645}
646
647
648/**
649 * cdk_subpkt_new:
650 * @size: the size of the new context
651 *
652 * Create a new sub packet node with the size of @size.
653 **/
654cdk_subpkt_t
655cdk_subpkt_new (size_t size)
656{
657 cdk_subpkt_t s;
658
659 if (!size)
660 return NULL;
661 s = cdk_calloc (1, sizeof *s + size + 1);
662 if (!s)
663 return NULL;
664 return s;
665}
666
667
668/**
669 * cdk_subpkt_get_data:
670 * @ctx: the sub packet node
671 * @r_type: pointer store the packet type
672 * @r_nbytes: pointer to store the packet size
673 *
674 * Extract the data from the given sub packet. The type is returned
675 * in @r_type and the size in @r_nbytes.
676 **/
677const byte *
678cdk_subpkt_get_data (cdk_subpkt_t ctx, size_t * r_type, size_t * r_nbytes)
679{
680 if (!ctx || !r_nbytes)
681 return NULL;
682 if (r_type)
683 *r_type = ctx->type;
684 *r_nbytes = ctx->size;
685 return ctx->d;
686}
687
688
689/**
690 * cdk_subpkt_add:
691 * @root: the root node
692 * @node: the node to add
693 *
694 * Add the node in @node to the root node @root.
695 **/
696cdk_error_t
697cdk_subpkt_add (cdk_subpkt_t root, cdk_subpkt_t node)
698{
699 cdk_subpkt_t n1;
700
701 if (!root)
702 return CDK_Inv_Value;
703 for (n1 = root; n1->next; n1 = n1->next)
704 ;
705 n1->next = node;
706 return 0;
707}
708
709
710byte *
711_cdk_subpkt_get_array (cdk_subpkt_t s, int count, size_t * r_nbytes)
712{
713 cdk_subpkt_t list;
714 byte *buf;
715 size_t n, nbytes;
716
717 if (!s)
718 {
719 if (r_nbytes)
720 *r_nbytes = 0;
721 return NULL;
722 }
723
724 for (n = 0, list = s; list; list = list->next)
725 {
726 n++; /* type */
727 n += list->size;
728 if (list->size < 192)
729 n++;
730 else if (list->size < 8384)
731 n += 2;
732 else
733 n += 5;
734 }
735 buf = cdk_calloc (1, n + 1);
736 if (!buf)
737 return NULL;
738
739 n = 0;
740 for (list = s; list; list = list->next)
741 {
742 nbytes = 1 + list->size; /* type */
743 if (nbytes < 192)
744 buf[n++] = nbytes;
745 else if (nbytes < 8384)
746 {
747 buf[n++] = nbytes / 256 + 192;
748 buf[n++] = nbytes % 256;
749 }
750 else
751 {
752 buf[n++] = 0xFF;
753 buf[n++] = nbytes >> 24;
754 buf[n++] = nbytes >> 16;
755 buf[n++] = nbytes >> 8;
756 buf[n++] = nbytes;
757 }
758 buf[n++] = list->type;
759 memcpy (buf + n, list->d, list->size);
760 n += list->size;
761 }
762
763 if (count)
764 {
765 cdk_free (buf);
766 buf = NULL;
767 }
768 if (r_nbytes)
769 *r_nbytes = n;
770 return buf;
771}
772
773
774cdk_error_t
775_cdk_subpkt_copy (cdk_subpkt_t * r_dst, cdk_subpkt_t src)
776{
777 cdk_subpkt_t root, p, node;
778
779 if (!src || !r_dst)
780 return CDK_Inv_Value;
781
782 root = NULL;
783 for (p = src; p; p = p->next)
784 {
785 node = cdk_subpkt_new (p->size);
786 if (node)
787 {
788 memcpy (node->d, p->d, p->size);
789 node->type = p->type;
790 node->size = p->size;
791 }
792 if (!root)
793 root = node;
794 else
795 cdk_subpkt_add (root, node);
796 }
797 *r_dst = root;
798 return 0;
799}
800
801
802/**
803 * cdk_subpkt_init:
804 * @node: the sub packet node
805 * @type: type of the packet which data should be initialized
806 * @buf: the buffer with the actual data
807 * @buflen: the size of the data
808 *
809 * Set the packet data of the given root and set the type of it.
810 **/
811void
812cdk_subpkt_init (cdk_subpkt_t node, size_t type,
813 const void *buf, size_t buflen)
814{
815 if (!node)
816 return;
817 node->type = type;
818 node->size = buflen;
819 memcpy (node->d, buf, buflen);
820}
821
822
823/* FIXME: We need to think of a public interface for it. */
824const byte *
825cdk_key_desig_revoker_walk (cdk_desig_revoker_t root,
826 cdk_desig_revoker_t * ctx,
827 int *r_class, int *r_algid)
828{
829 cdk_desig_revoker_t n;
830
831 if (!*ctx)
832 {
833 *ctx = root;
834 n = root;
835 }
836 else
837 {
838 n = (*ctx)->next;
839 *ctx = n;
840 }
841
842 if (n && r_class && r_algid)
843 {
844 *r_class = n->r_class;
845 *r_algid = n->algid;
846 }
847
848 return n ? n->fpr : NULL;
849}
850
851
852/**
853 * cdk_subpkt_find_next:
854 * @root: the base where to begin the iteration
855 * @type: the type to find or 0 for the next node.
856 *
857 * Try to find the next node after @root with type.
858 * If type is 0, the next node will be returned.
859 **/
860cdk_subpkt_t
861cdk_subpkt_find_next (cdk_subpkt_t root, size_t type)
862{
863 cdk_subpkt_t node;
864
865 for (node = root->next; node; node = node->next)
866 {
867 if (!type)
868 return node;
869 else if (node->type == type)
870 return node;
871 }
872
873 return NULL;
874}
diff --git a/src/daemon/https/opencdk/opencdk.h b/src/daemon/https/opencdk/opencdk.h
new file mode 100644
index 00000000..83ca487e
--- /dev/null
+++ b/src/daemon/https/opencdk/opencdk.h
@@ -0,0 +1,1169 @@
1/* opencdk.h - Open Crypto Development Kit (OpenCDK)
2 * Copyright (C) 2001, 2002, 2003, 2007 Timo Schulz
3 * Copyright (C) 2006, 2007 Free Software Foundation, Inc.
4 *
5 * This file is part of OpenCDK.
6 *
7 * OpenCDK is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * OpenCDK is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18#ifndef OPENCDK_H
19#define OPENCDK_H
20
21#include <stddef.h> /* for size_t */
22#include <stdarg.h>
23#include <gcrypt.h>
24
25/* The OpenCDK version as a string. */
26#define OPENCDK_VERSION "0.6.6"
27
28/* The OpenCDK version as integer components major.minor.path */
29#define OPENCDK_VERSION_MAJOR 0
30#define OPENCDK_VERSION_MINOR 6
31#define OPENCDK_VERSION_PATCH 6
32
33#ifdef __cplusplus
34extern "C" {
35#if 0
36}
37#endif
38#endif
39
40/* General contexts */
41
42/* 'Session' handle to support the various options and run-time
43 information. */
44struct cdk_ctx_s;
45typedef struct cdk_ctx_s *cdk_ctx_t;
46
47/* A generic context to store list of strings. */
48struct cdk_strlist_s;
49typedef struct cdk_strlist_s *cdk_strlist_t;
50
51/* Context used to list keys of a keyring. */
52struct cdk_listkey_s;
53typedef struct cdk_listkey_s *cdk_listkey_t;
54
55/* Opaque Data Encryption Key (DEK) context. */
56struct cdk_dek_s;
57typedef struct cdk_dek_s *cdk_dek_t;
58
59/* Opaque String to Key (S2K) handle. */
60struct cdk_s2k_s;
61typedef struct cdk_s2k_s *cdk_s2k_t;
62
63/* Abstract I/O object, a stream, which is used for most operations. */
64struct cdk_stream_s;
65typedef struct cdk_stream_s *cdk_stream_t;
66
67/* Opaque handle for the user ID preferences. */
68struct cdk_prefitem_s;
69typedef struct cdk_prefitem_s *cdk_prefitem_t;
70
71/* Node to store a single key node packet. */
72struct cdk_kbnode_s;
73typedef struct cdk_kbnode_s *cdk_kbnode_t;
74
75/* Key database handle. */
76struct cdk_keydb_hd_s;
77typedef struct cdk_keydb_hd_s *cdk_keydb_hd_t;
78
79/* Context to store a list of recipient keys. */
80struct cdk_keylist_s;
81typedef struct cdk_keylist_s *cdk_keylist_t;
82
83/* Context to encapsulate a single sub packet of a signature. */
84struct cdk_subpkt_s;
85typedef struct cdk_subpkt_s *cdk_subpkt_t;
86
87/* Context used to generate key pairs. */
88struct cdk_keygen_ctx_s;
89typedef struct cdk_keygen_ctx_s *cdk_keygen_ctx_t;
90
91/* Handle for a single designated revoker. */
92struct cdk_desig_revoker_s;
93typedef struct cdk_desig_revoker_s *cdk_desig_revoker_t;
94
95/* Alias for backward compatibility. */
96typedef gcry_mpi_t cdk_mpi_t;
97
98
99/* All valid error constants. */
100typedef enum {
101 CDK_EOF = -1,
102 CDK_Success = 0,
103 CDK_General_Error = 1,
104 CDK_File_Error = 2,
105 CDK_Bad_Sig = 3,
106 CDK_Inv_Packet = 4,
107 CDK_Inv_Algo = 5,
108 CDK_Not_Implemented = 6,
109 CDK_Armor_Error = 8,
110 CDK_Armor_CRC_Error = 9,
111 CDK_MPI_Error = 10,
112 CDK_Inv_Value = 11,
113 CDK_Error_No_Key = 12,
114 CDK_Chksum_Error = 13,
115 CDK_Time_Conflict = 14,
116 CDK_Zlib_Error = 15,
117 CDK_Weak_Key = 16,
118 CDK_Out_Of_Core = 17,
119 CDK_Wrong_Seckey = 18,
120 CDK_Bad_MDC = 19,
121 CDK_Inv_Mode = 20,
122 CDK_Error_No_Keyring = 21,
123 CDK_Wrong_Format = 22,
124 CDK_Inv_Packet_Ver = 23,
125 CDK_Too_Short = 24,
126 CDK_Unusable_Key = 25,
127 CDK_No_Data = 26,
128 CDK_No_Passphrase = 27,
129 CDK_Network_Error = 28
130} cdk_error_t;
131
132
133enum cdk_control_flags {
134 CDK_CTLF_SET = 0, /* Value to set an option */
135 CDK_CTLF_GET = 1, /* Value to get an option */
136 CDK_CTL_DIGEST = 10, /* Option to set the digest algorithm. */
137 CDK_CTL_CIPHER = 11, /* Option to set the cipher algorithm. */
138 CDK_CTL_ARMOR = 12, /* Option to enable armor output. */
139 CDK_CTL_COMPRESS = 13, /* Option to enable compression. */
140 CDK_CTL_COMPAT = 14, /* Option to switch in compat mode. */
141 CDK_CTL_OVERWRITE = 15, /* Option to enable file overwritting. */
142 CDK_CTL_S2K = 16, /* Option to set S2K values. */
143 CDK_CTL_FORCE_DIGEST = 19, /* Force the use of a digest algorithm. */
144 CDK_CTL_BLOCKMODE_ON = 20 /* Enable partial body lengths */
145};
146
147
148/* Specifies all valid log levels. */
149enum cdk_log_level_t {
150 CDK_LOG_NONE = 0, /* No log message will be shown. */
151 CDK_LOG_INFO = 1,
152 CDK_LOG_DEBUG = 2,
153 CDK_LOG_DEBUG_PKT = 3
154};
155
156
157/* All valid compression algorithms in OpenPGP */
158enum cdk_compress_algo_t {
159 CDK_COMPRESS_NONE = 0,
160 CDK_COMPRESS_ZIP = 1,
161 CDK_COMPRESS_ZLIB = 2,
162 CDK_COMPRESS_BZIP2 = 3 /* Not supported in this version */
163};
164
165
166/* All valid public key algorithms valid in OpenPGP */
167enum cdk_pubkey_algo_t {
168 CDK_PK_RSA = 1,
169 CDK_PK_RSA_E = 2, /* RSA-E and RSA-S are deprecated use RSA instead */
170 CDK_PK_RSA_S = 3, /* and use the key flags in the self signatures. */
171 CDK_PK_ELG_E = 16,
172 CDK_PK_DSA = 17
173};
174
175
176/* All valid message digest algorithms in OpenPGP. */
177enum cdk_digest_algo_t {
178 CDK_MD_NONE = 0,
179 CDK_MD_MD5 = 1,
180 CDK_MD_SHA1 = 2,
181 CDK_MD_RMD160 = 3,
182 CDK_MD_SHA256 = 8,
183 CDK_MD_SHA384 = 9,
184 CDK_MD_SHA512 = 10,
185 CDK_MD_SHA224 = 11 /* This algorithm is NOT available. */
186};
187
188
189/* All valid symmetric cipher algorithms in OpenPGP */
190enum cdk_cipher_algo_t {
191 CDK_CIPHER_NONE = 0,
192 CDK_CIPHER_IDEA = 1, /* This algorithm is NOT available */
193 CDK_CIPHER_3DES = 2,
194 CDK_CIPHER_CAST5 = 3,
195 CDK_CIPHER_BLOWFISH = 4,
196 CDK_CIPHER_AES = 7,
197 CDK_CIPHER_AES192 = 8,
198 CDK_CIPHER_AES256 = 9,
199 CDK_CIPHER_TWOFISH = 10
200};
201
202
203/* The valid 'String-To-Key' modes */
204enum cdk_s2k_type_t {
205 CDK_S2K_SIMPLE = 0,
206 CDK_S2K_SALTED = 1,
207 CDK_S2K_ITERSALTED = 3
208};
209
210
211/* The different kind of user ID preferences. */
212enum cdk_pref_type_t {
213 CDK_PREFTYPE_NONE = 0,
214 CDK_PREFTYPE_SYM = 1, /* Symmetric ciphers */
215 CDK_PREFTYPE_HASH = 2, /* Message digests */
216 CDK_PREFTYPE_ZIP = 3 /* Compression algorithms */
217};
218
219
220/* All valid sub packet types. */
221enum cdk_sig_subpacket_t {
222 CDK_SIGSUBPKT_NONE = 0,
223 CDK_SIGSUBPKT_SIG_CREATED = 2,
224 CDK_SIGSUBPKT_SIG_EXPIRE = 3,
225 CDK_SIGSUBPKT_EXPORTABLE = 4,
226 CDK_SIGSUBPKT_TRUST = 5,
227 CDK_SIGSUBPKT_REGEXP = 6,
228 CDK_SIGSUBPKT_REVOCABLE = 7,
229 CDK_SIGSUBPKT_KEY_EXPIRE = 9,
230 CDK_SIGSUBPKT_PREFS_SYM = 11,
231 CDK_SIGSUBPKT_REV_KEY = 12,
232 CDK_SIGSUBPKT_ISSUER = 16,
233 CDK_SIGSUBPKT_NOTATION = 20,
234 CDK_SIGSUBPKT_PREFS_HASH = 21,
235 CDK_SIGSUBPKT_PREFS_ZIP = 22,
236 CDK_SIGSUBPKT_KS_FLAGS = 23,
237 CDK_SIGSUBPKT_PREF_KS = 24,
238 CDK_SIGSUBPKT_PRIMARY_UID = 25,
239 CDK_SIGSUBPKT_POLICY = 26,
240 CDK_SIGSUBPKT_KEY_FLAGS = 27,
241 CDK_SIGSUBPKT_SIGNERS_UID = 28,
242 CDK_SIGSUBPKT_REVOC_REASON = 29,
243 CDK_SIGSUBPKT_FEATURES = 30
244};
245
246
247/* All valid armor types. */
248enum cdk_armor_type_t {
249 CDK_ARMOR_MESSAGE = 0,
250 CDK_ARMOR_PUBKEY = 1,
251 CDK_ARMOR_SECKEY = 2,
252 CDK_ARMOR_SIGNATURE = 3,
253 CDK_ARMOR_CLEARSIG = 4
254};
255
256enum cdk_keydb_flag_t {
257 /* Valid database search modes */
258 CDK_DBSEARCH_EXACT = 1, /* Exact string search */
259 CDK_DBSEARCH_SUBSTR = 2, /* Sub string search */
260 CDK_DBSEARCH_SHORT_KEYID = 3, /* 32-bit keyid search */
261 CDK_DBSEARCH_KEYID = 4, /* 64-bit keyid search */
262 CDK_DBSEARCH_FPR = 5, /* 160-bit fingerprint search */
263 CDK_DBSEARCH_NEXT = 6, /* Enumerate all keys */
264 CDK_DBSEARCH_AUTO = 7, /* Try to classify the string */
265 /* Valid database types */
266 CDK_DBTYPE_PK_KEYRING = 100, /* A file with one or more public keys */
267 CDK_DBTYPE_SK_KEYRING = 101, /* A file with one or more secret keys */
268 CDK_DBTYPE_DATA = 102, /* A buffer with at least one public key */
269 CDK_DBTYPE_STREAM = 103 /* A stream is used to read keys from */
270};
271
272
273/* All valid modes for cdk_data_transform() */
274enum cdk_crypto_mode_t {
275 CDK_CRYPTYPE_NONE = 0,
276 CDK_CRYPTYPE_ENCRYPT = 1,
277 CDK_CRYPTYPE_DECRYPT = 2,
278 CDK_CRYPTYPE_SIGN = 3,
279 CDK_CRYPTYPE_VERIFY = 4,
280 CDK_CRYPTYPE_EXPORT = 5,
281 CDK_CRYPTYPE_IMPORT = 6
282};
283
284
285/* A list of valid public key usages. */
286enum cdk_key_usage_t {
287 CDK_KEY_USG_ENCR = 1, /* Key can be used for encryption. */
288 CDK_KEY_USG_SIGN = 2, /* Key can be used for signing and certifying. */
289 CDK_KEY_USG_AUTH = 4 /* Key can be used for authentication. */
290};
291
292
293/* Valid flags for keys. */
294enum cdk_key_flag_t {
295 CDK_KEY_VALID = 0,
296 CDK_KEY_INVALID = 1, /* Missing or wrong self signature */
297 CDK_KEY_EXPIRED = 2, /* Key is expired. */
298 CDK_KEY_REVOKED = 4, /* Key has been revoked. */
299 CDK_KEY_NOSIGNER = 8
300};
301
302
303/* Trust values and flags for keys and user IDs */
304enum cdk_trust_flag_t {
305 CDK_TRUST_UNKNOWN = 0,
306 CDK_TRUST_EXPIRED = 1,
307 CDK_TRUST_UNDEFINED = 2,
308 CDK_TRUST_NEVER = 3,
309 CDK_TRUST_MARGINAL = 4,
310 CDK_TRUST_FULLY = 5,
311 CDK_TRUST_ULTIMATE = 6,
312 /* trust flags */
313 CDK_TFLAG_REVOKED = 32,
314 CDK_TFLAG_SUB_REVOKED = 64,
315 CDK_TFLAG_DISABLED = 128
316};
317
318
319/* Signature states and the signature modes. */
320enum cdk_signature_stat_t {
321 /* Signature status */
322 CDK_SIGSTAT_NONE = 0,
323 CDK_SIGSTAT_GOOD = 1,
324 CDK_SIGSTAT_BAD = 2,
325 CDK_SIGSTAT_NOKEY = 3,
326 CDK_SIGSTAT_VALID = 4, /* True if made with a valid key. */
327 /* FIXME: We need indicators for revoked/expires signatures. */
328
329 /* Signature modes */
330 CDK_SIGMODE_NORMAL = 100,
331 CDK_SIGMODE_DETACHED = 101,
332 CDK_SIGMODE_CLEAR = 102
333};
334
335
336/* Key flags. */
337typedef enum {
338 CDK_FLAG_KEY_REVOKED = 256,
339 CDK_FLAG_KEY_EXPIRED = 512,
340 CDK_FLAG_SIG_EXPIRED = 1024
341} cdk_key_flags_t;
342
343
344/* Possible format for the literal data. */
345typedef enum {
346 CDK_LITFMT_BINARY = 0,
347 CDK_LITFMT_TEXT = 1,
348 CDK_LITFMT_UNICODE= 2
349} cdk_lit_format_t;
350
351/* Valid OpenPGP packet types and their IDs */
352typedef enum {
353 CDK_PKT_RESERVED = 0,
354 CDK_PKT_PUBKEY_ENC = 1,
355 CDK_PKT_SIGNATURE = 2,
356 CDK_PKT_SYMKEY_ENC = 3,
357 CDK_PKT_ONEPASS_SIG = 4,
358 CDK_PKT_SECRET_KEY = 5,
359 CDK_PKT_PUBLIC_KEY = 6,
360 CDK_PKT_SECRET_SUBKEY = 7,
361 CDK_PKT_COMPRESSED = 8,
362 CDK_PKT_ENCRYPTED = 9,
363 CDK_PKT_MARKER = 10,
364 CDK_PKT_LITERAL = 11,
365 CDK_PKT_RING_TRUST = 12,
366 CDK_PKT_USER_ID = 13,
367 CDK_PKT_PUBLIC_SUBKEY = 14,
368 CDK_PKT_OLD_COMMENT = 16,
369 CDK_PKT_ATTRIBUTE = 17,
370 CDK_PKT_ENCRYPTED_MDC = 18,
371 CDK_PKT_MDC = 19
372} cdk_packet_type_t;
373
374/* Define the maximal number of multiprecion integers for
375 a public key. */
376#define MAX_CDK_PK_PARTS 4
377
378/* Define the maximal number of multiprecision integers for
379 a signature/encrypted blob issued by a secret key. */
380#define MAX_CDK_DATA_PARTS 2
381
382
383/* Helper macro to figure out if the packet is encrypted */
384#define CDK_PKT_IS_ENCRYPTED(pkttype) (\
385 ((pkttype)==CDK_PKT_ENCRYPTED_MDC) \
386 || ((pkttype)==CDK_PKT_ENCRYPTED))
387
388
389struct cdk_pkt_signature_s {
390 unsigned char version;
391 unsigned char sig_class;
392 unsigned int timestamp;
393 unsigned int expiredate;
394 unsigned int keyid[2];
395 unsigned char pubkey_algo;
396 unsigned char digest_algo;
397 unsigned char digest_start[2];
398 unsigned short hashed_size;
399 cdk_subpkt_t hashed;
400 unsigned short unhashed_size;
401 cdk_subpkt_t unhashed;
402 gcry_mpi_t mpi[MAX_CDK_DATA_PARTS];
403 cdk_desig_revoker_t revkeys;
404 struct {
405 unsigned exportable:1;
406 unsigned revocable:1;
407 unsigned policy_url:1;
408 unsigned notation:1;
409 unsigned expired:1;
410 unsigned checked:1;
411 unsigned valid:1;
412 unsigned missing_key:1;
413 } flags;
414 unsigned int key[2]; /* only valid for key signatures */
415};
416typedef struct cdk_pkt_signature_s *cdk_pkt_signature_t;
417
418
419struct cdk_pkt_userid_s {
420 unsigned int len;
421 unsigned is_primary:1;
422 unsigned is_revoked:1;
423 unsigned mdc_feature:1;
424 cdk_prefitem_t prefs;
425 size_t prefs_size;
426 unsigned char * attrib_img; /* Tag 17 if not null */
427 size_t attrib_len;
428 cdk_pkt_signature_t selfsig;
429 char name[1];
430};
431typedef struct cdk_pkt_userid_s *cdk_pkt_userid_t;
432
433
434struct cdk_pkt_pubkey_s {
435 unsigned char version;
436 unsigned char pubkey_algo;
437 unsigned char fpr[20];
438 unsigned int keyid[2];
439 unsigned int main_keyid[2];
440 unsigned int timestamp;
441 unsigned int expiredate;
442 gcry_mpi_t mpi[MAX_CDK_PK_PARTS];
443 unsigned is_revoked:1;
444 unsigned is_invalid:1;
445 unsigned has_expired:1;
446 int pubkey_usage;
447 cdk_pkt_userid_t uid;
448 cdk_prefitem_t prefs;
449 size_t prefs_size;
450 cdk_desig_revoker_t revkeys;
451};
452typedef struct cdk_pkt_pubkey_s *cdk_pkt_pubkey_t;
453
454/* Alias to define a generic public key context. */
455typedef cdk_pkt_pubkey_t cdk_pubkey_t;
456
457
458struct cdk_pkt_seckey_s {
459 cdk_pkt_pubkey_t pk;
460 unsigned int expiredate;
461 int version;
462 int pubkey_algo;
463 unsigned int keyid[2];
464 unsigned int main_keyid[2];
465 unsigned char s2k_usage;
466 struct {
467 unsigned char algo;
468 unsigned char sha1chk; /* SHA1 is used instead of a 16 bit checksum */
469 cdk_s2k_t s2k;
470 unsigned char iv[16];
471 unsigned char ivlen;
472 } protect;
473 unsigned short csum;
474 gcry_mpi_t mpi[MAX_CDK_PK_PARTS];
475 unsigned char * encdata;
476 size_t enclen;
477 unsigned char is_protected;
478 unsigned is_primary:1;
479 unsigned has_expired:1;
480 unsigned is_revoked:1;
481};
482typedef struct cdk_pkt_seckey_s *cdk_pkt_seckey_t;
483
484/* Alias to define a generic secret key context. */
485typedef cdk_pkt_seckey_t cdk_seckey_t;
486
487
488struct cdk_pkt_onepass_sig_s {
489 unsigned char version;
490 unsigned int keyid[2];
491 unsigned char sig_class;
492 unsigned char digest_algo;
493 unsigned char pubkey_algo;
494 unsigned char last;
495};
496typedef struct cdk_pkt_onepass_sig_s * cdk_pkt_onepass_sig_t;
497
498
499struct cdk_pkt_pubkey_enc_s {
500 unsigned char version;
501 unsigned int keyid[2];
502 int throw_keyid;
503 unsigned char pubkey_algo;
504 gcry_mpi_t mpi[MAX_CDK_DATA_PARTS];
505};
506typedef struct cdk_pkt_pubkey_enc_s * cdk_pkt_pubkey_enc_t;
507
508
509struct cdk_pkt_symkey_enc_s {
510 unsigned char version;
511 unsigned char cipher_algo;
512 cdk_s2k_t s2k;
513 unsigned char seskeylen;
514 unsigned char seskey[32];
515};
516typedef struct cdk_pkt_symkey_enc_s *cdk_pkt_symkey_enc_t;
517
518
519struct cdk_pkt_encrypted_s {
520 unsigned int len;
521 int extralen;
522 unsigned char mdc_method;
523 cdk_stream_t buf;
524};
525typedef struct cdk_pkt_encrypted_s *cdk_pkt_encrypted_t;
526
527
528struct cdk_pkt_mdc_s {
529 unsigned char hash[20];
530};
531typedef struct cdk_pkt_mdc_s *cdk_pkt_mdc_t;
532
533
534struct cdk_pkt_literal_s {
535 unsigned int len;
536 cdk_stream_t buf;
537 int mode;
538 unsigned int timestamp;
539 int namelen;
540 char name[1];
541};
542typedef struct cdk_pkt_literal_s *cdk_pkt_literal_t;
543
544
545struct cdk_pkt_compressed_s {
546 unsigned int len;
547 int algorithm;
548 cdk_stream_t buf;
549};
550typedef struct cdk_pkt_compressed_s *cdk_pkt_compressed_t;
551
552
553/* Structure which represents a single OpenPGP packet. */
554struct cdk_packet_s {
555 size_t pktlen; /* real packet length */
556 size_t pktsize; /* length with all headers */
557 int old_ctb; /* 1 if RFC1991 mode is used */
558 cdk_packet_type_t pkttype;
559 union {
560 cdk_pkt_mdc_t mdc;
561 cdk_pkt_userid_t user_id;
562 cdk_pkt_pubkey_t public_key;
563 cdk_pkt_seckey_t secret_key;
564 cdk_pkt_signature_t signature;
565 cdk_pkt_pubkey_enc_t pubkey_enc;
566 cdk_pkt_symkey_enc_t symkey_enc;
567 cdk_pkt_compressed_t compressed;
568 cdk_pkt_encrypted_t encrypted;
569 cdk_pkt_literal_t literal;
570 cdk_pkt_onepass_sig_t onepass_sig;
571 } pkt;
572};
573typedef struct cdk_packet_s *cdk_packet_t;
574
575/* memory routines */
576typedef void (*cdk_log_fnc_t) (void *, int, const char *, va_list);
577
578/* Set the log level. */
579void cdk_set_log_level (int lvl);
580
581/* Set a custom log handler which is used for logging. */
582void cdk_set_log_handler (cdk_log_fnc_t logfnc, void *opaque);
583
584/* Return a human readable error description of the given error coe. */
585const char* cdk_strerror (int ec);
586
587/* Allow the user to set custom hooks for memory allocation.
588 If this function is not used, the standard allocation functions
589 will be used. Extra care must be taken for the 'secure' alloc
590 function. */
591void cdk_set_malloc_hooks (void *(*new_alloc_func) (size_t n),
592 void *(*new_alloc_secure_func) (size_t n),
593 void *(*new_realloc_func) (void *p, size_t n),
594 void *(*new_calloc_func) (size_t m, size_t n),
595 void (*new_free_func) (void *));
596
597/* Return 1 if the malloc hooks were already set via the function above. */
598int cdk_malloc_hook_initialized (void);
599
600/* Standard memory wrapper. */
601void *cdk_malloc (size_t size);
602void *cdk_calloc (size_t n, size_t m);
603void *cdk_realloc (void * ptr, size_t size);
604void *cdk_salloc (size_t size, int clear);
605char *cdk_strdup (const char * ptr);
606void cdk_free (void * ptr);
607
608/* Startup routines. */
609
610/* This function has to be called before any other
611 CDK function is executed. */
612void cdk_lib_startup (void);
613
614/* This function should be called before the application exists
615 to allow the lib to cleanup its internal structures. */
616void cdk_lib_shutdown (void);
617
618/* Session handle routines */
619cdk_error_t cdk_handle_new (cdk_ctx_t *r_ctx);
620void cdk_handle_free (cdk_ctx_t c);
621
622/* Set the key database handle for the given session handle.
623 The type of the key db handle (public or secret) decides
624 which session key db handle to use. */
625void cdk_handle_set_keydb (cdk_ctx_t hd, cdk_keydb_hd_t db);
626
627/* Convenient function to avoid to open a key db first.
628 The user can directly use the file name, the rest is
629 done internally. */
630cdk_error_t cdk_handle_set_keyring (cdk_ctx_t hd, int type,
631 const char *kringname);
632
633/* Return keydb handle stored in the session handle. */
634cdk_keydb_hd_t cdk_handle_get_keydb (cdk_ctx_t hd, int type);
635int cdk_handle_control (cdk_ctx_t hd, int action, int cmd, ...);
636
637/* Set a passphrase callback for the given session handle. */
638void cdk_handle_set_passphrase_cb (cdk_ctx_t hd,
639 char *(*cb) (void *opa, const char *prompt),
640 void *cb_value);
641
642/* shortcuts for some controls */
643
644/* Enable or disable armor output. */
645#define cdk_handle_set_armor(a, val) \
646 cdk_handle_control ((a), CDK_CTLF_SET, CDK_CTL_ARMOR, (val))
647
648/* Set the compression algorithm and level. 0 means disable compression. */
649#define cdk_handle_set_compress(a, algo, level) \
650 cdk_handle_control ((a), CDK_CTLF_SET, CDK_CTL_COMPRESS, (algo), (level))
651
652/* Activate partial bodies for the output. This is needed if the length
653 of the data is not known in advance or for the use with sockets
654 or pipes. */
655#define cdk_handle_set_blockmode(a, val) \
656 cdk_handle_control ((a), CDK_CTLF_SET, CDK_CTL_BLOCKMODE_ON, (val))
657
658/* Set the symmetric cipher for encryption. */
659#define cdk_handle_set_cipher(a, val) \
660 cdk_handle_control ((a), CDK_CTLF_SET, CDK_CTL_CIPHER, (val))
661
662/* Set the digest for the PK signing operation. */
663#define cdk_handle_set_digest(a, val) \
664 cdk_handle_control ((a), CDK_CTLF_SET, CDK_CTL_DIGEST, (val))
665
666/* Set the mode and the digest for the S2K operation. */
667#define cdk_handle_set_s2k(a, val1, val2) \
668 cdk_handle_control ((a), CDK_CTLF_SET, CDK_CTL_S2K, (val1), (val2))
669
670
671/* This context holds all information of the verification process. */
672struct cdk_verify_result_s {
673 int sig_ver; /* Version of the signature. */
674 int sig_status; /* The status (GOOD, BAD) of the signature */
675 int sig_flags; /* May contain expired or revoked flags */
676 unsigned int keyid[2]; /* The issuer key ID */
677 unsigned int created; /* Timestamp when the sig was created. */
678 unsigned int expires;
679 int pubkey_algo;
680 int digest_algo;
681 char *user_id; /* NULL or user ID which issued the signature. */
682 char *policy_url; /* If set, the policy the sig was created under. */
683 size_t sig_len; /* Size of the signature data inbits. */
684 unsigned char *sig_data; /* Raw signature data. */
685};
686typedef struct cdk_verify_result_s *cdk_verify_result_t;
687
688/* Return the verify result. Do not free the data. */
689cdk_verify_result_t cdk_handle_verify_get_result (cdk_ctx_t hd);
690
691/* Raw packet routines. */
692
693/* Allocate a new packet or a new packet with the given packet type. */
694cdk_error_t cdk_pkt_new (cdk_packet_t *r_pkt);
695cdk_error_t cdk_pkt_alloc (cdk_packet_t *r_pkt, int pkttype);
696
697/* Only release the contents of the packet but not @PKT itself. */
698void cdk_pkt_free (cdk_packet_t pkt);
699
700/* Release the packet contents and the packet structure @PKT itself. */
701void cdk_pkt_release (cdk_packet_t pkt);
702
703/* Read or write the given output from or to the stream. */
704cdk_error_t cdk_pkt_read (cdk_stream_t inp, cdk_packet_t pkt);
705cdk_error_t cdk_pkt_write (cdk_stream_t out, cdk_packet_t pkt);
706
707/* Sub packet routines */
708cdk_subpkt_t cdk_subpkt_new (size_t size);
709void cdk_subpkt_free (cdk_subpkt_t ctx);
710cdk_subpkt_t cdk_subpkt_find (cdk_subpkt_t ctx, size_t type);
711cdk_subpkt_t cdk_subpkt_find_next (cdk_subpkt_t root, size_t type);
712size_t cdk_subpkt_type_count (cdk_subpkt_t ctx, size_t type);
713cdk_subpkt_t cdk_subpkt_find_nth (cdk_subpkt_t ctx, size_t type, size_t index);
714cdk_error_t cdk_subpkt_add (cdk_subpkt_t root, cdk_subpkt_t node);
715const unsigned char * cdk_subpkt_get_data (cdk_subpkt_t ctx,
716 size_t * r_type, size_t *r_nbytes);
717void cdk_subpkt_init (cdk_subpkt_t node, size_t type,
718 const void *buf, size_t buflen);
719
720/* Designated Revoker routines */
721const unsigned char* cdk_key_desig_revoker_walk (cdk_desig_revoker_t root,
722 cdk_desig_revoker_t * ctx,
723 int *r_class, int *r_algid);
724
725#define is_RSA(a) ((a) == CDK_PK_RSA \
726 || (a) == CDK_PK_RSA_E \
727 || (a) == CDK_PK_RSA_S)
728#define is_ELG(a) ((a) == CDK_PK_ELG_E)
729#define is_DSA(a) ((a) == CDK_PK_DSA)
730
731/* Encrypt the given session key @SK with the public key @PK
732 and write the contents into the packet @PKE. */
733cdk_error_t cdk_pk_encrypt (cdk_pubkey_t pk, cdk_pkt_pubkey_enc_t pke,
734 gcry_mpi_t sk);
735
736/* Decrypt the given encrypted session key in @PKE with the secret key
737 @SK and store it in @R_SK. */
738cdk_error_t cdk_pk_decrypt (cdk_seckey_t sk, cdk_pkt_pubkey_enc_t pke,
739 gcry_mpi_t *r_sk);
740
741/* Sign the given message digest @MD with the secret key @SK and
742 store the signature in the packet @SIG. */
743cdk_error_t cdk_pk_sign (cdk_seckey_t sk, cdk_pkt_signature_t sig,
744 const unsigned char *md);
745
746/* Verify the given signature in @SIG with the public key @PK
747 and compare it against the message digest @MD. */
748cdk_error_t cdk_pk_verify (cdk_pubkey_t pk, cdk_pkt_signature_t sig,
749 const unsigned char *md);
750
751/* Use cdk_pk_get_npkey() and cdk_pk_get_nskey to find out how much
752 multiprecision integers a key consists of. */
753
754/* Return a multi precision integer of the public key with the index @IDX
755 in the buffer @BUF. @R_NWRITTEN will contain the length in octets.
756 Optional @R_NBITS may contain the size in bits. */
757cdk_error_t cdk_pk_get_mpi (cdk_pubkey_t pk, size_t idx,
758 unsigned char *buf, size_t buflen,
759 size_t *r_nwritten, size_t *r_nbits);
760
761/* Same as the function above but of the secret key. */
762cdk_error_t cdk_sk_get_mpi (cdk_seckey_t sk, size_t idx,
763 unsigned char * buf, size_t buflen,
764 size_t *r_nwritten, size_t *r_nbits);
765
766/* Helper to get the exact number of multi precision integers
767 for the given object. */
768int cdk_pk_get_nbits (cdk_pubkey_t pk);
769int cdk_pk_get_npkey (int algo);
770int cdk_pk_get_nskey (int algo);
771int cdk_pk_get_nsig (int algo);
772int cdk_pk_get_nenc (int algo);
773
774/* Fingerprint and key ID routines. */
775
776/* Calculate the fingerprint of the given public key.
777 the FPR parameter must be at least 20 octets to hold the SHA1 hash. */
778cdk_error_t cdk_pk_get_fingerprint (cdk_pubkey_t pk, unsigned char *fpr);
779
780/* Same as above, but with additional sanity checks of the buffer size. */
781cdk_error_t cdk_pk_to_fingerprint (cdk_pubkey_t pk,
782 unsigned char *fpr, size_t fprlen,
783 size_t *r_nout);
784
785/* Derive the keyid from the fingerprint. This is only possible for
786 modern, version 4 keys. */
787unsigned int cdk_pk_fingerprint_get_keyid (const unsigned char *fpr,
788 size_t fprlen,
789 unsigned int *keyid);
790
791/* Various functions to get the keyid from the specific packet type. */
792unsigned int cdk_pk_get_keyid (cdk_pubkey_t pk, unsigned int *keyid);
793unsigned int cdk_sk_get_keyid (cdk_seckey_t sk, unsigned int *keyid);
794unsigned int cdk_sig_get_keyid (cdk_pkt_signature_t sig,
795 unsigned int *keyid);
796
797/* Key release functions. */
798void cdk_pk_release (cdk_pubkey_t pk);
799void cdk_sk_release (cdk_seckey_t sk);
800
801/* Secret key related functions. */
802cdk_error_t cdk_sk_unprotect (cdk_seckey_t sk, const char *pw);
803cdk_error_t cdk_sk_protect (cdk_seckey_t sk, const char *pw);
804
805/* Create a public key with the data from the secret key @SK. */
806cdk_error_t cdk_pk_from_secret_key (cdk_seckey_t sk,
807 cdk_pubkey_t *ret_pk);
808
809/* Sexp conversion of keys. */
810cdk_error_t cdk_pubkey_to_sexp (cdk_pubkey_t pk,
811 char **sexp, size_t *len);
812cdk_error_t cdk_seckey_to_sexp (cdk_seckey_t sk,
813 char **sexp, size_t *len);
814
815
816/* Data Encryption Key (DEK) routines */
817cdk_error_t cdk_dek_new (cdk_dek_t *r_dek);
818void cdk_dek_free (cdk_dek_t dek);
819
820/* Set the symmetric cipher algorithm which shall be used for this
821 DEK object. */
822cdk_error_t cdk_dek_set_cipher (cdk_dek_t dek, int cipher_algo);
823
824/* Return the symmetric cipher which is used for this DEK object. */
825cdk_error_t cdk_dek_get_cipher (cdk_dek_t dek, int *r_cipher_algo);
826
827
828/* Set the session key for the given DEK object.
829 If @KEY and @KEYLEN are both NULL/0, a random key will be generated
830 and stored in the DEK object. */
831cdk_error_t cdk_dek_set_key (cdk_dek_t dek, const unsigned char *key,
832 size_t keylen);
833
834/* Enable the MDC feature for the current DEK object. */
835void cdk_dek_set_mdc_flag (cdk_dek_t dek, int val);
836
837/* Return if the MDC feature is enabled for the current DEK object.*/
838int cdk_dek_get_mdc_flag (cdk_dek_t dek);
839
840/* Transform the given passphrase into a DEK.
841 If @rndsalt is set, a random salt will be generated. */
842cdk_error_t cdk_dek_from_passphrase (cdk_dek_t *ret_dek, int cipher_algo,
843 cdk_s2k_t s2k, int rndsalt,
844 const char *passphrase);
845
846/* String to Key routines. */
847cdk_error_t cdk_s2k_new (cdk_s2k_t *ret_s2k, int mode, int digest_algo,
848 const unsigned char *salt);
849void cdk_s2k_free (cdk_s2k_t s2k);
850
851cdk_error_t cdk_file_armor (cdk_ctx_t hd, const char *file,
852 const char *output);
853cdk_error_t cdk_file_dearmor (const char * file, const char *output);
854int cdk_armor_filter_use (cdk_stream_t inp);
855
856/* Protect the inbuf with ASCII armor of the specified type.
857 If @outbuf and @outlen are NULL, the function returns the calculated
858 size of the base64 encoded data in @nwritten. */
859cdk_error_t cdk_armor_encode_buffer (const unsigned char *inbuf, size_t inlen,
860 char *outbuf, size_t outlen,
861 size_t *nwritten, int type);
862
863
864/* This context contain user callbacks for different stream operations.
865 Some of these callbacks might be NULL to indicate that the callback
866 is not used. */
867struct cdk_stream_cbs_s
868{
869 cdk_error_t (*open)(void *);
870 cdk_error_t (*release)(void *);
871 int (*read)(void *, void *buf, size_t);
872 int (*write)(void *, const void *buf, size_t);
873 int (*seek)(void *, off_t);
874};
875typedef struct cdk_stream_cbs_s *cdk_stream_cbs_t;
876
877
878int cdk_stream_is_compressed (cdk_stream_t s);
879
880/* Return a stream object which is associated to a socket. */
881cdk_error_t cdk_stream_sockopen (const char *host, unsigned short port,
882 cdk_stream_t *ret_out);
883
884/* Return a stream object which is associated to an existing file. */
885cdk_error_t cdk_stream_open (const char * file, cdk_stream_t * ret_s);
886
887/* Return a stream object which is associated to a file which will
888 be created when the stream is closed. */
889cdk_error_t cdk_stream_new (const char * file, cdk_stream_t * ret_s);
890
891/* Return a stream object with custom callback functions for the
892 various core operations. */
893cdk_error_t cdk_stream_new_from_cbs (cdk_stream_cbs_t cbs, void *opa,
894 cdk_stream_t *ret_s);
895cdk_error_t cdk_stream_create (const char * file, cdk_stream_t * ret_s);
896cdk_error_t cdk_stream_tmp_new (cdk_stream_t *r_out);
897cdk_error_t cdk_stream_tmp_from_mem (const void * buf, size_t buflen,
898 cdk_stream_t *r_out);
899void cdk_stream_tmp_set_mode (cdk_stream_t s, int val);
900cdk_error_t cdk_stream_flush (cdk_stream_t s);
901cdk_error_t cdk_stream_enable_cache (cdk_stream_t s, int val);
902cdk_error_t cdk_stream_filter_disable (cdk_stream_t s, int type);
903cdk_error_t cdk_stream_close (cdk_stream_t s);
904off_t cdk_stream_get_length (cdk_stream_t s);
905int cdk_stream_read (cdk_stream_t s, void * buf, size_t count);
906int cdk_stream_write (cdk_stream_t s, const void * buf, size_t count);
907int cdk_stream_putc (cdk_stream_t s, int c);
908int cdk_stream_getc (cdk_stream_t s);
909int cdk_stream_eof (cdk_stream_t s);
910off_t cdk_stream_tell (cdk_stream_t s);
911cdk_error_t cdk_stream_seek (cdk_stream_t s, off_t offset);
912cdk_error_t cdk_stream_set_armor_flag (cdk_stream_t s, int type);
913
914/* Push the literal filter for the given stream. */
915cdk_error_t cdk_stream_set_literal_flag (cdk_stream_t s,
916 cdk_lit_format_t mode,
917 const char * fname);
918
919cdk_error_t cdk_stream_set_cipher_flag (cdk_stream_t s, cdk_dek_t dek,
920 int use_mdc);
921cdk_error_t cdk_stream_set_compress_flag (cdk_stream_t s, int algo, int level);
922cdk_error_t cdk_stream_set_hash_flag (cdk_stream_t s, int algo);
923cdk_error_t cdk_stream_set_text_flag (cdk_stream_t s, const char * lf);
924cdk_error_t cdk_stream_kick_off (cdk_stream_t inp, cdk_stream_t out);
925cdk_error_t cdk_stream_mmap (cdk_stream_t s, unsigned char **ret_buf,
926 size_t *ret_buflen);
927cdk_error_t cdk_stream_mmap_part (cdk_stream_t s, off_t off, size_t len,
928 unsigned char **ret_buf, size_t *ret_buflen);
929
930/* Read from the stream but restore the file pointer after reading
931 the requested amount of bytes. */
932int cdk_stream_peek (cdk_stream_t inp, unsigned char *buf, size_t buflen);
933
934/* A wrapper around the various new_from_XXX functions. Because
935 the function does not support all combinations, the dedicated
936 functions should be preferred. */
937cdk_error_t cdk_keydb_new (cdk_keydb_hd_t *r_hd, int type, void *data,
938 size_t count);
939
940/* Create a new key db handle from a memory buffer. */
941cdk_error_t cdk_keydb_new_from_mem (cdk_keydb_hd_t *r_hd, int secret,
942 const void *data, size_t datlen);
943
944/* Create a new key db which uses an existing file. */
945cdk_error_t cdk_keydb_new_from_file (cdk_keydb_hd_t *r_hd, int secret,
946 const char *fname);
947
948/* Uses a stream as the key db input. For searching it is important
949 that the seek function is supported on the stream. Furthermore,
950 the stream is not closed in cdk_keydb_free(). The caller must do it. */
951cdk_error_t cdk_keydb_new_from_stream (cdk_keydb_hd_t *r_hd, int secret,
952 cdk_stream_t in);
953
954/* Check that a secret key with the given key ID is available. */
955cdk_error_t cdk_keydb_check_sk (cdk_keydb_hd_t hd, unsigned int *keyid);
956
957/* Prepare the key db search. */
958cdk_error_t cdk_keydb_search_start (cdk_keydb_hd_t hd, int type, void *desc);
959
960/* Return a key which matches a valid description given in
961 cdk_keydb_search_start(). */
962cdk_error_t cdk_keydb_search (cdk_keydb_hd_t hd, cdk_kbnode_t *ret_key);
963
964/* Release the key db handle and all its resources. */
965void cdk_keydb_free (cdk_keydb_hd_t hd);
966
967/* The following functions will try to find a key in the given key
968 db handle either by keyid, by fingerprint or by some pattern. */
969cdk_error_t cdk_keydb_get_bykeyid (cdk_keydb_hd_t hd, unsigned int *keyid,
970 cdk_kbnode_t *ret_pk);
971cdk_error_t cdk_keydb_get_byfpr (cdk_keydb_hd_t hd, const unsigned char *fpr,
972 cdk_kbnode_t *ret_pk);
973cdk_error_t cdk_keydb_get_bypattern (cdk_keydb_hd_t hd, const char *patt,
974 cdk_kbnode_t *ret_pk);
975
976/* These function, in contrast to most other key db functions, only
977 return the public or secret key packet without the additional
978 signatures and user IDs. */
979cdk_error_t cdk_keydb_get_pk (cdk_keydb_hd_t khd, unsigned int * keyid,
980 cdk_pubkey_t *ret_pk);
981cdk_error_t cdk_keydb_get_sk (cdk_keydb_hd_t khd, unsigned int * keyid,
982 cdk_seckey_t *ret_sk);
983
984/* Try to read the next key block from the given input stream.
985 The key will be returned in @RET_KEY on success. */
986cdk_error_t cdk_keydb_get_keyblock (cdk_stream_t inp, cdk_kbnode_t * ret_key);
987
988/* Rebuild the key db index if possible. */
989cdk_error_t cdk_keydb_idx_rebuild (cdk_keydb_hd_t hd);
990
991/* Export one or more keys from the given key db handle into
992 the stream @OUT. The export is done by substring search and
993 uses the string list @REMUSR for the pattern. */
994cdk_error_t cdk_keydb_export (cdk_keydb_hd_t hd, cdk_stream_t out,
995 cdk_strlist_t remusr);
996
997/* Import the given key node @knode into the key db. */
998cdk_error_t cdk_keydb_import (cdk_keydb_hd_t hd, cdk_kbnode_t knode);
999
1000
1001/* List or enumerate keys from a given key db handle. */
1002
1003/* Start the key list process. Either use @PATT for a pattern search
1004 or @FPATT for a list of pattern. */
1005cdk_error_t cdk_listkey_start (cdk_listkey_t *r_ctx, cdk_keydb_hd_t db,
1006 const char *patt, cdk_strlist_t fpatt);
1007void cdk_listkey_close (cdk_listkey_t ctx);
1008
1009/* Return the next key which matches the pattern. */
1010cdk_error_t cdk_listkey_next (cdk_listkey_t ctx, cdk_kbnode_t *ret_key);
1011
1012cdk_kbnode_t cdk_kbnode_new (cdk_packet_t pkt);
1013cdk_error_t cdk_kbnode_read_from_mem (cdk_kbnode_t * ret_node,
1014 const unsigned char * buf,
1015 size_t buflen);
1016cdk_error_t cdk_kbnode_write_to_mem (cdk_kbnode_t node,
1017 unsigned char * buf, size_t * r_nbytes);
1018cdk_error_t cdk_kbnode_write_to_mem_alloc (cdk_kbnode_t node,
1019 unsigned char **r_buf,
1020 size_t *r_buflen);
1021
1022void cdk_kbnode_release (cdk_kbnode_t node);
1023cdk_kbnode_t cdk_kbnode_walk (cdk_kbnode_t root, cdk_kbnode_t * ctx, int all);
1024cdk_packet_t cdk_kbnode_find_packet (cdk_kbnode_t node, int pkttype);
1025cdk_packet_t cdk_kbnode_get_packet (cdk_kbnode_t node);
1026cdk_kbnode_t cdk_kbnode_find (cdk_kbnode_t node, int pkttype);
1027cdk_kbnode_t cdk_kbnode_find_prev (cdk_kbnode_t root, cdk_kbnode_t node,
1028 int pkttype);
1029cdk_kbnode_t cdk_kbnode_find_next (cdk_kbnode_t node, int pkttype);
1030cdk_error_t cdk_kbnode_hash (cdk_kbnode_t node, gcry_md_hd_t md, int is_v4,
1031 int pkttype, int flags);
1032
1033/* Check each signature in the key node and return a summary of the
1034 key status in @r_status. Values of cdk_key_flag_t are used. */
1035cdk_error_t cdk_pk_check_sigs (cdk_kbnode_t knode, cdk_keydb_hd_t hd,
1036 int *r_status);
1037
1038/* Check the self signature of the key to make sure it is valid. */
1039cdk_error_t cdk_pk_check_self_sig (cdk_kbnode_t knode, int *r_status);
1040
1041/* Return a matching algorithm from the given public key list.
1042 @PREFTYPE can be either sym-cipher/compress/digest. */
1043int cdk_pklist_select_algo (cdk_keylist_t pkl, int preftype);
1044
1045/* Return 0 or 1 if the given key list is able to understand the
1046 MDC feature. */
1047int cdk_pklist_use_mdc (cdk_keylist_t pkl);
1048cdk_error_t cdk_pklist_build (cdk_keylist_t *ret_pkl, cdk_keydb_hd_t hd,
1049 cdk_strlist_t remusr, int use);
1050void cdk_pklist_release (cdk_keylist_t pkl);
1051
1052/* Encrypt the given DEK key with the list of public keys given
1053 in @PKL. The result will be written to the stream output @OUT. */
1054cdk_error_t cdk_pklist_encrypt (cdk_keylist_t pkl, cdk_dek_t dek,
1055 cdk_stream_t out);
1056
1057/* Secret key lists */
1058cdk_error_t cdk_sklist_build (cdk_keylist_t * ret_skl,
1059 cdk_keydb_hd_t db, cdk_ctx_t hd,
1060 cdk_strlist_t locusr,
1061 int unlock, unsigned int use);
1062void cdk_sklist_release (cdk_keylist_t skl);
1063cdk_error_t cdk_sklist_write (cdk_keylist_t skl, cdk_stream_t outp,
1064 gcry_md_hd_t mdctx,
1065 int sigclass, int sigver);
1066cdk_error_t cdk_sklist_write_onepass (cdk_keylist_t skl, cdk_stream_t outp,
1067 int sigclass, int mdalgo);
1068
1069/* Encrypt the given stream @INP with the recipients given in @REMUSR.
1070 If @REMUSR is NULL, symmetric encryption will be used. The output
1071 will be written to @OUT. */
1072cdk_error_t cdk_stream_encrypt (cdk_ctx_t hd, cdk_strlist_t remusr,
1073 cdk_stream_t inp, cdk_stream_t out);
1074
1075/* Decrypt the @INP stream into @OUT. */
1076cdk_error_t cdk_stream_decrypt (cdk_ctx_t hd, cdk_stream_t inp,
1077 cdk_stream_t out);
1078
1079/* Same as the function above but it works on files. */
1080cdk_error_t cdk_file_encrypt (cdk_ctx_t hd, cdk_strlist_t remusr,
1081 const char *file, const char *output);
1082cdk_error_t cdk_file_decrypt (cdk_ctx_t hd, const char * file,
1083 const char *output);
1084
1085/* Generic function to transform data. The mode can be either sign,
1086 verify, encrypt, decrypt, import or export. The meanings of the
1087 parameters are similar to the functions above.
1088 @OUTBUF will contain the output and @OUTSIZE the length of it. */
1089cdk_error_t cdk_data_transform (cdk_ctx_t hd, enum cdk_crypto_mode_t mode,
1090 cdk_strlist_t locusr, cdk_strlist_t remusr,
1091 const void * inbuf, size_t insize,
1092 unsigned char ** outbuf, size_t * outsize,
1093 int modval);
1094
1095/* Sign the stream @INP. Optionally, the output will be encrypted
1096 if @REMUSR is not NULL and the @ENCRYPTFLAG is set.
1097 The output will be written to @OUT.
1098 @LOCUSR contains one ore more pattern for the secret key(s) to use. */
1099cdk_error_t cdk_stream_sign (cdk_ctx_t hd, cdk_stream_t inp, cdk_stream_t out,
1100 cdk_strlist_t locusr, cdk_strlist_t remusr,
1101 int encryptflag, int sigmode);
1102
1103/* Same as the function above but it works on files. */
1104cdk_error_t cdk_file_sign (cdk_ctx_t hd, cdk_strlist_t locusr,
1105 cdk_strlist_t remusr,
1106 const char *file, const char *output,
1107 int sigmode, int encryptflag);
1108
1109cdk_error_t cdk_stream_verify (cdk_ctx_t hd, cdk_stream_t inp,
1110 cdk_stream_t data,
1111 cdk_stream_t out);
1112
1113/* Verify the given file @FILE. For a detached signature, @DATA_FILE
1114 contains the actual file data and @FILE is only the signature.
1115 If the @OUTPUT is not NULL, the plaintext will be written to this file. */
1116cdk_error_t cdk_file_verify (cdk_ctx_t hd, const char *file,
1117 const char *data_file, const char *output);
1118
1119int cdk_trustdb_get_validity (cdk_stream_t inp, cdk_pkt_userid_t id,
1120 int *r_val);
1121int cdk_trustdb_get_ownertrust (cdk_stream_t inp, cdk_pubkey_t pk,
1122 int *r_val, int *r_flags);
1123
1124void cdk_strlist_free (cdk_strlist_t sl);
1125cdk_strlist_t cdk_strlist_add (cdk_strlist_t * list, const char * string);
1126cdk_strlist_t cdk_strlist_next (cdk_strlist_t root, const char **r_str);
1127const char * cdk_check_version (const char * req_version);
1128/* UTF8 */
1129char* cdk_utf8_encode (const char * string);
1130char* cdk_utf8_decode (const char * string, size_t length, int delim);
1131
1132/* Try to receive the key, which has the key ID @KEYID, from the
1133 keyserver host @HOST and the port @PORT. */
1134cdk_error_t cdk_keyserver_recv_key (const char *host, int port,
1135 const unsigned char *keyid, int kid_type,
1136 cdk_kbnode_t *r_key);
1137
1138cdk_error_t cdk_keygen_new (cdk_keygen_ctx_t * r_hd);
1139void cdk_keygen_free (cdk_keygen_ctx_t hd);
1140
1141/* Set the preferences of the given type for the new key.
1142 @ARRAY is an array which list of algorithm IDs. */
1143cdk_error_t cdk_keygen_set_prefs (cdk_keygen_ctx_t hd,
1144 enum cdk_pref_type_t type,
1145 const unsigned char * array, size_t n);
1146cdk_error_t cdk_keygen_set_algo_info (cdk_keygen_ctx_t hd, int type,
1147 int usage, enum cdk_pubkey_algo_t algo,
1148 unsigned int bits);
1149int cdk_keygen_set_keyserver_flags (cdk_keygen_ctx_t hd, int no_modify,
1150 const char *pref_url);
1151int cdk_keygen_set_expire_date (cdk_keygen_ctx_t hd, int type,
1152 long timestamp);
1153
1154/* Set the user ID specifc parts for the new key.
1155 It is suggested to use a name in the form of
1156 'First Name' 'Last Name' <email-address@host.domain> */
1157void cdk_keygen_set_name (cdk_keygen_ctx_t hd, const char * name);
1158void cdk_keygen_set_passphrase (cdk_keygen_ctx_t hd, const char * pass);
1159cdk_error_t cdk_keygen_start (cdk_keygen_ctx_t hd);
1160cdk_error_t cdk_keygen_save (cdk_keygen_ctx_t hd,
1161 const char * pubf,
1162 const char * secf);
1163
1164#ifdef __cplusplus
1165}
1166#endif
1167
1168#endif /* OPENCDK_H */
1169
diff --git a/src/daemon/https/opencdk/packet.h b/src/daemon/https/opencdk/packet.h
new file mode 100644
index 00000000..03547ace
--- /dev/null
+++ b/src/daemon/https/opencdk/packet.h
@@ -0,0 +1,40 @@
1/* packet.h
2 * Copyright (C) 2002, 2003, 2007 Timo Schulz
3 *
4 * This file is part of OpenCDK.
5 *
6 * OpenCDK is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * OpenCDK is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16#ifndef CDK_PACKET_H
17#define CDK_PACKET_H
18
19struct cdk_kbnode_s
20{
21 struct cdk_kbnode_s *next;
22 cdk_packet_t pkt;
23 unsigned int is_deleted:1;
24 unsigned int is_cloned:1;
25};
26
27/*-- new-packet.c --*/
28void _cdk_free_mpibuf (size_t n, gcry_mpi_t *array);
29void _cdk_free_userid (cdk_pkt_userid_t uid);
30void _cdk_free_signature( cdk_pkt_signature_t sig );
31cdk_prefitem_t _cdk_copy_prefs( const cdk_prefitem_t prefs );
32int _cdk_copy_userid( cdk_pkt_userid_t *dst, cdk_pkt_userid_t src );
33int _cdk_copy_pubkey( cdk_pkt_pubkey_t* dst, cdk_pkt_pubkey_t src );
34int _cdk_copy_seckey( cdk_pkt_seckey_t* dst, cdk_pkt_seckey_t src );
35int _cdk_copy_pk_to_sk( cdk_pkt_pubkey_t pk, cdk_pkt_seckey_t sk );
36int _cdk_copy_signature( cdk_pkt_signature_t* dst, cdk_pkt_signature_t src );
37int _cdk_pubkey_compare( cdk_pkt_pubkey_t a, cdk_pkt_pubkey_t b );
38
39#endif /* CDK_PACKET_H */
40
diff --git a/src/daemon/https/opencdk/pubkey.c b/src/daemon/https/opencdk/pubkey.c
new file mode 100644
index 00000000..0d24df12
--- /dev/null
+++ b/src/daemon/https/opencdk/pubkey.c
@@ -0,0 +1,1380 @@
1/* pubkey.c - Public key API
2 * Copyright (C) 2007 Free Software Foundation, Inc.
3 * Copyright (C) 2002, 2003, 2007 Timo Schulz
4 *
5 * This file is part of OpenCDK.
6 *
7 * OpenCDK is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * OpenCDK is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17#ifdef HAVE_CONFIG_H
18#include <config.h>
19#endif
20#include <stdio.h>
21#include <gcrypt.h>
22
23#include "opencdk.h"
24#include "main.h"
25#include "packet.h"
26
27
28/* Convert the given secret key into a gcrypt SEXP object. */
29static int
30seckey_to_sexp (gcry_sexp_t * r_skey, cdk_seckey_t sk)
31{
32 gcry_sexp_t sexp = NULL;
33 gcry_mpi_t *mpk = NULL, *msk = NULL;
34 gcry_error_t err;
35 cdk_pubkey_t pk;
36 const char *fmt;
37
38 if (!r_skey || !sk || !sk->pk)
39 return CDK_Inv_Value;
40
41 pk = sk->pk;
42 mpk = pk->mpi;
43 msk = sk->mpi;
44
45 *r_skey = NULL;
46 if (is_RSA (sk->pubkey_algo))
47 {
48 fmt = "(private-key(openpgp-rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))";
49 err = gcry_sexp_build (&sexp, NULL, fmt, mpk[0], mpk[1],
50 msk[0], msk[1], msk[2], msk[3]);
51 }
52 else if (is_ELG (sk->pubkey_algo))
53 {
54 fmt = "(private-key(openpgp-elg(p%m)(g%m)(y%m)(x%m)))";
55 err = gcry_sexp_build (&sexp, NULL, fmt, mpk[0], mpk[1],
56 mpk[2], msk[0]);
57 }
58 else if (is_DSA (sk->pubkey_algo))
59 {
60 fmt = "(private-key(openpgp-dsa(p%m)(q%m)(g%m)(y%m)(x%m)))";
61 err = gcry_sexp_build (&sexp, NULL, fmt, mpk[0], mpk[1], mpk[2],
62 mpk[3], msk[0]);
63 }
64 else
65 return CDK_Inv_Algo;
66 if (err)
67 return map_gcry_error (err);
68 *r_skey = sexp;
69 return 0;
70}
71
72
73/* Convert the given public key to a gcrypt SEXP object. */
74static cdk_error_t
75pubkey_to_sexp (gcry_sexp_t * r_key_sexp, cdk_pubkey_t pk)
76{
77 gcry_mpi_t *m;
78 gcry_error_t err;
79 const char *fmt = NULL;
80 cdk_error_t rc = 0;
81
82 if (!r_key_sexp || !pk)
83 return CDK_Inv_Value;
84
85 m = pk->mpi;
86 if (is_RSA (pk->pubkey_algo))
87 {
88 fmt = "(public-key(openpgp-rsa(n%m)(e%m)))";
89 err = gcry_sexp_build (r_key_sexp, NULL, fmt, m[0], m[1]);
90 if (err)
91 rc = map_gcry_error (err);
92 }
93 else if (is_ELG (pk->pubkey_algo))
94 {
95 fmt = "(public-key(openpgp-elg(p%m)(g%m)(y%m)))";
96 err = gcry_sexp_build (r_key_sexp, NULL, fmt, m[0], m[1], m[2]);
97 if (err)
98 rc = map_gcry_error (err);
99 }
100 else if (is_DSA (pk->pubkey_algo))
101 {
102 fmt = "(public-key(openpgp-dsa(p%m)(q%m)(g%m)(y%m)))";
103 err = gcry_sexp_build (r_key_sexp, NULL, fmt, m[0], m[1], m[2], m[3]);
104 if (err)
105 rc = map_gcry_error (err);
106 }
107 else
108 rc = CDK_Inv_Algo;
109 return rc;
110}
111
112
113static cdk_error_t
114enckey_to_sexp (gcry_sexp_t * r_sexp, gcry_mpi_t esk)
115{
116 gcry_error_t err;
117
118 if (!r_sexp || !esk)
119 return CDK_Inv_Value;
120 err = gcry_sexp_build (r_sexp, NULL, "%m", esk);
121 if (err)
122 return map_gcry_error (err);
123 return 0;
124}
125
126
127static cdk_error_t
128digest_to_sexp (gcry_sexp_t * r_md_sexp, int digest_algo,
129 const byte * md, size_t mdlen)
130{
131 gcry_mpi_t m;
132 gcry_error_t err;
133
134 if (!r_md_sexp || !md)
135 return CDK_Inv_Value;
136
137 if (!mdlen)
138 mdlen = gcry_md_get_algo_dlen (digest_algo);
139 if (!mdlen)
140 return CDK_Inv_Algo;
141
142 err = gcry_mpi_scan (&m, GCRYMPI_FMT_USG, md, mdlen, &mdlen);
143 if (err)
144 return map_gcry_error (err);
145
146 err = gcry_sexp_build (r_md_sexp, NULL, "%m", m);
147 gcry_mpi_release (m);
148 if (err)
149 return map_gcry_error (err);
150 return 0;
151}
152
153
154static cdk_error_t
155sexp_to_mpi (gcry_sexp_t sexp, const char *val, gcry_mpi_t * ret_buf)
156{
157 gcry_sexp_t list;
158
159 if (!sexp || !val || !ret_buf)
160 return CDK_Inv_Value;
161
162 list = gcry_sexp_find_token (sexp, val, 0);
163 if (!list)
164 return CDK_Inv_Value;
165
166 *ret_buf = gcry_sexp_nth_mpi (list, 1, 0);
167 gcry_sexp_release (list);
168 if (!*ret_buf)
169 return CDK_Inv_Value;
170 return 0;
171}
172
173
174static cdk_error_t
175sexp_to_sig (cdk_pkt_signature_t sig, gcry_sexp_t sexp)
176{
177 if (!sig || !sexp)
178 return CDK_Inv_Value;
179
180 /* ElGamal signatures are not supported any longer. */
181 if (is_ELG (sig->pubkey_algo))
182 {
183 _cdk_log_debug ("sexp_to_sig: unsupported signature type (ElGamal)\n");
184 return CDK_Not_Implemented;
185 }
186
187 if (is_RSA (sig->pubkey_algo))
188 return sexp_to_mpi (sexp, "s", &sig->mpi[0]);
189 else if (is_DSA (sig->pubkey_algo))
190 {
191 cdk_error_t rc;
192
193 rc = sexp_to_mpi (sexp, "r", &sig->mpi[0]);
194 if (!rc)
195 rc = sexp_to_mpi (sexp, "s", &sig->mpi[1]);
196 return rc;
197 }
198 return CDK_Inv_Algo;
199}
200
201
202static cdk_error_t
203sig_to_sexp (gcry_sexp_t * r_sig_sexp, cdk_pkt_signature_t sig)
204{
205 gcry_error_t err;
206 cdk_error_t rc;
207 const char *fmt;
208
209 if (!r_sig_sexp || !sig)
210 return CDK_Inv_Value;
211 if (is_ELG (sig->pubkey_algo))
212 return CDK_Not_Implemented;
213
214 rc = 0;
215 if (is_RSA (sig->pubkey_algo))
216 {
217 fmt = "(sig-val(openpgp-rsa(s%m)))";
218 err = gcry_sexp_build (r_sig_sexp, NULL, fmt, sig->mpi[0]);
219 if (err)
220 rc = map_gcry_error (err);
221 }
222 else if (is_DSA (sig->pubkey_algo))
223 {
224 fmt = "(sig-val(openpgp-dsa(r%m)(s%m)))";
225 err = gcry_sexp_build (r_sig_sexp, NULL, fmt, sig->mpi[0], sig->mpi[1]);
226 if (err)
227 rc = map_gcry_error (err);
228 }
229 else
230 rc = CDK_Inv_Algo;
231 return rc;
232}
233
234
235static cdk_error_t
236sexp_to_pubenc (cdk_pkt_pubkey_enc_t enc, gcry_sexp_t sexp)
237{
238 if (!sexp || !enc)
239 return CDK_Inv_Value;
240
241 if (is_RSA (enc->pubkey_algo))
242 return sexp_to_mpi (sexp, "a", &enc->mpi[0]);
243 else if (is_ELG (enc->pubkey_algo))
244 {
245 cdk_error_t rc = sexp_to_mpi (sexp, "a", &enc->mpi[0]);
246 if (!rc)
247 rc = sexp_to_mpi (sexp, "b", &enc->mpi[1]);
248 return rc;
249 }
250 return CDK_Inv_Algo;
251}
252
253
254static cdk_error_t
255pubenc_to_sexp (gcry_sexp_t * r_sexp, cdk_pkt_pubkey_enc_t enc)
256{
257 gcry_sexp_t sexp = NULL;
258 gcry_error_t err;
259 const char *fmt;
260
261 if (!r_sexp || !enc)
262 return CDK_Inv_Value;
263
264 *r_sexp = NULL;
265 if (is_RSA (enc->pubkey_algo))
266 {
267 fmt = "(enc-val(openpgp-rsa((a%m))))";
268 err = gcry_sexp_build (&sexp, NULL, fmt, enc->mpi[0]);
269 }
270 else if (is_ELG (enc->pubkey_algo))
271 {
272 fmt = "(enc-val(openpgp-elg((a%m)(b%m))))";
273 err = gcry_sexp_build (&sexp, NULL, fmt, enc->mpi[0], enc->mpi[1]);
274 }
275 else
276 return CDK_Inv_Algo;
277 if (err)
278 return map_gcry_error (err);
279 *r_sexp = sexp;
280 return 0;
281}
282
283
284static int
285is_unprotected (cdk_seckey_t sk)
286{
287 if (sk->is_protected && !sk->mpi[0])
288 return 0;
289 return 1;
290}
291
292
293/**
294 * cdk_pk_encrypt:
295 * @pk: the public key
296 * @pke: the public key encrypted packet
297 * @esk: the actual session key
298 *
299 * Encrypt the session key in @esk and write its encrypted content
300 * into the @pke struct.
301 **/
302cdk_error_t
303cdk_pk_encrypt (cdk_pubkey_t pk, cdk_pkt_pubkey_enc_t pke, gcry_mpi_t esk)
304{
305 gcry_sexp_t s_data = NULL, s_pkey = NULL, s_ciph = NULL;
306 gcry_error_t err;
307 cdk_error_t rc;
308
309 if (!pk || !esk || !pke)
310 return CDK_Inv_Value;
311
312 if (!KEY_CAN_ENCRYPT (pk->pubkey_algo))
313 return CDK_Inv_Algo;
314
315 rc = enckey_to_sexp (&s_data, esk);
316 if (!rc)
317 rc = pubkey_to_sexp (&s_pkey, pk);
318 if (!rc)
319 {
320 err = gcry_pk_encrypt (&s_ciph, s_data, s_pkey);
321 if (err)
322 return map_gcry_error (err);
323 }
324 if (!rc)
325 rc = sexp_to_pubenc (pke, s_ciph);
326
327 gcry_sexp_release (s_data);
328 gcry_sexp_release (s_pkey);
329 gcry_sexp_release (s_ciph);
330 return rc;
331}
332
333
334/**
335 * cdk_pk_decrypt:
336 * @sk: the secret key
337 * @pke: public key encrypted packet
338 * @r_sk: the object to store the plain session key
339 *
340 * Decrypt the encrypted session key from @pke into @r_sk.
341 **/
342cdk_error_t
343cdk_pk_decrypt (cdk_seckey_t sk, cdk_pkt_pubkey_enc_t pke, gcry_mpi_t * r_sk)
344{
345 gcry_sexp_t s_data = NULL, s_skey = NULL, s_plain = NULL;
346 cdk_error_t rc;
347 gcry_error_t err;
348
349 if (!sk || !r_sk || !pke)
350 return CDK_Inv_Value;
351
352 if (!is_unprotected (sk))
353 return CDK_Inv_Mode;
354
355 *r_sk = NULL;
356 rc = seckey_to_sexp (&s_skey, sk);
357 if (rc)
358 return rc;
359
360 rc = pubenc_to_sexp (&s_data, pke);
361 if (rc)
362 {
363 gcry_sexp_release (s_skey);
364 return rc;
365 }
366
367 err = gcry_pk_decrypt (&s_plain, s_data, s_skey);
368 if (err)
369 rc = map_gcry_error (err);
370 else
371 *r_sk = gcry_sexp_nth_mpi (s_plain, 0, 0);
372
373 gcry_sexp_release (s_data);
374 gcry_sexp_release (s_skey);
375 gcry_sexp_release (s_plain);
376 return rc;
377}
378
379
380/**
381 * cdk_pk_sign:
382 * @sk: secret key
383 * @sig: signature
384 * @md: the message digest
385 *
386 * Sign the message digest from @md and write the result into @sig.
387 **/
388cdk_error_t
389cdk_pk_sign (cdk_seckey_t sk, cdk_pkt_signature_t sig, const byte * md)
390{
391 gcry_sexp_t s_skey = NULL, s_sig = NULL, s_hash = NULL;
392 byte *encmd = NULL;
393 size_t enclen = 0;
394 int nbits;
395 cdk_error_t rc;
396 gcry_error_t err;
397
398 if (!sk || !sk->pk || !sig || !md)
399 return CDK_Inv_Value;
400
401 if (!is_unprotected (sk))
402 return CDK_Inv_Mode;
403
404 if (!KEY_CAN_SIGN (sig->pubkey_algo))
405 return CDK_Inv_Algo;
406
407 nbits = cdk_pk_get_nbits (sk->pk);
408 rc = _cdk_digest_encode_pkcs1 (&encmd, &enclen, sk->pk->pubkey_algo, md,
409 sig->digest_algo, nbits);
410 if (rc)
411 return rc;
412
413 rc = seckey_to_sexp (&s_skey, sk);
414 if (!rc)
415 rc = digest_to_sexp (&s_hash, sig->digest_algo, encmd, enclen);
416 if (rc)
417 {
418 cdk_free (encmd);
419 gcry_sexp_release (s_skey);
420 return rc;
421 }
422
423 err = gcry_pk_sign (&s_sig, s_hash, s_skey);
424 if (err)
425 rc = map_gcry_error (err);
426 else
427 {
428 rc = sexp_to_sig (sig, s_sig);
429 if (!rc)
430 {
431 sig->digest_start[0] = md[0];
432 sig->digest_start[1] = md[1];
433 }
434 }
435
436 gcry_sexp_release (s_skey);
437 gcry_sexp_release (s_hash);
438 gcry_sexp_release (s_sig);
439 cdk_free (encmd);
440 return rc;
441}
442
443
444/**
445 * cdk_pk_verify:
446 * @pk: the public key
447 * @sig: signature
448 * @md: the message digest
449 *
450 * Verify the signature in @sig and compare it with the message digest in @md.
451 **/
452cdk_error_t
453cdk_pk_verify (cdk_pubkey_t pk, cdk_pkt_signature_t sig, const byte * md)
454{
455 gcry_sexp_t s_pkey = NULL, s_sig = NULL, s_hash = NULL;
456 byte *encmd = NULL;
457 size_t enclen;
458 cdk_error_t rc;
459
460 if (!pk || !sig || !md)
461 return CDK_Inv_Value;
462
463 rc = pubkey_to_sexp (&s_pkey, pk);
464 if (rc)
465 return rc;
466
467 rc = sig_to_sexp (&s_sig, sig);
468 if (rc)
469 goto leave;
470
471 rc = _cdk_digest_encode_pkcs1 (&encmd, &enclen, pk->pubkey_algo, md,
472 sig->digest_algo, cdk_pk_get_nbits (pk));
473 if (rc)
474 goto leave;
475
476 rc = digest_to_sexp (&s_hash, sig->digest_algo, encmd, enclen);
477 if (rc)
478 goto leave;
479
480 if (gcry_pk_verify (s_sig, s_hash, s_pkey))
481 rc = CDK_Bad_Sig;
482
483leave:
484 gcry_sexp_release (s_sig);
485 gcry_sexp_release (s_hash);
486 gcry_sexp_release (s_pkey);
487 cdk_free (encmd);
488 return rc;
489}
490
491
492/**
493 * cdk_pk_get_nbits:
494 * @pk: the public key
495 *
496 * Return the length of the public key in bits.
497 * The meaning of length is actually the size of the 'prime'
498 * object in the key. For RSA keys the modulus, for ElG/DSA
499 * the size of the public prime.
500 **/
501int
502cdk_pk_get_nbits (cdk_pubkey_t pk)
503{
504 if (!pk || !pk->mpi[0])
505 return 0;
506 return gcry_mpi_get_nbits (pk->mpi[0]);
507}
508
509
510/**
511 * cdk_pk_get_npkey:
512 * @algo: The public key algorithm.
513 *
514 * Return the number of multiprecison integer forming an public
515 * key with the given algorithm.
516 */
517int
518cdk_pk_get_npkey (int algo)
519{
520 size_t bytes;
521
522 if (algo == 16)
523 algo = 20; /* FIXME: libgcrypt returns 0 for 16 */
524 if (gcry_pk_algo_info (algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &bytes))
525 return 0;
526 return bytes;
527}
528
529
530/**
531 * cdk_pk_get_nskey:
532 * @algo: the public key algorithm
533 *
534 * Return the number of multiprecision integers forming an
535 * secret key with the given algorithm.
536 **/
537int
538cdk_pk_get_nskey (int algo)
539{
540 size_t bytes;
541
542 if (gcry_pk_algo_info (algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &bytes))
543 return 0;
544 bytes -= cdk_pk_get_npkey (algo);
545 return bytes;
546}
547
548
549/**
550 * cdk_pk_get_nbits:
551 * @algo: the public key algorithm
552 *
553 * Return the number of MPIs a signature consists of.
554 **/
555int
556cdk_pk_get_nsig (int algo)
557{
558 size_t bytes;
559
560 if (gcry_pk_algo_info (algo, GCRYCTL_GET_ALGO_NSIGN, NULL, &bytes))
561 return 0;
562 return bytes;
563}
564
565
566/**
567 * cdk_pk_get_nenc:
568 * @algo: the public key algorithm
569 *
570 * Return the number of MPI's the encrypted data consists of.
571 **/
572int
573cdk_pk_get_nenc (int algo)
574{
575 size_t bytes;
576
577 if (gcry_pk_algo_info (algo, GCRYCTL_GET_ALGO_NENCR, NULL, &bytes))
578 return 0;
579 return bytes;
580}
581
582
583int
584_cdk_pk_algo_usage (int algo)
585{
586 int usage;
587
588 /* The ElGamal sign+encrypt algorithm is not supported any longer. */
589 switch (algo)
590 {
591 case CDK_PK_RSA:
592 usage = CDK_KEY_USG_SIGN | CDK_KEY_USG_ENCR;
593 break;
594 case CDK_PK_RSA_E:
595 usage = CDK_KEY_USG_ENCR;
596 break;
597 case CDK_PK_RSA_S:
598 usage = CDK_KEY_USG_SIGN;
599 break;
600 case CDK_PK_ELG_E:
601 usage = CDK_KEY_USG_ENCR;
602 break;
603 case CDK_PK_DSA:
604 usage = CDK_KEY_USG_SIGN;
605 break;
606 default:
607 usage = 0;
608 }
609 return usage;
610}
611
612
613static cdk_error_t
614mpi_to_buffer (gcry_mpi_t a, byte * buf, size_t buflen,
615 size_t * r_nwritten, size_t * r_nbits)
616{
617 size_t nbits;
618
619 if (!a || !buf || !r_nwritten)
620 return CDK_Inv_Value;
621
622 nbits = gcry_mpi_get_nbits (a);
623 if (r_nbits)
624 *r_nbits = nbits;
625 if ((nbits + 7) / 8 + 2 > buflen)
626 return CDK_Too_Short;
627 *r_nwritten = (nbits + 7) / 8 + 2;
628 if (gcry_mpi_print (GCRYMPI_FMT_PGP, buf, buflen, r_nwritten, a))
629 return CDK_Wrong_Format;
630 return 0;
631}
632
633
634/**
635 * cdk_pk_get_mpi:
636 * @pk: public key
637 * @idx: index of the MPI to retrieve
638 * @buf: buffer to hold the raw data
639 * @r_nwritten: output how large the raw data is
640 * @r_nbits: size of the MPI in bits.
641 *
642 * Return the MPI with the given index of the public key.
643 **/
644cdk_error_t
645cdk_pk_get_mpi (cdk_pubkey_t pk, size_t idx,
646 byte * buf, size_t buflen, size_t * r_nwritten,
647 size_t * r_nbits)
648{
649 if (!pk || !r_nwritten)
650 return CDK_Inv_Value;
651 if (idx > cdk_pk_get_npkey (pk->pubkey_algo))
652 return CDK_Inv_Value;
653 return mpi_to_buffer (pk->mpi[idx], buf, buflen, r_nwritten, r_nbits);
654}
655
656
657/**
658 * cdk_sk_get_mpi:
659 * @sk: secret key
660 * @idx: index of the MPI to retrieve
661 * @buf: buffer to hold the raw data
662 * @r_nwritten: output length of the raw data
663 * @r_nbits: length of the MPI data in bits.
664 *
665 * Return the MPI of the given secret key with the
666 * index @idx. It is important to check if the key
667 * is protected and thus no real MPI data will be returned then.
668 **/
669cdk_error_t
670cdk_sk_get_mpi (cdk_pkt_seckey_t sk, size_t idx,
671 byte * buf, size_t buflen, size_t * r_nwritten,
672 size_t * r_nbits)
673{
674 if (!sk || !r_nwritten)
675 return CDK_Inv_Value;
676 if (idx > cdk_pk_get_nskey (sk->pubkey_algo))
677 return CDK_Inv_Value;
678 return mpi_to_buffer (sk->mpi[idx], buf, buflen, r_nwritten, r_nbits);
679}
680
681
682static u16
683checksum_mpi (gcry_mpi_t m)
684{
685 byte buf[MAX_MPI_BYTES + 2];
686 size_t nread;
687 int i;
688 u16 chksum = 0;
689
690 if (!m)
691 return 0;
692 if (gcry_mpi_print (GCRYMPI_FMT_PGP, buf, DIM (buf), &nread, m))
693 return 0;
694 for (i = 0; i < nread; i++)
695 chksum += buf[i];
696 return chksum;
697}
698
699
700/**
701 * cdk_sk_unprotect:
702 * @sk: the secret key
703 * @pw: the passphrase
704 *
705 * Unprotect the given secret key with the passphrase.
706 **/
707cdk_error_t
708cdk_sk_unprotect (cdk_pkt_seckey_t sk, const char *pw)
709{
710 gcry_cipher_hd_t hd;
711 cdk_dek_t dek = NULL;
712 byte *data = NULL;
713 u16 chksum = 0;
714 size_t ndata, nbits, nbytes;
715 int i, dlen, pos = 0, nskey;
716 cdk_error_t rc;
717 gcry_error_t err;
718
719 if (!sk)
720 return CDK_Inv_Value;
721
722 nskey = cdk_pk_get_nskey (sk->pubkey_algo);
723 if (!sk->is_protected)
724 {
725 chksum = 0;
726 for (i = 0; i < nskey; i++)
727 chksum += checksum_mpi (sk->mpi[i]);
728 if (chksum != sk->csum)
729 return CDK_Chksum_Error;
730 }
731
732 rc = cdk_dek_from_passphrase (&dek, sk->protect.algo,
733 sk->protect.s2k, 0, pw);
734 if (rc)
735 return rc;
736 err = gcry_cipher_open (&hd, sk->protect.algo, GCRY_CIPHER_MODE_CFB,
737 GCRY_CIPHER_ENABLE_SYNC);
738 if (!err)
739 err = gcry_cipher_setiv (hd, sk->protect.iv, sk->protect.ivlen);
740 if (!err)
741 err = gcry_cipher_setkey (hd, dek->key, dek->keylen);
742 if (err)
743 {
744 cdk_free (dek);
745 return map_gcry_error (err);
746 }
747 cdk_dek_free (dek);
748 chksum = 0;
749 if (sk->version == 4)
750 {
751 ndata = sk->enclen;
752 data = cdk_salloc (ndata, 1);
753 if (!data)
754 return CDK_Out_Of_Core;
755 gcry_cipher_decrypt (hd, data, ndata, sk->encdata, ndata);
756 if (sk->protect.sha1chk)
757 {
758 /* This is the new SHA1 checksum method to detect tampering
759 with the key as used by the Klima/Rosa attack */
760 sk->csum = 0;
761 chksum = 1;
762 dlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
763 if (ndata < dlen)
764 {
765 cdk_free (data);
766 return CDK_Inv_Packet;
767 }
768 else
769 {
770 byte mdcheck[20];
771
772 gcry_md_hash_buffer (GCRY_MD_SHA1, mdcheck, data, ndata - dlen);
773 if (!memcmp (mdcheck, data + ndata - dlen, dlen))
774 chksum = 0; /* Digest does match */
775 }
776 }
777 else
778 {
779 for (i = 0; i < ndata - 2; i++)
780 chksum += data[i];
781 sk->csum = data[ndata - 2] << 8 | data[ndata - 1];
782 }
783 if (sk->csum == chksum)
784 {
785 for (i = 0; i < nskey; i++)
786 {
787 nbits = data[pos] << 8 | data[pos + 1];
788
789 if (gcry_mpi_scan (&sk->mpi[i], GCRYMPI_FMT_PGP, data,
790 (nbits + 7) / 8 + 2, &nbytes))
791 {
792 wipemem (data, sk->enclen);
793 cdk_free (data);
794 return CDK_Wrong_Format;
795 }
796 gcry_mpi_set_flag (sk->mpi[i], GCRYMPI_FLAG_SECURE);
797 pos += (nbits + 7) / 8 + 2;
798 }
799 }
800 wipemem (data, sk->enclen);
801 cdk_free (data);
802 }
803 else
804 {
805 byte buf[MAX_MPI_BYTES + 2];
806
807 chksum = 0;
808 for (i = 0; i < nskey; i++)
809 {
810 gcry_cipher_sync (hd);
811 gcry_mpi_print (GCRYMPI_FMT_PGP, buf, DIM (buf),
812 &nbytes, sk->mpi[i]);
813 gcry_cipher_decrypt (hd, buf + 2, nbytes - 2, NULL, 0);
814 gcry_mpi_release (sk->mpi[i]);
815 if (gcry_mpi_scan (&sk->mpi[i], GCRYMPI_FMT_PGP,
816 buf, nbytes, &nbytes))
817 return CDK_Wrong_Format;
818 chksum += checksum_mpi (sk->mpi[i]);
819 }
820 }
821 gcry_cipher_close (hd);
822 if (chksum != sk->csum)
823 return CDK_Chksum_Error;
824 sk->is_protected = 0;
825 return 0;
826}
827
828
829/**
830 * cdk_sk_protect:
831 * @sk: the secret key
832 * @pw: the passphrase to use
833 *
834 * Protect the given secret key with a passphrase.
835 **/
836cdk_error_t
837cdk_sk_protect (cdk_pkt_seckey_t sk, const char *pw)
838{
839 gcry_cipher_hd_t hd = NULL;
840 cdk_dek_t dek = NULL;
841 cdk_s2k_t s2k;
842 byte *p = NULL, buf[MAX_MPI_BYTES + 2];
843 size_t enclen = 0, nskey, i, nbytes;
844 size_t dlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
845 gcry_error_t err;
846 cdk_error_t rc;
847
848 nskey = cdk_pk_get_nskey (sk->pubkey_algo);
849 if (!nskey)
850 return CDK_Inv_Algo;
851
852 rc = cdk_s2k_new (&s2k, CDK_S2K_ITERSALTED, GCRY_MD_SHA256, NULL);
853 if (!rc)
854 rc = cdk_dek_from_passphrase (&dek, GCRY_CIPHER_AES, s2k, 1, pw);
855 if (rc)
856 {
857 cdk_s2k_free (s2k);
858 return rc;
859 }
860
861 for (i = 0; i < nskey; i++)
862 {
863 enclen += 2;
864 enclen += (gcry_mpi_get_nbits (sk->mpi[i]) + 7) / 8;
865 }
866 p = sk->encdata = cdk_calloc (1, enclen + dlen + 1);
867 if (!p)
868 {
869 cdk_s2k_free (s2k);
870 return CDK_Out_Of_Core;
871 }
872
873 enclen = 0;
874 for (i = 0; i < nskey; i++)
875 {
876 if (gcry_mpi_print (GCRYMPI_FMT_PGP, buf,
877 DIM (buf), &nbytes, sk->mpi[i]))
878 {
879 cdk_free (p);
880 cdk_s2k_free (s2k);
881 return CDK_Wrong_Format;
882 }
883 memcpy (p + enclen, buf, nbytes);
884 enclen += nbytes;
885 }
886
887 enclen += dlen;
888 sk->enclen = enclen;
889 sk->protect.s2k = s2k;
890 sk->protect.algo = GCRY_CIPHER_AES;
891 sk->protect.ivlen = gcry_cipher_get_algo_blklen (sk->protect.algo);
892 gcry_randomize (sk->protect.iv, sk->protect.ivlen, GCRY_STRONG_RANDOM);
893 err = gcry_cipher_open (&hd, sk->protect.algo, GCRY_CIPHER_MODE_CFB,
894 GCRY_CIPHER_ENABLE_SYNC);
895 if (err)
896 {
897 cdk_dek_free (dek);
898 rc = map_gcry_error (err);
899 goto leave;
900 }
901
902 err = gcry_cipher_setkey (hd, dek->key, dek->keylen);
903 if (!err)
904 err = gcry_cipher_setiv (hd, sk->protect.iv, sk->protect.ivlen);
905 cdk_dek_free (dek);
906 if (err)
907 {
908 rc = map_gcry_error (err);
909 goto leave;
910 }
911
912 sk->protect.sha1chk = 1;
913 sk->is_protected = 1;
914 sk->csum = 0;
915
916 gcry_md_hash_buffer (GCRY_MD_SHA1, buf, p, enclen - dlen);
917 memcpy (p + enclen - dlen, buf, dlen);
918 gcry_cipher_encrypt (hd, p, enclen, NULL, 0);
919
920 /* FIXME: We should release all MPI's and set the elements to NULL. */
921
922leave:
923 gcry_cipher_close (hd);
924 return rc;
925}
926
927
928/**
929 * cdk_pk_from_secret_key:
930 * @sk: the secret key
931 * @ret_pk: the new public key
932 *
933 * Create a new public key from a secret key.
934 **/
935cdk_error_t
936cdk_pk_from_secret_key (cdk_pkt_seckey_t sk, cdk_pubkey_t * ret_pk)
937{
938 if (!sk)
939 return CDK_Inv_Value;
940 return _cdk_copy_pubkey (ret_pk, sk->pk);
941}
942
943
944#if 0 /* FIXME: Code is not finished yet. */
945cdk_error_t
946cdk_pk_revoke_cert_create (cdk_pkt_seckey_t sk, int code, const char *inf,
947 char **ret_revcert)
948{
949 gcry_md_hd_t md;
950 cdk_subpkt_t node;
951 cdk_pkt_signature_t sig;
952 char *p = NULL, *dat;
953 gcry_error_t err;
954 cdk_error_t rc = 0;
955 size_t n;
956
957 if (!sk || !ret_revcert)
958 return CDK_Inv_Value;
959 if (code < 0 || code > 3)
960 return CDK_Inv_Value;
961
962 sig = cdk_calloc (1, sizeof *sig);
963 if (!sig)
964 return CDK_Out_Of_Core;
965 _cdk_sig_create (sk->pk, sig);
966 n = 1;
967 if (inf)
968 {
969 n += strlen (p);
970 p = cdk_utf8_encode (inf);
971 }
972 dat = cdk_calloc (1, n + 1);
973 if (!dat)
974 {
975 _cdk_free_signature (sig);
976 return CDK_Out_Of_Core;
977 }
978 dat[0] = code;
979 if (inf)
980 memcpy (dat + 1, p, strlen (p));
981 cdk_free (p);
982
983 node = cdk_subpkt_new (n);
984 if (node)
985 {
986 cdk_subpkt_init (node, CDK_SIGSUBPKT_REVOC_REASON, dat, n);
987 cdk_subpkt_add (sig->hashed, node);
988 }
989 cdk_free (dat);
990
991 err = gcry_md_open (&md, GCRY_MD_SHA1, 0);
992 if (err)
993 rc = map_gcry_error (err);
994 else
995 _cdk_hash_pubkey (sk->pk, md, 0);
996 _cdk_free_signature (sig);
997
998 return rc;
999}
1000#endif
1001
1002int
1003_cdk_sk_get_csum (cdk_pkt_seckey_t sk)
1004{
1005 u16 csum = 0, i;
1006
1007 if (!sk)
1008 return 0;
1009 for (i = 0; i < cdk_pk_get_nskey (sk->pubkey_algo); i++)
1010 csum += checksum_mpi (sk->mpi[i]);
1011 return csum;
1012}
1013
1014
1015/**
1016 * cdk_pk_get_fingerprint:
1017 * @pk: the public key
1018 * @fpr: the buffer to hold the fingerprint
1019 *
1020 * Return the fingerprint of the given public key.
1021 * The buffer must be at least 20 octets.
1022 * This function should be considered deprecated and
1023 * the new cdk_pk_to_fingerprint() should be used whenever
1024 * possible to avoid overflows.
1025 **/
1026cdk_error_t
1027cdk_pk_get_fingerprint (cdk_pubkey_t pk, byte * fpr)
1028{
1029 gcry_md_hd_t hd;
1030 int md_algo;
1031 int dlen = 0;
1032 gcry_error_t err;
1033
1034 if (!pk || !fpr)
1035 return CDK_Inv_Value;
1036
1037 if (pk->version < 4 && is_RSA (pk->pubkey_algo))
1038 md_algo = GCRY_MD_MD5; /* special */
1039 else
1040 md_algo = GCRY_MD_SHA1;
1041 dlen = gcry_md_get_algo_dlen (md_algo);
1042 err = gcry_md_open (&hd, md_algo, 0);
1043 if (err)
1044 return map_gcry_error (err);
1045 _cdk_hash_pubkey (pk, hd, 1);
1046 gcry_md_final (hd);
1047 memcpy (fpr, gcry_md_read (hd, md_algo), dlen);
1048 gcry_md_close (hd);
1049 if (dlen == 16)
1050 memset (fpr + 16, 0, 4);
1051 return 0;
1052}
1053
1054
1055/**
1056 * cdk_pk_to_fingerprint:
1057 * @pk: the public key
1058 * @fprbuf: buffer to save the fingerprint
1059 * @fprbuflen: buffer size
1060 * @r_nout: actual length of the fingerprint.
1061 *
1062 * Calculate a fingerprint of the given key and
1063 * return it in the given byte array.
1064 **/
1065cdk_error_t
1066cdk_pk_to_fingerprint (cdk_pubkey_t pk,
1067 byte * fprbuf, size_t fprbuflen, size_t * r_nout)
1068{
1069 size_t key_fprlen;
1070 cdk_error_t err;
1071
1072 if (!pk)
1073 return CDK_Inv_Value;
1074
1075 if (pk->version < 4)
1076 key_fprlen = 16;
1077 else
1078 key_fprlen = 20;
1079
1080 /* Only return the required buffer size for the fingerprint. */
1081 if (!fprbuf && !fprbuflen && r_nout)
1082 {
1083 *r_nout = key_fprlen;
1084 return 0;
1085 }
1086
1087 if (!fprbuf || key_fprlen > fprbuflen)
1088 return CDK_Too_Short;
1089
1090 err = cdk_pk_get_fingerprint (pk, fprbuf);
1091 if (r_nout)
1092 *r_nout = key_fprlen;
1093
1094 return err;
1095}
1096
1097
1098/**
1099 * cdk_pk_fingerprint_get_keyid:
1100 * @fpr: the key fingerprint
1101 * @fprlen: the length of the fingerprint
1102 *
1103 * Derive the key ID from the key fingerprint.
1104 * For version 3 keys, this is not working.
1105 **/
1106u32
1107cdk_pk_fingerprint_get_keyid (const byte * fpr, size_t fprlen, u32 * keyid)
1108{
1109 u32 lowbits = 0;
1110
1111 /* In this case we say the key is a V3 RSA key and we can't
1112 use the fingerprint to get the keyid. */
1113 if (fpr && fprlen == 16)
1114 {
1115 keyid[0] = 0;
1116 keyid[1] = 0;
1117 return 0;
1118 }
1119 else if (keyid && fpr)
1120 {
1121 keyid[0] = _cdk_buftou32 (fpr + 12);
1122 keyid[1] = _cdk_buftou32 (fpr + 16);
1123 lowbits = keyid[1];
1124 }
1125 else if (fpr)
1126 lowbits = _cdk_buftou32 (fpr + 16);
1127 return lowbits;
1128}
1129
1130
1131/**
1132 * cdk_pk_get_keyid:
1133 * @pk: the public key
1134 * @keyid: buffer to store the key ID
1135 *
1136 * Calculate the key ID of the given public key.
1137 **/
1138u32
1139cdk_pk_get_keyid (cdk_pubkey_t pk, u32 * keyid)
1140{
1141 u32 lowbits = 0;
1142 byte buf[24];
1143
1144 if (pk && (!pk->keyid[0] || !pk->keyid[1]))
1145 {
1146 if (pk->version < 4 && is_RSA (pk->pubkey_algo))
1147 {
1148 byte p[MAX_MPI_BYTES];
1149 size_t n;
1150
1151 gcry_mpi_print (GCRYMPI_FMT_USG, p, MAX_MPI_BYTES, &n, pk->mpi[0]);
1152 pk->keyid[0] =
1153 p[n - 8] << 24 | p[n - 7] << 16 | p[n - 6] << 8 | p[n - 5];
1154 pk->keyid[1] =
1155 p[n - 4] << 24 | p[n - 3] << 16 | p[n - 2] << 8 | p[n - 1];
1156 }
1157 else if (pk->version == 4)
1158 {
1159 cdk_pk_get_fingerprint (pk, buf);
1160 pk->keyid[0] = _cdk_buftou32 (buf + 12);
1161 pk->keyid[1] = _cdk_buftou32 (buf + 16);
1162 }
1163 }
1164 lowbits = pk ? pk->keyid[1] : 0;
1165 if (keyid && pk)
1166 {
1167 keyid[0] = pk->keyid[0];
1168 keyid[1] = pk->keyid[1];
1169 }
1170
1171 return lowbits;
1172}
1173
1174
1175/**
1176 * cdk_sk_get_keyid:
1177 * @sk: the secret key
1178 * @keyid: buffer to hold the key ID
1179 *
1180 * Calculate the key ID of the secret key, actually the public key.
1181 **/
1182u32
1183cdk_sk_get_keyid (cdk_pkt_seckey_t sk, u32 * keyid)
1184{
1185 u32 lowbits = 0;
1186
1187 if (sk && sk->pk)
1188 {
1189 lowbits = cdk_pk_get_keyid (sk->pk, keyid);
1190 sk->keyid[0] = sk->pk->keyid[0];
1191 sk->keyid[1] = sk->pk->keyid[1];
1192 }
1193
1194 return lowbits;
1195}
1196
1197
1198/**
1199 * cdk_sig_get_keyid:
1200 * @sig: the signature
1201 * @keyid: buffer to hold the key ID
1202 *
1203 * Retrieve the key ID from the given signature.
1204 **/
1205u32
1206cdk_sig_get_keyid (cdk_pkt_signature_t sig, u32 * keyid)
1207{
1208 u32 lowbits = sig ? sig->keyid[1] : 0;
1209
1210 if (keyid && sig)
1211 {
1212 keyid[0] = sig->keyid[0];
1213 keyid[1] = sig->keyid[1];
1214 }
1215 return lowbits;
1216}
1217
1218
1219/* Return the key ID from the given packet.
1220 If this is not possible, 0 is returned */
1221u32
1222_cdk_pkt_get_keyid (cdk_packet_t pkt, u32 * keyid)
1223{
1224 u32 lowbits;
1225
1226 if (!pkt)
1227 return 0;
1228
1229 switch (pkt->pkttype)
1230 {
1231 case CDK_PKT_PUBLIC_KEY:
1232 case CDK_PKT_PUBLIC_SUBKEY:
1233 lowbits = cdk_pk_get_keyid (pkt->pkt.public_key, keyid);
1234 break;
1235
1236 case CDK_PKT_SECRET_KEY:
1237 case CDK_PKT_SECRET_SUBKEY:
1238 lowbits = cdk_sk_get_keyid (pkt->pkt.secret_key, keyid);
1239 break;
1240
1241 case CDK_PKT_SIGNATURE:
1242 lowbits = cdk_sig_get_keyid (pkt->pkt.signature, keyid);
1243 break;
1244
1245 default:
1246 lowbits = 0;
1247 break;
1248 }
1249
1250 return lowbits;
1251}
1252
1253
1254/* Get the fingerprint of the packet if possible. */
1255int
1256_cdk_pkt_get_fingerprint (cdk_packet_t pkt, byte * fpr)
1257{
1258 if (!pkt || !fpr)
1259 return CDK_Inv_Value;
1260
1261 switch (pkt->pkttype)
1262 {
1263 case CDK_PKT_PUBLIC_KEY:
1264 case CDK_PKT_PUBLIC_SUBKEY:
1265 return cdk_pk_get_fingerprint (pkt->pkt.public_key, fpr);
1266
1267 case CDK_PKT_SECRET_KEY:
1268 case CDK_PKT_SECRET_SUBKEY:
1269 return cdk_pk_get_fingerprint (pkt->pkt.secret_key->pk, fpr);
1270
1271 default:
1272 return CDK_Inv_Mode;
1273 }
1274 return 0;
1275}
1276
1277
1278/**
1279 * cdk_pubkey_to_sexp:
1280 * @pk: the public key
1281 * @sexp: where to store the S-expression
1282 * @len: the length of sexp
1283 *
1284 * Convert a public key to an S-expression. sexp is allocated by this
1285 * function, but you have to cdk_free() it yourself. The S-expression
1286 * is stored in canonical format as used by libgcrypt
1287 * (GCRYSEXP_FMT_CANON).
1288 **/
1289cdk_error_t
1290cdk_pubkey_to_sexp (cdk_pubkey_t pk, char **sexp, size_t * len)
1291{
1292 char *buf;
1293 size_t sexp_len;
1294 gcry_sexp_t pk_sexp;
1295 cdk_error_t rc;
1296
1297 if (!pk || !sexp)
1298 return CDK_Inv_Value;
1299
1300 rc = pubkey_to_sexp (&pk_sexp, pk);
1301 if (rc)
1302 return rc;
1303
1304 sexp_len = gcry_sexp_sprint (pk_sexp, GCRYSEXP_FMT_CANON, NULL, 0);
1305 if (!sexp_len)
1306 return CDK_Wrong_Format;
1307
1308 buf = (char *) cdk_malloc (sexp_len);
1309 if (!buf)
1310 {
1311 gcry_sexp_release (pk_sexp);
1312 return CDK_Out_Of_Core;
1313 }
1314
1315 sexp_len = gcry_sexp_sprint (pk_sexp, GCRYSEXP_FMT_CANON, buf, sexp_len);
1316 gcry_sexp_release (pk_sexp);
1317 if (!sexp_len)
1318 {
1319 cdk_free (buf);
1320 return CDK_Wrong_Format;
1321 }
1322
1323 if (len)
1324 *len = sexp_len;
1325 *sexp = buf;
1326 return CDK_Success;
1327}
1328
1329
1330/**
1331 * cdk_seckey_to_sexp:
1332 * @sk: the secret key
1333 * @sexp: where to store the S-expression
1334 * @len: the length of sexp
1335 *
1336 * Convert a public key to an S-expression. sexp is allocated by this
1337 * function, but you have to cdk_free() it yourself. The S-expression
1338 * is stored in canonical format as used by libgcrypt
1339 * (GCRYSEXP_FMT_CANON).
1340 **/
1341cdk_error_t
1342cdk_seckey_to_sexp (cdk_pkt_seckey_t sk, char **sexp, size_t * len)
1343{
1344 char *buf;
1345 size_t sexp_len;
1346 gcry_sexp_t sk_sexp;
1347 cdk_error_t rc;
1348
1349 if (!sk || !sexp)
1350 return CDK_Inv_Value;
1351
1352 rc = seckey_to_sexp (&sk_sexp, sk);
1353 if (rc)
1354 return rc;
1355
1356 sexp_len = gcry_sexp_sprint (sk_sexp, GCRYSEXP_FMT_CANON, NULL, 0);
1357 if (!sexp_len)
1358 return CDK_Wrong_Format;
1359
1360 buf = (char *) cdk_malloc (sexp_len);
1361 if (!buf)
1362 {
1363 gcry_sexp_release (sk_sexp);
1364 return CDK_Out_Of_Core;
1365 }
1366
1367 sexp_len = gcry_sexp_sprint (sk_sexp, GCRYSEXP_FMT_CANON, buf, sexp_len);
1368 gcry_sexp_release (sk_sexp);
1369 if (!sexp_len)
1370 {
1371 cdk_free (buf);
1372 return CDK_Wrong_Format;
1373 }
1374
1375 if (len)
1376 *len = sexp_len;
1377 *sexp = buf;
1378
1379 return CDK_Success;
1380}
diff --git a/src/daemon/https/opencdk/read-packet.c b/src/daemon/https/opencdk/read-packet.c
new file mode 100644
index 00000000..7c7a91af
--- /dev/null
+++ b/src/daemon/https/opencdk/read-packet.c
@@ -0,0 +1,1179 @@
1/* read-packet.c - Read OpenPGP packets
2 * Copyright (C) 2001, 2002, 2003, 2007 Timo Schulz
3 *
4 * This file is part of OpenCDK.
5 *
6 * OpenCDK is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * OpenCDK is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19#include <string.h>
20#include <stdio.h>
21#include <time.h>
22#include <assert.h>
23
24#include "opencdk.h"
25#include "main.h"
26#include "packet.h"
27#include "types.h"
28
29
30/* The version of the MDC packet considering the lastest OpenPGP draft. */
31#define MDC_PKT_VER 1
32
33static int
34stream_read (cdk_stream_t s, void *buf, size_t buflen, size_t * r_nread)
35{
36 *r_nread = cdk_stream_read (s, buf, buflen);
37 return *r_nread > 0 ? 0 : _cdk_stream_get_errno (s);
38}
39
40
41/* Try to read 4 octets from the stream. */
42static u32
43read_32 (cdk_stream_t s)
44{
45 byte buf[4];
46 size_t nread;
47
48 assert (s != NULL);
49
50 stream_read (s, buf, 4, &nread);
51 if (nread != 4)
52 return (u32) - 1;
53 return buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3];
54}
55
56
57/* Try to read 2 octets from a stream. */
58static u16
59read_16 (cdk_stream_t s)
60{
61 byte buf[2];
62 size_t nread;
63
64 assert (s != NULL);
65
66 stream_read (s, buf, 2, &nread);
67 if (nread != 2)
68 return (u16) - 1;
69 return buf[0] << 8 | buf[1];
70}
71
72
73static int
74read_s2k (cdk_stream_t inp, cdk_s2k_t s2k)
75{
76 size_t nread;
77
78 if (!inp || !s2k)
79 return CDK_Inv_Value;
80
81 if (DEBUG_PKT)
82 _cdk_log_debug ("read_s2k:\n");
83
84 s2k->mode = cdk_stream_getc (inp);
85 if (cdk_stream_eof (inp))
86 return CDK_Inv_Packet;
87 if (s2k->mode != CDK_S2K_SIMPLE && s2k->mode != CDK_S2K_SALTED &&
88 s2k->mode != CDK_S2K_ITERSALTED)
89 return CDK_Inv_Packet;
90 s2k->hash_algo = cdk_stream_getc (inp);
91 if (s2k->mode == CDK_S2K_SIMPLE) /* No additional elements. */
92 memset (s2k->salt, 0, sizeof (s2k->salt));
93 else if (s2k->mode == CDK_S2K_SALTED || s2k->mode == CDK_S2K_ITERSALTED)
94 {
95 if (stream_read (inp, s2k->salt, DIM (s2k->salt), &nread))
96 return CDK_Inv_Packet;
97 if (nread != DIM (s2k->salt))
98 return CDK_Inv_Packet;
99 if (s2k->mode == CDK_S2K_ITERSALTED)
100 {
101 s2k->count = cdk_stream_getc (inp);
102 if (cdk_stream_eof (inp))
103 return CDK_Inv_Packet;
104 }
105 }
106 else
107 return CDK_Inv_Mode;
108 return 0;
109}
110
111
112static cdk_error_t
113read_mpi (cdk_stream_t inp, gcry_mpi_t * ret_m, int secure)
114{
115 gcry_mpi_t m;
116 gcry_error_t err;
117 byte buf[MAX_MPI_BYTES + 2];
118 size_t nread, nbits;
119 cdk_error_t rc;
120
121 if (!inp || !ret_m)
122 return CDK_Inv_Value;
123
124 *ret_m = NULL;
125 nbits = read_16 (inp);
126 nread = (nbits + 7) / 8;
127
128 if (nbits > MAX_MPI_BITS || nbits == 0)
129 {
130 _cdk_log_debug ("read_mpi: too large %d bits\n", nbits);
131 return CDK_MPI_Error; /* Sanity check */
132 }
133
134 rc = stream_read (inp, buf + 2, nread, &nread);
135 if (!rc && nread != ((nbits + 7) / 8))
136 {
137 _cdk_log_debug ("read_mpi: too short %d < %d\n", nread,
138 (nbits + 7) / 8);
139 return CDK_MPI_Error;
140 }
141
142 buf[0] = nbits >> 8;
143 buf[1] = nbits >> 0;
144 err = gcry_mpi_scan (&m, GCRYMPI_FMT_PGP, buf, nread + 2, &nread);
145 if (err)
146 return map_gcry_error (err);
147 if (secure)
148 gcry_mpi_set_flag (m, GCRYMPI_FLAG_SECURE);
149 *ret_m = m;
150 return rc;
151}
152
153
154/* Read the encoded packet length directly from the file
155 object INP and return it. Reset RET_PARTIAL if this is
156 the last packet in block mode. */
157size_t
158_cdk_pkt_read_len (FILE * inp, size_t * ret_partial)
159{
160 int c1, c2;
161 size_t pktlen;
162
163 c1 = fgetc (inp);
164 if (c1 == EOF)
165 return (size_t) EOF;
166 if (c1 < 224 || c1 == 255)
167 *ret_partial = 0; /* End of partial data */
168 if (c1 < 192)
169 pktlen = c1;
170 else if (c1 >= 192 && c1 <= 223)
171 {
172 c2 = fgetc (inp);
173 if (c2 == EOF)
174 return (size_t) EOF;
175 pktlen = ((c1 - 192) << 8) + c2 + 192;
176 }
177 else if (c1 == 255)
178 {
179 pktlen = fgetc (inp) << 24;
180 pktlen |= fgetc (inp) << 16;
181 pktlen |= fgetc (inp) << 8;
182 pktlen |= fgetc (inp) << 0;
183 }
184 else
185 pktlen = 1 << (c1 & 0x1f);
186 return pktlen;
187}
188
189
190static cdk_error_t
191read_encrypted (cdk_stream_t inp, size_t pktlen, cdk_pkt_encrypted_t enc,
192 int is_partial, int is_mdc)
193{
194 if (!inp || !enc)
195 return CDK_Inv_Value;
196
197 if (DEBUG_PKT)
198 _cdk_log_debug ("read_encrypted: %d octets\n", pktlen);
199
200 if (is_mdc)
201 {
202 int version = cdk_stream_getc (inp);
203 if (version != MDC_PKT_VER)
204 return CDK_Inv_Packet;
205 enc->mdc_method = CDK_MD_SHA1;
206 pktlen--;
207 }
208 /* The packet must at least contain blocksize + 2 octets. */
209 if (pktlen < 10)
210 return CDK_Inv_Packet;
211 if (is_partial)
212 _cdk_stream_set_blockmode (inp, pktlen);
213 enc->len = pktlen;
214 enc->buf = inp;
215 return 0;
216}
217
218
219static cdk_error_t
220read_symkey_enc (cdk_stream_t inp, size_t pktlen, cdk_pkt_symkey_enc_t ske)
221{
222 cdk_s2k_t s2k;
223 size_t minlen;
224 size_t nread, nleft;
225
226 if (!inp || !ske)
227 return CDK_Inv_Value;
228
229 if (DEBUG_PKT)
230 _cdk_log_debug ("read_symkey_enc: %d octets\n", pktlen);
231
232 ske->version = cdk_stream_getc (inp);
233 if (ske->version != 4 || cdk_stream_eof (inp))
234 return CDK_Inv_Packet;
235
236 s2k = ske->s2k = cdk_calloc (1, sizeof *ske->s2k);
237 if (!ske->s2k)
238 return CDK_Out_Of_Core;
239
240 ske->cipher_algo = cdk_stream_getc (inp);
241 s2k->mode = cdk_stream_getc (inp);
242 switch (s2k->mode)
243 {
244 case CDK_S2K_SIMPLE:
245 minlen = 0;
246 break;
247 case CDK_S2K_SALTED:
248 minlen = 8;
249 break;
250 case CDK_S2K_ITERSALTED:
251 minlen = 9;
252 break;
253
254 default:
255 /* Invalid S2K mode. */
256 return CDK_Inv_Packet;
257 }
258
259 s2k->hash_algo = cdk_stream_getc (inp);
260 if (s2k->mode == CDK_S2K_SALTED || s2k->mode == CDK_S2K_ITERSALTED)
261 {
262 if (stream_read (inp, s2k->salt, DIM (s2k->salt), &nread))
263 return CDK_Inv_Packet;
264 if (nread != DIM (s2k->salt))
265 return CDK_Inv_Packet;
266
267 if (s2k->mode == CDK_S2K_ITERSALTED)
268 s2k->count = cdk_stream_getc (inp);
269 }
270
271 ske->seskeylen = pktlen - 4 - minlen;
272 /* We check if there is an encrypted session key and if it fits into
273 the buffer. The maximal key length is 256-bit. */
274 if (ske->seskeylen > DIM (ske->seskey))
275 return CDK_Inv_Packet;
276 nleft = ske->seskeylen;
277 for (nread = 0; nread < ske->seskeylen; nread++)
278 {
279 ske->seskey[nread] = cdk_stream_getc (inp);
280 if (cdk_stream_eof (inp) && --nleft > 0)
281 return CDK_Inv_Packet;
282 }
283
284 return 0;
285}
286
287
288static cdk_error_t
289read_pubkey_enc (cdk_stream_t inp, size_t pktlen, cdk_pkt_pubkey_enc_t pke)
290{
291 size_t i, nenc;
292
293 if (!inp || !pke)
294 return CDK_Inv_Value;
295
296 if (DEBUG_PKT)
297 _cdk_log_debug ("read_pubkey_enc: %d octets\n", pktlen);
298
299 if (pktlen < 12)
300 return CDK_Inv_Packet;
301 pke->version = cdk_stream_getc (inp);
302 if (pke->version < 2 || pke->version > 3)
303 return CDK_Inv_Packet;
304 pke->keyid[0] = read_32 (inp);
305 pke->keyid[1] = read_32 (inp);
306 if (!pke->keyid[0] && !pke->keyid[1])
307 pke->throw_keyid = 1; /* RFC2440 "speculative" keyID */
308 pke->pubkey_algo = cdk_stream_getc (inp);
309 nenc = cdk_pk_get_nenc (pke->pubkey_algo);
310 if (!nenc)
311 return CDK_Inv_Algo;
312 for (i = 0; i < nenc; i++)
313 {
314 cdk_error_t rc = read_mpi (inp, &pke->mpi[i], 0);
315 if (rc)
316 return rc;
317 }
318
319 return 0;
320}
321
322
323
324static cdk_error_t
325read_mdc (cdk_stream_t inp, cdk_pkt_mdc_t mdc)
326{
327 size_t n;
328 cdk_error_t rc;
329
330 if (!inp || !mdc)
331 return CDK_Inv_Value;
332
333 if (DEBUG_PKT)
334 _cdk_log_debug ("read_mdc:\n");
335
336 rc = stream_read (inp, mdc->hash, DIM (mdc->hash), &n);
337 if (rc)
338 return rc;
339
340 return n != DIM (mdc->hash) ? CDK_Inv_Packet : 0;
341}
342
343
344static cdk_error_t
345read_compressed (cdk_stream_t inp, size_t pktlen, cdk_pkt_compressed_t c)
346{
347 if (!inp || !c)
348 return CDK_Inv_Value;
349
350 if (DEBUG_PKT)
351 _cdk_log_debug ("read_compressed: %d octets\n", pktlen);
352
353 c->algorithm = cdk_stream_getc (inp);
354 if (c->algorithm > 3)
355 return CDK_Inv_Packet;
356
357 /* don't know the size, so we read until EOF */
358 if (!pktlen)
359 {
360 c->len = 0;
361 c->buf = inp;
362 }
363
364 /* FIXME: Support partial bodies. */
365 return 0;
366}
367
368
369static cdk_error_t
370read_public_key (cdk_stream_t inp, size_t pktlen, cdk_pkt_pubkey_t pk)
371{
372 size_t i, ndays, npkey;
373
374 if (!inp || !pk)
375 return CDK_Inv_Value;
376
377 if (DEBUG_PKT)
378 _cdk_log_debug ("read_public_key: %d octets\n", pktlen);
379
380 pk->is_invalid = 1; /* default to detect missing self signatures */
381 pk->is_revoked = 0;
382 pk->has_expired = 0;
383
384 pk->version = cdk_stream_getc (inp);
385 if (pk->version < 2 || pk->version > 4)
386 return CDK_Inv_Packet_Ver;
387 pk->timestamp = read_32 (inp);
388 if (pk->version < 4)
389 {
390 ndays = read_16 (inp);
391 if (ndays)
392 pk->expiredate = pk->timestamp + ndays * 86400L;
393 }
394
395 pk->pubkey_algo = cdk_stream_getc (inp);
396 npkey = cdk_pk_get_npkey (pk->pubkey_algo);
397 if (!npkey)
398 {
399 _cdk_log_debug ("invalid public key algorithm %d\n", pk->pubkey_algo);
400 return CDK_Inv_Algo;
401 }
402 for (i = 0; i < npkey; i++)
403 {
404 cdk_error_t rc = read_mpi (inp, &pk->mpi[i], 0);
405 if (rc)
406 return rc;
407 }
408
409 /* These values are just for the first run and should be
410 replaced with the actual key flags from the self signature. */
411 pk->pubkey_usage = _cdk_pk_algo_usage (pk->pubkey_algo);
412 return 0;
413}
414
415
416static cdk_error_t
417read_public_subkey (cdk_stream_t inp, size_t pktlen, cdk_pkt_pubkey_t pk)
418{
419 if (!inp || !pk)
420 return CDK_Inv_Value;
421 return read_public_key (inp, pktlen, pk);
422}
423
424
425static cdk_error_t
426read_secret_key (cdk_stream_t inp, size_t pktlen, cdk_pkt_seckey_t sk)
427{
428 size_t p1, p2, nread;
429 int i, nskey;
430 int rc;
431
432 if (!inp || !sk || !sk->pk)
433 return CDK_Inv_Value;
434
435 if (DEBUG_PKT)
436 _cdk_log_debug ("read_secret_key: %d octets\n", pktlen);
437
438 p1 = cdk_stream_tell (inp);
439 rc = read_public_key (inp, pktlen, sk->pk);
440 if (rc)
441 return rc;
442
443 sk->s2k_usage = cdk_stream_getc (inp);
444 sk->protect.sha1chk = 0;
445 if (sk->s2k_usage == 254 || sk->s2k_usage == 255)
446 {
447 sk->protect.sha1chk = (sk->s2k_usage == 254);
448 sk->protect.algo = cdk_stream_getc (inp);
449 sk->protect.s2k = cdk_calloc (1, sizeof *sk->protect.s2k);
450 if (!sk->protect.s2k)
451 return CDK_Out_Of_Core;
452 rc = read_s2k (inp, sk->protect.s2k);
453 if (rc)
454 return rc;
455 sk->protect.ivlen = gcry_cipher_get_algo_blklen (sk->protect.algo);
456 if (!sk->protect.ivlen)
457 return CDK_Inv_Packet;
458 rc = stream_read (inp, sk->protect.iv, sk->protect.ivlen, &nread);
459 if (rc)
460 return rc;
461 if (nread != sk->protect.ivlen)
462 return CDK_Inv_Packet;
463 }
464 else
465 sk->protect.algo = sk->s2k_usage;
466 if (sk->protect.algo == GCRY_CIPHER_NONE)
467 {
468 sk->csum = 0;
469 nskey = cdk_pk_get_nskey (sk->pk->pubkey_algo);
470 if (!nskey)
471 return CDK_Inv_Algo;
472 for (i = 0; i < nskey; i++)
473 {
474 rc = read_mpi (inp, &sk->mpi[i], 1);
475 if (rc)
476 return rc;
477 }
478 sk->csum = read_16 (inp);
479 sk->is_protected = 0;
480 }
481 else if (sk->pk->version < 4)
482 {
483 /* The length of each multiprecision integer is stored in plaintext. */
484 nskey = cdk_pk_get_nskey (sk->pk->pubkey_algo);
485 if (!nskey)
486 return CDK_Inv_Algo;
487 for (i = 0; i < nskey; i++)
488 {
489 rc = read_mpi (inp, &sk->mpi[i], 1);
490 if (rc)
491 return rc;
492 }
493 sk->csum = read_16 (inp);
494 sk->is_protected = 1;
495 }
496 else
497 {
498 /* We need to read the rest of the packet because we do not
499 have any information how long the encrypted mpi's are */
500 p2 = cdk_stream_tell (inp);
501 p2 -= p1;
502 sk->enclen = pktlen - p2;
503 if (sk->enclen < 2)
504 return CDK_Inv_Packet; /* at least 16 bits for the checksum! */
505 sk->encdata = cdk_calloc (1, sk->enclen + 1);
506 if (!sk->encdata)
507 return CDK_Out_Of_Core;
508 if (stream_read (inp, sk->encdata, sk->enclen, &nread))
509 return CDK_Inv_Packet;
510 nskey = cdk_pk_get_nskey (sk->pk->pubkey_algo);
511 if (!nskey)
512 return CDK_Inv_Algo;
513 /* We mark each MPI entry with NULL to indicate a protected key. */
514 for (i = 0; i < nskey; i++)
515 sk->mpi[i] = NULL;
516 sk->is_protected = 1;
517 }
518
519 sk->is_primary = 1;
520 _cdk_copy_pk_to_sk (sk->pk, sk);
521 return 0;
522}
523
524
525static cdk_error_t
526read_secret_subkey (cdk_stream_t inp, size_t pktlen, cdk_pkt_seckey_t sk)
527{
528 cdk_error_t rc;
529
530 if (!inp || !sk || !sk->pk)
531 return CDK_Inv_Value;
532
533 rc = read_secret_key (inp, pktlen, sk);
534 sk->is_primary = 0;
535 return rc;
536}
537
538
539static cdk_error_t
540read_attribute (cdk_stream_t inp, size_t pktlen, cdk_pkt_userid_t attr)
541{
542 const byte *p;
543 byte *buf;
544 size_t len, nread;
545 cdk_error_t rc;
546
547 if (!inp || !attr || !pktlen)
548 return CDK_Inv_Value;
549
550 if (DEBUG_PKT)
551 _cdk_log_debug ("read_attribute: %d octets\n", pktlen);
552
553 strcpy (attr->name, "[attribute]");
554 attr->len = strlen (attr->name);
555 buf = cdk_calloc (1, pktlen);
556 if (!buf)
557 return CDK_Out_Of_Core;
558 rc = stream_read (inp, buf, pktlen, &nread);
559 if (rc)
560 {
561 cdk_free (buf);
562 return CDK_Inv_Packet;
563 }
564 p = buf;
565 len = *p++;
566 pktlen--;
567 if (len == 255)
568 {
569 len = _cdk_buftou32 (p);
570 p += 4;
571 pktlen -= 4;
572 }
573 else if (len >= 192)
574 {
575 if (pktlen < 2)
576 {
577 cdk_free (buf);
578 return CDK_Inv_Packet;
579 }
580 len = ((len - 192) << 8) + *p + 192;
581 p++;
582 pktlen--;
583 }
584
585 if (*p != 1) /* Currently only 1, meaning an image, is defined. */
586 {
587 cdk_free (buf);
588 return CDK_Inv_Packet;
589 }
590 p++;
591 len--;
592
593 if (pktlen - (len + 1) > 0)
594 return CDK_Inv_Packet;
595 attr->attrib_img = cdk_calloc (1, len);
596 if (!attr->attrib_img)
597 {
598 cdk_free (buf);
599 return CDK_Out_Of_Core;
600 }
601 attr->attrib_len = len;
602 memcpy (attr->attrib_img, p, len);
603 cdk_free (buf);
604 return rc;
605}
606
607
608static cdk_error_t
609read_user_id (cdk_stream_t inp, size_t pktlen, cdk_pkt_userid_t user_id)
610{
611 size_t nread;
612 cdk_error_t rc;
613
614 if (!inp || !user_id)
615 return CDK_Inv_Value;
616 if (!pktlen)
617 return CDK_Inv_Packet;
618
619 if (DEBUG_PKT)
620 _cdk_log_debug ("read_user_id: %lu octets\n", pktlen);
621
622 user_id->len = pktlen;
623 rc = stream_read (inp, user_id->name, pktlen, &nread);
624 if (rc)
625 return rc;
626 if (nread != pktlen)
627 return CDK_Inv_Packet;
628 user_id->name[nread] = '\0';
629 return rc;
630}
631
632
633static cdk_error_t
634read_subpkt (cdk_stream_t inp, cdk_subpkt_t * r_ctx, size_t * r_nbytes)
635{
636 byte c, c1;
637 size_t size, nread, n;
638 cdk_subpkt_t node;
639 cdk_error_t rc;
640
641 if (!inp || !r_nbytes)
642 return CDK_Inv_Value;
643
644 if (DEBUG_PKT)
645 _cdk_log_debug ("read_subpkt:\n");
646
647 n = 0;
648 *r_nbytes = 0;
649 c = cdk_stream_getc (inp);
650 n++;
651 if (c == 255)
652 {
653 size = read_32 (inp);
654 n += 4;
655 }
656 else if (c >= 192 && c < 255)
657 {
658 c1 = cdk_stream_getc (inp);
659 n++;
660 if (c1 == 0)
661 return 0;
662 size = ((c - 192) << 8) + c1 + 192;
663 }
664 else if (c < 192)
665 size = c;
666 else
667 return CDK_Inv_Packet;
668
669 node = cdk_subpkt_new (size);
670 if (!node)
671 return CDK_Out_Of_Core;
672 node->size = size;
673 node->type = cdk_stream_getc (inp);
674 if (DEBUG_PKT)
675 _cdk_log_debug (" %d octets %d type\n", node->size, node->type);
676 n++;
677 node->size--;
678 rc = stream_read (inp, node->d, node->size, &nread);
679 n += nread;
680 if (rc)
681 return rc;
682 *r_nbytes = n;
683 if (!*r_ctx)
684 *r_ctx = node;
685 else
686 cdk_subpkt_add (*r_ctx, node);
687 return rc;
688}
689
690
691static cdk_error_t
692read_onepass_sig (cdk_stream_t inp, size_t pktlen, cdk_pkt_onepass_sig_t sig)
693{
694 if (!inp || !sig)
695 return CDK_Inv_Value;
696
697 if (DEBUG_PKT)
698 _cdk_log_debug ("read_onepass_sig: %d octets\n", pktlen);
699
700 if (pktlen != 13)
701 return CDK_Inv_Packet;
702 sig->version = cdk_stream_getc (inp);
703 if (sig->version != 3)
704 return CDK_Inv_Packet_Ver;
705 sig->sig_class = cdk_stream_getc (inp);
706 sig->digest_algo = cdk_stream_getc (inp);
707 sig->pubkey_algo = cdk_stream_getc (inp);
708 sig->keyid[0] = read_32 (inp);
709 sig->keyid[1] = read_32 (inp);
710 sig->last = cdk_stream_getc (inp);
711 return 0;
712}
713
714
715static cdk_error_t
716parse_sig_subpackets (cdk_pkt_signature_t sig)
717{
718 cdk_subpkt_t node;
719
720 /* Setup the standard packet entries, so we can use V4
721 signatures similar to V3. */
722 for (node = sig->unhashed; node; node = node->next)
723 {
724 if (node->type == CDK_SIGSUBPKT_ISSUER && node->size >= 8)
725 {
726 sig->keyid[0] = _cdk_buftou32 (node->d);
727 sig->keyid[1] = _cdk_buftou32 (node->d + 4);
728 }
729 else if (node->type == CDK_SIGSUBPKT_EXPORTABLE && node->d[0] == 0)
730 {
731 /* Sometimes this packet might be placed in the unhashed area */
732 sig->flags.exportable = 0;
733 }
734 }
735 for (node = sig->hashed; node; node = node->next)
736 {
737 if (node->type == CDK_SIGSUBPKT_SIG_CREATED && node->size >= 4)
738 sig->timestamp = _cdk_buftou32 (node->d);
739 else if (node->type == CDK_SIGSUBPKT_SIG_EXPIRE && node->size >= 4)
740 {
741 sig->expiredate = _cdk_buftou32 (node->d);
742 if (sig->expiredate > 0 && sig->expiredate < (u32) time (NULL))
743 sig->flags.expired = 1;
744 }
745 else if (node->type == CDK_SIGSUBPKT_POLICY)
746 sig->flags.policy_url = 1;
747 else if (node->type == CDK_SIGSUBPKT_NOTATION)
748 sig->flags.notation = 1;
749 else if (node->type == CDK_SIGSUBPKT_REVOCABLE && node->d[0] == 0)
750 sig->flags.revocable = 0;
751 else if (node->type == CDK_SIGSUBPKT_EXPORTABLE && node->d[0] == 0)
752 sig->flags.exportable = 0;
753 }
754 if (sig->sig_class == 0x1F)
755 {
756 cdk_desig_revoker_t r, rnode;
757
758 for (node = sig->hashed; node; node = node->next)
759 {
760 if (node->type == CDK_SIGSUBPKT_REV_KEY)
761 {
762 if (node->size < 22)
763 continue;
764 rnode = cdk_calloc (1, sizeof *rnode);
765 if (!rnode)
766 return CDK_Out_Of_Core;
767 rnode->r_class = node->d[0];
768 rnode->algid = node->d[1];
769 memcpy (rnode->fpr, node->d + 2, KEY_FPR_LEN);
770 if (!sig->revkeys)
771 sig->revkeys = rnode;
772 else
773 {
774 for (r = sig->revkeys; r->next; r = r->next)
775 ;
776 r->next = rnode;
777 }
778 }
779 }
780 }
781
782 return 0;
783}
784
785
786static cdk_error_t
787read_signature (cdk_stream_t inp, size_t pktlen, cdk_pkt_signature_t sig)
788{
789 size_t nbytes;
790 size_t i, size, nsig;
791 cdk_error_t rc;
792
793 if (!inp || !sig)
794 return CDK_Inv_Value;
795
796 if (DEBUG_PKT)
797 _cdk_log_debug ("read_signature: %d octets\n", pktlen);
798
799 if (pktlen < 16)
800 return CDK_Inv_Packet;
801 sig->version = cdk_stream_getc (inp);
802 if (sig->version < 2 || sig->version > 4)
803 return CDK_Inv_Packet_Ver;
804
805 sig->flags.exportable = 1;
806 sig->flags.revocable = 1;
807
808 if (sig->version < 4)
809 {
810 if (cdk_stream_getc (inp) != 5)
811 return CDK_Inv_Packet;
812 sig->sig_class = cdk_stream_getc (inp);
813 sig->timestamp = read_32 (inp);
814 sig->keyid[0] = read_32 (inp);
815 sig->keyid[1] = read_32 (inp);
816 sig->pubkey_algo = cdk_stream_getc (inp);
817 sig->digest_algo = cdk_stream_getc (inp);
818 sig->digest_start[0] = cdk_stream_getc (inp);
819 sig->digest_start[1] = cdk_stream_getc (inp);
820 nsig = cdk_pk_get_nsig (sig->pubkey_algo);
821 if (!nsig)
822 return CDK_Inv_Algo;
823 for (i = 0; i < nsig; i++)
824 {
825 rc = read_mpi (inp, &sig->mpi[i], 0);
826 if (rc)
827 return rc;
828 }
829 }
830 else
831 {
832 sig->sig_class = cdk_stream_getc (inp);
833 sig->pubkey_algo = cdk_stream_getc (inp);
834 sig->digest_algo = cdk_stream_getc (inp);
835 sig->hashed_size = read_16 (inp);
836 size = sig->hashed_size;
837 sig->hashed = NULL;
838 while (size > 0)
839 {
840 rc = read_subpkt (inp, &sig->hashed, &nbytes);
841 if (rc)
842 return rc;
843 size -= nbytes;
844 }
845 sig->unhashed_size = read_16 (inp);
846 size = sig->unhashed_size;
847 sig->unhashed = NULL;
848 while (size > 0)
849 {
850 rc = read_subpkt (inp, &sig->unhashed, &nbytes);
851 if (rc)
852 return rc;
853 size -= nbytes;
854 }
855
856 rc = parse_sig_subpackets (sig);
857 if (rc)
858 return rc;
859
860 sig->digest_start[0] = cdk_stream_getc (inp);
861 sig->digest_start[1] = cdk_stream_getc (inp);
862 nsig = cdk_pk_get_nsig (sig->pubkey_algo);
863 if (!nsig)
864 return CDK_Inv_Algo;
865 for (i = 0; i < nsig; i++)
866 {
867 rc = read_mpi (inp, &sig->mpi[i], 0);
868 if (rc)
869 return rc;
870 }
871 }
872
873 return 0;
874}
875
876
877static cdk_error_t
878read_literal (cdk_stream_t inp, size_t pktlen,
879 cdk_pkt_literal_t * ret_pt, int is_partial)
880{
881 cdk_pkt_literal_t pt = *ret_pt;
882 size_t nread;
883 cdk_error_t rc;
884
885 if (!inp || !pt)
886 return CDK_Inv_Value;
887
888 if (DEBUG_PKT)
889 _cdk_log_debug ("read_literal: %d octets\n", pktlen);
890
891 pt->mode = cdk_stream_getc (inp);
892 if (pt->mode != 0x62 && pt->mode != 0x74 && pt->mode != 0x75)
893 return CDK_Inv_Packet;
894 if (cdk_stream_eof (inp))
895 return CDK_Inv_Packet;
896
897 pt->namelen = cdk_stream_getc (inp);
898 if (pt->namelen > 0)
899 {
900 *ret_pt = pt = cdk_realloc (pt, sizeof *pt + pt->namelen + 1);
901 if (!pt)
902 return CDK_Out_Of_Core;
903 rc = stream_read (inp, pt->name, pt->namelen, &nread);
904 if (rc)
905 return rc;
906 if (nread != pt->namelen)
907 return CDK_Inv_Packet;
908 pt->name[pt->namelen] = '\0';
909 }
910 pt->timestamp = read_32 (inp);
911 pktlen = pktlen - 6 - pt->namelen;
912 if (is_partial)
913 _cdk_stream_set_blockmode (inp, pktlen);
914 pt->buf = inp;
915 pt->len = pktlen;
916 return 0;
917}
918
919
920/* Read an old packet CTB and return the length of the body. */
921static void
922read_old_length (cdk_stream_t inp, int ctb, size_t * r_len, size_t * r_size)
923{
924 int llen = ctb & 0x03;
925
926 if (llen == 0)
927 {
928 *r_len = cdk_stream_getc (inp);
929 (*r_size)++;
930 }
931 else if (llen == 1)
932 {
933 *r_len = read_16 (inp);
934 (*r_size) += 2;
935 }
936 else if (llen == 2)
937 {
938 *r_len = read_32 (inp);
939 (*r_size) += 4;
940 }
941 else
942 {
943 *r_len = 0;
944 *r_size = 0;
945 }
946}
947
948
949/* Read a new CTB and decode the body length. */
950static void
951read_new_length (cdk_stream_t inp,
952 size_t * r_len, size_t * r_size, size_t * r_partial)
953{
954 int c, c1;
955
956 c = cdk_stream_getc (inp);
957 (*r_size)++;
958 if (c < 192)
959 *r_len = c;
960 else if (c >= 192 && c <= 223)
961 {
962 c1 = cdk_stream_getc (inp);
963 (*r_size)++;
964 *r_len = ((c - 192) << 8) + c1 + 192;
965 }
966 else if (c == 255)
967 {
968 *r_len = read_32 (inp);
969 (*r_size) += 4;
970 }
971 else
972 {
973 *r_len = 1 << (c & 0x1f);
974 *r_partial = 1;
975 }
976}
977
978
979/* Skip the current packet body. */
980static void
981skip_packet (cdk_stream_t inp, size_t pktlen)
982{
983 byte buf[BUFSIZE];
984 size_t nread, buflen = DIM (buf);
985
986 while (pktlen > 0)
987 {
988 stream_read (inp, buf, pktlen > buflen ? buflen : pktlen, &nread);
989 pktlen -= nread;
990 }
991
992 assert (pktlen == 0);
993}
994
995
996/**
997 * cdk_pkt_read:
998 * @inp: the input stream
999 * @pkt: allocated packet handle to store the packet
1000 *
1001 * Parse the next packet on the @inp stream and return its contents in @pkt.
1002 **/
1003cdk_error_t
1004cdk_pkt_read (cdk_stream_t inp, cdk_packet_t pkt)
1005{
1006 int use_mdc = 0;
1007 int ctb, is_newctb;
1008 int pkttype;
1009 size_t pktlen = 0, pktsize = 0, is_partial = 0;
1010 cdk_error_t rc;
1011
1012 if (!inp || !pkt)
1013 return CDK_Inv_Value;
1014
1015 ctb = cdk_stream_getc (inp);
1016 if (cdk_stream_eof (inp) || ctb == EOF)
1017 return CDK_EOF;
1018 else if (!ctb)
1019 return CDK_Inv_Packet;
1020
1021 pktsize++;
1022 if (!(ctb & 0x80))
1023 {
1024 _cdk_log_info ("cdk_pkt_read: no openpgp data found. "
1025 "(ctb=%02X; fpos=%02X)\n", ctb, cdk_stream_tell (inp));
1026 return CDK_Inv_Packet;
1027 }
1028
1029 if (ctb & 0x40) /* RFC2440 packet format. */
1030 {
1031 pkttype = ctb & 0x3f;
1032 is_newctb = 1;
1033 }
1034 else /* the old RFC1991 packet format. */
1035 {
1036 pkttype = ctb & 0x3f;
1037 pkttype >>= 2;
1038 is_newctb = 0;
1039 }
1040
1041 if (pkttype > 63)
1042 {
1043 _cdk_log_info ("cdk_pkt_read: unknown type %d\n", pkttype);
1044 return CDK_Inv_Packet;
1045 }
1046
1047 if (is_newctb)
1048 read_new_length (inp, &pktlen, &pktsize, &is_partial);
1049 else
1050 read_old_length (inp, ctb, &pktlen, &pktsize);
1051
1052 pkt->pkttype = pkttype;
1053 pkt->pktlen = pktlen;
1054 pkt->pktsize = pktsize + pktlen;
1055 pkt->old_ctb = is_newctb ? 0 : 1;
1056
1057 rc = 0;
1058 switch (pkt->pkttype)
1059 {
1060 case CDK_PKT_ATTRIBUTE:
1061 pkt->pkt.user_id = cdk_calloc (1, sizeof *pkt->pkt.user_id
1062 + pkt->pktlen + 16 + 1);
1063 if (!pkt->pkt.user_id)
1064 return CDK_Out_Of_Core;
1065 rc = read_attribute (inp, pktlen, pkt->pkt.user_id);
1066 pkt->pkttype = CDK_PKT_ATTRIBUTE;
1067 break;
1068
1069 case CDK_PKT_USER_ID:
1070 pkt->pkt.user_id = cdk_calloc (1, sizeof *pkt->pkt.user_id
1071 + pkt->pktlen);
1072 if (!pkt->pkt.user_id)
1073 return CDK_Out_Of_Core;
1074 rc = read_user_id (inp, pktlen, pkt->pkt.user_id);
1075 break;
1076
1077 case CDK_PKT_PUBLIC_KEY:
1078 pkt->pkt.public_key = cdk_calloc (1, sizeof *pkt->pkt.public_key);
1079 if (!pkt->pkt.public_key)
1080 return CDK_Out_Of_Core;
1081 rc = read_public_key (inp, pktlen, pkt->pkt.public_key);
1082 break;
1083
1084 case CDK_PKT_PUBLIC_SUBKEY:
1085 pkt->pkt.public_key = cdk_calloc (1, sizeof *pkt->pkt.public_key);
1086 if (!pkt->pkt.public_key)
1087 return CDK_Out_Of_Core;
1088 rc = read_public_subkey (inp, pktlen, pkt->pkt.public_key);
1089 break;
1090
1091 case CDK_PKT_SECRET_KEY:
1092 pkt->pkt.secret_key = cdk_calloc (1, sizeof *pkt->pkt.secret_key);
1093 if (!pkt->pkt.secret_key)
1094 return CDK_Out_Of_Core;
1095 pkt->pkt.secret_key->pk = cdk_calloc (1,
1096 sizeof *pkt->pkt.secret_key->pk);
1097 if (!pkt->pkt.secret_key->pk)
1098 return CDK_Out_Of_Core;
1099 rc = read_secret_key (inp, pktlen, pkt->pkt.secret_key);
1100 break;
1101
1102 case CDK_PKT_SECRET_SUBKEY:
1103 pkt->pkt.secret_key = cdk_calloc (1, sizeof *pkt->pkt.secret_key);
1104 if (!pkt->pkt.secret_key)
1105 return CDK_Out_Of_Core;
1106 pkt->pkt.secret_key->pk = cdk_calloc (1,
1107 sizeof *pkt->pkt.secret_key->pk);
1108 if (!pkt->pkt.secret_key->pk)
1109 return CDK_Out_Of_Core;
1110 rc = read_secret_subkey (inp, pktlen, pkt->pkt.secret_key);
1111 break;
1112
1113 case CDK_PKT_LITERAL:
1114 pkt->pkt.literal = cdk_calloc (1, sizeof *pkt->pkt.literal);
1115 if (!pkt->pkt.literal)
1116 return CDK_Out_Of_Core;
1117 rc = read_literal (inp, pktlen, &pkt->pkt.literal, is_partial);
1118 break;
1119
1120 case CDK_PKT_ONEPASS_SIG:
1121 pkt->pkt.onepass_sig = cdk_calloc (1, sizeof *pkt->pkt.onepass_sig);
1122 if (!pkt->pkt.onepass_sig)
1123 return CDK_Out_Of_Core;
1124 rc = read_onepass_sig (inp, pktlen, pkt->pkt.onepass_sig);
1125 break;
1126
1127 case CDK_PKT_SIGNATURE:
1128 pkt->pkt.signature = cdk_calloc (1, sizeof *pkt->pkt.signature);
1129 if (!pkt->pkt.signature)
1130 return CDK_Out_Of_Core;
1131 rc = read_signature (inp, pktlen, pkt->pkt.signature);
1132 break;
1133
1134 case CDK_PKT_ENCRYPTED_MDC:
1135 case CDK_PKT_ENCRYPTED:
1136 pkt->pkt.encrypted = cdk_calloc (1, sizeof *pkt->pkt.encrypted);
1137 if (!pkt->pkt.encrypted)
1138 return CDK_Out_Of_Core;
1139 use_mdc = (pkt->pkttype == CDK_PKT_ENCRYPTED_MDC) ? 1 : 0;
1140 rc = read_encrypted (inp, pktlen, pkt->pkt.encrypted,
1141 is_partial, use_mdc);
1142 break;
1143
1144 case CDK_PKT_SYMKEY_ENC:
1145 pkt->pkt.symkey_enc = cdk_calloc (1, sizeof *pkt->pkt.symkey_enc);
1146 if (!pkt->pkt.symkey_enc)
1147 return CDK_Out_Of_Core;
1148 rc = read_symkey_enc (inp, pktlen, pkt->pkt.symkey_enc);
1149 break;
1150
1151 case CDK_PKT_PUBKEY_ENC:
1152 pkt->pkt.pubkey_enc = cdk_calloc (1, sizeof *pkt->pkt.pubkey_enc);
1153 if (!pkt->pkt.pubkey_enc)
1154 return CDK_Out_Of_Core;
1155 rc = read_pubkey_enc (inp, pktlen, pkt->pkt.pubkey_enc);
1156 break;
1157
1158 case CDK_PKT_COMPRESSED:
1159 pkt->pkt.compressed = cdk_calloc (1, sizeof *pkt->pkt.compressed);
1160 if (!pkt->pkt.compressed)
1161 return CDK_Out_Of_Core;
1162 rc = read_compressed (inp, pktlen, pkt->pkt.compressed);
1163 break;
1164
1165 case CDK_PKT_MDC:
1166 pkt->pkt.mdc = cdk_calloc (1, sizeof *pkt->pkt.mdc);
1167 if (!pkt->pkt.mdc)
1168 return CDK_Out_Of_Core;
1169 rc = read_mdc (inp, pkt->pkt.mdc);
1170 break;
1171
1172 default:
1173 /* Skip all packets we don't understand */
1174 skip_packet (inp, pktlen);
1175 break;
1176 }
1177
1178 return rc;
1179}
diff --git a/src/daemon/https/opencdk/seskey.c b/src/daemon/https/opencdk/seskey.c
new file mode 100644
index 00000000..54c25af2
--- /dev/null
+++ b/src/daemon/https/opencdk/seskey.c
@@ -0,0 +1,717 @@
1/* seskey.c - Session key routines
2 * Copyright (C) 2002, 2003, 2007 Timo Schulz
3 * Copyright (C) 1998-2000, 2002 Free Software Foundation, Inc.
4 *
5 * This file is part of OpenCDK.
6 *
7 * OpenCDK is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * OpenCDK is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17#ifdef HAVE_CONFIG_H
18# include <config.h>
19#endif
20#include <assert.h>
21#include <stdio.h>
22#include <gcrypt.h>
23
24#include "opencdk.h"
25#include "main.h"
26#include "packet.h"
27
28
29/* We encode the MD in this way:
30 *
31 * 0 1 PAD(n bytes) 0 ASN(asnlen bytes) MD(len bytes)
32 *
33 * PAD consists of FF bytes.
34 */
35static cdk_error_t
36do_encode_md (byte ** r_frame, size_t * r_flen, const byte * md, int algo,
37 size_t len, unsigned nbits, const byte * asn, size_t asnlen)
38{
39 byte *frame = NULL;
40 size_t nframe = (nbits + 7) / 8;
41 size_t i, n = 0;
42
43 if (!asn || !md || !r_frame || !r_flen)
44 return CDK_Inv_Value;
45
46 if (len + asnlen + 4 > nframe)
47 return CDK_General_Error;
48
49 frame = cdk_calloc (1, nframe);
50 if (!frame)
51 return CDK_Out_Of_Core;
52 frame[n++] = 0;
53 frame[n++] = 1;
54 i = nframe - len - asnlen - 3;
55 if (i < 0)
56 {
57 cdk_free (frame);
58 return CDK_Inv_Value;
59 }
60 memset (frame + n, 0xFF, i);
61 n += i;
62 frame[n++] = 0;
63 memcpy (frame + n, asn, asnlen);
64 n += asnlen;
65 memcpy (frame + n, md, len);
66 n += len;
67 if (n != nframe)
68 {
69 cdk_free (frame);
70 return CDK_Inv_Value;
71 }
72 *r_frame = frame;
73 *r_flen = n;
74 return 0;
75}
76
77
78
79/* RFC2437 format:
80 *
81 * 0 2 RND(n bytes) 0 [A DEK(k bytes) CSUM(2 bytes)]
82 *
83 * RND - randomized bytes for padding.
84 * A - cipher algorithm.
85 * DEK - random session key.
86 * CKSUM - algebraic checksum of the DEK.
87 */
88
89/**
90 * cdk_dek_encode_pkcs1
91 * @dek: DEK object
92 * @nbits: size of the multi precision integer frame
93 * @r_enc: output of the encoded multiprecision integer
94 *
95 * Encode the given random session key in the DEK object
96 * into a multiprecision integer.
97 **/
98cdk_error_t
99cdk_dek_encode_pkcs1 (cdk_dek_t dek, size_t nbits, gcry_mpi_t * r_enc)
100{
101 gcry_mpi_t a = NULL;
102 gcry_error_t err;
103 byte *p, *frame;
104 size_t n;
105 size_t nframe;
106 size_t i;
107 u16 chksum;
108
109 if (!r_enc || !dek)
110 return CDK_Inv_Value;
111
112 *r_enc = NULL;
113 chksum = 0;
114 for (i = 0; i < dek->keylen; i++)
115 chksum += dek->key[i];
116 nframe = (nbits + 7) / 8;
117 frame = cdk_salloc (nframe + 1, 1);
118 if (!frame)
119 return CDK_Out_Of_Core;
120 n = 0;
121 frame[n++] = 0x00;
122 frame[n++] = 0x02;
123 i = nframe - 6 - dek->keylen;
124 p = gcry_random_bytes (i, GCRY_STRONG_RANDOM);
125 /* Replace zero bytes by new values */
126 for (;;)
127 {
128 size_t j, k;
129 byte *pp;
130
131 /* count the zero bytes */
132 for (j = k = 0; j < i; j++)
133 {
134 if (!p[j])
135 k++;
136 }
137 if (!k)
138 break; /* No zeroes remain. */
139 k += k / 128; /* better get some more */
140 pp = gcry_random_bytes (k, GCRY_STRONG_RANDOM);
141 for (j = 0; j < i && k; j++)
142 {
143 if (!p[j])
144 p[j] = pp[--k];
145 }
146 cdk_free (pp);
147 }
148 memcpy (frame + n, p, i);
149 cdk_free (p);
150 n += i;
151 frame[n++] = 0;
152 frame[n++] = dek->algo;
153 memcpy (frame + n, dek->key, dek->keylen);
154 n += dek->keylen;
155 frame[n++] = chksum >> 8;
156 frame[n++] = chksum;
157 err = gcry_mpi_scan (&a, GCRYMPI_FMT_USG, frame, nframe, &nframe);
158 cdk_free (frame);
159 if (err)
160 return map_gcry_error (err);
161 *r_enc = a;
162 return 0;
163}
164
165
166/**
167 * cdk_dek_decode_pkcs1:
168 * @ret_dek: the decoded DEK object
169 * @esk: the pkcs#1 encoded session key.
170 *
171 * Decode the given multi precision integer in pkcs#1 and
172 * store it into the DEK object.
173 **/
174cdk_error_t
175cdk_dek_decode_pkcs1 (cdk_dek_t * ret_dek, gcry_mpi_t esk)
176{
177 cdk_dek_t dek;
178 byte frame[MAX_MPI_BYTES + 2 + 1];
179 size_t nframe, n;
180 u16 csum, csum2;
181 gcry_error_t err;
182
183 if (!ret_dek || !esk)
184 return CDK_Inv_Value;
185
186 *ret_dek = NULL; /* reset */
187 nframe = DIM (frame) - 1;
188 err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &nframe, esk);
189 if (err)
190 return map_gcry_error (err);
191 dek = cdk_salloc (sizeof *dek, 1);
192 if (!dek)
193 return CDK_Out_Of_Core;
194
195 /* Now get the DEK (data encryption key) from the frame
196 *
197 * 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes)
198 *
199 * (gcry_mpi_print already removed the leading zero).
200 *
201 * RND are non-zero randow bytes.
202 * A is the cipher algorithm
203 * DEK is the encryption key (session key) with length k
204 * CSUM
205 */
206 n = 0;
207 if (frame[n] != 2)
208 {
209 cdk_free (dek);
210 return CDK_Inv_Mode;
211 }
212 for (n++; n < nframe && frame[n]; n++)
213 ;
214 n++;
215 dek->keylen = nframe - (n + 1) - 2;
216 dek->algo = frame[n++];
217 if (dek->keylen != gcry_cipher_get_algo_keylen (dek->algo))
218 {
219 _cdk_log_debug ("pkcs1 decode: invalid cipher keylen %d\n",
220 dek->keylen);
221 cdk_free (dek);
222 return CDK_Inv_Algo;
223 }
224 csum = frame[nframe - 2] << 8;
225 csum |= frame[nframe - 1];
226 memcpy (dek->key, frame + n, dek->keylen);
227 csum2 = 0;
228 for (n = 0; n < dek->keylen; n++)
229 csum2 += dek->key[n];
230 if (csum != csum2)
231 {
232 _cdk_log_debug ("pkcs decode: checksum does not match\n");
233 cdk_free (dek);
234 return CDK_Chksum_Error;
235 }
236 *ret_dek = dek;
237 return 0;
238}
239
240
241/* Encode the given digest into a pkcs#1 compatible format. */
242cdk_error_t
243_cdk_digest_encode_pkcs1 (byte ** r_md, size_t * r_mdlen, int pk_algo,
244 const byte * md, int digest_algo, unsigned nbits)
245{
246 gcry_error_t err;
247 size_t dlen;
248
249 if (!md || !r_md || !r_mdlen)
250 return CDK_Inv_Value;
251
252 dlen = gcry_md_get_algo_dlen (digest_algo);
253 if (!dlen)
254 return CDK_Inv_Algo;
255 if (is_DSA (pk_algo)) /* DSS does not use a special encoding. */
256 {
257 *r_md = cdk_malloc (dlen + 1);
258 if (!*r_md)
259 return CDK_Out_Of_Core;
260 *r_mdlen = dlen;
261 memcpy (*r_md, md, dlen);
262 return 0;
263 }
264 else
265 {
266 byte *asn;
267 size_t asnlen;
268 cdk_error_t rc;
269
270 err = gcry_md_get_asnoid (digest_algo, NULL, &asnlen);
271 if (err)
272 return map_gcry_error (err);
273 asn = cdk_malloc (asnlen + 1);
274 if (!asn)
275 return CDK_Out_Of_Core;
276 err = gcry_md_get_asnoid (digest_algo, asn, &asnlen);
277 if (err)
278 {
279 cdk_free (asn);
280 return map_gcry_error (err);
281 }
282 rc = do_encode_md (r_md, r_mdlen, md, digest_algo, dlen,
283 nbits, asn, asnlen);
284 cdk_free (asn);
285 return rc;
286 }
287 return 0;
288}
289
290
291/* FIXME: The prompt should be provided in a more generic way.
292 Like: (keyid, algorithm, [user-id]) */
293static char *
294passphrase_prompt (cdk_pkt_seckey_t sk)
295{
296 u32 keyid = cdk_pk_get_keyid (sk->pk, NULL);
297 int bits = cdk_pk_get_nbits (sk->pk), pk_algo = sk->pubkey_algo;
298 const char *algo = "???", *fmt;
299 char *p;
300
301 if (is_RSA (pk_algo))
302 algo = "RSA";
303 else if (is_ELG (pk_algo))
304 algo = "ELG";
305 else if (is_DSA (pk_algo))
306 algo = "DSA";
307
308 fmt = "%d-bit %s key, ID %08lX\nEnter Passphrase: ";
309 p = cdk_calloc (1, 64 + strlen (fmt) + strlen (algo) + 1);
310 if (!p)
311 return NULL;
312 sprintf (p, fmt, bits, algo, keyid);
313 return p;
314}
315
316
317/* Try to unprotect the secret key, if needed, automatically.
318 The passphrase callback is used to get the passphrase directly
319 from the user. */
320cdk_error_t
321_cdk_sk_unprotect_auto (cdk_ctx_t hd, cdk_pkt_seckey_t sk)
322{
323 char *pw, *p;
324 cdk_error_t rc;
325
326 if (!sk->is_protected)
327 return 0;
328
329 p = passphrase_prompt (sk);
330 pw = _cdk_passphrase_get (hd, p);
331 cdk_free (p);
332 if (!pw)
333 return CDK_No_Passphrase;
334
335 rc = cdk_sk_unprotect (sk, pw);
336
337 wipemem (pw, strlen (pw));
338 cdk_free (pw);
339 return rc;
340}
341
342
343/**
344 * cdk_dek_extract:
345 * @ret_dek: the raw DEK object
346 * @hd: the session handle
347 * @enc: the public key encrypted packet
348 * @sk: the secret key.
349 *
350 * Try to extract the DEK from the public key encrypted packet.
351 **/
352cdk_error_t
353cdk_dek_extract (cdk_dek_t * ret_dek, cdk_ctx_t hd,
354 cdk_pkt_pubkey_enc_t enc, cdk_pkt_seckey_t sk)
355{
356 gcry_mpi_t skey = NULL;
357 cdk_dek_t dek;
358 cdk_error_t rc;
359
360 if (!enc || !sk || !ret_dek)
361 return CDK_Inv_Value;
362
363 /* FIXME: it is not very elegant that we need the session handle here. */
364 if (sk->is_protected)
365 {
366 rc = _cdk_sk_unprotect_auto (hd, sk);
367 if (rc)
368 return rc;
369 }
370
371 rc = cdk_pk_decrypt (sk, enc, &skey);
372 if (rc)
373 return rc;
374
375 rc = cdk_dek_decode_pkcs1 (&dek, skey);
376 gcry_mpi_release (skey);
377 if (rc)
378 {
379 cdk_dek_free (dek);
380 dek = NULL;
381 }
382 *ret_dek = dek;
383 return rc;
384}
385
386
387/**
388 * cdk_dek_new:
389 * @r_dek: the new DEK object
390 *
391 * Create a new DEK object.
392 **/
393cdk_error_t
394cdk_dek_new (cdk_dek_t * r_dek)
395{
396 cdk_dek_t dek;
397
398 if (!r_dek)
399 return CDK_Inv_Value;
400 *r_dek = NULL;
401 dek = cdk_salloc (sizeof *dek, 1);
402 if (!dek)
403 return CDK_Out_Of_Core;
404 *r_dek = dek;
405 return 0;
406}
407
408
409/**
410 * cdk_dek_set_cipher:
411 * @dek: the DEK object
412 * @algo: the cipher algorithm to use
413 *
414 * Set the cipher for the given DEK object.
415 **/
416cdk_error_t
417cdk_dek_set_cipher (cdk_dek_t dek, int algo)
418{
419 if (!dek)
420 return CDK_Inv_Value;
421
422 if (!algo)
423 algo = GCRY_CIPHER_AES128;
424 if (gcry_cipher_test_algo (algo))
425 return CDK_Inv_Algo;
426 dek->algo = algo;
427 dek->keylen = gcry_cipher_get_algo_keylen (dek->algo);
428 return 0;
429}
430
431cdk_error_t
432cdk_dek_get_cipher (cdk_dek_t dek, int *r_algo)
433{
434 if (!dek || !r_algo)
435 return CDK_Inv_Value;
436
437
438 *r_algo = dek->algo;
439 return 0;
440}
441
442
443/**
444 * cdk_dek_set_key:
445 * @dek: the DEK object
446 * @key: the random session key
447 * @keylen: the length of the session key.
448 *
449 * Set the random session key for the given DEK object.
450 * If @key and @keylen is NULL (0) a random key will be generated.
451 * In any case, cdk_dek_set_cipher must be called first.
452 **/
453cdk_error_t
454cdk_dek_set_key (cdk_dek_t dek, const byte * key, size_t keylen)
455{
456 gcry_cipher_hd_t hd;
457 size_t i;
458
459 if (!dek)
460 return CDK_Inv_Value;
461
462 /* The given key must be compatible with the symmetric
463 cipher algorithm set before. */
464 if (keylen > 0 && keylen != dek->keylen)
465 return CDK_Inv_Mode;
466
467 if (!key && !keylen)
468 {
469 gcry_error_t err;
470
471 /* Used to generate a random session key. The extra code is used
472 to detect weak keys, if they are possible at all. */
473 err = gcry_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB,
474 GCRY_CIPHER_ENABLE_SYNC);
475 if (err)
476 return map_gcry_error (err);
477 gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM);
478 for (i = 0; i < 8; i++)
479 {
480 if (!gcry_cipher_setkey (hd, dek->key, dek->keylen))
481 {
482 gcry_cipher_close (hd);
483 return 0;
484 }
485 gcry_randomize (dek->key, dek->keylen, GCRY_STRONG_RANDOM);
486 }
487 gcry_cipher_close (hd);
488 return CDK_Weak_Key;
489 }
490
491 memcpy (dek->key, key, dek->keylen);
492 return 0;
493}
494
495
496/**
497 * cdk_dek_set_mdc_flag:
498 * @dek: the DEK object
499 * @val: value to enable or disable the use
500 *
501 * Enable or disable the MDC flag for the given DEK object.
502 **/
503void
504cdk_dek_set_mdc_flag (cdk_dek_t dek, int val)
505{
506 if (dek)
507 dek->use_mdc = val;
508}
509
510
511int
512cdk_dek_get_mdc_flag (cdk_dek_t dek)
513{
514 if (!dek)
515 return 0;
516 return dek->use_mdc;
517}
518
519
520/**
521 * cdk_dek_free:
522 * @dek: the DEK object
523 *
524 * Release the DEK object.
525 **/
526void
527cdk_dek_free (cdk_dek_t dek)
528{
529 if (!dek)
530 return;
531
532 /* Make sure sentensive data is overwritten. */
533 wipemem (dek->key, sizeof (dek->key));
534 cdk_free (dek);
535}
536
537
538/* Hash the passphrase to produce the a DEK.
539 If create is set, a random salt will be generated. */
540static cdk_error_t
541hash_passphrase (cdk_dek_t dek, const char *pw, cdk_s2k_t s2k, int create)
542{
543 gcry_md_hd_t md;
544 byte zero[1] = { 0x00 };
545 int pass, i;
546 int used = 0, pwlen;
547 gcry_error_t err;
548
549 if (!dek || !pw || !s2k)
550 return CDK_Inv_Value;
551
552 if (!s2k->hash_algo)
553 s2k->hash_algo = GCRY_MD_SHA1;
554 pwlen = strlen (pw);
555
556 dek->keylen = gcry_cipher_get_algo_keylen (dek->algo);
557 err = gcry_md_open (&md, s2k->hash_algo, 0);
558 if (err)
559 return map_gcry_error (err);
560
561 for (pass = 0; used < dek->keylen; pass++)
562 {
563 if (pass)
564 {
565 gcry_md_reset (md);
566 for (i = 0; i < pass; i++) /* preset the hash context */
567 gcry_md_write (md, zero, 1);
568 }
569 if (s2k->mode == CDK_S2K_SALTED || s2k->mode == CDK_S2K_ITERSALTED)
570 {
571 int len2 = pwlen + 8;
572 u32 count = len2;
573 if (create && !pass)
574 {
575 gcry_randomize (s2k->salt, 8, GCRY_STRONG_RANDOM);
576 if (s2k->mode == 3)
577 s2k->count = 96; /* 65536 iterations */
578 }
579 if (s2k->mode == 3)
580 {
581 count = (16ul + (s2k->count & 15)) << ((s2k->count >> 4) + 6);
582 if (count < len2)
583 count = len2;
584 }
585 /* a little bit complicated because we need a ulong for count */
586 while (count > len2)
587 { /* maybe iterated+salted */
588 gcry_md_write (md, s2k->salt, 8);
589 gcry_md_write (md, pw, pwlen);
590 count -= len2;
591 }
592 if (count < 8)
593 gcry_md_write (md, s2k->salt, count);
594 else
595 {
596 gcry_md_write (md, s2k->salt, 8);
597 count -= 8;
598 gcry_md_write (md, pw, count);
599 }
600 }
601 else
602 gcry_md_write (md, pw, pwlen);
603 gcry_md_final (md);
604 i = gcry_md_get_algo_dlen (s2k->hash_algo);
605 if (i > dek->keylen - used)
606 i = dek->keylen - used;
607 memcpy (dek->key + used, gcry_md_read (md, s2k->hash_algo), i);
608 used += i;
609 }
610 gcry_md_close (md);
611 return 0;
612}
613
614
615/**
616 * cdk_dek_from_passphrase:
617 * @ret_dek: the new DEK.
618 * @cipher_algo: symmetric key algorithm to use
619 * @s2k: the S2K to use
620 * @rndsalt: 1=create random salt
621 * @pw: the passphrase.
622 *
623 * Transform a passphrase into a DEK object.
624 */
625cdk_error_t
626cdk_dek_from_passphrase (cdk_dek_t * ret_dek, int cipher_algo, cdk_s2k_t s2k,
627 int rndsalt, const char *pw)
628{
629 cdk_dek_t dek;
630 cdk_error_t rc;
631
632 if (!ret_dek)
633 return CDK_Inv_Value;
634
635 *ret_dek = NULL;
636 rc = cdk_dek_new (&dek);
637 if (rc)
638 return rc;
639 rc = cdk_dek_set_cipher (dek, cipher_algo);
640 if (!rc)
641 rc = hash_passphrase (dek, pw, s2k, rndsalt);
642 if (rc)
643 {
644 cdk_dek_free (dek);
645 return rc;
646 }
647
648 *ret_dek = dek;
649 return 0;
650}
651
652
653/**
654 * cdk_s2k_new:
655 * @ret_s2k: output for the new S2K object
656 * @mode: the S2K mode (simple, salted, iter+salted)
657 * @digest_algo: the hash algorithm
658 * @salt: random salt
659 *
660 * Create a new S2K object with the given parameter.
661 * The @salt parameter must be always 8 octets.
662 **/
663cdk_error_t
664cdk_s2k_new (cdk_s2k_t * ret_s2k, int mode, int digest_algo,
665 const byte * salt)
666{
667 cdk_s2k_t s2k;
668
669 if (!ret_s2k)
670 return CDK_Inv_Value;
671
672 if (mode != 0x00 && mode != 0x01 && mode != 0x03)
673 return CDK_Inv_Mode;
674
675 if (gcry_md_test_algo (digest_algo))
676 return CDK_Inv_Algo;
677
678 s2k = cdk_calloc (1, sizeof *s2k);
679 if (!s2k)
680 return CDK_Out_Of_Core;
681 s2k->mode = mode;
682 s2k->hash_algo = digest_algo;
683 if (salt)
684 memcpy (s2k->salt, salt, 8);
685 *ret_s2k = s2k;
686 return 0;
687}
688
689
690/**
691 * cdk_s2k_free:
692 * @s2k: the S2K object
693 *
694 * Release the given S2K object.
695 **/
696void
697cdk_s2k_free (cdk_s2k_t s2k)
698{
699 cdk_free (s2k);
700}
701
702
703/* Make a copy of the source s2k into R_DST. */
704cdk_error_t
705_cdk_s2k_copy (cdk_s2k_t * r_dst, cdk_s2k_t src)
706{
707 cdk_s2k_t dst;
708 cdk_error_t err;
709
710 err = cdk_s2k_new (&dst, src->mode, src->hash_algo, src->salt);
711 if (err)
712 return err;
713 dst->count = src->count;
714 *r_dst = dst;
715
716 return 0;
717}
diff --git a/src/daemon/https/opencdk/sig-check.c b/src/daemon/https/opencdk/sig-check.c
new file mode 100644
index 00000000..f1ad5b2f
--- /dev/null
+++ b/src/daemon/https/opencdk/sig-check.c
@@ -0,0 +1,489 @@
1/* sig-check.c - Check signatures
2 * Copyright (C) 2001, 2002, 2003, 2007 Timo Schulz
3 * Copyright (C) 1998-2002 Free Software Foundation, Inc.
4 *
5 * This file is part of OpenCDK.
6 *
7 * OpenCDK is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * OpenCDK is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17#ifdef HAVE_CONFIG_H
18# include <config.h>
19#endif
20#include <stdio.h>
21#include <time.h>
22#include <gcrypt.h>
23#include <assert.h>
24
25#include "opencdk.h"
26#include "main.h"
27#include "packet.h"
28
29
30/* Hash all multi precision integers of the key PK with the given
31 message digest context MD. */
32static int
33hash_mpibuf (cdk_pubkey_t pk, gcry_md_hd_t md, int usefpr)
34{
35 byte buf[MAX_MPI_BYTES]; /* FIXME: do not use hardcoded length. */
36 size_t nbytes;
37 size_t i, npkey;
38 gcry_error_t err;
39
40 /* We have to differ between two modes for v3 keys. To form the
41 fingerprint, we hash the MPI values without the length prefix.
42 But if we calculate the hash for verifying/signing we use all data. */
43 npkey = cdk_pk_get_npkey (pk->pubkey_algo);
44 for (i = 0; i < npkey; i++)
45 {
46 err = gcry_mpi_print (GCRYMPI_FMT_PGP, buf, MAX_MPI_BYTES,
47 &nbytes, pk->mpi[i]);
48 if (err)
49 return map_gcry_error (err);
50 if (!usefpr || pk->version == 4)
51 gcry_md_write (md, buf, nbytes);
52 else /* without the prefix. */
53 gcry_md_write (md, buf + 2, nbytes - 2);
54 }
55 return 0;
56}
57
58
59/* Hash an entire public key PK with the given message digest context
60 MD. The @usefpr param is only valid for version 3 keys because of
61 the different way to calculate the fingerprint. */
62cdk_error_t
63_cdk_hash_pubkey (cdk_pubkey_t pk, gcry_md_hd_t md, int usefpr)
64{
65 byte buf[12];
66 size_t i, n, npkey;
67
68 if (!pk || !md)
69 return CDK_Inv_Value;
70
71 if (usefpr && pk->version < 4 && is_RSA (pk->pubkey_algo))
72 return hash_mpibuf (pk, md, 1);
73
74 /* The version 4 public key packet does not have the 2 octets for
75 the expiration date. */
76 n = pk->version < 4 ? 8 : 6;
77 npkey = cdk_pk_get_npkey (pk->pubkey_algo);
78 for (i = 0; i < npkey; i++)
79 n = n + (gcry_mpi_get_nbits (pk->mpi[i]) + 7) / 8 + 2;
80
81 i = 0;
82 buf[i++] = 0x99;
83 buf[i++] = n >> 8;
84 buf[i++] = n >> 0;
85 buf[i++] = pk->version;
86 buf[i++] = pk->timestamp >> 24;
87 buf[i++] = pk->timestamp >> 16;
88 buf[i++] = pk->timestamp >> 8;
89 buf[i++] = pk->timestamp >> 0;
90
91 if (pk->version < 4)
92 {
93 u16 a = 0;
94
95 /* Convert the expiration date into days. */
96 if (pk->expiredate)
97 a = (u16) ((pk->expiredate - pk->timestamp) / 86400L);
98 buf[i++] = a >> 8;
99 buf[i++] = a;
100 }
101 buf[i++] = pk->pubkey_algo;
102 gcry_md_write (md, buf, i);
103 return hash_mpibuf (pk, md, 0);
104}
105
106
107/* Hash the user ID @uid with the given message digest @md.
108 Use openpgp mode if @is_v4 is 1. */
109cdk_error_t
110_cdk_hash_userid (cdk_pkt_userid_t uid, int is_v4, gcry_md_hd_t md)
111{
112 const byte *data;
113 byte buf[5];
114 u32 dlen;
115
116 if (!uid || !md)
117 return CDK_Inv_Value;
118
119 if (!is_v4)
120 {
121 gcry_md_write (md, (byte *) uid->name, uid->len);
122 return 0;
123 }
124
125 dlen = uid->attrib_img ? uid->attrib_len : uid->len;
126 data = uid->attrib_img ? uid->attrib_img : (byte *) uid->name;
127 buf[0] = uid->attrib_img ? 0xD1 : 0xB4;
128 buf[1] = dlen >> 24;
129 buf[2] = dlen >> 16;
130 buf[3] = dlen >> 8;
131 buf[4] = dlen >> 0;
132 gcry_md_write (md, buf, 5);
133 gcry_md_write (md, data, dlen);
134 return 0;
135}
136
137
138/* Hash all parts of the signature which are needed to derive
139 the correct message digest to verify the sig. */
140cdk_error_t
141_cdk_hash_sig_data (cdk_pkt_signature_t sig, gcry_md_hd_t md)
142{
143 byte buf[4];
144
145 if (!sig || !md)
146 return CDK_Inv_Value;
147
148 if (sig->version == 4)
149 gcry_md_putc (md, sig->version);
150 gcry_md_putc (md, sig->sig_class);
151 if (sig->version < 4)
152 {
153 buf[0] = sig->timestamp >> 24;
154 buf[1] = sig->timestamp >> 16;
155 buf[2] = sig->timestamp >> 8;
156 buf[3] = sig->timestamp >> 0;
157 gcry_md_write (md, buf, 4);
158 }
159 else
160 {
161 size_t n;
162
163 gcry_md_putc (md, sig->pubkey_algo);
164 gcry_md_putc (md, sig->digest_algo);
165 if (sig->hashed != NULL)
166 {
167 byte *p = _cdk_subpkt_get_array (sig->hashed, 0, &n);
168 assert (p != NULL);
169 buf[0] = n >> 8;
170 buf[1] = n >> 0;
171 gcry_md_write (md, buf, 2);
172 gcry_md_write (md, p, n);
173 cdk_free (p);
174 sig->hashed_size = n;
175 n = sig->hashed_size + 6;
176 }
177 else
178 {
179 gcry_md_putc (md, 0x00);
180 gcry_md_putc (md, 0x00);
181 n = 6;
182 }
183 gcry_md_putc (md, sig->version);
184 gcry_md_putc (md, 0xFF);
185 buf[0] = n >> 24;
186 buf[1] = n >> 16;
187 buf[2] = n >> 8;
188 buf[3] = n >> 0;
189 gcry_md_write (md, buf, 4);
190 }
191 return 0;
192}
193
194
195/* Cache the signature result and store it inside the sig. */
196static void
197cache_sig_result (cdk_pkt_signature_t sig, int res)
198{
199 sig->flags.checked = 0;
200 sig->flags.valid = 0;
201 if (res == 0)
202 {
203 sig->flags.checked = 1;
204 sig->flags.valid = 1;
205 }
206 else if (res == CDK_Bad_Sig)
207 {
208 sig->flags.checked = 1;
209 sig->flags.valid = 0;
210 }
211}
212
213
214/* Check the given signature @sig with the public key @pk.
215 Use the digest handle @digest. */
216cdk_error_t
217_cdk_sig_check (cdk_pubkey_t pk, cdk_pkt_signature_t sig,
218 gcry_md_hd_t digest, int *r_expired)
219{
220 cdk_error_t rc;
221 byte md[MAX_DIGEST_LEN];
222 time_t cur_time = (u32) time (NULL);
223
224 if (!pk || !sig || !digest)
225 return CDK_Inv_Value;
226
227 if (sig->flags.checked)
228 return sig->flags.valid ? 0 : CDK_Bad_Sig;
229 if (!KEY_CAN_SIGN (pk->pubkey_algo))
230 return CDK_Inv_Algo;
231 if (pk->timestamp > sig->timestamp || pk->timestamp > cur_time)
232 return CDK_Time_Conflict;
233
234 if (r_expired && pk->expiredate
235 && (pk->expiredate + pk->timestamp) > cur_time)
236 *r_expired = 1;
237
238 _cdk_hash_sig_data (sig, digest);
239 gcry_md_final (digest);
240 memcpy (md, gcry_md_read (digest, sig->digest_algo),
241 gcry_md_get_algo_dlen (sig->digest_algo));
242
243 if (md[0] != sig->digest_start[0] || md[1] != sig->digest_start[1])
244 return CDK_Chksum_Error;
245
246 rc = cdk_pk_verify (pk, sig, md);
247 cache_sig_result (sig, rc);
248 return rc;
249}
250
251
252/* Check the given key signature.
253 @knode is the key node and @snode the signature node. */
254cdk_error_t
255_cdk_pk_check_sig (cdk_keydb_hd_t keydb,
256 cdk_kbnode_t knode, cdk_kbnode_t snode, int *is_selfsig)
257{
258 gcry_md_hd_t md;
259 gcry_error_t err;
260 cdk_pubkey_t pk;
261 cdk_pkt_signature_t sig;
262 cdk_kbnode_t node;
263 cdk_error_t rc = 0;
264 int is_expired;
265
266 if (!knode || !snode)
267 return CDK_Inv_Value;
268
269 if (is_selfsig)
270 *is_selfsig = 0;
271 if (knode->pkt->pkttype != CDK_PKT_PUBLIC_KEY ||
272 snode->pkt->pkttype != CDK_PKT_SIGNATURE)
273 return CDK_Inv_Value;
274 pk = knode->pkt->pkt.public_key;
275 sig = snode->pkt->pkt.signature;
276
277 err = gcry_md_open (&md, sig->digest_algo, 0);
278 if (err)
279 return map_gcry_error (err);
280
281 is_expired = 0;
282 if (sig->sig_class == 0x20)
283 { /* key revocation */
284 cdk_kbnode_hash (knode, md, 0, 0, 0);
285 rc = _cdk_sig_check (pk, sig, md, &is_expired);
286 }
287 else if (sig->sig_class == 0x28)
288 { /* subkey revocation */
289 node = cdk_kbnode_find_prev (knode, snode, CDK_PKT_PUBLIC_SUBKEY);
290 if (!node)
291 { /* no subkey for subkey revocation packet */
292 rc = CDK_Error_No_Key;
293 goto fail;
294 }
295 cdk_kbnode_hash (knode, md, 0, 0, 0);
296 cdk_kbnode_hash (node, md, 0, 0, 0);
297 rc = _cdk_sig_check (pk, sig, md, &is_expired);
298 }
299 else if (sig->sig_class == 0x18 || sig->sig_class == 0x19)
300 { /* primary/secondary key binding */
301 node = cdk_kbnode_find_prev (knode, snode, CDK_PKT_PUBLIC_SUBKEY);
302 if (!node)
303 { /* no subkey for subkey binding packet */
304 rc = CDK_Error_No_Key;
305 goto fail;
306 }
307 cdk_kbnode_hash (knode, md, 0, 0, 0);
308 cdk_kbnode_hash (node, md, 0, 0, 0);
309 rc = _cdk_sig_check (pk, sig, md, &is_expired);
310 }
311 else if (sig->sig_class == 0x1F)
312 { /* direct key signature */
313 cdk_kbnode_hash (knode, md, 0, 0, 0);
314 rc = _cdk_sig_check (pk, sig, md, &is_expired);
315 }
316 else
317 { /* all other classes */
318 node = cdk_kbnode_find_prev (knode, snode, CDK_PKT_USER_ID);
319 if (!node)
320 { /* no user ID for key signature packet */
321 rc = CDK_Error_No_Key;
322 goto fail;
323 }
324 cdk_kbnode_hash (knode, md, 0, 0, 0);
325 cdk_kbnode_hash (node, md, sig->version == 4, 0, 0);
326 if (pk->keyid[0] == sig->keyid[0] && pk->keyid[1] == sig->keyid[1])
327 {
328 rc = _cdk_sig_check (pk, sig, md, &is_expired);
329 if (is_selfsig)
330 *is_selfsig = 1;
331 }
332 else if (keydb != NULL)
333 {
334 cdk_pubkey_t sig_pk;
335
336 rc = cdk_keydb_get_pk (keydb, sig->keyid, &sig_pk);
337 if (!rc)
338 rc = _cdk_sig_check (sig_pk, sig, md, &is_expired);
339 cdk_pk_release (sig_pk);
340 }
341 }
342fail:
343 gcry_md_close (md);
344 return rc;
345}
346
347
348/**
349 * cdk_pk_check_sigs:
350 * @key: the public key
351 * @hd: an optinal key database handle
352 * @r_status: variable to store the status of the key
353 *
354 * Check all signatures. When no key is available for checking, the
355 * sigstat is marked as 'NOKEY'. The @r_status contains the key flags
356 * which are or-ed or zero when there are no flags.
357 **/
358cdk_error_t
359cdk_pk_check_sigs (cdk_kbnode_t key, cdk_keydb_hd_t keydb, int *r_status)
360{
361 cdk_pkt_signature_t sig;
362 cdk_kbnode_t node;
363 cdk_error_t rc;
364 u32 keyid;
365 int key_status, is_selfsig = 0;
366 int no_signer, n_sigs = 0;
367
368 if (!key || !r_status)
369 return CDK_Inv_Value;
370
371 *r_status = 0;
372 node = cdk_kbnode_find (key, CDK_PKT_PUBLIC_KEY);
373 if (!node)
374 return CDK_Error_No_Key;
375
376 key_status = 0;
377 /* Continue with the signature check but adjust the
378 key status flags accordingly. */
379 if (node->pkt->pkt.public_key->is_revoked)
380 key_status |= CDK_KEY_REVOKED;
381 if (node->pkt->pkt.public_key->has_expired)
382 key_status |= CDK_KEY_EXPIRED;
383
384 rc = 0;
385 no_signer = 0;
386 keyid = cdk_pk_get_keyid (node->pkt->pkt.public_key, NULL);
387 for (node = key; node; node = node->next)
388 {
389 if (node->pkt->pkttype != CDK_PKT_SIGNATURE)
390 continue;
391 sig = node->pkt->pkt.signature;
392 rc = _cdk_pk_check_sig (keydb, key, node, &is_selfsig);
393 if (IS_UID_SIG (sig))
394 {
395 if (is_selfsig == 0)
396 n_sigs++;
397 }
398 if (rc && IS_UID_SIG (sig) && rc == CDK_Error_No_Key)
399 {
400 /* We do not consider it a problem when the signing key
401 is not avaiable. We just mark the signature accordingly
402 and contine. */
403 sig->flags.missing_key = 1;
404 no_signer++;
405 }
406 else if (rc && rc != CDK_Error_No_Key)
407 {
408 /* It might be possible that a single signature has been
409 corrupted, thus we do not consider it a problem when
410 one ore more signatures are bad. But at least the self
411 signature has to be valid. */
412 if (is_selfsig)
413 {
414 key_status |= CDK_KEY_INVALID;
415 break;
416 }
417 }
418 _cdk_log_debug ("signature %s: signer %08lX keyid %08lX\n",
419 rc == CDK_Bad_Sig ? "BAD" : "good", sig->keyid[1],
420 keyid);
421 }
422
423 if (n_sigs == no_signer)
424 key_status |= CDK_KEY_NOSIGNER;
425 *r_status = key_status;
426 if (rc == CDK_Error_No_Key)
427 rc = 0;
428 return rc;
429}
430
431
432/**
433 * cdk_pk_check_self_sig:
434 * @key: the key node
435 * @r_status: output the status of the key.
436 *
437 * A convenient function to make sure the key is valid.
438 * Valid means the self signature is ok.
439 **/
440cdk_error_t
441cdk_pk_check_self_sig (cdk_kbnode_t key, int *r_status)
442{
443 cdk_pkt_signature_t sig;
444 cdk_kbnode_t node;
445 cdk_error_t rc;
446 u32 keyid[2], sigid[2];
447 int is_selfsig, sig_ok;
448
449 if (!key || !r_status)
450 return CDK_Inv_Value;
451
452 node = cdk_kbnode_find (key, CDK_PKT_PUBLIC_KEY);
453 if (!node)
454 return CDK_Error_No_Key;
455 /* FIXME: we should set expire/revoke here also but callers
456 expect CDK_KEY_VALID=0 if the key is okay. */
457 cdk_pk_get_keyid (key->pkt->pkt.public_key, keyid);
458 sig_ok = 0;
459 for (node = key; node; node = node->next)
460 {
461 if (node->pkt->pkttype != CDK_PKT_SIGNATURE)
462 continue;
463 sig = node->pkt->pkt.signature;
464 if (!IS_UID_SIG (sig))
465 continue;
466 cdk_sig_get_keyid (sig, sigid);
467 if (sigid[0] != keyid[0] || sigid[1] != keyid[1])
468 continue;
469 /* FIXME: Now we check all self signatures. */
470 rc = _cdk_pk_check_sig (NULL, key, node, &is_selfsig);
471 if (rc)
472 {
473 *r_status = CDK_KEY_INVALID;
474 return rc;
475 }
476 else /* For each valid self sig we increase this counter. */
477 sig_ok++;
478 }
479
480 /* A key without a self signature is not valid. */
481 if (!sig_ok)
482 {
483 *r_status = CDK_KEY_INVALID;
484 return CDK_General_Error;
485 }
486 /* No flags indicate a valid key. */
487 *r_status = CDK_KEY_VALID;
488 return 0;
489}
diff --git a/src/daemon/https/opencdk/stream.c b/src/daemon/https/opencdk/stream.c
new file mode 100644
index 00000000..8389401f
--- /dev/null
+++ b/src/daemon/https/opencdk/stream.c
@@ -0,0 +1,1446 @@
1/* stream.c - The stream implementation
2 * Copyright (C) 2002, 2003, 2007 Timo Schulz
3 *
4 * This file is part of OpenCDK.
5 *
6 * OpenCDK is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * OpenCDK is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19#include <assert.h>
20#include <stdio.h>
21#include <sys/stat.h>
22#include <string.h>
23#include <stdlib.h>
24#include <errno.h>
25#ifdef HAVE_UNISTD_H
26# include <unistd.h>
27#endif
28
29#include "opencdk.h"
30#include "main.h"
31#include "filters.h"
32#include "stream.h"
33#include "types.h"
34
35/* This is the maximal amount of bytes we map. */
36#define MAX_MAP_SIZE 16777216
37
38static int stream_flush (cdk_stream_t s);
39static int stream_filter_write (cdk_stream_t s);
40static int stream_cache_flush (cdk_stream_t s, FILE * fp);
41
42/* Customized tmpfile() version from misc.c */
43FILE *my_tmpfile (void);
44
45
46/* FIXME: The read/write/putc/getc function cannot directly
47 return an error code. It is stored in an error variable
48 inside the string. Right now there is no code to
49 return the error code or to reset it. */
50
51/**
52 * cdk_stream_open:
53 * @file: The file to open
54 * @ret_s: The new STREAM object
55 *
56 * Create a new stream based on an existing file. The stream is
57 * opened in read-only mode.
58 **/
59cdk_error_t
60cdk_stream_open (const char *file, cdk_stream_t * ret_s)
61{
62 return _cdk_stream_open_mode (file, "rb", ret_s);
63}
64
65
66/* Helper function to allow to open a stream in different modes. */
67cdk_error_t
68_cdk_stream_open_mode (const char *file, const char *mode,
69 cdk_stream_t * ret_s)
70{
71 cdk_stream_t s;
72
73 if (!file || !ret_s)
74 return CDK_Inv_Value;
75
76 _cdk_log_debug ("open stream `%s'\n", file);
77 *ret_s = NULL;
78 s = cdk_calloc (1, sizeof *s);
79 if (!s)
80 return CDK_Out_Of_Core;
81 s->fname = cdk_strdup (file);
82 if (!s->fname)
83 {
84 cdk_free (s);
85 return CDK_Out_Of_Core;
86 }
87 s->fp = fopen (file, mode);
88 if (!s->fp)
89 {
90 cdk_free (s->fname);
91 cdk_free (s);
92 return CDK_File_Error;
93 }
94 _cdk_log_debug ("open stream fd=%d\n", fileno (s->fp));
95 s->flags.write = 0;
96 *ret_s = s;
97 return 0;
98}
99
100
101/**
102 * cdk_stream_new_from_cbs:
103 * @cbs: the callback context with all user callback functions
104 * @opa: opaque handle which is passed to all callbacks.
105 * @ret_s: the allocated stream
106 *
107 * This function creates a stream which uses user callback
108 * for the core operations (open, close, read, write, seek).
109 */
110cdk_error_t
111cdk_stream_new_from_cbs (cdk_stream_cbs_t cbs, void *opa,
112 cdk_stream_t * ret_s)
113{
114 cdk_stream_t s;
115
116 if (!cbs || !opa || !ret_s)
117 return CDK_Inv_Value;
118
119 *ret_s = NULL;
120 s = cdk_calloc (1, sizeof *s);
121 if (!s)
122 return CDK_Out_Of_Core;
123
124 s->cbs.read = cbs->read;
125 s->cbs.write = cbs->write;
126 s->cbs.seek = cbs->seek;
127 s->cbs.release = cbs->release;
128 s->cbs.open = cbs->open;
129 s->cbs_hd = opa;
130 *ret_s = s;
131
132 /* If there is a user callback for open, we need to call it
133 here because read/write expects an open stream. */
134 if (s->cbs.open)
135 return s->cbs.open (s->cbs_hd);
136 return 0;
137}
138
139
140/**
141 * cdk_stream_new: Create a new stream into into the given file.
142 * @file: The name of the new file
143 * @ret_s: The new STREAM object
144 **/
145cdk_error_t
146cdk_stream_new (const char *file, cdk_stream_t * ret_s)
147{
148 cdk_stream_t s;
149
150 if (!ret_s)
151 return CDK_Inv_Value;
152
153 _cdk_log_debug ("new stream `%s'\n", file ? file : "[temp]");
154 *ret_s = NULL;
155 s = cdk_calloc (1, sizeof *s);
156 if (!s)
157 return CDK_Out_Of_Core;
158 s->flags.write = 1;
159 if (!file)
160 s->flags.temp = 1;
161 else
162 {
163 s->fname = cdk_strdup (file);
164 if (!s->fname)
165 {
166 cdk_free (s);
167 return CDK_Out_Of_Core;
168 }
169 }
170 s->fp = my_tmpfile ();
171 if (!s->fp)
172 {
173 cdk_free (s->fname);
174 cdk_free (s);
175 return CDK_File_Error;
176 }
177 _cdk_log_debug ("new stream fd=%d\n", fileno (s->fp));
178 *ret_s = s;
179 return 0;
180}
181
182
183/**
184 * cdk_stream_create: create a new stream.
185 * @file: the filename
186 * @ret_s: the object
187 *
188 * The difference to cdk_stream_new is, that no filtering can be used with
189 * this kind of stream and everything is written directly to the stream.
190 **/
191cdk_error_t
192cdk_stream_create (const char *file, cdk_stream_t * ret_s)
193{
194 cdk_stream_t s;
195
196 if (!file || !ret_s)
197 return CDK_Inv_Value;
198
199 _cdk_log_debug ("create stream `%s'\n", file);
200 *ret_s = NULL;
201 s = cdk_calloc (1, sizeof *s);
202 if (!s)
203 return CDK_Out_Of_Core;
204 s->flags.write = 1;
205 s->flags.filtrated = 1;
206 s->fname = cdk_strdup (file);
207 if (!s->fname)
208 {
209 cdk_free (s);
210 return CDK_Out_Of_Core;
211 }
212 s->fp = fopen (file, "w+b");
213 if (!s->fp)
214 {
215 cdk_free (s->fname);
216 cdk_free (s);
217 return CDK_File_Error;
218 }
219 _cdk_log_debug ("stream create fd=%d\n", fileno (s->fp));
220 *ret_s = s;
221 return 0;
222}
223
224
225/**
226 * cdk_stream_tmp_new:
227 * @r_out: the new temp stream.
228 *
229 * Allocate a new tempory stream which is not associated with a file.
230 */
231cdk_error_t
232cdk_stream_tmp_new (cdk_stream_t * r_out)
233{
234 return cdk_stream_new (NULL, r_out);
235}
236
237
238
239/**
240 * cdk_stream_tmp_from_mem:
241 * @buf: the buffer which shall be written to the temp stream.
242 * @buflen: how large the buffer is
243 * @r_out: the new stream with the given contents.
244 *
245 * Create a new tempory stream with the given contests.
246 */
247cdk_error_t
248cdk_stream_tmp_from_mem (const void *buf, size_t buflen, cdk_stream_t * r_out)
249{
250 cdk_stream_t s;
251 cdk_error_t rc;
252 int nwritten;
253
254 *r_out = NULL;
255 rc = cdk_stream_tmp_new (&s);
256 if (rc)
257 return rc;
258
259 nwritten = cdk_stream_write (s, buf, buflen);
260 if (nwritten == EOF)
261 {
262 cdk_stream_close (s);
263 return s->error;
264 }
265 cdk_stream_seek (s, 0);
266 *r_out = s;
267 return 0;
268}
269
270
271cdk_error_t
272_cdk_stream_fpopen (FILE * fp, unsigned write_mode, cdk_stream_t * ret_out)
273{
274 cdk_stream_t s;
275
276 *ret_out = NULL;
277 s = cdk_calloc (1, sizeof *s);
278 if (!s)
279 return CDK_Out_Of_Core;
280
281 _cdk_log_debug ("stream ref fd=%d\n", fileno (fp));
282 s->fp = fp;
283 s->fp_ref = 1;
284 s->flags.filtrated = 1;
285 s->flags.write = write_mode;
286
287 *ret_out = s;
288 return 0;
289}
290
291
292cdk_error_t
293_cdk_stream_append (const char *file, cdk_stream_t * ret_s)
294{
295 cdk_stream_t s;
296 cdk_error_t rc;
297
298 if (!ret_s)
299 return CDK_Inv_Value;
300 *ret_s = NULL;
301
302 rc = _cdk_stream_open_mode (file, "a+b", &s);
303 if (rc)
304 return rc;
305
306 /* In the append mode, we need to write to the flag. */
307 s->flags.write = 1;
308 *ret_s = s;
309 return 0;
310}
311
312
313/**
314 * cdk_stream_is_compressed:
315 * @s: the stream
316 *
317 * Return 0 if the stream is uncompressed, otherwise the
318 * compression algorithm.
319 */
320int
321cdk_stream_is_compressed (cdk_stream_t s)
322{
323 if (!s)
324 return 0;
325 return s->flags.compressed;
326}
327
328void
329_cdk_stream_set_compress_algo (cdk_stream_t s, int algo)
330{
331 if (!s)
332 return;
333 s->flags.compressed = algo;
334}
335
336
337cdk_error_t
338cdk_stream_flush (cdk_stream_t s)
339{
340 cdk_error_t rc;
341
342 if (!s)
343 return CDK_Inv_Value;
344
345 /* The user callback does not support flush */
346 if (s->cbs_hd)
347 return 0;
348
349 /* For read-only streams, no flush is needed. */
350 if (!s->flags.write)
351 return 0;
352
353 if (!s->flags.filtrated)
354 {
355 if (!cdk_stream_get_length (s))
356 return 0;
357 rc = cdk_stream_seek (s, 0);
358 if (!rc)
359 rc = stream_flush (s);
360 if (!rc)
361 rc = stream_filter_write (s);
362 s->flags.filtrated = 1;
363 if (rc)
364 {
365 s->error = rc;
366 return rc;
367 }
368 }
369 return 0;
370}
371
372
373void
374cdk_stream_tmp_set_mode (cdk_stream_t s, int val)
375{
376 if (s && s->flags.temp)
377 s->fmode = val;
378}
379
380
381/**
382 * cdk_stream_close: Close a stream and flush all buffers.
383 * @s: The STREAM object.
384 *
385 * This function work different for read or write streams. When the
386 * stream is for reading, the filtering is already done and we can
387 * simply close the file and all buffers.
388 * But for the case it's a write stream, we need to apply all registered
389 * filters now. The file is closed in the filter function and not here.
390 **/
391cdk_error_t
392cdk_stream_close (cdk_stream_t s)
393{
394 struct stream_filter_s *f, *f2;
395 cdk_error_t rc;
396
397 if (!s)
398 return CDK_Inv_Value;
399
400 _cdk_log_debug ("close stream ref=%d `%s'\n",
401 s->fp_ref, s->fname ? s->fname : "[temp]");
402
403 /* In the user callback mode, we call the release cb if possible
404 and just free the stream. */
405 if (s->cbs_hd)
406 {
407 if (s->cbs.release)
408 rc = s->cbs.release (s->cbs_hd);
409 else
410 rc = 0;
411 cdk_free (s);
412 return rc;
413 }
414
415
416 rc = 0;
417 if (!s->flags.filtrated && !s->error)
418 rc = cdk_stream_flush (s);
419 if (!s->fp_ref && (s->fname || s->flags.temp))
420 {
421 int err;
422
423 _cdk_log_debug ("close stream fd=%d\n", fileno (s->fp));
424 err = fclose (s->fp);
425 s->fp = NULL;
426 if (err)
427 rc = CDK_File_Error;
428 }
429
430 /* Iterate over the filter list and use the cleanup flag to
431 free the allocated internal structures. */
432 f = s->filters;
433 while (f)
434 {
435 f2 = f->next;
436 if (f->fnct)
437 f->fnct (f->opaque, STREAMCTL_FREE, NULL, NULL);
438 cdk_free (f);
439 f = f2;
440 }
441
442 if (s->fname)
443 {
444 cdk_free (s->fname);
445 s->fname = NULL;
446 }
447
448 cdk_free (s->cache.buf);
449 s->cache.alloced = 0;
450
451 cdk_free (s);
452 return rc;
453}
454
455
456/**
457 * cdk_stream_eof: Return if the associated file handle was set to EOF.
458 * @s: The STREAM object.
459 *
460 * This function will only work with read streams.
461 **/
462int
463cdk_stream_eof (cdk_stream_t s)
464{
465 return s ? s->flags.eof : -1;
466}
467
468
469const char *
470_cdk_stream_get_fname (cdk_stream_t s)
471{
472 if (!s)
473 return NULL;
474 if (s->flags.temp)
475 return NULL;
476 return s->fname ? s->fname : NULL;
477}
478
479
480/* Return the underlying FP of the stream.
481 WARNING: This handle should not be closed. */
482FILE *
483_cdk_stream_get_fp (cdk_stream_t s)
484{
485 return s ? s->fp : NULL;
486}
487
488
489int
490_cdk_stream_get_errno (cdk_stream_t s)
491{
492 return s ? s->error : CDK_Inv_Value;
493}
494
495
496/**
497 * cdk_stream_get_length: Return the length of the associated file handle.
498 * @s: The STREAM object.
499 *
500 * This function should work for both read and write streams. For write
501 * streams an additional flush is used to write possible pending data.
502 **/
503off_t
504cdk_stream_get_length (cdk_stream_t s)
505{
506 struct stat statbuf;
507 cdk_error_t rc;
508
509 if (!s)
510 return (off_t) - 1;
511
512 /* The user callback does not support stat. */
513 if (s->cbs_hd)
514 return 0;
515
516 rc = stream_flush (s);
517 if (rc)
518 {
519 s->error = rc;
520 return (off_t) - 1;
521 }
522
523 if (fstat (fileno (s->fp), &statbuf))
524 {
525 s->error = CDK_File_Error;
526 return (off_t) - 1;
527 }
528
529 return statbuf.st_size;
530}
531
532
533static struct stream_filter_s *
534filter_add2 (cdk_stream_t s)
535{
536 struct stream_filter_s *f;
537
538 assert (s);
539
540 f = cdk_calloc (1, sizeof *f);
541 if (!f)
542 return NULL;
543 f->next = s->filters;
544 s->filters = f;
545 return f;
546}
547
548
549static struct stream_filter_s *
550filter_search (cdk_stream_t s, filter_fnct_t fnc)
551{
552 struct stream_filter_s *f;
553
554 assert (s);
555
556 for (f = s->filters; f; f = f->next)
557 {
558 if (f->fnct == fnc)
559 return f;
560 }
561
562 return NULL;
563}
564
565
566struct stream_filter_s *
567filter_add (cdk_stream_t s, filter_fnct_t fnc, int type)
568{
569 struct stream_filter_s *f;
570
571 assert (s);
572
573 s->flags.filtrated = 0;
574 f = filter_search (s, fnc);
575 if (f)
576 return f;
577 f = filter_add2 (s);
578 if (!f)
579 return NULL;
580 f->fnct = fnc;
581 f->flags.enabled = 1;
582 f->tmp = NULL;
583 f->type = type;
584 switch (type)
585 {
586 case fARMOR:
587 f->opaque = &f->u.afx;
588 break;
589 case fCIPHER:
590 f->opaque = &f->u.cfx;
591 break;
592 case fLITERAL:
593 f->opaque = &f->u.pfx;
594 break;
595 case fCOMPRESS:
596 f->opaque = &f->u.zfx;
597 break;
598 case fHASH:
599 f->opaque = &f->u.mfx;
600 break;
601 case fTEXT:
602 f->opaque = &f->u.tfx;
603 break;
604 default:
605 f->opaque = NULL;
606 }
607
608 return f;
609}
610
611
612static int
613stream_get_mode (cdk_stream_t s)
614{
615 assert (s);
616
617 if (s->flags.temp)
618 return s->fmode;
619 return s->flags.write;
620}
621
622
623static filter_fnct_t
624stream_id_to_filter (int type)
625{
626 switch (type)
627 {
628 case fARMOR:
629 return _cdk_filter_armor;
630 case fLITERAL:
631 return _cdk_filter_literal;
632 case fTEXT:
633 return _cdk_filter_text;
634 case fCIPHER:
635 return _cdk_filter_cipher;
636 case fCOMPRESS:
637 return _cdk_filter_compress;
638 default:
639 return NULL;
640 }
641}
642
643
644/**
645 * cdk_stream_filter_disable: Disable the filter with the type 'type'
646 * @s: The STREAM object
647 * @type: The numberic filter ID.
648 *
649 **/
650cdk_error_t
651cdk_stream_filter_disable (cdk_stream_t s, int type)
652{
653 struct stream_filter_s *f;
654 filter_fnct_t fnc;
655
656 if (!s)
657 return CDK_Inv_Value;
658
659 fnc = stream_id_to_filter (type);
660 if (!fnc)
661 return CDK_Inv_Value;
662 f = filter_search (s, fnc);
663 if (f)
664 f->flags.enabled = 0;
665 return 0;
666}
667
668
669/* WARNING: tmp should not be closed by the caller. */
670static cdk_error_t
671stream_fp_replace (cdk_stream_t s, FILE ** tmp)
672{
673 int rc;
674
675 assert (s);
676
677 _cdk_log_debug ("replace stream fd=%d with fd=%d\n",
678 fileno (s->fp), fileno (*tmp));
679 rc = fclose (s->fp);
680 if (rc)
681 return CDK_File_Error;
682 s->fp = *tmp;
683 *tmp = NULL;
684 return 0;
685}
686
687
688/* This function is exactly like filter_read, except the fact that we can't
689 use tmpfile () all the time. That's why we open the real file when there
690 is no last filter. */
691static cdk_error_t
692stream_filter_write (cdk_stream_t s)
693{
694 struct stream_filter_s *f;
695 cdk_error_t rc = 0;
696
697 assert (s);
698
699 if (s->flags.filtrated)
700 return CDK_Inv_Value;
701
702 for (f = s->filters; f; f = f->next)
703 {
704 if (!f->flags.enabled)
705 continue;
706 /* if there is no next filter, create the final output file */
707 _cdk_log_debug ("filter [write]: last filter=%d fname=%s\n",
708 f->next ? 1 : 0, s->fname);
709 if (!f->next && s->fname)
710 f->tmp = fopen (s->fname, "w+b");
711 else
712 f->tmp = my_tmpfile ();
713 if (!f->tmp)
714 {
715 rc = CDK_File_Error;
716 break;
717 }
718 /* If there is no next filter, flush the cache. We also do this
719 when the next filter is the armor filter because this filter
720 is special and before it starts, all data should be written. */
721 if ((!f->next || f->next->type == fARMOR) && s->cache.size)
722 {
723 rc = stream_cache_flush (s, f->tmp);
724 if (rc)
725 break;
726 }
727 rc = f->fnct (f->opaque, f->ctl, s->fp, f->tmp);
728 _cdk_log_debug ("filter [write]: type=%d rc=%d\n", f->type, rc);
729 if (!rc)
730 rc = stream_fp_replace (s, &f->tmp);
731 if (!rc)
732 rc = cdk_stream_seek (s, 0);
733 if (rc)
734 {
735 _cdk_log_debug ("filter [close]: fd=%d\n", fileno (f->tmp));
736 fclose (f->tmp);
737 break;
738 }
739 }
740 return rc;
741}
742
743
744/* Here all data from the file handle is passed through all filters.
745 The scheme works like this:
746 Create a tempfile and use it for the output of the filter. Then the
747 original file handle will be closed and replace with the temp handle.
748 The file pointer will be set to the begin and the game starts again. */
749static cdk_error_t
750stream_filter_read (cdk_stream_t s)
751{
752 struct stream_filter_s *f;
753 cdk_error_t rc = 0;
754
755 assert (s);
756
757 if (s->flags.filtrated)
758 return 0;
759
760 for (f = s->filters; f; f = f->next)
761 {
762 if (!f->flags.enabled)
763 continue;
764 if (f->flags.error)
765 {
766 _cdk_log_debug ("filter %s [read]: has the error flag; skipped\n",
767 s->fname ? s->fname : "[temp]");
768 continue;
769 }
770
771 f->tmp = my_tmpfile ();
772 if (!f->tmp)
773 {
774 rc = CDK_File_Error;
775 break;
776 }
777 rc = f->fnct (f->opaque, f->ctl, s->fp, f->tmp);
778 _cdk_log_debug ("filter %s [read]: type=%d rc=%d\n",
779 s->fname ? s->fname : "[temp]", f->type, rc);
780 if (rc)
781 {
782 f->flags.error = 1;
783 break;
784 }
785
786 f->flags.error = 0;
787 /* If the filter is read-only, do not replace the FP because
788 the contents were not altered in any way. */
789 if (!f->flags.rdonly)
790 {
791 rc = stream_fp_replace (s, &f->tmp);
792 if (rc)
793 break;
794 }
795 else
796 {
797 fclose (f->tmp);
798 f->tmp = NULL;
799 }
800 rc = cdk_stream_seek (s, 0);
801 if (rc)
802 break;
803 /* Disable the filter after it was successfully used. The idea
804 is the following: let's say the armor filter was pushed and
805 later more filters were added. The second time the filter code
806 will be executed, only the new filter should be started but
807 not the old because we already used it. */
808 f->flags.enabled = 0;
809 }
810
811 return rc;
812}
813
814
815void *
816_cdk_stream_get_opaque (cdk_stream_t s, int fid)
817{
818 struct stream_filter_s *f;
819
820 if (!s)
821 return NULL;
822
823 for (f = s->filters; f; f = f->next)
824 {
825 if (f->type == fid)
826 return f->opaque;
827 }
828 return NULL;
829}
830
831
832/**
833 * cdk_stream_read: Try to read count bytes from the STREAM object.
834 * @s: The STREAM object.
835 * @buf: The buffer to insert the readed bytes.
836 * @count: Request so much bytes.
837 *
838 * When this function is called the first time, it can take a while
839 * because all filters need to be processed. Please remember that you
840 * need to add the filters in reserved order.
841 **/
842int
843cdk_stream_read (cdk_stream_t s, void *buf, size_t buflen)
844{
845 int nread;
846 int rc;
847
848 if (!s)
849 {
850 s->error = CDK_Inv_Value;
851 return EOF;
852 }
853
854 if (s->cbs_hd)
855 {
856 if (s->cbs.read)
857 return s->cbs.read (s->cbs_hd, buf, buflen);
858 return 0;
859 }
860
861 if (s->flags.write && !s->flags.temp)
862 {
863 s->error = CDK_Inv_Mode;
864 return EOF; /* This is a write stream */
865 }
866
867 if (!s->flags.no_filter && !s->cache.on && !s->flags.filtrated)
868 {
869 rc = stream_filter_read (s);
870 if (rc)
871 {
872 s->error = rc;
873 if (feof (s->fp))
874 s->flags.eof = 1;
875 return EOF;
876 }
877 s->flags.filtrated = 1;
878 }
879 if (!buf && !buflen)
880 return 0;
881 nread = fread (buf, 1, buflen, s->fp);
882 if (!nread)
883 nread = EOF;
884 if (feof (s->fp))
885 {
886 s->error = 0;
887 s->flags.eof = 1;
888 }
889 return nread;
890}
891
892
893int
894cdk_stream_getc (cdk_stream_t s)
895{
896 unsigned char buf[2];
897 int nread;
898
899 if (!s)
900 {
901 s->error = CDK_Inv_Value;
902 return EOF;
903 }
904 nread = cdk_stream_read (s, buf, 1);
905 if (nread == EOF)
906 {
907 s->error = CDK_File_Error;
908 return EOF;
909 }
910 return buf[0];
911}
912
913
914/**
915 * cdk_stream_write: Try to write count bytes into the stream.
916 * @s: The STREAM object
917 * @buf: The buffer with the values to write.
918 * @count: The size of the buffer.
919 *
920 * In this function we simply write the bytes to the stream. We can't
921 * use the filters here because it would mean they have to support
922 * partial flushing.
923 **/
924int
925cdk_stream_write (cdk_stream_t s, const void *buf, size_t count)
926{
927 int nwritten;
928
929 if (!s)
930 {
931 s->error = CDK_Inv_Value;
932 return EOF;
933 }
934
935 if (s->cbs_hd)
936 {
937 if (s->cbs.write)
938 return s->cbs.write (s->cbs_hd, buf, count);
939 return 0;
940 }
941
942 if (!s->flags.write)
943 {
944 s->error = CDK_Inv_Mode; /* this is a read stream */
945 return EOF;
946 }
947
948 if (!buf && !count)
949 return stream_flush (s);
950
951 if (s->cache.on)
952 {
953 /* We need to resize the buffer if the additional data wouldn't
954 fit into it. We allocate more memory to avoid to resize it the
955 next time the function is used. */
956 if (s->cache.size + count > s->cache.alloced)
957 {
958 byte *old = s->cache.buf;
959
960 s->cache.buf =
961 cdk_calloc (1, s->cache.alloced + count + STREAM_BUFSIZE);
962 s->cache.alloced += (count + STREAM_BUFSIZE);
963 memcpy (s->cache.buf, old, s->cache.size);
964 cdk_free (old);
965 _cdk_log_debug ("stream: enlarge cache to %d octets\n",
966 s->cache.alloced);
967 }
968 memcpy (s->cache.buf + s->cache.size, buf, count);
969 s->cache.size += count;
970 return count;
971 }
972
973 nwritten = fwrite (buf, 1, count, s->fp);
974 if (!nwritten)
975 nwritten = EOF;
976 return nwritten;
977}
978
979
980int
981cdk_stream_putc (cdk_stream_t s, int c)
982{
983 byte buf[2];
984 int nwritten;
985
986 if (!s)
987 {
988 s->error = CDK_Inv_Value;
989 return EOF;
990 }
991 buf[0] = c;
992 nwritten = cdk_stream_write (s, buf, 1);
993 if (nwritten == EOF)
994 return EOF;
995 return 0;
996}
997
998
999off_t
1000cdk_stream_tell (cdk_stream_t s)
1001{
1002 return s ? ftell (s->fp) : (off_t) - 1;
1003}
1004
1005
1006cdk_error_t
1007cdk_stream_seek (cdk_stream_t s, off_t offset)
1008{
1009 off_t len;
1010
1011 if (!s)
1012 return CDK_Inv_Value;
1013
1014 if (s->cbs_hd)
1015 {
1016 if (s->cbs.seek)
1017 return s->cbs.seek (s->cbs_hd, offset);
1018 return 0;
1019 }
1020
1021 /* Set or reset the EOF flag. */
1022 len = cdk_stream_get_length (s);
1023 if (len == offset)
1024 s->flags.eof = 1;
1025 else
1026 s->flags.eof = 0;
1027
1028 if (fseek (s->fp, offset, SEEK_SET))
1029 return CDK_File_Error;
1030 return 0;
1031}
1032
1033
1034static cdk_error_t
1035stream_flush (cdk_stream_t s)
1036{
1037 assert (s);
1038
1039 /* For some constellations it cannot be assured that the
1040 return value is defined, thus we ignore it for now. */
1041 (void) fflush (s->fp);
1042 return 0;
1043}
1044
1045
1046/**
1047 * cdk_stream_set_armor_flag:
1048 * @s: the stream object
1049 * @type: the type of armor to use
1050 *
1051 * If the file is in read-mode, no armor type needs to be
1052 * defined (armor_type=0) because the armor filter will be
1053 * used for decoding existing armor data.
1054 * For the write mode, @armor_type can be set to any valid
1055 * armor type (message, key, sig).
1056 **/
1057cdk_error_t
1058cdk_stream_set_armor_flag (cdk_stream_t s, int armor_type)
1059{
1060 struct stream_filter_s *f;
1061
1062 if (!s)
1063 return CDK_Inv_Value;
1064 f = filter_add (s, _cdk_filter_armor, fARMOR);
1065 if (!f)
1066 return CDK_Out_Of_Core;
1067 f->u.afx.idx = f->u.afx.idx2 = armor_type;
1068 f->ctl = stream_get_mode (s);
1069 return 0;
1070}
1071
1072
1073/**
1074 * cdk_stream_set_literal_flag:
1075 * @s: the stream object
1076 * @mode: the mode to use (binary, text, unicode)
1077 * @fname: the file name to store in the packet.
1078 *
1079 * In read mode it kicks off the literal decoding routine to
1080 * unwrap the data from the packet. The @mode parameter is ignored.
1081 * In write mode the function can be used to wrap the stream data
1082 * into a literal packet with the given mode and file name.
1083 **/
1084cdk_error_t
1085cdk_stream_set_literal_flag (cdk_stream_t s, cdk_lit_format_t mode,
1086 const char *fname)
1087{
1088 struct stream_filter_s *f;
1089 const char *orig_fname;
1090
1091 _cdk_log_debug ("stream: enable literal mode.\n");
1092
1093 if (!s)
1094 return CDK_Inv_Value;
1095
1096 orig_fname = _cdk_stream_get_fname (s);
1097 f = filter_add (s, _cdk_filter_literal, fLITERAL);
1098 if (!f)
1099 return CDK_Out_Of_Core;
1100 f->u.pfx.mode = mode;
1101 f->u.pfx.filename = fname ? cdk_strdup (fname) : NULL;
1102 f->u.pfx.orig_filename = orig_fname ? cdk_strdup (orig_fname) : NULL;
1103 f->ctl = stream_get_mode (s);
1104 if (s->blkmode > 0)
1105 {
1106 f->u.pfx.blkmode.on = 1;
1107 f->u.pfx.blkmode.size = s->blkmode;
1108 }
1109 return 0;
1110}
1111
1112
1113/**
1114 * cdk_stream_set_cipher_flag:
1115 * @s: the stream object
1116 * @dek: the data encryption key
1117 * @use_mdc: 1 means to use the MDC mode
1118 *
1119 * In read mode it kicks off the cipher filter to decrypt the data
1120 * from the stream with the key given in @dek.
1121 * In write mode the stream data will be encrypted with the DEK object
1122 * and optionally, the @use_mdc parameter can be used to enable the MDC mode.
1123 **/
1124cdk_error_t
1125cdk_stream_set_cipher_flag (cdk_stream_t s, cdk_dek_t dek, int use_mdc)
1126{
1127 struct stream_filter_s *f;
1128
1129 _cdk_log_debug ("stream: enable cipher mode\n");
1130 if (!s)
1131 return CDK_Inv_Value;
1132 f = filter_add (s, _cdk_filter_cipher, fCIPHER);
1133 if (!f)
1134 return CDK_Out_Of_Core;
1135 dek->use_mdc = use_mdc;
1136 f->ctl = stream_get_mode (s);
1137 f->u.cfx.dek = dek;
1138 f->u.cfx.mdc_method = use_mdc ? GCRY_MD_SHA1 : 0;
1139 if (s->blkmode > 0)
1140 {
1141 f->u.cfx.blkmode.on = 1;
1142 f->u.cfx.blkmode.size = s->blkmode;
1143 }
1144 return 0;
1145}
1146
1147
1148/**
1149 * cdk_stream_set_compress_flag:
1150 * @s: the stream object
1151 * @algo: the compression algo
1152 * @level: level of compression (0..9)
1153 *
1154 * In read mode it kicks off the decompression filter to retrieve
1155 * the uncompressed data.
1156 * In write mode the stream data will be compressed with the
1157 * given algorithm at the given level.
1158 **/
1159cdk_error_t
1160cdk_stream_set_compress_flag (cdk_stream_t s, int algo, int level)
1161{
1162 struct stream_filter_s *f;
1163
1164 if (!s)
1165 return CDK_Inv_Value;
1166 f = filter_add (s, _cdk_filter_compress, fCOMPRESS);
1167 if (!f)
1168 return CDK_Out_Of_Core;
1169 f->ctl = stream_get_mode (s);
1170 f->u.zfx.algo = algo;
1171 f->u.zfx.level = level;
1172 return 0;
1173}
1174
1175
1176/**
1177 * cdk_stream_set_text_flag:
1178 * @s: the stream object
1179 * @lf: line ending
1180 *
1181 * Pushes the text filter to store the stream data in cannoncial format.
1182 **/
1183cdk_error_t
1184cdk_stream_set_text_flag (cdk_stream_t s, const char *lf)
1185{
1186 struct stream_filter_s *f;
1187
1188 if (!s)
1189 return CDK_Inv_Value;
1190 f = filter_add (s, _cdk_filter_text, fTEXT);
1191 if (!f)
1192 return CDK_Out_Of_Core;
1193 f->ctl = stream_get_mode (s);
1194 f->u.tfx.lf = lf;
1195 return 0;
1196}
1197
1198
1199/**
1200 * cdk_stream_set_hash_flag:
1201 * @s: the stream object
1202 * @digest_algo: the digest algorithm to use
1203 *
1204 * This is for read-only streams. It pushes a digest filter to
1205 * calculate the digest of the given stream data.
1206 **/
1207cdk_error_t
1208cdk_stream_set_hash_flag (cdk_stream_t s, int digest_algo)
1209{
1210 struct stream_filter_s *f;
1211
1212 if (!s)
1213 return CDK_Inv_Value;
1214 if (stream_get_mode (s))
1215 return CDK_Inv_Mode;
1216 f = filter_add (s, _cdk_filter_hash, fHASH);
1217 if (!f)
1218 return CDK_Out_Of_Core;
1219 f->ctl = stream_get_mode (s);
1220 f->u.mfx.digest_algo = digest_algo;
1221 f->flags.rdonly = 1;
1222 return 0;
1223}
1224
1225
1226/**
1227 * cdk_stream_enable_cache:
1228 * @s: the stream object
1229 * @val: 1=on, 0=off
1230 *
1231 * Enable or disable the cache section of a stream object.
1232 **/
1233cdk_error_t
1234cdk_stream_enable_cache (cdk_stream_t s, int val)
1235{
1236 if (!s)
1237 return CDK_Inv_Value;
1238 if (!s->flags.write)
1239 return CDK_Inv_Mode;
1240 s->cache.on = val;
1241 if (!s->cache.buf)
1242 {
1243 s->cache.buf = cdk_calloc (1, STREAM_BUFSIZE);
1244 s->cache.alloced = STREAM_BUFSIZE;
1245 _cdk_log_debug ("stream: allocate cache of %d octets\n",
1246 STREAM_BUFSIZE);
1247 }
1248 return 0;
1249}
1250
1251
1252static int
1253stream_cache_flush (cdk_stream_t s, FILE * fp)
1254{
1255 int nwritten;
1256
1257 assert (s);
1258
1259 /* FIXME: We should find a way to use cdk_stream_write here. */
1260 if (s->cache.size > 0)
1261 {
1262 nwritten = fwrite (s->cache.buf, 1, s->cache.size, fp);
1263 if (!nwritten)
1264 return CDK_File_Error;
1265 s->cache.size = 0;
1266 s->cache.on = 0;
1267 wipemem (s->cache.buf, s->cache.alloced);
1268 }
1269 return 0;
1270}
1271
1272
1273/**
1274 * cdk_stream_kick_off:
1275 * @inp: the input stream
1276 * @out: the output stream.
1277 *
1278 * Passes the entire data from @inp into the output stream @out
1279 * with all the activated filters.
1280 */
1281cdk_error_t
1282cdk_stream_kick_off (cdk_stream_t inp, cdk_stream_t out)
1283{
1284 byte buf[BUFSIZE];
1285 int nread, nwritten;
1286 cdk_error_t rc;
1287
1288 if (!inp || !out)
1289 return CDK_Inv_Value;
1290 rc = CDK_Success;
1291 while (!cdk_stream_eof (inp))
1292 {
1293 nread = cdk_stream_read (inp, buf, DIM (buf));
1294 if (!nread || nread == EOF)
1295 break;
1296 nwritten = cdk_stream_write (out, buf, nread);
1297 if (!nwritten || nwritten == EOF)
1298 { /* In case of errors, we leave the loop. */
1299 rc = inp->error;
1300 break;
1301 }
1302 }
1303
1304 wipemem (buf, sizeof (buf));
1305 return rc;
1306}
1307
1308
1309/**
1310 * cdk_stream_mmap_part:
1311 * @s: the stream
1312 * @off: the offset where to start
1313 * @len: how much bytes shall be mapped
1314 * @ret_buf: the buffer to store the content
1315 * @ret_buflen: length of the buffer
1316 *
1317 * Map the data of the given stream into a memory section. @ret_count
1318 * contains the length of the buffer.
1319 **/
1320cdk_error_t
1321cdk_stream_mmap_part (cdk_stream_t s, off_t off, size_t len,
1322 byte ** ret_buf, size_t * ret_buflen)
1323{
1324 off_t oldpos;
1325 int n;
1326 cdk_error_t rc;
1327
1328 if (!s || !ret_buf || !ret_buflen)
1329 return CDK_Inv_Value;
1330 if (s->cbs_hd)
1331 return CDK_Inv_Mode;
1332
1333 *ret_buflen = 0;
1334 *ret_buf = NULL;
1335 oldpos = cdk_stream_tell (s);
1336 rc = cdk_stream_flush (s);
1337 if (!rc)
1338 rc = cdk_stream_seek (s, off);
1339 if (rc)
1340 return rc;
1341 if (!len)
1342 len = cdk_stream_get_length (s);
1343 if (!len || len > MAX_MAP_SIZE)
1344 return 0;
1345 *ret_buf = cdk_calloc (1, len + 1);
1346 *ret_buflen = len;
1347 n = cdk_stream_read (s, *ret_buf, len);
1348 if (n != len)
1349 *ret_buflen = n;
1350 rc = cdk_stream_seek (s, oldpos);
1351 return rc;
1352}
1353
1354
1355cdk_error_t
1356cdk_stream_mmap (cdk_stream_t inp, byte ** buf, size_t * buflen)
1357{
1358 off_t len;
1359
1360 /* We need to make sure all data is flushed before we retrieve the size. */
1361 cdk_stream_flush (inp);
1362 len = cdk_stream_get_length (inp);
1363 return cdk_stream_mmap_part (inp, 0, len, buf, buflen);
1364}
1365
1366
1367/**
1368 * cdk_stream_peek:
1369 * @inp: the input stream handle
1370 * @s: buffer
1371 * @count: number of bytes to peek
1372 *
1373 * The function acts like cdk_stream_read with the difference that
1374 * the file pointer is moved to the old position after the bytes were read.
1375 **/
1376int
1377cdk_stream_peek (cdk_stream_t inp, byte * buf, size_t buflen)
1378{
1379 off_t off;
1380 int nbytes;
1381
1382 if (!inp || !buf)
1383 return 0;
1384 if (inp->cbs_hd)
1385 return 0;
1386
1387 off = cdk_stream_tell (inp);
1388 nbytes = cdk_stream_read (inp, buf, buflen);
1389 if (nbytes == -1)
1390 return 0;
1391 if (cdk_stream_seek (inp, off))
1392 return 0;
1393 return nbytes;
1394}
1395
1396
1397/* Try to read a line from the given stream. */
1398int
1399_cdk_stream_gets (cdk_stream_t s, char *buf, size_t count)
1400{
1401 int c, i;
1402
1403 assert (s);
1404
1405 i = 0;
1406 while (!cdk_stream_eof (s) && count > 0)
1407 {
1408 c = cdk_stream_getc (s);
1409 if (c == EOF || c == '\r' || c == '\n')
1410 {
1411 buf[i++] = '\0';
1412 break;
1413 }
1414 buf[i++] = c;
1415 count--;
1416 }
1417 return i;
1418}
1419
1420
1421/* Try to write string into the stream @s. */
1422int
1423_cdk_stream_puts (cdk_stream_t s, const char *buf)
1424{
1425 return cdk_stream_write (s, buf, strlen (buf));
1426}
1427
1428
1429/* Activate the block mode for the given stream. */
1430cdk_error_t
1431_cdk_stream_set_blockmode (cdk_stream_t s, size_t nbytes)
1432{
1433 assert (s);
1434
1435 _cdk_log_debug ("stream: activate block mode with blocksize %d\n", nbytes);
1436 s->blkmode = nbytes;
1437 return 0;
1438}
1439
1440
1441/* Return the block mode state of the given stream. */
1442int
1443_cdk_stream_get_blockmode (cdk_stream_t s)
1444{
1445 return s ? s->blkmode : 0;
1446}
diff --git a/src/daemon/https/opencdk/stream.h b/src/daemon/https/opencdk/stream.h
new file mode 100644
index 00000000..df44c6c6
--- /dev/null
+++ b/src/daemon/https/opencdk/stream.h
@@ -0,0 +1,88 @@
1/* stream.h - internal definiton for the STREAM object
2 * Copyright (C) 2002, 2003, 2007 Timo Schulz
3 *
4 * This file is part of OpenCDK.
5 *
6 * OpenCDK is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * OpenCDK is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16#ifndef CDK_STREAM_H
17#define CDK_STREAM_H
18
19/* The default buffer size for the stream. */
20#define STREAM_BUFSIZE 8192
21
22enum {
23 fDUMMY = 0,
24 fARMOR = 1,
25 fCIPHER = 2,
26 fLITERAL = 3,
27 fCOMPRESS= 4,
28 fHASH = 5,
29 fTEXT = 6
30};
31
32/* Type definition for the filter function. */
33typedef int (*filter_fnct_t) (void * opaque, int ctl, FILE * in, FILE * out);
34
35/* The stream filter context structure. */
36struct stream_filter_s
37{
38 struct stream_filter_s *next;
39 filter_fnct_t fnct;
40 void *opaque;
41 FILE *tmp;
42 union {
43 armor_filter_t afx;
44 cipher_filter_t cfx;
45 literal_filter_t pfx;
46 compress_filter_t zfx;
47 text_filter_t tfx;
48 md_filter_t mfx;
49 } u;
50 struct {
51 unsigned enabled:1;
52 unsigned rdonly:1;
53 unsigned error:1;
54 } flags;
55 unsigned type;
56 unsigned ctl;
57};
58
59
60/* The stream context structure. */
61struct cdk_stream_s {
62 struct stream_filter_s *filters;
63 int fmode;
64 int error;
65 size_t blkmode;
66 struct {
67 unsigned filtrated:1;
68 unsigned eof:1;
69 unsigned write:1;
70 unsigned temp:1;
71 unsigned reset:1;
72 unsigned no_filter:1;
73 unsigned compressed:3;
74 } flags;
75 struct {
76 unsigned char *buf;
77 unsigned on:1;
78 size_t size;
79 size_t alloced;
80 } cache;
81 char *fname;
82 FILE *fp;
83 unsigned int fp_ref:1;
84 struct cdk_stream_cbs_s cbs;
85 void *cbs_hd;
86};
87
88#endif /* CDK_STREAM_H */
diff --git a/src/daemon/https/opencdk/types.h b/src/daemon/https/opencdk/types.h
new file mode 100644
index 00000000..c53a0850
--- /dev/null
+++ b/src/daemon/https/opencdk/types.h
@@ -0,0 +1,44 @@
1/* types.h - Some type definitions
2 * Copyright (C) 2002, 2003, 2007 Timo Schulz
3 *
4 * This file is part of OpenCDK.
5 *
6 * OpenCDK is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * OpenCDK is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16#ifndef CDK_TYPES_H
17#define CDK_TYPES_H
18
19#include <gcrypt.h>
20
21#ifndef HAVE_BYTE_TYPEDEF
22# undef byte
23 typedef unsigned char byte;
24# define HAVE_BYTE_TYPEDEF
25#endif
26
27#ifndef HAVE_U16_TYPEDEF
28# undef u16
29 typedef unsigned short u16;
30# define HAVE_U16_TYPEDEF
31#endif
32
33#ifndef HAVE_U32_TYPEDEF
34# undef u32
35 typedef unsigned int u32;
36# define HAVE_U32_TYPEDEF
37#endif
38
39#ifndef DIM
40# define DIM(v) (sizeof (v)/sizeof ((v)[0]))
41# define DIMof(type, member) DIM(((type *)0)->member)
42#endif
43
44#endif /* CDK_TYPES_H */
diff --git a/src/daemon/https/opencdk/verify.c b/src/daemon/https/opencdk/verify.c
new file mode 100644
index 00000000..71b4c237
--- /dev/null
+++ b/src/daemon/https/opencdk/verify.c
@@ -0,0 +1,306 @@
1/* verify.c - Verify signatures
2 * Copyright (C) 2001, 2002, 2003, 2007 Timo Schulz
3 *
4 * This file is part of OpenCDK.
5 *
6 * OpenCDK is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * OpenCDK is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16#ifdef HAVE_CONFIG_H
17# include <config.h>
18#endif
19#include <stdio.h>
20#include <string.h>
21#include <assert.h>
22#include <sys/stat.h>
23
24#include "opencdk.h"
25#include "main.h"
26#include "filters.h"
27#include "packet.h"
28
29
30/* Table of all supported digest algorithms and their names. */
31struct
32{
33 const char *name;
34 int algo;
35} digest_table[] =
36{
37 {
38 "MD5", GCRY_MD_MD5},
39 {
40 "SHA1", GCRY_MD_SHA1},
41 {
42 "RIPEMD160", GCRY_MD_RMD160},
43 {
44 "SHA256", GCRY_MD_SHA256},
45 {
46 "SHA384", GCRY_MD_SHA384},
47 {
48 "SHA512", GCRY_MD_SHA512},
49 {
50 NULL, 0}
51};
52
53
54static int file_verify_clearsign (cdk_ctx_t, const char *, const char *);
55
56
57/**
58 * cdk_stream_verify:
59 * @hd: session handle
60 * @inp: the input stream
61 * @data: for detached signatures, this is the data stream @inp is the sig
62 * @out: where the output shall be written.
63 */
64cdk_error_t
65cdk_stream_verify (cdk_ctx_t hd, cdk_stream_t inp, cdk_stream_t data,
66 cdk_stream_t out)
67{
68 /* FIXME: out is not currently used. */
69 if (cdk_armor_filter_use (inp))
70 cdk_stream_set_armor_flag (inp, 0);
71 return _cdk_proc_packets (hd, inp, data, NULL, NULL, NULL);
72}
73
74
75/**
76 * cdk_file_verify:
77 * @hd: the session handle
78 * @file: the input file
79 * @data_file: for detached signature this is the data file and @file is the sig.
80 * @output: the output file
81 *
82 * Verify a signature.
83 **/
84cdk_error_t
85cdk_file_verify (cdk_ctx_t hd, const char *file, const char *data_file,
86 const char *output)
87{
88 struct stat stbuf;
89 cdk_stream_t inp, data;
90 char buf[4096];
91 int n;
92 cdk_error_t rc;
93
94 if (!hd || !file)
95 return CDK_Inv_Value;
96 if (output && !hd->opt.overwrite && !stat (output, &stbuf))
97 return CDK_Inv_Mode;
98
99 rc = cdk_stream_open (file, &inp);
100 if (rc)
101 return rc;
102 if (cdk_armor_filter_use (inp))
103 {
104 n = cdk_stream_peek (inp, (byte *) buf, DIM (buf) - 1);
105 if (!n || n == -1)
106 return CDK_EOF;
107 buf[n] = '\0';
108 if (strstr (buf, "BEGIN PGP SIGNED MESSAGE"))
109 {
110 cdk_stream_close (inp);
111 return file_verify_clearsign (hd, file, output);
112 }
113 cdk_stream_set_armor_flag (inp, 0);
114 }
115
116 if (data_file)
117 {
118 rc = cdk_stream_open (data_file, &data);
119 if (rc)
120 {
121 cdk_stream_close (inp);
122 return rc;
123 }
124 }
125 else
126 data = NULL;
127
128 rc = _cdk_proc_packets (hd, inp, data, NULL, NULL, NULL);
129
130 if (data != NULL)
131 cdk_stream_close (data);
132 cdk_stream_close (inp);
133 return rc;
134}
135
136
137void
138_cdk_result_verify_free (cdk_verify_result_t res)
139{
140 if (!res)
141 return;
142 cdk_free (res->policy_url);
143 cdk_free (res->sig_data);
144 cdk_free (res);
145}
146
147
148cdk_verify_result_t
149_cdk_result_verify_new (void)
150{
151 cdk_verify_result_t res;
152
153 res = cdk_calloc (1, sizeof *res);
154 if (!res)
155 return NULL;
156 return res;
157}
158
159
160static cdk_error_t
161file_verify_clearsign (cdk_ctx_t hd, const char *file, const char *output)
162{
163 cdk_stream_t inp = NULL, out = NULL, tmp = NULL;
164 gcry_md_hd_t md = NULL;
165 char buf[512], chk[512];
166 const char *s;
167 int i, is_signed = 0, nbytes;
168 int digest_algo = 0;
169 gcry_error_t err;
170 cdk_error_t rc;
171
172 if (output)
173 {
174 rc = cdk_stream_create (output, &out);
175 if (rc)
176 return rc;
177 }
178
179 rc = cdk_stream_open (file, &inp);
180 if (rc)
181 {
182 if (output)
183 cdk_stream_close (out);
184 return rc;
185 }
186
187 s = "-----BEGIN PGP SIGNED MESSAGE-----";
188 while (!cdk_stream_eof (inp))
189 {
190 nbytes = _cdk_stream_gets (inp, buf, DIM (buf) - 1);
191 if (!nbytes || nbytes == -1)
192 break;
193 if (!strncmp (buf, s, strlen (s)))
194 {
195 is_signed = 1;
196 break;
197 }
198 }
199
200 if (cdk_stream_eof (inp) && !is_signed)
201 {
202 rc = CDK_Armor_Error;
203 goto leave;
204 }
205
206 while (!cdk_stream_eof (inp))
207 {
208 nbytes = _cdk_stream_gets (inp, buf, DIM (buf) - 1);
209 if (!nbytes || nbytes == -1)
210 break;
211 if (nbytes == 1) /* Empty line */
212 break;
213 else if (!strncmp (buf, "Hash: ", 6))
214 {
215 for (i = 0; digest_table[i].name; i++)
216 {
217 if (!strcmp (buf + 6, digest_table[i].name))
218 {
219 digest_algo = digest_table[i].algo;
220 break;
221 }
222 }
223 }
224 }
225
226 if (digest_algo && gcry_md_test_algo (digest_algo))
227 {
228 rc = CDK_Inv_Algo;
229 goto leave;
230 }
231
232 if (!digest_algo)
233 digest_algo = GCRY_MD_MD5;
234
235 err = gcry_md_open (&md, digest_algo, 0);
236 if (err)
237 {
238 rc = map_gcry_error (err);
239 goto leave;
240 }
241
242 s = "-----BEGIN PGP SIGNATURE-----";
243 while (!cdk_stream_eof (inp))
244 {
245 nbytes = _cdk_stream_gets (inp, buf, DIM (buf) - 1);
246 if (!nbytes || nbytes == -1)
247 break;
248 if (!strncmp (buf, s, strlen (s)))
249 break;
250 else
251 {
252 cdk_stream_peek (inp, (byte *) chk, DIM (chk) - 1);
253 i = strncmp (chk, s, strlen (s));
254 if (strlen (buf) == 0 && i == 0)
255 continue; /* skip last '\n' */
256 _cdk_trim_string (buf, i == 0 ? 0 : 1);
257 gcry_md_write (md, buf, strlen (buf));
258 }
259 if (!strncmp (buf, "- ", 2)) /* FIXME: handle it recursive. */
260 memmove (buf, buf + 2, nbytes - 2);
261 if (out)
262 {
263 if (strstr (buf, "\r\n"))
264 buf[strlen (buf) - 2] = '\0';
265 cdk_stream_write (out, buf, strlen (buf));
266 _cdk_stream_puts (out, _cdk_armor_get_lineend ());
267 }
268 }
269
270 /* We create a temporary stream object to store the
271 signature data in there. */
272 rc = cdk_stream_tmp_new (&tmp);
273 if (rc)
274 goto leave;
275
276 s = "-----BEGIN PGP SIGNATURE-----\n";
277 _cdk_stream_puts (tmp, s);
278 while (!cdk_stream_eof (inp))
279 {
280 nbytes = _cdk_stream_gets (inp, buf, DIM (buf) - 1);
281 if (!nbytes || nbytes == -1)
282 break;
283 if (nbytes < (DIM (buf) - 3))
284 {
285 buf[nbytes - 1] = '\n';
286 buf[nbytes] = '\0';
287 }
288 cdk_stream_write (tmp, buf, nbytes);
289 }
290
291 /* FIXME: This code is not very elegant. */
292 cdk_stream_tmp_set_mode (tmp, STREAMCTL_READ);
293 cdk_stream_seek (tmp, 0);
294 cdk_stream_set_armor_flag (tmp, 0);
295 cdk_stream_read (tmp, NULL, 0);
296
297 /* the digest handle will be closed there. */
298 rc = _cdk_proc_packets (hd, tmp, NULL, NULL, NULL, md);
299
300leave:
301 gcry_md_close (md);
302 cdk_stream_close (out);
303 cdk_stream_close (tmp);
304 cdk_stream_close (inp);
305 return rc;
306}
diff --git a/src/daemon/https/opencdk/write-packet.c b/src/daemon/https/opencdk/write-packet.c
new file mode 100644
index 00000000..46d239dd
--- /dev/null
+++ b/src/daemon/https/opencdk/write-packet.c
@@ -0,0 +1,947 @@
1/* write-packet.c - Write OpenPGP packets
2 * Copyright (C) 2001, 2002, 2003, 2007 Timo Schulz
3 *
4 * This file is part of OpenCDK.
5 *
6 * OpenCDK is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * OpenCDK is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19#include <string.h>
20#include <stdio.h>
21#include <assert.h>
22
23#include "opencdk.h"
24#include "main.h"
25
26
27static int
28stream_write (cdk_stream_t s, const void *buf, size_t buflen)
29{
30 int nwritten;
31
32 nwritten = cdk_stream_write (s, buf, buflen);
33 if (nwritten == EOF)
34 return _cdk_stream_get_errno (s);
35 return 0;
36}
37
38
39static int
40stream_read (cdk_stream_t s, void *buf, size_t buflen, size_t * r_nread)
41{
42 int nread;
43
44 assert (r_nread);
45
46 nread = cdk_stream_read (s, buf, buflen);
47 if (nread == EOF)
48 return _cdk_stream_get_errno (s);
49 *r_nread = nread;
50 return 0;
51}
52
53
54static int
55stream_putc (cdk_stream_t s, int c)
56{
57 int nwritten = cdk_stream_putc (s, c);
58 if (nwritten == EOF)
59 return _cdk_stream_get_errno (s);
60 return 0;
61}
62
63
64static int
65write_32 (cdk_stream_t out, u32 u)
66{
67 byte buf[4];
68
69 buf[0] = u >> 24;
70 buf[1] = u >> 16;
71 buf[2] = u >> 8;
72 buf[3] = u;
73 return stream_write (out, buf, 4);
74}
75
76
77static int
78write_16 (cdk_stream_t out, u16 u)
79{
80 byte buf[2];
81
82 buf[0] = u >> 8;
83 buf[1] = u;
84 return stream_write (out, buf, 2);
85}
86
87
88static size_t
89calc_mpisize (gcry_mpi_t mpi[MAX_CDK_PK_PARTS], size_t ncount)
90{
91 size_t size, i;
92
93 size = 0;
94 for (i = 0; i < ncount; i++)
95 size += (gcry_mpi_get_nbits (mpi[i]) + 7) / 8 + 2;
96 return size;
97}
98
99
100static int
101write_mpi (cdk_stream_t out, gcry_mpi_t m)
102{
103 byte buf[MAX_MPI_BYTES + 2];
104 size_t nbits, nread;
105 gcry_error_t err;
106
107 if (!out || !m)
108 return CDK_Inv_Value;
109 nbits = gcry_mpi_get_nbits (m);
110 if (nbits > MAX_MPI_BITS || nbits < 1)
111 return CDK_MPI_Error;
112 err = gcry_mpi_print (GCRYMPI_FMT_PGP, buf, MAX_MPI_BYTES + 2, &nread, m);
113 if (err)
114 return map_gcry_error (err);
115 return stream_write (out, buf, nread);
116}
117
118
119static cdk_error_t
120write_mpibuf (cdk_stream_t out, gcry_mpi_t mpi[MAX_CDK_PK_PARTS],
121 size_t count)
122{
123 size_t i;
124 cdk_error_t rc;
125
126 for (i = 0; i < count; i++)
127 {
128 rc = write_mpi (out, mpi[i]);
129 if (rc)
130 return rc;
131 }
132 return 0;
133}
134
135
136static cdk_error_t
137pkt_encode_len (cdk_stream_t out, size_t pktlen)
138{
139 cdk_error_t rc;
140
141 assert (out);
142
143 rc = 0;
144 if (!pktlen)
145 {
146 /* Block mode, partial bodies, with 'DEF_BLOCKSIZE' from main.h */
147 rc = stream_putc (out, (0xE0 | DEF_BLOCKBITS));
148 }
149 else if (pktlen < 192)
150 rc = stream_putc (out, pktlen);
151 else if (pktlen < 8384)
152 {
153 pktlen -= 192;
154 rc = stream_putc (out, (pktlen / 256) + 192);
155 if (!rc)
156 rc = stream_putc (out, (pktlen % 256));
157 }
158 else
159 {
160 rc = stream_putc (out, 255);
161 if (!rc)
162 rc = write_32 (out, pktlen);
163 }
164
165 return rc;
166}
167
168
169static cdk_error_t
170write_head_new (cdk_stream_t out, size_t size, int type)
171{
172 cdk_error_t rc;
173
174 assert (out);
175
176 if (type < 0 || type > 63)
177 return CDK_Inv_Packet;
178 rc = stream_putc (out, (0xC0 | type));
179 if (!rc)
180 rc = pkt_encode_len (out, size);
181 return rc;
182}
183
184
185static cdk_error_t
186write_head_old (cdk_stream_t out, size_t size, int type)
187{
188 cdk_error_t rc;
189 int ctb;
190
191 assert (out);
192
193 if (type < 0 || type > 16)
194 return CDK_Inv_Packet;
195 ctb = 0x80 | (type << 2);
196 if (!size)
197 ctb |= 3;
198 else if (size < 256)
199 ;
200 else if (size < 65536)
201 ctb |= 1;
202 else
203 ctb |= 2;
204 rc = stream_putc (out, ctb);
205 if (!size)
206 return rc;
207 if (!rc)
208 {
209 if (size < 256)
210 rc = stream_putc (out, size);
211 else if (size < 65536)
212 rc = write_16 (out, size);
213 else
214 rc = write_32 (out, size);
215 }
216
217 return rc;
218}
219
220
221/* Write special PGP2 packet header. PGP2 (wrongly) uses two byte header
222 length for signatures and keys even if the size is < 256. */
223static cdk_error_t
224pkt_write_head2 (cdk_stream_t out, size_t size, int type)
225{
226 cdk_error_t rc;
227
228 rc = cdk_stream_putc (out, 0x80 | (type << 2) | 1);
229 if (!rc)
230 rc = cdk_stream_putc (out, size >> 8);
231 if (!rc)
232 rc = cdk_stream_putc (out, size & 0xff);
233 return rc;
234}
235
236
237static int
238pkt_write_head (cdk_stream_t out, int old_ctb, size_t size, int type)
239{
240 if (old_ctb)
241 return write_head_old (out, size, type);
242 return write_head_new (out, size, type);
243}
244
245
246static cdk_error_t
247write_encrypted (cdk_stream_t out, cdk_pkt_encrypted_t enc, int old_ctb)
248{
249 size_t nbytes;
250 cdk_error_t rc;
251
252 assert (out);
253 assert (enc);
254
255 if (DEBUG_PKT)
256 _cdk_log_debug ("write_encrypted: %lu bytes\n", enc->len);
257
258 nbytes = enc->len ? (enc->len + enc->extralen) : 0;
259 rc = pkt_write_head (out, old_ctb, nbytes, CDK_PKT_ENCRYPTED);
260 /* The rest of the packet is ciphertext */
261 return rc;
262}
263
264
265static int
266write_encrypted_mdc (cdk_stream_t out, cdk_pkt_encrypted_t enc)
267{
268 size_t nbytes;
269 cdk_error_t rc;
270
271 assert (out);
272 assert (enc);
273
274 if (!enc->mdc_method)
275 return CDK_Inv_Packet;
276
277 if (DEBUG_PKT)
278 _cdk_log_debug ("write_encrypted_mdc: %lu bytes\n", enc->len);
279
280 nbytes = enc->len ? (enc->len + enc->extralen + 1) : 0;
281 rc = pkt_write_head (out, 0, nbytes, CDK_PKT_ENCRYPTED_MDC);
282 if (!rc)
283 rc = stream_putc (out, 1); /* version */
284 /* The rest of the packet is ciphertext */
285 return rc;
286}
287
288
289static cdk_error_t
290write_symkey_enc (cdk_stream_t out, cdk_pkt_symkey_enc_t ske)
291{
292 cdk_s2k_t s2k;
293 size_t size = 0, s2k_size = 0;
294 cdk_error_t rc;
295
296 assert (out);
297 assert (ske);
298
299 if (ske->version != 4)
300 return CDK_Inv_Packet;
301
302 if (DEBUG_PKT)
303 _cdk_log_debug ("write_symkey_enc:\n");
304
305 s2k = ske->s2k;
306 if (s2k->mode == CDK_S2K_SALTED || s2k->mode == CDK_S2K_ITERSALTED)
307 s2k_size = 8;
308 if (s2k->mode == CDK_S2K_ITERSALTED)
309 s2k_size++;
310 size = 4 + s2k_size + ske->seskeylen;
311 rc = pkt_write_head (out, 0, size, CDK_PKT_SYMKEY_ENC);
312 if (!rc)
313 rc = stream_putc (out, ske->version);
314 if (!rc)
315 rc = stream_putc (out, ske->cipher_algo);
316 if (!rc)
317 rc = stream_putc (out, s2k->mode);
318 if (!rc)
319 rc = stream_putc (out, s2k->hash_algo);
320 if (s2k->mode == CDK_S2K_SALTED || s2k->mode == CDK_S2K_ITERSALTED)
321 {
322 rc = stream_write (out, s2k->salt, 8);
323 if (!rc)
324 {
325 if (s2k->mode == CDK_S2K_ITERSALTED)
326 rc = stream_putc (out, s2k->count);
327 }
328 }
329 return rc;
330}
331
332
333static int
334write_pubkey_enc (cdk_stream_t out, cdk_pkt_pubkey_enc_t pke, int old_ctb)
335{
336 size_t size;
337 int rc, nenc;
338
339 assert (out);
340 assert (pke);
341
342 if (pke->version < 2 || pke->version > 3)
343 return CDK_Inv_Packet;
344 if (!KEY_CAN_ENCRYPT (pke->pubkey_algo))
345 return CDK_Inv_Algo;
346
347 if (DEBUG_PKT)
348 _cdk_log_debug ("write_pubkey_enc:\n");
349
350 nenc = cdk_pk_get_nenc (pke->pubkey_algo);
351 size = 10 + calc_mpisize (pke->mpi, nenc);
352 rc = pkt_write_head (out, old_ctb, size, CDK_PKT_PUBKEY_ENC);
353 if (rc)
354 return rc;
355
356 rc = stream_putc (out, pke->version);
357 if (!rc)
358 rc = write_32 (out, pke->keyid[0]);
359 if (!rc)
360 rc = write_32 (out, pke->keyid[1]);
361 if (!rc)
362 rc = stream_putc (out, pke->pubkey_algo);
363 if (!rc)
364 rc = write_mpibuf (out, pke->mpi, nenc);
365 return rc;
366}
367
368
369static cdk_error_t
370write_mdc (cdk_stream_t out, cdk_pkt_mdc_t mdc)
371{
372 cdk_error_t rc;
373
374 assert (mdc);
375 assert (out);
376
377 if (DEBUG_PKT)
378 _cdk_log_debug ("write_mdc:\n");
379
380 /* This packet requires a fixed header encoding */
381 rc = stream_putc (out, 0xD3); /* packet ID and 1 byte length */
382 if (!rc)
383 rc = stream_putc (out, 0x14);
384 if (!rc)
385 rc = stream_write (out, mdc->hash, DIM (mdc->hash));
386 return rc;
387}
388
389
390static size_t
391calc_subpktsize (cdk_subpkt_t s)
392{
393 size_t nbytes;
394
395 /* In the count mode, no buffer is returned. */
396 _cdk_subpkt_get_array (s, 1, &nbytes);
397 return nbytes;
398}
399
400
401static cdk_error_t
402write_v3_sig (cdk_stream_t out, cdk_pkt_signature_t sig, int nsig)
403{
404 size_t size;
405 cdk_error_t rc;
406
407 size = 19 + calc_mpisize (sig->mpi, nsig);
408 if (is_RSA (sig->pubkey_algo))
409 rc = pkt_write_head2 (out, size, CDK_PKT_SIGNATURE);
410 else
411 rc = pkt_write_head (out, 1, size, CDK_PKT_SIGNATURE);
412 if (!rc)
413 rc = stream_putc (out, sig->version);
414 if (!rc)
415 rc = stream_putc (out, 5);
416 if (!rc)
417 rc = stream_putc (out, sig->sig_class);
418 if (!rc)
419 rc = write_32 (out, sig->timestamp);
420 if (!rc)
421 rc = write_32 (out, sig->keyid[0]);
422 if (!rc)
423 rc = write_32 (out, sig->keyid[1]);
424 if (!rc)
425 rc = stream_putc (out, sig->pubkey_algo);
426 if (!rc)
427 rc = stream_putc (out, sig->digest_algo);
428 if (!rc)
429 rc = stream_putc (out, sig->digest_start[0]);
430 if (!rc)
431 rc = stream_putc (out, sig->digest_start[1]);
432 if (!rc)
433 rc = write_mpibuf (out, sig->mpi, nsig);
434 return rc;
435}
436
437
438static cdk_error_t
439write_signature (cdk_stream_t out, cdk_pkt_signature_t sig, int old_ctb)
440{
441 byte *buf;
442 size_t nbytes, size, nsig;
443 cdk_error_t rc;
444
445 assert (out);
446 assert (sig);
447
448 if (!KEY_CAN_SIGN (sig->pubkey_algo))
449 return CDK_Inv_Algo;
450 if (sig->version < 2 || sig->version > 4)
451 return CDK_Inv_Packet;
452
453 if (DEBUG_PKT)
454 _cdk_log_debug ("write_signature:\n");
455
456 nsig = cdk_pk_get_nsig (sig->pubkey_algo);
457 if (!nsig)
458 return CDK_Inv_Algo;
459 if (sig->version < 4)
460 return write_v3_sig (out, sig, nsig);
461
462 size = 10 + calc_subpktsize (sig->hashed)
463 + calc_subpktsize (sig->unhashed) + calc_mpisize (sig->mpi, nsig);
464 rc = pkt_write_head (out, 0, size, CDK_PKT_SIGNATURE);
465 if (!rc)
466 rc = stream_putc (out, 4);
467 if (!rc)
468 rc = stream_putc (out, sig->sig_class);
469 if (!rc)
470 rc = stream_putc (out, sig->pubkey_algo);
471 if (!rc)
472 rc = stream_putc (out, sig->digest_algo);
473 if (!rc)
474 rc = write_16 (out, sig->hashed_size);
475 if (!rc)
476 {
477 buf = _cdk_subpkt_get_array (sig->hashed, 0, &nbytes);
478 if (!buf)
479 return CDK_Out_Of_Core;
480 rc = stream_write (out, buf, nbytes);
481 cdk_free (buf);
482 }
483 if (!rc)
484 rc = write_16 (out, sig->unhashed_size);
485 if (!rc)
486 {
487 buf = _cdk_subpkt_get_array (sig->unhashed, 0, &nbytes);
488 if (!buf)
489 return CDK_Out_Of_Core;
490 rc = stream_write (out, buf, nbytes);
491 cdk_free (buf);
492 }
493 if (!rc)
494 rc = stream_putc (out, sig->digest_start[0]);
495 if (!rc)
496 rc = stream_putc (out, sig->digest_start[1]);
497 if (!rc)
498 rc = write_mpibuf (out, sig->mpi, nsig);
499 return rc;
500}
501
502
503static cdk_error_t
504write_public_key (cdk_stream_t out, cdk_pkt_pubkey_t pk,
505 int is_subkey, int old_ctb)
506{
507 int pkttype, ndays = 0;
508 size_t npkey = 0, size = 6;
509 cdk_error_t rc;
510
511 assert (out);
512 assert (pk);
513
514 if (pk->version < 2 || pk->version > 4)
515 return CDK_Inv_Packet;
516
517 if (DEBUG_PKT)
518 _cdk_log_debug ("write_public_key: subkey=%d\n", is_subkey);
519
520 pkttype = is_subkey ? CDK_PKT_PUBLIC_SUBKEY : CDK_PKT_PUBLIC_KEY;
521 npkey = cdk_pk_get_npkey (pk->pubkey_algo);
522 if (!npkey)
523 return CDK_Inv_Algo;
524 if (pk->version < 4)
525 size += 2; /* expire date */
526 if (is_subkey)
527 old_ctb = 0;
528 size += calc_mpisize (pk->mpi, npkey);
529 if (old_ctb)
530 rc = pkt_write_head2 (out, size, pkttype);
531 else
532 rc = pkt_write_head (out, old_ctb, size, pkttype);
533 if (!rc)
534 rc = stream_putc (out, pk->version);
535 if (!rc)
536 rc = write_32 (out, pk->timestamp);
537 if (!rc && pk->version < 4)
538 {
539 if (pk->expiredate)
540 ndays = (u16) ((pk->expiredate - pk->timestamp) / 86400L);
541 rc = write_16 (out, ndays);
542 }
543 if (!rc)
544 rc = stream_putc (out, pk->pubkey_algo);
545 if (!rc)
546 rc = write_mpibuf (out, pk->mpi, npkey);
547 return rc;
548}
549
550
551static int
552calc_s2ksize (cdk_pkt_seckey_t sk)
553{
554 size_t nbytes = 0;
555
556 if (!sk->is_protected)
557 return 0;
558 switch (sk->protect.s2k->mode)
559 {
560 case CDK_S2K_SIMPLE:
561 nbytes = 2;
562 break;
563 case CDK_S2K_SALTED:
564 nbytes = 10;
565 break;
566 case CDK_S2K_ITERSALTED:
567 nbytes = 11;
568 break;
569 }
570 nbytes += sk->protect.ivlen;
571 nbytes++; /* single cipher byte */
572 return nbytes;
573}
574
575
576static cdk_error_t
577write_secret_key (cdk_stream_t out, cdk_pkt_seckey_t sk,
578 int is_subkey, int old_ctb)
579{
580 cdk_pkt_pubkey_t pk = NULL;
581 size_t size = 6, npkey, nskey;
582 int pkttype, s2k_mode;
583 cdk_error_t rc;
584
585 assert (out);
586 assert (sk);
587
588 if (!sk->pk)
589 return CDK_Inv_Value;
590 pk = sk->pk;
591 if (pk->version < 2 || pk->version > 4)
592 return CDK_Inv_Packet;
593
594 if (DEBUG_PKT)
595 _cdk_log_debug ("write_secret_key:\n");
596
597 npkey = cdk_pk_get_npkey (pk->pubkey_algo);
598 nskey = cdk_pk_get_nskey (pk->pubkey_algo);
599 if (!npkey || !nskey)
600 return CDK_Inv_Algo;
601 if (pk->version < 4)
602 size += 2;
603 /* If the key is unprotected, the 1 extra byte:
604 1 octet - cipher algorithm byte (0x00)
605 the other bytes depend on the mode:
606 a) simple checksum - 2 octets
607 b) sha-1 checksum - 20 octets */
608 size = !sk->is_protected ? size + 1 : size + 1 + calc_s2ksize (sk);
609 size += calc_mpisize (pk->mpi, npkey);
610 if (sk->version == 3 || !sk->is_protected)
611 {
612 if (sk->version == 3)
613 {
614 size += 2; /* force simple checksum */
615 sk->protect.sha1chk = 0;
616 }
617 else
618 size += sk->protect.sha1chk ? 20 : 2;
619 size += calc_mpisize (sk->mpi, nskey);
620 }
621 else /* We do not know anything about the encrypted mpi's so we
622 treat the data as opaque. */
623 size += sk->enclen;
624
625 pkttype = is_subkey ? CDK_PKT_SECRET_SUBKEY : CDK_PKT_SECRET_KEY;
626 rc = pkt_write_head (out, old_ctb, size, pkttype);
627 if (!rc)
628 rc = stream_putc (out, pk->version);
629 if (!rc)
630 rc = write_32 (out, pk->timestamp);
631 if (!rc && pk->version < 4)
632 {
633 u16 ndays = 0;
634 if (pk->expiredate)
635 ndays = (u16) ((pk->expiredate - pk->timestamp) / 86400L);
636 rc = write_16 (out, ndays);
637 }
638 if (!rc)
639 rc = stream_putc (out, pk->pubkey_algo);
640 if (!rc)
641 rc = write_mpibuf (out, pk->mpi, npkey);
642 if (sk->is_protected == 0)
643 rc = stream_putc (out, 0x00);
644 else
645 {
646 if (is_RSA (pk->pubkey_algo) && pk->version < 4)
647 stream_putc (out, sk->protect.algo);
648 else if (sk->protect.s2k)
649 {
650 s2k_mode = sk->protect.s2k->mode;
651 rc = stream_putc (out, sk->protect.sha1chk ? 0xFE : 0xFF);
652 if (!rc)
653 rc = stream_putc (out, sk->protect.algo);
654 if (!rc)
655 rc = stream_putc (out, sk->protect.s2k->mode);
656 if (!rc)
657 rc = stream_putc (out, sk->protect.s2k->hash_algo);
658 if (!rc && (s2k_mode == 1 || s2k_mode == 3))
659 {
660 rc = stream_write (out, sk->protect.s2k->salt, 8);
661 if (!rc && s2k_mode == 3)
662 rc = stream_putc (out, sk->protect.s2k->count);
663 }
664 }
665 else
666 return CDK_Inv_Value;
667 rc = stream_write (out, sk->protect.iv, sk->protect.ivlen);
668 }
669 if (!rc && sk->is_protected && pk->version == 4)
670 {
671 if (sk->encdata && sk->enclen)
672 rc = stream_write (out, sk->encdata, sk->enclen);
673 }
674 else
675 {
676 if (!rc)
677 rc = write_mpibuf (out, sk->mpi, nskey);
678 if (!rc)
679 {
680 if (!sk->csum)
681 sk->csum = _cdk_sk_get_csum (sk);
682 rc = write_16 (out, sk->csum);
683 }
684 }
685
686 return rc;
687}
688
689
690static cdk_error_t
691write_compressed (cdk_stream_t out, cdk_pkt_compressed_t cd)
692{
693 cdk_error_t rc;
694
695 assert (out);
696 assert (cd);
697
698 if (DEBUG_PKT)
699 _cdk_log_debug ("packet: write_compressed\n");
700
701 /* Use an old (RFC1991) header for this packet. */
702 rc = pkt_write_head (out, 1, 0, CDK_PKT_COMPRESSED);
703 if (!rc)
704 rc = stream_putc (out, cd->algorithm);
705 return rc;
706}
707
708
709static cdk_error_t
710write_literal (cdk_stream_t out, cdk_pkt_literal_t pt, int old_ctb)
711{
712 byte buf[BUFSIZE];
713 size_t size;
714 cdk_error_t rc;
715
716 assert (out);
717 assert (pt);
718
719 /* We consider a packet without a body as an invalid packet.
720 At least one octet must be present. */
721 if (!pt->len)
722 return CDK_Inv_Packet;
723
724 if (DEBUG_PKT)
725 _cdk_log_debug ("write_literal:\n");
726
727 size = 6 + pt->namelen + pt->len;
728 rc = pkt_write_head (out, old_ctb, size, CDK_PKT_LITERAL);
729 if (rc)
730 return rc;
731
732 rc = stream_putc (out, pt->mode);
733 if (rc)
734 return rc;
735 rc = stream_putc (out, pt->namelen);
736 if (rc)
737 return rc;
738
739 if (pt->namelen > 0)
740 rc = stream_write (out, pt->name, pt->namelen);
741 if (!rc)
742 rc = write_32 (out, pt->timestamp);
743 if (rc)
744 return rc;
745
746 while (!cdk_stream_eof (pt->buf) && !rc)
747 {
748 rc = stream_read (pt->buf, buf, DIM (buf), &size);
749 if (!rc)
750 rc = stream_write (out, buf, size);
751 }
752
753 wipemem (buf, sizeof (buf));
754 return rc;
755}
756
757
758static cdk_error_t
759write_onepass_sig (cdk_stream_t out, cdk_pkt_onepass_sig_t sig)
760{
761 cdk_error_t rc;
762
763 assert (out);
764 assert (sig);
765
766 if (sig->version != 3)
767 return CDK_Inv_Packet;
768
769 if (DEBUG_PKT)
770 _cdk_log_debug ("write_onepass_sig:\n");
771
772 rc = pkt_write_head (out, 0, 13, CDK_PKT_ONEPASS_SIG);
773 if (!rc)
774 rc = stream_putc (out, sig->version);
775 if (!rc)
776 rc = stream_putc (out, sig->sig_class);
777 if (!rc)
778 rc = stream_putc (out, sig->digest_algo);
779 if (!rc)
780 rc = stream_putc (out, sig->pubkey_algo);
781 if (!rc)
782 rc = write_32 (out, sig->keyid[0]);
783 if (!rc)
784 rc = write_32 (out, sig->keyid[1]);
785 if (!rc)
786 rc = stream_putc (out, sig->last);
787 return rc;
788}
789
790
791static cdk_error_t
792write_user_id (cdk_stream_t out, cdk_pkt_userid_t id, int old_ctb,
793 int pkttype)
794{
795 cdk_error_t rc;
796
797 if (!out || !id)
798 return CDK_Inv_Value;
799
800 if (pkttype == CDK_PKT_ATTRIBUTE)
801 {
802 if (!id->attrib_img)
803 return CDK_Inv_Value;
804 rc =
805 pkt_write_head (out, old_ctb, id->attrib_len + 6, CDK_PKT_ATTRIBUTE);
806 if (rc)
807 return rc;
808 /* Write subpacket part. */
809 stream_putc (out, 255);
810 write_32 (out, id->attrib_len + 1);
811 stream_putc (out, 1);
812 rc = stream_write (out, id->attrib_img, id->attrib_len);
813 }
814 else
815 {
816 if (!id->name)
817 return CDK_Inv_Value;
818 rc = pkt_write_head (out, old_ctb, id->len, CDK_PKT_USER_ID);
819 if (!rc)
820 rc = stream_write (out, id->name, id->len);
821 }
822
823 return rc;
824}
825
826
827/**
828 * cdk_pkt_write:
829 * @out: the output stream handle
830 * @pkt: the packet itself
831 *
832 * Write the contents of @pkt into the @out stream.
833 * Return 0 on success.
834 **/
835cdk_error_t
836cdk_pkt_write (cdk_stream_t out, cdk_packet_t pkt)
837{
838 cdk_error_t rc;
839
840 if (!out || !pkt)
841 return CDK_Inv_Value;
842
843 _cdk_log_debug ("write packet pkttype=%d\n", pkt->pkttype);
844 switch (pkt->pkttype)
845 {
846 case CDK_PKT_LITERAL:
847 rc = write_literal (out, pkt->pkt.literal, pkt->old_ctb);
848 break;
849 case CDK_PKT_ONEPASS_SIG:
850 rc = write_onepass_sig (out, pkt->pkt.onepass_sig);
851 break;
852 case CDK_PKT_MDC:
853 rc = write_mdc (out, pkt->pkt.mdc);
854 break;
855 case CDK_PKT_SYMKEY_ENC:
856 rc = write_symkey_enc (out, pkt->pkt.symkey_enc);
857 break;
858 case CDK_PKT_ENCRYPTED:
859 rc = write_encrypted (out, pkt->pkt.encrypted, pkt->old_ctb);
860 break;
861 case CDK_PKT_ENCRYPTED_MDC:
862 rc = write_encrypted_mdc (out, pkt->pkt.encrypted);
863 break;
864 case CDK_PKT_PUBKEY_ENC:
865 rc = write_pubkey_enc (out, pkt->pkt.pubkey_enc, pkt->old_ctb);
866 break;
867 case CDK_PKT_SIGNATURE:
868 rc = write_signature (out, pkt->pkt.signature, pkt->old_ctb);
869 break;
870 case CDK_PKT_PUBLIC_KEY:
871 rc = write_public_key (out, pkt->pkt.public_key, 0, pkt->old_ctb);
872 break;
873 case CDK_PKT_PUBLIC_SUBKEY:
874 rc = write_public_key (out, pkt->pkt.public_key, 1, pkt->old_ctb);
875 break;
876 case CDK_PKT_COMPRESSED:
877 rc = write_compressed (out, pkt->pkt.compressed);
878 break;
879 case CDK_PKT_SECRET_KEY:
880 rc = write_secret_key (out, pkt->pkt.secret_key, 0, pkt->old_ctb);
881 break;
882 case CDK_PKT_SECRET_SUBKEY:
883 rc = write_secret_key (out, pkt->pkt.secret_key, 1, pkt->old_ctb);
884 break;
885 case CDK_PKT_USER_ID:
886 case CDK_PKT_ATTRIBUTE:
887 rc = write_user_id (out, pkt->pkt.user_id, pkt->old_ctb, pkt->pkttype);
888 break;
889 default:
890 rc = CDK_Inv_Packet;
891 break;
892 }
893
894 if (DEBUG_PKT)
895 _cdk_log_debug ("write_packet rc=%d pkttype=%d\n", rc, pkt->pkttype);
896 return rc;
897}
898
899
900cdk_error_t
901_cdk_pkt_write2 (cdk_stream_t out, int pkttype, void *pktctx)
902{
903 cdk_packet_t pkt;
904 cdk_error_t rc;
905
906 rc = cdk_pkt_new (&pkt);
907 if (rc)
908 return rc;
909
910 switch (pkttype)
911 {
912 case CDK_PKT_PUBLIC_KEY:
913 case CDK_PKT_PUBLIC_SUBKEY:
914 pkt->pkt.public_key = pktctx;
915 break;
916 case CDK_PKT_SIGNATURE:
917 pkt->pkt.signature = pktctx;
918 break;
919 case CDK_PKT_SECRET_KEY:
920 case CDK_PKT_SECRET_SUBKEY:
921 pkt->pkt.secret_key = pktctx;
922 break;
923
924 case CDK_PKT_USER_ID:
925 pkt->pkt.user_id = pktctx;
926 break;
927 }
928 pkt->pkttype = pkttype;
929 rc = cdk_pkt_write (out, pkt);
930 cdk_free (pkt);
931 return rc;
932}
933
934
935cdk_error_t
936_cdk_pkt_write_fp (FILE * out, cdk_packet_t pkt)
937{
938 cdk_stream_t so;
939 cdk_error_t rc;
940
941 rc = _cdk_stream_fpopen (out, 1, &so);
942 if (rc)
943 return rc;
944 rc = cdk_pkt_write (so, pkt);
945 cdk_stream_close (so);
946 return rc;
947}
diff --git a/src/daemon/https/openpgp/Makefile.am b/src/daemon/https/openpgp/Makefile.am
new file mode 100644
index 00000000..94c27ac1
--- /dev/null
+++ b/src/daemon/https/openpgp/Makefile.am
@@ -0,0 +1,27 @@
1SUBDIRS = .
2
3AM_CPPFLAGS = -I./includes \
4-I$(top_srcdir)/src/daemon/https/includes \
5-I$(top_srcdir)/src/daemon/https/lgl \
6-I$(top_srcdir)/src/daemon/https/x509 \
7-I$(top_srcdir)/src/daemon/https/tls \
8-I$(top_srcdir)/src/daemon/https/openpgp \
9-I$(top_srcdir)/src/daemon/https/opencdk \
10-I$(top_srcdir)/src/daemon/https/minitasn1
11
12noinst_LTLIBRARIES = libopenpgp.la
13
14# libopenpgp_la_LDFLAGS = -l$(top_srcdir)/src/daemon/https/libextra/.lib/libextra.la
15
16libopenpgp_la_SOURCES = \
17pgp_privkey.c \
18compat.c \
19pgp_verify.c \
20extras.c \
21pgp.c
22
23# x libextra source list
24libopenpgp_la_SOURCES += \
25gnutls_openpgp.c \
26gnutls_ia.c \
27gnutls_extra.c
diff --git a/src/daemon/https/openpgp/compat.c b/src/daemon/https/openpgp/compat.c
new file mode 100644
index 00000000..1ba7177a
--- /dev/null
+++ b/src/daemon/https/openpgp/compat.c
@@ -0,0 +1,252 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Timo Schulz, Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS-EXTRA.
7 *
8 * GNUTLS-EXTRA is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * GNUTLS-EXTRA is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22/* Compatibility functions on OpenPGP key parsing.
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_errors.h>
27#include <gnutls_openpgp.h>
28#include "openpgp.h"
29
30/*-
31 * gnutls_openpgp_verify_key - Verify all signatures on the key
32 * @cert_list: the structure that holds the certificates.
33 * @cert_list_lenght: the items in the cert_list.
34 * @status: the output of the verification function
35 *
36 * Verify all signatures in the certificate list. When the key
37 * is not available, the signature is skipped.
38 *
39 * The return value is one of the CertificateStatus entries.
40 *
41 * NOTE: this function does not verify using any "web of trust". You
42 * may use GnuPG for that purpose, or any other external PGP application.
43 -*/
44int
45_gnutls_openpgp_verify_key (const gnutls_certificate_credentials_t cred,
46 const gnutls_datum_t * cert_list,
47 int cert_list_length, unsigned int *status)
48{
49 int ret = 0;
50 gnutls_openpgp_crt_t key = NULL;
51 unsigned int verify = 0, verify_self = 0;
52
53 if (!cert_list || cert_list_length != 1)
54 {
55 gnutls_assert ();
56 return GNUTLS_E_NO_CERTIFICATE_FOUND;
57 }
58
59 ret = gnutls_openpgp_crt_init (&key);
60 if (ret < 0)
61 {
62 gnutls_assert ();
63 return ret;
64 }
65
66 ret =
67 gnutls_openpgp_crt_import (key, &cert_list[0], GNUTLS_OPENPGP_FMT_RAW);
68 if (ret < 0)
69 {
70 gnutls_assert ();
71 goto leave;
72 }
73
74#ifndef KEYRING_HACK
75 if (cred->keyring != NULL)
76 {
77 ret = gnutls_openpgp_crt_verify_ring (key, cred->keyring, 0, &verify);
78 if (ret < 0)
79 {
80 gnutls_assert ();
81 goto leave;
82 }
83 }
84#else
85 {
86 gnutls_openpgp_keyring_t kring;
87
88 ret = gnutls_openpgp_keyring_init (&kring);
89 if (ret < 0)
90 {
91 gnutls_assert ();
92 return ret;
93 }
94
95 ret =
96 gnutls_openpgp_keyring_import (kring, &cred->keyring,
97 cred->keyring_format);
98 if (ret < 0)
99 {
100 gnutls_assert ();
101 gnutls_openpgp_keyring_deinit (kring);
102 return ret;
103 }
104
105 ret = gnutls_openpgp_crt_verify_ring (key, kring, 0, &verify);
106 if (ret < 0)
107 {
108 gnutls_assert ();
109 gnutls_openpgp_keyring_deinit (kring);
110 return ret;
111 }
112 gnutls_openpgp_keyring_deinit (kring);
113 }
114#endif
115
116 /* Now try the self signature. */
117 ret = gnutls_openpgp_crt_verify_self (key, 0, &verify_self);
118 if (ret < 0)
119 {
120 gnutls_assert ();
121 goto leave;
122 }
123
124 *status = verify_self | verify;
125
126#ifndef KEYRING_HACK
127 /* If we only checked the self signature. */
128 if (!cred->keyring)
129#else
130 if (!cred->keyring.data || !cred->keyring.size)
131#endif
132 *status |= GNUTLS_CERT_SIGNER_NOT_FOUND;
133
134
135 ret = 0;
136
137leave:
138 gnutls_openpgp_crt_deinit (key);
139
140 return ret;
141}
142
143/*-
144 * gnutls_openpgp_fingerprint - Gets the fingerprint
145 * @cert: the raw data that contains the OpenPGP public key.
146 * @fpr: the buffer to save the fingerprint.
147 * @fprlen: the integer to save the length of the fingerprint.
148 *
149 * Returns the fingerprint of the OpenPGP key. Depence on the algorithm,
150 * the fingerprint can be 16 or 20 bytes.
151 -*/
152int
153_gnutls_openpgp_fingerprint (const gnutls_datum_t * cert,
154 unsigned char *fpr, size_t * fprlen)
155{
156 gnutls_openpgp_crt_t key;
157 int ret;
158
159 ret = gnutls_openpgp_crt_init (&key);
160 if (ret < 0)
161 {
162 gnutls_assert ();
163 return ret;
164 }
165
166 ret = gnutls_openpgp_crt_import (key, cert, GNUTLS_OPENPGP_FMT_RAW);
167 if (ret < 0)
168 {
169 gnutls_assert ();
170 return ret;
171 }
172
173 ret = gnutls_openpgp_crt_get_fingerprint (key, fpr, fprlen);
174 gnutls_openpgp_crt_deinit (key);
175 if (ret < 0)
176 {
177 gnutls_assert ();
178 return ret;
179 }
180
181 return 0;
182}
183
184/*-
185 * gnutls_openpgp_get_raw_key_creation_time - Extract the timestamp
186 * @cert: the raw data that contains the OpenPGP public key.
187 *
188 * Returns the timestamp when the OpenPGP key was created.
189 -*/
190time_t
191_gnutls_openpgp_get_raw_key_creation_time (const gnutls_datum_t * cert)
192{
193 gnutls_openpgp_crt_t key;
194 int ret;
195 time_t tim;
196
197 ret = gnutls_openpgp_crt_init (&key);
198 if (ret < 0)
199 {
200 gnutls_assert ();
201 return ret;
202 }
203
204 ret = gnutls_openpgp_crt_import (key, cert, GNUTLS_OPENPGP_FMT_RAW);
205 if (ret < 0)
206 {
207 gnutls_assert ();
208 return ret;
209 }
210
211 tim = gnutls_openpgp_crt_get_creation_time (key);
212
213 gnutls_openpgp_crt_deinit (key);
214
215 return tim;
216}
217
218
219/*-
220 * gnutls_openpgp_get_raw_key_expiration_time - Extract the expire date
221 * @cert: the raw data that contains the OpenPGP public key.
222 *
223 * Returns the time when the OpenPGP key expires. A value of '0' means
224 * that the key doesn't expire at all.
225 -*/
226time_t
227_gnutls_openpgp_get_raw_key_expiration_time (const gnutls_datum_t * cert)
228{
229 gnutls_openpgp_crt_t key;
230 int ret;
231 time_t tim;
232
233 ret = gnutls_openpgp_crt_init (&key);
234 if (ret < 0)
235 {
236 gnutls_assert ();
237 return ret;
238 }
239
240 ret = gnutls_openpgp_crt_import (key, cert, GNUTLS_OPENPGP_FMT_RAW);
241 if (ret < 0)
242 {
243 gnutls_assert ();
244 return ret;
245 }
246
247 tim = gnutls_openpgp_crt_get_expiration_time (key);
248
249 gnutls_openpgp_crt_deinit (key);
250
251 return tim;
252}
diff --git a/src/daemon/https/openpgp/extras.c b/src/daemon/https/openpgp/extras.c
new file mode 100644
index 00000000..d3c755d4
--- /dev/null
+++ b/src/daemon/https/openpgp/extras.c
@@ -0,0 +1,165 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos, Timo Schulz
5 *
6 * This file is part of GNUTLS-EXTRA.
7 *
8 * GNUTLS-EXTRA is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * GNUTLS-EXTRA is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22/* Functions on OpenPGP keyring parsing
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_datum.h>
27#include <gnutls_global.h>
28#include <gnutls_errors.h>
29#include <gnutls_openpgp.h>
30#include <gnutls_num.h>
31#include "openpgp.h"
32
33/* Keyring stuff. */
34
35/**
36 * gnutls_openpgp_keyring_init - This function initializes a gnutls_openpgp_keyring_t structure
37 * @keyring: The structure to be initialized
38 *-
39 * This function will initialize an OpenPGP keyring structure.
40 *
41 * Returns 0 on success.
42 *
43 **/
44int gnutls_openpgp_keyring_init(gnutls_openpgp_keyring_t * keyring)
45{
46 *keyring = gnutls_calloc(1, sizeof(gnutls_openpgp_keyring_int));
47
48 if (*keyring)
49 return 0; /* success */
50 return GNUTLS_E_MEMORY_ERROR;
51}
52
53/**
54 * gnutls_openpgp_keyring_deinit - This function deinitializes memory used by a gnutls_openpgp_keyring_t structure
55 * @keyring: The structure to be initialized
56 *
57 * This function will deinitialize a keyring structure.
58 *
59 **/
60void gnutls_openpgp_keyring_deinit(gnutls_openpgp_keyring_t keyring)
61{
62 if (!keyring)
63 return;
64
65 if (keyring->db)
66 {
67 cdk_keydb_free(keyring->db);
68 keyring->db = NULL;
69 }
70
71 /* In some cases the stream is also stored outside the keydb context
72 and we need to close it here then. */
73 if (keyring->db_stream)
74 {
75 cdk_stream_close(keyring->db_stream);
76 keyring->db_stream = NULL;
77 }
78
79 gnutls_free(keyring);
80}
81
82/**
83 * gnutls_openpgp_keyring_check_id - Check if a key id exists in the keyring
84 * @ring: holds the keyring to check against
85 * @keyid: will hold the keyid to check for.
86 * @flags: unused (should be 0)
87 *
88 * Check if a given key ID exists in the keyring.
89 *
90 * Returns 0 on success (if keyid exists) and a negative error code
91 * on failure.
92 **/
93int gnutls_openpgp_keyring_check_id(gnutls_openpgp_keyring_t ring,
94 const unsigned char keyid[8],
95 unsigned int flags)
96{
97 cdk_pkt_pubkey_t pk;
98 uint32_t id[2];
99
100 id[0] = _gnutls_read_uint32(keyid);
101 id[1] = _gnutls_read_uint32(&keyid[4]);
102
103 if (!cdk_keydb_get_pk(ring->db, id, &pk))
104 {
105 cdk_pk_release(pk);
106 return 0;
107 }
108
109 _gnutls_debug_log ("PGP: key not found %08lX\n", (unsigned long) id[1]);
110 return GNUTLS_E_NO_CERTIFICATE_FOUND;
111}
112
113/**
114 * gnutls_openpgp_keyring_import - Import a raw- or Base64-encoded OpenPGP keyring
115 * @keyring: The structure to store the parsed key.
116 * @data: The RAW or BASE64 encoded keyring.
117 * @format: One of #gnutls_openpgp_keyring_fmt elements.
118 *
119 * This function will convert the given RAW or Base64 encoded keyring to the
120 * native #gnutls_openpgp_keyring_t format. The output will be stored in
121 * 'keyring'.
122 *
123 * Returns 0 on success.
124 *
125 **/
126int gnutls_openpgp_keyring_import(gnutls_openpgp_keyring_t keyring,
127 const gnutls_datum_t * data,
128 gnutls_openpgp_crt_fmt_t format)
129{
130 cdk_error_t err;
131 cdk_stream_t input;
132
133 _gnutls_debug_log ("PGP: keyring import format '%s'\n",
134 format == GNUTLS_OPENPGP_FMT_RAW ? "raw" : "base64");
135
136 if (format == GNUTLS_OPENPGP_FMT_RAW)
137 {
138 err
139 = cdk_keydb_new(&keyring->db, CDK_DBTYPE_DATA, data->data, data->size);
140 if (err)
141 gnutls_assert ();
142 return _gnutls_map_cdk_rc (err);
143 }
144
145 /* Create a new stream from the given data, which means to
146 allocate a new stream and to write the data in the stream.
147 Then push the armor filter to decode the data and to store
148 it in the raw format. */
149 err = cdk_stream_tmp_from_mem(data->data, data->size, &input);
150 if (!err)
151 err = cdk_stream_set_armor_flag(input, 0);
152 if (!err)
153 err = cdk_keydb_new_from_stream(&keyring->db, 0, input);
154 if (err)
155 {
156 cdk_stream_close(input);
157 gnutls_assert ();
158 }
159 else
160 /* The keydb function will not close the stream itself, so we need to
161 store it separately to close it later. */
162 keyring->db_stream = input;
163
164 return _gnutls_map_cdk_rc (err);
165}
diff --git a/src/daemon/https/openpgp/gnutls_extra.c b/src/daemon/https/openpgp/gnutls_extra.c
new file mode 100644
index 00000000..7c47e3f1
--- /dev/null
+++ b/src/daemon/https/openpgp/gnutls_extra.c
@@ -0,0 +1,110 @@
1/*
2 * Copyright (C) 2001, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS-EXTRA.
7 *
8 * GNUTLS-EXTRA is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * GNUTLS-EXTRA is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <gnutls_int.h>
23#include <gnutls_errors.h>
24#include <gnutls_extensions.h>
25#include <gnutls_openpgp.h>
26#include <gnutls_extra.h>
27#include <gnutls_extra_hooks.h>
28#include <gnutls_algorithms.h>
29
30/* the number of the compression algorithms available in the compression
31 * structure.
32 */
33extern int _gnutls_comp_algorithms_size;
34
35/* Functions in gnutls that have not been initialized.
36 */
37
38static int _gnutls_init_extra = 0;
39
40/**
41 * gnutls_global_init_extra - This function initializes the global state of gnutls-extra
42 *
43 * This function initializes the global state of gnutls-extra library
44 * to defaults. Returns zero on success.
45 *
46 * Note that gnutls_global_init() has to be called before this
47 * function. If this function is not called then the gnutls-extra
48 * library will not be usable.
49 *
50 **/
51int
52gnutls_global_init_extra (void)
53{
54 int ret;
55
56 /* If the version of libgnutls != version of
57 * libextra, then do not initialize the library.
58 * This is because it may break things.
59 */
60 if (strcmp (gnutls_check_version (NULL), VERSION) != 0)
61 {
62 return GNUTLS_E_LIBRARY_VERSION_MISMATCH;
63 }
64
65 _gnutls_init_extra++;
66
67 if (_gnutls_init_extra != 1)
68 {
69 return 0;
70 }
71
72 /* Register the openpgp functions. This is because some
73 * of them are defined to be NULL in the main library.
74 */
75 _gnutls_add_openpgp_functions (_gnutls_openpgp_verify_key,
76 _gnutls_openpgp_get_raw_key_creation_time,
77 _gnutls_openpgp_get_raw_key_expiration_time,
78 _gnutls_openpgp_fingerprint,
79 _gnutls_openpgp_request_key,
80 _gnutls_openpgp_raw_key_to_gcert,
81 _gnutls_openpgp_raw_privkey_to_gkey,
82 _gnutls_openpgp_crt_to_gcert,
83 _gnutls_openpgp_privkey_to_gkey,
84 gnutls_openpgp_crt_deinit,
85 gnutls_openpgp_keyring_deinit,
86 gnutls_openpgp_privkey_deinit);
87
88 return 0;
89}
90
91#include <strverscmp.h>
92
93/**
94 * gnutls_extra_check_version - This function checks the library's version
95 * @req_version: the version to check
96 *
97 * Check that the version of the gnutls-extra library is at minimum
98 * the requested one and return the version string; return NULL if the
99 * condition is not satisfied. If a NULL is passed to this function,
100 * no check is done, but the version string is simply returned.
101 *
102 **/
103const char *
104gnutls_extra_check_version (const char *req_version)
105{
106 if (!req_version || strverscmp (req_version, VERSION) <= 0)
107 return VERSION;
108
109 return NULL;
110}
diff --git a/src/daemon/https/openpgp/gnutls_extra.h b/src/daemon/https/openpgp/gnutls_extra.h
new file mode 100644
index 00000000..de7fc889
--- /dev/null
+++ b/src/daemon/https/openpgp/gnutls_extra.h
@@ -0,0 +1,50 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS-EXTRA.
7 *
8 * GNUTLS-EXTRA is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 3 of the
11 * License, or (at your option) any later version.
12 *
13 * GNUTLS-EXTRA is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with GNUTLS-EXTRA; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 *
23 */
24
25#include <auth_cert.h>
26
27typedef int (*OPENPGP_VERIFY_KEY_FUNC) (const
28 gnutls_certificate_credentials_t,
29 const gnutls_datum_t *, int,
30 unsigned int *);
31
32typedef time_t (*OPENPGP_KEY_CREATION_TIME_FUNC) (const gnutls_datum_t *);
33typedef time_t (*OPENPGP_KEY_EXPIRATION_TIME_FUNC) (const gnutls_datum_t *);
34typedef int (*OPENPGP_KEY_REQUEST) (gnutls_session_t, gnutls_datum_t *,
35 const gnutls_certificate_credentials_t,
36 opaque *, int);
37
38typedef int (*OPENPGP_FINGERPRINT) (const gnutls_datum_t *,
39 unsigned char *, size_t *);
40
41typedef int (*OPENPGP_RAW_KEY_TO_GCERT) (gnutls_cert *,
42 const gnutls_datum_t *);
43typedef int (*OPENPGP_RAW_PRIVKEY_TO_GKEY) (gnutls_privkey *,
44 const gnutls_datum_t *);
45
46typedef int (*OPENPGP_KEY_TO_GCERT) (gnutls_cert *, gnutls_openpgp_crt_t);
47typedef int (*OPENPGP_PRIVKEY_TO_GKEY) (gnutls_privkey *,
48 gnutls_openpgp_privkey_t);
49typedef void (*OPENPGP_KEY_DEINIT) (gnutls_openpgp_crt_t);
50typedef void (*OPENPGP_PRIVKEY_DEINIT) (gnutls_openpgp_privkey_t);
diff --git a/src/daemon/https/openpgp/gnutls_ia.c b/src/daemon/https/openpgp/gnutls_ia.c
new file mode 100644
index 00000000..55b22e9c
--- /dev/null
+++ b/src/daemon/https/openpgp/gnutls_ia.c
@@ -0,0 +1,905 @@
1/*
2 * Copyright (C) 2005, 2006 Free Software Foundation
3 *
4 * Author: Simon Josefsson
5 *
6 * This file is part of GNUTLS-EXTRA.
7 *
8 * GNUTLS-EXTRA is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * GNUTLS-EXTRA is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include "gnutls_int.h"
23#include "gnutls_record.h"
24#include "gnutls_errors.h"
25#include "gnutls_num.h"
26#include "gnutls_state.h"
27
28#define CHECKSUM_SIZE 12
29
30struct gnutls_ia_client_credentials_st
31{
32 gnutls_ia_avp_func avp_func;
33 void *avp_ptr;
34};
35
36struct gnutls_ia_server_credentials_st
37{
38 gnutls_ia_avp_func avp_func;
39 void *avp_ptr;
40};
41
42static const char server_finished_label[] = "server phase finished";
43static const char client_finished_label[] = "client phase finished";
44static const char inner_permutation_label[] = "inner secret permutation";
45static const char challenge_label[] = "inner application challenge";
46
47/*
48 * The TLS/IA packet is the InnerApplication token, described as
49 * follows in draft-funk-tls-inner-application-extension-01.txt:
50 *
51 * enum {
52 * application_payload(0), intermediate_phase_finished(1),
53 * final_phase_finished(2), (255)
54 * } InnerApplicationType;
55 *
56 * struct {
57 * InnerApplicationType msg_type;
58 * uint24 length;
59 * select (InnerApplicationType) {
60 * case application_payload: ApplicationPayload;
61 * case intermediate_phase_finished: IntermediatePhaseFinished;
62 * case final_phase_finished: FinalPhaseFinished;
63 * } body;
64 * } InnerApplication;
65 *
66 */
67
68/* Send TLS/IA data. If data==NULL && sizeofdata==NULL, then the last
69 send was interrupted for some reason, and then we try to send it
70 again. Returns the number of bytes sent, or an error code. If
71 this return E_AGAIN and E_INTERRUPTED, call this function again
72 with data==NULL&&sizeofdata=0NULL until it returns successfully. */
73static ssize_t
74_gnutls_send_inner_application (gnutls_session_t session,
75 gnutls_ia_apptype_t msg_type,
76 const char *data, size_t sizeofdata)
77{
78 opaque *p = NULL;
79 size_t plen = 0;
80 ssize_t len;
81
82 if (data != NULL)
83 {
84 plen = sizeofdata + 4;
85 p = gnutls_malloc (plen);
86 if (!p)
87 {
88 gnutls_assert ();
89 return GNUTLS_E_MEMORY_ERROR;
90 }
91
92 *(unsigned char *) p = (unsigned char) (msg_type & 0xFF);
93 _gnutls_write_uint24 (sizeofdata, p + 1);
94 memcpy (p + 4, data, sizeofdata);
95 }
96
97 len = _gnutls_send_int (session, GNUTLS_INNER_APPLICATION, -1, p, plen);
98
99 if (p)
100 gnutls_free (p);
101
102 return len;
103}
104
105/* Receive TLS/IA data. Store received TLS/IA message type in
106 *MSG_TYPE, and the data in DATA of max SIZEOFDATA size. Return the
107 number of bytes read, or an error code. */
108static ssize_t
109_gnutls_recv_inner_application (gnutls_session_t session,
110 gnutls_ia_apptype_t * msg_type,
111 opaque * data, size_t sizeofdata)
112{
113 ssize_t len;
114 opaque pkt[4];
115
116 len = _gnutls_recv_int (session, GNUTLS_INNER_APPLICATION, -1, pkt, 4);
117 if (len != 4)
118 {
119 gnutls_assert ();
120 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
121 }
122
123 *msg_type = pkt[0];
124 len = _gnutls_read_uint24 (&pkt[1]);
125
126 if (*msg_type != GNUTLS_IA_APPLICATION_PAYLOAD && len != CHECKSUM_SIZE)
127 {
128 gnutls_assert ();
129 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
130 }
131
132 if (sizeofdata < len)
133 {
134 /* XXX push back pkt to IA buffer? */
135 gnutls_assert ();
136 return GNUTLS_E_SHORT_MEMORY_BUFFER;
137 }
138
139 if (len > 0)
140 {
141 int tmplen = len;
142
143 len = _gnutls_recv_int (session, GNUTLS_INNER_APPLICATION, -1,
144 data, tmplen);
145 if (len != tmplen)
146 {
147 gnutls_assert ();
148 /* XXX Correct? */
149 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
150 }
151 }
152
153 return len;
154}
155
156/* Apply the TLS PRF using the TLS/IA inner secret as keying material,
157 where the seed is the client random concatenated with the server
158 random concatenated EXTRA of EXTRA_SIZE length (which can be NULL/0
159 respectively). LABEL and LABEL_SIZE is used as the label. The
160 result is placed in pre-allocated OUT of OUTSIZE length. */
161static int
162_gnutls_ia_prf (gnutls_session_t session,
163 size_t label_size,
164 const char *label,
165 size_t extra_size,
166 const char *extra, size_t outsize, opaque * out)
167{
168 int ret;
169 opaque *seed;
170 size_t seedsize = 2 * TLS_RANDOM_SIZE + extra_size;
171
172 seed = gnutls_malloc (seedsize);
173 if (!seed)
174 {
175 gnutls_assert ();
176 return GNUTLS_E_MEMORY_ERROR;
177 }
178
179 memcpy (seed, session->security_parameters.server_random, TLS_RANDOM_SIZE);
180 memcpy (seed + TLS_RANDOM_SIZE, session->security_parameters.client_random,
181 TLS_RANDOM_SIZE);
182 memcpy (seed + 2 * TLS_RANDOM_SIZE, extra, extra_size);
183
184 ret = _gnutls_PRF (session, session->security_parameters.inner_secret,
185 TLS_MASTER_SIZE,
186 label, label_size, seed, seedsize, outsize, out);
187
188 gnutls_free (seed);
189
190 return ret;
191}
192
193/**
194 * gnutls_ia_permute_inner_secret:
195 * @session: is a #gnutls_session_t structure.
196 * @session_keys_size: Size of generated session keys (0 if none).
197 * @session_keys: Generated session keys, used to permute inner secret
198 * (NULL if none).
199 *
200 * Permute the inner secret using the generated session keys.
201 *
202 * This can be called in the TLS/IA AVP callback to mix any generated
203 * session keys with the TLS/IA inner secret.
204 *
205 * Return value: Return zero on success, or a negative error code.
206 **/
207int
208gnutls_ia_permute_inner_secret (gnutls_session_t session,
209 size_t session_keys_size,
210 const char *session_keys)
211{
212 return _gnutls_ia_prf (session,
213 sizeof (inner_permutation_label) - 1,
214 inner_permutation_label,
215 session_keys_size,
216 session_keys,
217 TLS_RANDOM_SIZE,
218 session->security_parameters.inner_secret);
219}
220
221/**
222 * gnutls_ia_generate_challenge:
223 * @session: is a #gnutls_session_t structure.
224 * @buffer_size: size of output buffer.
225 * @buffer: pre-allocated buffer to contain @buffer_size bytes of output.
226 *
227 * Generate an application challenge that the client cannot control or
228 * predict, based on the TLS/IA inner secret.
229 *
230 * Return value: Returns 0 on success, or an negative error code.
231 **/
232int
233gnutls_ia_generate_challenge (gnutls_session_t session,
234 size_t buffer_size, char *buffer)
235{
236 return _gnutls_ia_prf (session,
237 sizeof (challenge_label) - 1,
238 challenge_label, 0, NULL, buffer_size, buffer);
239}
240
241/**
242 * gnutls_ia_extract_inner_secret:
243 * @session: is a #gnutls_session_t structure.
244 * @buffer: pre-allocated buffer to hold 48 bytes of inner secret.
245 *
246 * Copy the 48 bytes large inner secret into the specified buffer
247 *
248 * This function is typically used after the TLS/IA handshake has
249 * concluded. The TLS/IA inner secret can be used as input to a PRF
250 * to derive session keys. Do not use the inner secret directly as a
251 * session key, because for a resumed session that does not include an
252 * application phase, the inner secret will be identical to the inner
253 * secret in the original session. It is important to include, for
254 * example, the client and server randomness when deriving a sesssion
255 * key from the inner secret.
256 **/
257void
258gnutls_ia_extract_inner_secret (gnutls_session_t session, char *buffer)
259{
260 memcpy (buffer, session->security_parameters.inner_secret, TLS_MASTER_SIZE);
261}
262
263/**
264 * gnutls_ia_endphase_send:
265 * @session: is a #gnutls_session_t structure.
266 * @final_p: Set iff this should signal the final phase.
267 *
268 * Send a TLS/IA end phase message.
269 *
270 * In the client, this should only be used to acknowledge an end phase
271 * message sent by the server.
272 *
273 * In the server, this can be called instead of gnutls_ia_send() if
274 * the server wishes to end an application phase.
275 *
276 * Return value: Return 0 on success, or an error code.
277 **/
278int
279gnutls_ia_endphase_send (gnutls_session_t session, int final_p)
280{
281 opaque local_checksum[CHECKSUM_SIZE];
282 int client = session->security_parameters.entity == GNUTLS_CLIENT;
283 const char *label = client ? client_finished_label : server_finished_label;
284 int size_of_label = client ? sizeof (client_finished_label) :
285 sizeof (server_finished_label);
286 ssize_t len;
287 int ret;
288
289 ret = _gnutls_PRF (session, session->security_parameters.inner_secret,
290 TLS_MASTER_SIZE, label, size_of_label - 1,
291 /* XXX specification unclear on seed. */
292 "", 0, CHECKSUM_SIZE, local_checksum);
293 if (ret < 0)
294 return ret;
295
296 len = _gnutls_send_inner_application
297 (session,
298 final_p ? GNUTLS_IA_FINAL_PHASE_FINISHED :
299 GNUTLS_IA_INTERMEDIATE_PHASE_FINISHED, local_checksum, CHECKSUM_SIZE);
300
301 /* XXX Instead of calling this function over and over...?
302 * while (len == GNUTLS_E_AGAIN || len == GNUTLS_E_INTERRUPTED)
303 * len = _gnutls_io_write_flush(session);
304 */
305
306 if (len < 0)
307 {
308 gnutls_assert ();
309 return len;
310 }
311
312 return 0;
313}
314
315/**
316 * gnutls_ia_verify_endphase:
317 * @session: is a #gnutls_session_t structure.
318 * @checksum: 12-byte checksum data, received from gnutls_ia_recv().
319 *
320 * Verify TLS/IA end phase checksum data. If verification fails, the
321 * %GNUTLS_A_INNER_APPLICATION_VERIFICATION alert is sent to the other
322 * sie.
323 *
324 * This function is called when gnutls_ia_recv() return
325 * %GNUTLS_E_WARNING_IA_IPHF_RECEIVED or
326 * %GNUTLS_E_WARNING_IA_FPHF_RECEIVED.
327 *
328 * Return value: Return 0 on successful verification, or an error
329 * code. If the checksum verification of the end phase message fails,
330 * %GNUTLS_E_IA_VERIFY_FAILED is returned.
331 **/
332int
333gnutls_ia_verify_endphase (gnutls_session_t session, const char *checksum)
334{
335 char local_checksum[CHECKSUM_SIZE];
336 int client = session->security_parameters.entity == GNUTLS_CLIENT;
337 const char *label = client ? server_finished_label : client_finished_label;
338 int size_of_label = client ? sizeof (server_finished_label) :
339 sizeof (client_finished_label);
340 int ret;
341
342 ret = _gnutls_PRF (session, session->security_parameters.inner_secret,
343 TLS_MASTER_SIZE,
344 label, size_of_label - 1,
345 "", 0, CHECKSUM_SIZE, local_checksum);
346 if (ret < 0)
347 {
348 gnutls_assert ();
349 return ret;
350 }
351
352 if (memcmp (local_checksum, checksum, CHECKSUM_SIZE) != 0)
353 {
354 ret = gnutls_alert_send (session, GNUTLS_AL_FATAL,
355 GNUTLS_A_INNER_APPLICATION_VERIFICATION);
356 if (ret < 0)
357 {
358 gnutls_assert ();
359 return ret;
360 }
361
362 return GNUTLS_E_IA_VERIFY_FAILED;
363 }
364
365 return 0;
366}
367
368/**
369 * gnutls_ia_send: Send peer the specified TLS/IA data.
370 * @session: is a #gnutls_session_t structure.
371 * @data: contains the data to send
372 * @sizeofdata: is the length of the data
373 *
374 * Send TLS/IA application payload data. This function has the
375 * similar semantics with send(). The only difference is that is
376 * accepts a GNUTLS session, and uses different error codes.
377 *
378 * The TLS/IA protocol is synchronous, so you cannot send more than
379 * one packet at a time. The client always send the first packet.
380 *
381 * To finish an application phase in the server, use
382 * gnutls_ia_endphase_send(). The client cannot end an application
383 * phase unilaterally; rather, a client is required to respond with an
384 * endphase of its own if gnutls_ia_recv indicates that the server has
385 * sent one.
386 *
387 * If the EINTR is returned by the internal push function (the default
388 * is send()} then %GNUTLS_E_INTERRUPTED will be returned. If
389 * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must call
390 * this function again, with the same parameters; alternatively you
391 * could provide a %NULL pointer for data, and 0 for size.
392 *
393 * Returns the number of bytes sent, or a negative error code.
394 **/
395ssize_t
396gnutls_ia_send (gnutls_session_t session, const char *data, size_t sizeofdata)
397{
398 ssize_t len;
399
400 len = _gnutls_send_inner_application (session,
401 GNUTLS_IA_APPLICATION_PAYLOAD,
402 data, sizeofdata);
403
404 return len;
405}
406
407/**
408 * gnutls_ia_recv - read data from the TLS/IA protocol
409 * @session: is a #gnutls_session_t structure.
410 * @data: the buffer that the data will be read into, must hold >= 12 bytes.
411 * @sizeofdata: the number of requested bytes, must be >= 12.
412 *
413 * Receive TLS/IA data. This function has the similar semantics with
414 * recv(). The only difference is that is accepts a GNUTLS session,
415 * and uses different error codes.
416 *
417 * If the server attempt to finish an application phase, this function
418 * will return %GNUTLS_E_WARNING_IA_IPHF_RECEIVED or
419 * %GNUTLS_E_WARNING_IA_FPHF_RECEIVED. The caller should then invoke
420 * gnutls_ia_verify_endphase(), and if it runs the client side, also
421 * send an endphase message of its own using gnutls_ia_endphase_send.
422 *
423 * If EINTR is returned by the internal push function (the default is
424 * @code{recv()}) then GNUTLS_E_INTERRUPTED will be returned. If
425 * GNUTLS_E_INTERRUPTED or GNUTLS_E_AGAIN is returned, you must call
426 * this function again, with the same parameters; alternatively you
427 * could provide a NULL pointer for data, and 0 for size.
428 *
429 * Returns the number of bytes received. A negative error code is
430 * returned in case of an error. The
431 * %GNUTLS_E_WARNING_IA_IPHF_RECEIVED and
432 * %GNUTLS_E_WARNING_IA_FPHF_RECEIVED errors are returned when an
433 * application phase finished message has been sent by the server.
434 **/
435ssize_t
436gnutls_ia_recv (gnutls_session_t session, char *data, size_t sizeofdata)
437{
438 gnutls_ia_apptype_t msg_type;
439 ssize_t len;
440
441 len = _gnutls_recv_inner_application (session, &msg_type, data, sizeofdata);
442
443 if (msg_type == GNUTLS_IA_INTERMEDIATE_PHASE_FINISHED)
444 return GNUTLS_E_WARNING_IA_IPHF_RECEIVED;
445 else if (msg_type == GNUTLS_IA_FINAL_PHASE_FINISHED)
446 return GNUTLS_E_WARNING_IA_FPHF_RECEIVED;
447
448 return len;
449}
450
451/* XXX rewrite the following two functions as state machines, to
452 handle EAGAIN/EINTERRUPTED? just add more problems to callers,
453 though. */
454
455int
456_gnutls_ia_client_handshake (gnutls_session_t session)
457{
458 char *buf = NULL;
459 size_t buflen = 0;
460 char tmp[1024]; /* XXX */
461 ssize_t len;
462 int ret;
463 const struct gnutls_ia_client_credentials_st *cred =
464 _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL);
465
466 if (cred == NULL)
467 return GNUTLS_E_INTERNAL_ERROR;
468
469 while (1)
470 {
471 char *avp;
472 size_t avplen;
473
474 ret = cred->avp_func (session, cred->avp_ptr,
475 buf, buflen, &avp, &avplen);
476 if (ret)
477 {
478 int tmpret;
479 tmpret = gnutls_alert_send (session, GNUTLS_AL_FATAL,
480 GNUTLS_A_INNER_APPLICATION_FAILURE);
481 if (tmpret < 0)
482 gnutls_assert ();
483 return ret;
484 }
485
486 len = gnutls_ia_send (session, avp, avplen);
487 gnutls_free (avp);
488 if (len < 0)
489 return len;
490
491 len = gnutls_ia_recv (session, tmp, sizeof (tmp));
492 if (len == GNUTLS_E_WARNING_IA_IPHF_RECEIVED ||
493 len == GNUTLS_E_WARNING_IA_FPHF_RECEIVED)
494 {
495 ret = gnutls_ia_verify_endphase (session, tmp);
496 if (ret < 0)
497 return ret;
498
499 ret = gnutls_ia_endphase_send
500 (session, len == GNUTLS_E_WARNING_IA_FPHF_RECEIVED);
501 if (ret < 0)
502 return ret;
503 }
504
505 if (len == GNUTLS_E_WARNING_IA_IPHF_RECEIVED)
506 {
507 buf = NULL;
508 buflen = 0;
509 continue;
510 }
511 else if (len == GNUTLS_E_WARNING_IA_FPHF_RECEIVED)
512 break;
513
514 if (len < 0)
515 return len;
516
517 buflen = len;
518 buf = tmp;
519 }
520
521 return 0;
522}
523
524int
525_gnutls_ia_server_handshake (gnutls_session_t session)
526{
527 gnutls_ia_apptype_t msg_type;
528 ssize_t len;
529 char buf[1024];
530 int ret;
531 const struct gnutls_ia_server_credentials_st *cred =
532 _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL);
533
534 if (cred == NULL)
535 return GNUTLS_E_INTERNAL_ERROR;
536
537 do
538 {
539 char *avp;
540 size_t avplen;
541
542 len = gnutls_ia_recv (session, buf, sizeof (buf));
543 if (len == GNUTLS_E_WARNING_IA_IPHF_RECEIVED ||
544 len == GNUTLS_E_WARNING_IA_FPHF_RECEIVED)
545 {
546 ret = gnutls_ia_verify_endphase (session, buf);
547 if (ret < 0)
548 return ret;
549 }
550
551 if (len == GNUTLS_E_WARNING_IA_IPHF_RECEIVED)
552 continue;
553 else if (len == GNUTLS_E_WARNING_IA_FPHF_RECEIVED)
554 break;
555
556 if (len < 0)
557 return len;
558
559 avp = NULL;
560 avplen = 0;
561
562 ret = cred->avp_func (session, cred->avp_ptr, buf, len, &avp, &avplen);
563 if (ret < 0)
564 {
565 int tmpret;
566 tmpret = gnutls_alert_send (session, GNUTLS_AL_FATAL,
567 GNUTLS_A_INNER_APPLICATION_FAILURE);
568 if (tmpret < 0)
569 gnutls_assert ();
570 return ret;
571 }
572
573 msg_type = ret;
574
575 if (msg_type != GNUTLS_IA_APPLICATION_PAYLOAD)
576 {
577 ret = gnutls_ia_endphase_send (session, msg_type ==
578 GNUTLS_IA_FINAL_PHASE_FINISHED);
579 if (ret < 0)
580 return ret;
581 }
582 else
583 {
584 len = gnutls_ia_send (session, avp, avplen);
585 gnutls_free (avp);
586 if (len < 0)
587 return len;
588 }
589 }
590 while (1);
591
592 return 0;
593}
594
595/**
596 * gnutls_ia_handshake_p:
597 * @session: is a #gnutls_session_t structure.
598 *
599 * Predicate to be used after gnutls_handshake() to decide whether to
600 * invoke gnutls_ia_handshake(). Usable by both clients and servers.
601 *
602 * Return value: non-zero if TLS/IA handshake is expected, zero
603 * otherwise.
604 **/
605int
606gnutls_ia_handshake_p (gnutls_session_t session)
607{
608 tls_ext_st *ext = &session->security_parameters.extensions;
609
610 /* Either local side or peer doesn't do TLS/IA: don't do IA */
611
612 if (!ext->gnutls_ia_enable || !ext->gnutls_ia_peer_enable)
613 return 0;
614
615 /* Not resuming or we don't allow skipping on resumption locally: do IA */
616
617 if (!ext->gnutls_ia_allowskip || !gnutls_session_is_resumed (session))
618 return 1;
619
620 /* If we're resuming and we and the peer both allow skipping on resumption:
621 * don't do IA */
622
623 return !ext->gnutls_ia_peer_allowskip;
624}
625
626
627/**
628 * gnutls_ia_handshake:
629 * @session: is a #gnutls_session_t structure.
630 *
631 * Perform a TLS/IA handshake. This should be called after
632 * gnutls_handshake() iff gnutls_ia_handshake_p().
633 *
634 * Return 0 on success, or an error code.
635 **/
636int
637gnutls_ia_handshake (gnutls_session_t session)
638{
639 int ret;
640
641 if (session->security_parameters.entity == GNUTLS_CLIENT)
642 ret = _gnutls_ia_client_handshake (session);
643 else
644 ret = _gnutls_ia_server_handshake (session);
645
646 return ret;
647}
648
649/**
650 * gnutls_ia_allocate_client_credentials - Used to allocate an gnutls_ia_server_credentials_t structure
651 * @sc: is a pointer to an #gnutls_ia_server_credentials_t structure.
652 *
653 * This structure is complex enough to manipulate directly thus this
654 * helper function is provided in order to allocate it.
655 *
656 * Adding this credential to a session will enable TLS/IA, and will
657 * require an Application Phase after the TLS handshake (if the server
658 * support TLS/IA). Use gnutls_ia_require_inner_phase() to toggle the
659 * TLS/IA mode.
660 *
661 * Returns 0 on success.
662 **/
663int
664gnutls_ia_allocate_client_credentials (gnutls_ia_client_credentials_t * sc)
665{
666 *sc = gnutls_calloc (1, sizeof (**sc));
667
668 if (*sc == NULL)
669 return GNUTLS_E_MEMORY_ERROR;
670
671 return 0;
672}
673
674/**
675 * gnutls_ia_free_client_credentials - Used to free an allocated #gnutls_ia_client_credentials_t structure
676 * @sc: is an #gnutls_ia_client_credentials_t structure.
677 *
678 * This structure is complex enough to manipulate directly thus this
679 * helper function is provided in order to free (deallocate) it.
680 *
681 **/
682void
683gnutls_ia_free_client_credentials (gnutls_ia_client_credentials_t sc)
684{
685 gnutls_free (sc);
686}
687
688/**
689 * gnutls_ia_set_client_avp_function - Used to set a AVP callback
690 * @cred: is a #gnutls_ia_client_credentials_t structure.
691 * @avp_func: is the callback function
692 *
693 * Set the TLS/IA AVP callback handler used for the session.
694 *
695 * The AVP callback is called to process AVPs received from the
696 * server, and to get a new AVP to send to the server.
697 *
698 * The callback's function form is:
699 * int (*avp_func) (gnutls_session_t session, void *ptr,
700 * const char *last, size_t lastlen,
701 * char **next, size_t *nextlen);
702 *
703 * The @session parameter is the #gnutls_session_t structure
704 * corresponding to the current session. The @ptr parameter is the
705 * application hook pointer, set through
706 * gnutls_ia_set_client_avp_ptr(). The AVP received from the server
707 * is present in @last of @lastlen size, which will be %NULL on the
708 * first invocation. The newly allocated output AVP to send to the
709 * server should be placed in *@next of *@nextlen size.
710 *
711 * The callback may invoke gnutls_ia_permute_inner_secret() to mix any
712 * generated session keys with the TLS/IA inner secret.
713 *
714 * Return 0 (%GNUTLS_IA_APPLICATION_PAYLOAD) on success, or a negative
715 * error code to abort the TLS/IA handshake.
716 *
717 * Note that the callback must use allocate the @next parameter using
718 * gnutls_malloc(), because it is released via gnutls_free() by the
719 * TLS/IA handshake function.
720 *
721 **/
722void
723gnutls_ia_set_client_avp_function (gnutls_ia_client_credentials_t cred,
724 gnutls_ia_avp_func avp_func)
725{
726 cred->avp_func = avp_func;
727}
728
729/**
730 * gnutls_ia_set_client_avp_ptr - Sets a pointer to be sent to TLS/IA callback
731 * @cred: is a #gnutls_ia_client_credentials_t structure.
732 * @ptr: is the pointer
733 *
734 * Sets the pointer that will be provided to the TLS/IA callback
735 * function as the first argument.
736 *
737 **/
738void
739gnutls_ia_set_client_avp_ptr (gnutls_ia_client_credentials_t cred, void *ptr)
740{
741 cred->avp_ptr = ptr;
742}
743
744/**
745 * gnutls_ia_get_client_avp_ptr - Returns the pointer which is sent to TLS/IA callback
746 * @cred: is a #gnutls_ia_client_credentials_t structure.
747 *
748 * Returns the pointer that will be provided to the TLS/IA callback
749 * function as the first argument.
750 *
751 **/
752void *
753gnutls_ia_get_client_avp_ptr (gnutls_ia_client_credentials_t cred)
754{
755 return cred->avp_ptr;
756}
757
758/**
759 * gnutls_ia_allocate_server_credentials - Used to allocate an gnutls_ia_server_credentials_t structure
760 * @sc: is a pointer to an #gnutls_ia_server_credentials_t structure.
761 *
762 * This structure is complex enough to manipulate directly thus this
763 * helper function is provided in order to allocate it.
764 *
765 * Adding this credential to a session will enable TLS/IA, and will
766 * require an Application Phase after the TLS handshake (if the client
767 * support TLS/IA). Use gnutls_ia_require_inner_phase() to toggle the
768 * TLS/IA mode.
769 *
770 * Returns 0 on success.
771 **/
772int
773gnutls_ia_allocate_server_credentials (gnutls_ia_server_credentials_t * sc)
774{
775 *sc = gnutls_calloc (1, sizeof (**sc));
776
777 if (*sc == NULL)
778 return GNUTLS_E_MEMORY_ERROR;
779
780 return 0;
781}
782
783/**
784 * gnutls_ia_free_server_credentials - Used to free an allocated #gnutls_ia_server_credentials_t structure
785 * @sc: is an #gnutls_ia_server_credentials_t structure.
786 *
787 * This structure is complex enough to manipulate directly thus this
788 * helper function is provided in order to free (deallocate) it.
789 *
790 **/
791void
792gnutls_ia_free_server_credentials (gnutls_ia_server_credentials_t sc)
793{
794 gnutls_free (sc);
795}
796
797/**
798 * gnutls_ia_set_server_credentials_function - Used to set a AVP callback
799 * @cred: is a #gnutls_ia_server_credentials_t structure.
800 * @func: is the callback function
801 *
802 * Set the TLS/IA AVP callback handler used for the session.
803 *
804 * The callback's function form is:
805 * int (*avp_func) (gnutls_session_t session, void *ptr,
806 * const char *last, size_t lastlen,
807 * char **next, size_t *nextlen);
808 *
809 * The @session parameter is the #gnutls_session_t structure
810 * corresponding to the current session. The @ptr parameter is the
811 * application hook pointer, set through
812 * gnutls_ia_set_server_avp_ptr(). The AVP received from the client
813 * is present in @last of @lastlen size. The newly allocated output
814 * AVP to send to the client should be placed in *@next of *@nextlen
815 * size.
816 *
817 * The AVP callback is called to process incoming AVPs from the
818 * client, and to get a new AVP to send to the client. It can also be
819 * used to instruct the TLS/IA handshake to do go into the
820 * Intermediate or Final phases. It return a negative error code, or
821 * an #gnutls_ia_apptype_t message type.
822 *
823 * The callback may invoke gnutls_ia_permute_inner_secret() to mix any
824 * generated session keys with the TLS/IA inner secret.
825 *
826 * Specifically, return %GNUTLS_IA_APPLICATION_PAYLOAD (0) to send
827 * another AVP to the client, return
828 * %GNUTLS_IA_INTERMEDIATE_PHASE_FINISHED (1) to indicate that an
829 * IntermediatePhaseFinished message should be sent, and return
830 * %GNUTLS_IA_FINAL_PHASE_FINISHED (2) to indicate that an
831 * FinalPhaseFinished message should be sent. In the last two cases,
832 * the contents of the @next and @nextlen parameter is not used.
833 *
834 * Note that the callback must use allocate the @next parameter using
835 * gnutls_malloc(), because it is released via gnutls_free() by the
836 * TLS/IA handshake function.
837 **/
838void
839gnutls_ia_set_server_avp_function (gnutls_ia_server_credentials_t cred,
840 gnutls_ia_avp_func avp_func)
841{
842 cred->avp_func = avp_func;
843}
844
845/**
846 * gnutls_ia_set_server_avp_ptr - Sets a pointer to be sent to TLS/IA callback
847 * @cred: is a #gnutls_ia_client_credentials_t structure.
848 * @ptr: is the pointer
849 *
850 * Sets the pointer that will be provided to the TLS/IA callback
851 * function as the first argument.
852 *
853 **/
854void
855gnutls_ia_set_server_avp_ptr (gnutls_ia_server_credentials_t cred, void *ptr)
856{
857 cred->avp_ptr = ptr;
858}
859
860/**
861 * gnutls_ia_get_server_avp_ptr - Returns the pointer which is sent to TLS/IA callback
862 * @cred: is a #gnutls_ia_client_credentials_t structure.
863 *
864 * Returns the pointer that will be provided to the TLS/IA callback
865 * function as the first argument.
866 *
867 **/
868void *
869gnutls_ia_get_server_avp_ptr (gnutls_ia_server_credentials_t cred)
870{
871 return cred->avp_ptr;
872}
873
874/**
875 * gnutls_ia_enable - Indicate willingness for TLS/IA application phases
876 * @session: is a #gnutls_session_t structure.
877 * @allow_skip_on_resume: non-zero if local party allows to skip the
878 * TLS/IA application phases for a resumed session.
879 *
880 * Specify whether we must advertise support for the TLS/IA extension
881 * during the handshake.
882 *
883 * At the client side, we always advertise TLS/IA if gnutls_ia_enable
884 * was called before the handshake; at the server side, we also
885 * require that the client has advertised that it wants to run TLS/IA
886 * before including the advertisement, as required by the protocol.
887 *
888 * Similarly, at the client side we always advertise that we allow
889 * TLS/IA to be skipped for resumed sessions if @allow_skip_on_resume
890 * is non-zero; at the server side, we also require that the session
891 * is indeed resumable and that the client has also advertised that it
892 * allows TLS/IA to be skipped for resumed sessions.
893 *
894 * After the TLS handshake, call gnutls_ia_handshake_p() to find out
895 * whether both parties agreed to do a TLS/IA handshake, before
896 * calling gnutls_ia_handshake() or one of the lower level gnutls_ia_*
897 * functions.
898 **/
899void
900gnutls_ia_enable (gnutls_session_t session, int allow_skip_on_resume)
901{
902 session->security_parameters.extensions.gnutls_ia_enable = 1;
903 session->security_parameters.extensions.gnutls_ia_allowskip =
904 allow_skip_on_resume;
905}
diff --git a/src/daemon/https/openpgp/gnutls_openpgp.c b/src/daemon/https/openpgp/gnutls_openpgp.c
new file mode 100644
index 00000000..02469463
--- /dev/null
+++ b/src/daemon/https/openpgp/gnutls_openpgp.c
@@ -0,0 +1,973 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Timo Schulz
5 *
6 * This file is part of GNUTLS-EXTRA.
7 *
8 * GNUTLS-EXTRA is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * GNUTLS-EXTRA is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include "gnutls_int.h"
23#include "gnutls_errors.h"
24#include "gnutls_mpi.h"
25#include "gnutls_cert.h"
26#include "gnutls_datum.h"
27#include "gnutls_global.h"
28#include "gnutls_openpgp.h"
29#include "read-file.h"
30#include <gnutls_str.h>
31#include <gnutls_sig.h>
32#include <stdio.h>
33#include <gcrypt.h>
34#include <time.h>
35#include <sys/stat.h>
36
37#define OPENPGP_NAME_SIZE 256
38
39#define datum_append(x, y, z) _gnutls_datum_append_m (x, y, z, gnutls_realloc)
40
41
42
43static void
44release_mpi_array (mpi_t * arr, size_t n)
45{
46 mpi_t x;
47
48 while (arr && n--)
49 {
50 x = *arr;
51 _gnutls_mpi_release (&x);
52 *arr = NULL;
53 arr++;
54 }
55}
56
57
58/* Map an OpenCDK error type to a GnuTLS error type. */
59int
60_gnutls_map_cdk_rc (int rc)
61{
62 switch (rc)
63 {
64 case CDK_Success:
65 return 0;
66 case CDK_Too_Short:
67 return GNUTLS_E_SHORT_MEMORY_BUFFER;
68 case CDK_General_Error:
69 return GNUTLS_E_INTERNAL_ERROR;
70 case CDK_File_Error:
71 return GNUTLS_E_FILE_ERROR;
72 case CDK_MPI_Error:
73 return GNUTLS_E_MPI_SCAN_FAILED;
74 case CDK_Error_No_Key:
75 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
76 case CDK_Armor_Error:
77 return GNUTLS_E_BASE64_DECODING_ERROR;
78 case CDK_Inv_Value:
79 return GNUTLS_E_INVALID_REQUEST;
80 default:
81 return GNUTLS_E_INTERNAL_ERROR;
82 }
83}
84
85static unsigned long
86buftou32 (const uint8_t * buf)
87{
88 unsigned a;
89 a = buf[0] << 24;
90 a |= buf[1] << 16;
91 a |= buf[2] << 8;
92 a |= buf[3];
93 return a;
94}
95
96static int
97openpgp_pk_to_gnutls_cert (gnutls_cert * cert, cdk_pkt_pubkey_t pk)
98{
99 uint8_t buf[512 + 2];
100 size_t nbytes;
101 int algo, i;
102 int rc = 0;
103
104 if (!cert || !pk)
105 {
106 gnutls_assert ();
107 return GNUTLS_E_INVALID_REQUEST;
108 }
109
110 /* GnuTLS OpenPGP does not support ELG keys */
111 if (is_ELG (pk->pubkey_algo))
112 {
113 gnutls_assert ();
114 return GNUTLS_E_UNWANTED_ALGORITHM;
115 }
116
117 algo = GNUTLS_PK_RSA;
118 cert->subject_pk_algorithm = algo;
119 cert->version = pk->version;
120 cert->cert_type = GNUTLS_CRT_OPENPGP;
121
122 cert->key_usage = 0;
123 if (pk->pubkey_usage & CDK_KEY_USG_SIGN)
124 cert->key_usage = KEY_DIGITAL_SIGNATURE;
125 if (pk->pubkey_usage & CDK_KEY_USG_ENCR)
126 cert->key_usage = KEY_KEY_ENCIPHERMENT;
127 if (!cert->key_usage) /* Fallback code. */
128 {
129 if (pk->pubkey_algo == GCRY_PK_DSA || pk->pubkey_algo == GCRY_PK_RSA_S)
130 cert->key_usage = KEY_DIGITAL_SIGNATURE;
131 else if (pk->pubkey_algo == GCRY_PK_RSA_E)
132 cert->key_usage = KEY_KEY_ENCIPHERMENT;
133 else if (pk->pubkey_algo == GCRY_PK_RSA)
134 cert->key_usage = KEY_DIGITAL_SIGNATURE | KEY_KEY_ENCIPHERMENT;
135 }
136
137 cert->params_size = cdk_pk_get_npkey (pk->pubkey_algo);
138 for (i = 0; i < cert->params_size; i++)
139 {
140 nbytes = sizeof (buf) / sizeof (buf[0]);
141 cdk_pk_get_mpi (pk, i, buf, nbytes, &nbytes, NULL);
142 rc = _gnutls_mpi_scan_pgp (&cert->params[i], buf, &nbytes);
143 if (rc)
144 {
145 rc = GNUTLS_E_MPI_SCAN_FAILED;
146 break;
147 }
148 }
149
150 if (rc)
151 release_mpi_array (cert->params, i - 1);
152 return rc;
153}
154
155/*-
156 * _gnutls_openpgp_raw_privkey_to_gkey - Converts an OpenPGP secret key to GnuTLS
157 * @pkey: the GnuTLS private key context to store the key.
158 * @raw_key: the raw data which contains the whole key packets.
159 * @format: the format of the key packets.
160 *
161 * The RFC2440 (OpenPGP Message Format) data is converted into the
162 * GnuTLS specific data which is need to perform secret key operations.
163 *
164 * This function can read both BASE64 and RAW keys.
165 -*/
166int
167_gnutls_openpgp_raw_privkey_to_gkey (gnutls_privkey * pkey,
168 const gnutls_datum_t * raw_key,
169 gnutls_openpgp_crt_fmt_t format)
170{
171 cdk_kbnode_t snode = NULL;
172 cdk_packet_t pkt;
173 cdk_stream_t out;
174 cdk_pkt_seckey_t sk = NULL;
175 int pke_algo, i, j;
176 size_t nbytes = 0;
177 uint8_t buf[512];
178 int rc = 0;
179
180 if (!pkey || raw_key->size <= 0)
181 {
182 gnutls_assert ();
183 return GNUTLS_E_CERTIFICATE_ERROR;
184 }
185
186 rc = cdk_stream_tmp_new (&out);
187 if (rc)
188 return GNUTLS_E_CERTIFICATE_ERROR;
189
190 if (format == GNUTLS_OPENPGP_FMT_BASE64)
191 {
192 rc = cdk_stream_set_armor_flag (out, 0);
193 if (rc)
194 {
195 cdk_stream_close (out);
196 rc = _gnutls_map_cdk_rc (rc);
197 gnutls_assert ();
198 goto leave;
199 }
200 }
201
202 cdk_stream_write (out, raw_key->data, raw_key->size);
203 cdk_stream_seek (out, 0);
204
205 rc = cdk_keydb_get_keyblock (out, &snode);
206 cdk_stream_close (out);
207 if (rc)
208 {
209 rc = GNUTLS_E_OPENPGP_GETKEY_FAILED;
210 goto leave;
211 }
212
213 pkt = cdk_kbnode_find_packet (snode, CDK_PKT_SECRET_KEY);
214 if (!pkt)
215 {
216 rc = GNUTLS_E_OPENPGP_GETKEY_FAILED;
217 goto leave;
218 }
219 sk = pkt->pkt.secret_key;
220 pke_algo = sk->pk->pubkey_algo;
221 pkey->params_size = cdk_pk_get_npkey (pke_algo);
222 for (i = 0; i < pkey->params_size; i++)
223 {
224 nbytes = sizeof (buf) / sizeof (buf[0]);
225 cdk_pk_get_mpi (sk->pk, i, buf, nbytes, &nbytes, NULL);
226 rc = _gnutls_mpi_scan_pgp (&pkey->params[i], buf, &nbytes);
227 if (rc)
228 {
229 rc = GNUTLS_E_MPI_SCAN_FAILED;
230 release_mpi_array (pkey->params, i - 1);
231 goto leave;
232 }
233 }
234
235 pkey->params_size += cdk_pk_get_nskey (pke_algo);
236 for (j = 0; j < cdk_pk_get_nskey (pke_algo); j++, i++)
237 {
238 nbytes = sizeof (buf) / sizeof (buf[0]);
239 cdk_sk_get_mpi (sk, j, buf, nbytes, &nbytes, NULL);
240 rc = _gnutls_mpi_scan_pgp (&pkey->params[i], buf, &nbytes);
241 if (rc)
242 {
243 rc = GNUTLS_E_MPI_SCAN_FAILED;
244 release_mpi_array (pkey->params, i - 1);
245 goto leave;
246 }
247 }
248
249 if (is_ELG (pke_algo))
250 return GNUTLS_E_UNWANTED_ALGORITHM;
251 else if (is_RSA (pke_algo))
252 pkey->pk_algorithm = GNUTLS_PK_RSA;
253
254leave:
255 cdk_kbnode_release (snode);
256 return rc;
257}
258
259
260/*-
261 * _gnutls_openpgp_raw_key_to_gcert - Converts raw OpenPGP data to GnuTLS certs
262 * @cert: the certificate to store the data.
263 * @raw: the buffer which contains the whole OpenPGP key packets.
264 *
265 * The RFC2440 (OpenPGP Message Format) data is converted to a GnuTLS
266 * specific certificate.
267 -*/
268int
269_gnutls_openpgp_raw_key_to_gcert (gnutls_cert * cert,
270 const gnutls_datum_t * raw)
271{
272 cdk_kbnode_t knode = NULL;
273 cdk_packet_t pkt = NULL;
274 int rc;
275
276 if (!cert)
277 {
278 gnutls_assert ();
279 return GNUTLS_E_INVALID_REQUEST;
280 }
281
282 memset (cert, 0, sizeof *cert);
283
284 rc = cdk_kbnode_read_from_mem (&knode, raw->data, raw->size);
285 if (!(rc = _gnutls_map_cdk_rc (rc)))
286 {
287 pkt = cdk_kbnode_find_packet (knode, CDK_PKT_PUBLIC_KEY);
288 }
289 if (!pkt)
290 {
291 gnutls_assert ();
292 rc = _gnutls_map_cdk_rc (rc);
293 }
294 if (!rc)
295 rc = _gnutls_set_datum (&cert->raw, raw->data, raw->size);
296 if (!rc)
297 rc = openpgp_pk_to_gnutls_cert (cert, pkt->pkt.public_key);
298
299 cdk_kbnode_release (knode);
300 return rc;
301}
302
303/**
304 * gnutls_certificate_set_openpgp_key - Used to set keys in a gnutls_certificate_credentials_t structure
305 * @res: is an #gnutls_certificate_credentials_t structure.
306 * @key: contains an openpgp public key
307 * @pkey: is an openpgp private key
308 *
309 * This function sets a certificate/private key pair in the
310 * gnutls_certificate_credentials_t structure. This function may be called
311 * more than once (in case multiple keys/certificates exist for the
312 * server).
313 *
314 **/
315int
316gnutls_certificate_set_openpgp_key (gnutls_certificate_credentials_t
317 res, gnutls_openpgp_crt_t crt,
318 gnutls_openpgp_privkey_t pkey)
319{
320 int ret;
321
322 /* this should be first */
323
324 res->pkey = gnutls_realloc_fast (res->pkey,
325 (res->ncerts + 1) *
326 sizeof (gnutls_privkey));
327 if (res->pkey == NULL)
328 {
329 gnutls_assert ();
330 return GNUTLS_E_MEMORY_ERROR;
331 }
332
333 ret = _gnutls_openpgp_privkey_to_gkey (&res->pkey[res->ncerts], pkey);
334 if (ret < 0)
335 {
336 gnutls_assert ();
337 return ret;
338 }
339
340 res->cert_list = gnutls_realloc_fast (res->cert_list,
341 (1 +
342 res->ncerts) *
343 sizeof (gnutls_cert *));
344 if (res->cert_list == NULL)
345 {
346 gnutls_assert ();
347 return GNUTLS_E_MEMORY_ERROR;
348 }
349
350 res->cert_list_length = gnutls_realloc_fast (res->cert_list_length,
351 (1 +
352 res->ncerts) * sizeof (int));
353 if (res->cert_list_length == NULL)
354 {
355 gnutls_assert ();
356 return GNUTLS_E_MEMORY_ERROR;
357 }
358
359 res->cert_list[res->ncerts] = gnutls_calloc (1, sizeof (gnutls_cert));
360 if (res->cert_list[res->ncerts] == NULL)
361 {
362 gnutls_assert ();
363 return GNUTLS_E_MEMORY_ERROR;
364 }
365
366 res->cert_list_length[res->ncerts] = 1;
367
368 ret = _gnutls_openpgp_crt_to_gcert (res->cert_list[res->ncerts], crt);
369 if (ret < 0)
370 {
371 gnutls_assert ();
372 return ret;
373 }
374
375 res->ncerts++;
376
377 /* FIXME: Check if the keys match. */
378
379 return 0;
380}
381
382
383/*-
384 * gnutls_openpgp_get_key - Retrieve a key from the keyring.
385 * @key: the destination context to save the key.
386 * @keyring: the datum struct that contains all keyring information.
387 * @attr: The attribute (keyid, fingerprint, ...).
388 * @by: What attribute is used.
389 *
390 * This function can be used to retrieve keys by different pattern
391 * from a binary or a file keyring.
392 -*/
393int
394gnutls_openpgp_get_key (gnutls_datum_t * key,
395 gnutls_openpgp_keyring_t keyring, key_attr_t by,
396 opaque * pattern)
397{
398 cdk_kbnode_t knode = NULL;
399 unsigned long keyid[2];
400 unsigned char *buf;
401 void *desc;
402 size_t len;
403 int rc = 0;
404
405 if (!key || !keyring || by == KEY_ATTR_NONE)
406 {
407 gnutls_assert ();
408 return GNUTLS_E_INVALID_REQUEST;
409 }
410
411 memset (key, 0, sizeof *key);
412
413 if (by == KEY_ATTR_SHORT_KEYID)
414 {
415 keyid[0] = buftou32 (pattern);
416 desc = keyid;
417 }
418 else if (by == KEY_ATTR_KEYID)
419 {
420 keyid[0] = buftou32 (pattern);
421 keyid[1] = buftou32 (pattern + 4);
422 desc = keyid;
423 }
424 else
425 desc = pattern;
426 rc = cdk_keydb_search_start (keyring->db, by, desc);
427 if (!rc)
428 rc = cdk_keydb_search (keyring->db, &knode);
429 if (rc)
430 {
431 rc = _gnutls_map_cdk_rc (rc);
432 goto leave;
433 }
434
435 if (!cdk_kbnode_find (knode, CDK_PKT_PUBLIC_KEY))
436 {
437 rc = GNUTLS_E_OPENPGP_GETKEY_FAILED;
438 goto leave;
439 }
440
441 /* We let the function allocate the buffer to avoid
442 to call the function twice. */
443 rc = cdk_kbnode_write_to_mem_alloc (knode, &buf, &len);
444 if (!rc)
445 datum_append (key, buf, len);
446 cdk_free (buf);
447
448leave:
449 cdk_kbnode_release (knode);
450 return rc;
451}
452
453
454/* Convert the stream to a datum. In this case we use the mmap
455 function to map the entire stream to a buffer. */
456static int
457stream_to_datum (cdk_stream_t inp, gnutls_datum_t * raw)
458{
459 uint8_t *buf;
460 size_t buflen;
461
462 if (!inp || !raw)
463 {
464 gnutls_assert ();
465 return GNUTLS_E_INVALID_REQUEST;
466 }
467
468 cdk_stream_mmap (inp, &buf, &buflen);
469 datum_append (raw, buf, buflen);
470 cdk_free (buf);
471
472 if (!buflen)
473 {
474 gnutls_assert ();
475 return GNUTLS_E_INTERNAL_ERROR;
476 }
477
478 return 0;
479}
480
481
482
483/**
484 * gnutls_certificate_set_openpgp_key_mem - Used to set OpenPGP keys
485 * @res: the destination context to save the data.
486 * @cert: the datum that contains the public key.
487 * @key: the datum that contains the secret key.
488 *
489 * This funtion is used to load OpenPGP keys into the GnuTLS credential
490 * structure.
491 * It doesn't matter whether the keys are armored or not, but the files
492 * should only contain one key which should not be encrypted.
493 **/
494int
495gnutls_certificate_set_openpgp_key_mem (gnutls_certificate_credentials_t
496 res, const gnutls_datum_t * icert,
497 const gnutls_datum_t * ikey,
498 gnutls_openpgp_crt_fmt_t format)
499{
500 gnutls_openpgp_privkey_t key;
501 gnutls_openpgp_crt_t cert;
502 int ret;
503
504 ret = gnutls_openpgp_privkey_init (&key);
505 if (ret < 0)
506 {
507 gnutls_assert ();
508 return ret;
509 }
510
511 ret = gnutls_openpgp_privkey_import (key, ikey, format, NULL, 0);
512 if (ret < 0)
513 {
514 gnutls_assert ();
515 gnutls_openpgp_privkey_deinit (key);
516 return ret;
517 }
518
519 ret = gnutls_openpgp_crt_init (&cert);
520 if (ret < 0)
521 {
522 gnutls_assert ();
523 gnutls_openpgp_privkey_deinit (key);
524 return ret;
525 }
526
527 ret = gnutls_openpgp_crt_import (cert, icert, format);
528 if (ret < 0)
529 {
530 gnutls_assert ();
531 gnutls_openpgp_privkey_deinit (key);
532 gnutls_openpgp_crt_deinit (cert);
533 return ret;
534 }
535
536
537 ret = gnutls_certificate_set_openpgp_key (res, cert, key);
538
539 gnutls_openpgp_privkey_deinit (key);
540 gnutls_openpgp_crt_deinit (cert);
541
542 return ret;
543}
544
545
546/**
547 * gnutls_certificate_set_openpgp_key_file - Used to set OpenPGP keys
548 * @res: the destination context to save the data.
549 * @certfile: the file that contains the public key.
550 * @keyfile: the file that contains the secret key.
551 *
552 * This funtion is used to load OpenPGP keys into the GnuTLS credentials structure.
553 * It doesn't matter whether the keys are armored or not, but the files
554 * should only contain one key which should not be encrypted.
555 **/
556int
557gnutls_certificate_set_openpgp_key_file (gnutls_certificate_credentials_t
558 res, const char *certfile,
559 const char *keyfile,
560 gnutls_openpgp_crt_fmt_t format)
561{
562 struct stat statbuf;
563 gnutls_datum_t key, cert;
564 int rc;
565 size_t size;
566
567 if (!res || !keyfile || !certfile)
568 {
569 gnutls_assert ();
570 return GNUTLS_E_INVALID_REQUEST;
571 }
572
573 if (stat (certfile, &statbuf) || stat (keyfile, &statbuf))
574 {
575 gnutls_assert ();
576 return GNUTLS_E_FILE_ERROR;
577 }
578
579 cert.data = read_binary_file (certfile, &size);
580 cert.size = (unsigned int) size;
581 if (cert.data == NULL)
582 {
583 gnutls_assert ();
584 return GNUTLS_E_FILE_ERROR;
585 }
586
587 key.data = read_binary_file (keyfile, &size);
588 key.size = (unsigned int) size;
589 if (key.data == NULL)
590 {
591 gnutls_assert ();
592 free (cert.data);
593 return GNUTLS_E_FILE_ERROR;
594 }
595
596 rc = gnutls_certificate_set_openpgp_key_mem (res, &cert, &key, format);
597
598 free (cert.data);
599 free (key.data);
600
601 if (rc < 0)
602 {
603 gnutls_assert ();
604 return rc;
605 }
606
607 return 0;
608}
609
610
611int
612gnutls_openpgp_count_key_names (const gnutls_datum_t * cert)
613{
614 cdk_kbnode_t knode, p, ctx;
615 cdk_packet_t pkt;
616 int nuids;
617
618 if (cert == NULL)
619 {
620 gnutls_assert ();
621 return 0;
622 }
623
624 if (cdk_kbnode_read_from_mem (&knode, cert->data, cert->size))
625 {
626 gnutls_assert ();
627 return 0;
628 }
629
630 ctx = NULL;
631 for (nuids = 0;;)
632 {
633 p = cdk_kbnode_walk (knode, &ctx, 0);
634 if (!p)
635 break;
636 pkt = cdk_kbnode_get_packet (p);
637 if (pkt->pkttype == CDK_PKT_USER_ID)
638 nuids++;
639 }
640
641 cdk_kbnode_release (knode);
642 return nuids;
643}
644
645
646/**
647 * gnutls_certificate_set_openpgp_keyring_file - Sets a keyring file for OpenPGP
648 * @c: A certificate credentials structure
649 * @file: filename of the keyring.
650 *
651 * The function is used to set keyrings that will be used internally
652 * by various OpenPGP functions. For example to find a key when it
653 * is needed for an operations. The keyring will also be used at the
654 * verification functions.
655 *
656 **/
657int
658gnutls_certificate_set_openpgp_keyring_file (gnutls_certificate_credentials_t
659 c, const char *file,
660 gnutls_openpgp_crt_fmt_t format)
661{
662 gnutls_datum_t ring;
663 size_t size;
664 int rc;
665
666 if (!c || !file)
667 {
668 gnutls_assert ();
669 return GNUTLS_E_INVALID_REQUEST;
670 }
671
672 ring.data = read_binary_file (file, &size);
673 ring.size = (unsigned int) size;
674 if (ring.data == NULL)
675 {
676 gnutls_assert ();
677 return GNUTLS_E_FILE_ERROR;
678 }
679
680 rc =
681 gnutls_certificate_set_openpgp_keyring_mem (c, ring.data, ring.size,
682 format);
683
684 free (ring.data);
685
686 return rc;
687}
688
689/**
690 * gnutls_certificate_set_openpgp_keyring_mem - Add keyring data for OpenPGP
691 * @c: A certificate credentials structure
692 * @data: buffer with keyring data.
693 * @dlen: length of data buffer.
694 *
695 * The function is used to set keyrings that will be used internally
696 * by various OpenPGP functions. For example to find a key when it
697 * is needed for an operations. The keyring will also be used at the
698 * verification functions.
699 *
700 **/
701int
702gnutls_certificate_set_openpgp_keyring_mem (gnutls_certificate_credentials_t
703 c, const opaque * data,
704 size_t dlen,
705 gnutls_openpgp_crt_fmt_t format)
706{
707#ifndef KEYRING_HACK
708 cdk_stream_t inp;
709 size_t count;
710 uint8_t *buf;
711 gnutls_datum ddata;
712 int rc;
713
714 ddata.data = (void *) data;
715 ddata.size = dlen;
716
717 if (!c || !data || !dlen)
718 {
719 gnutls_assert ();
720 return GNUTLS_E_INVALID_REQUEST;
721 }
722
723 rc = gnutls_openpgp_keyring_init (&c->keyring);
724 if (rc < 0)
725 {
726 gnutls_assert ();
727 return rc;
728 }
729
730 rc = gnutls_openpgp_keyring_import (c->keyring, &ddata, format);
731 if (rc < 0)
732 {
733 gnutls_assert ();
734 gnutls_openpgp_keyring_deinit (c->keyring);
735 return rc;
736 }
737
738 return 0;
739#else
740
741 c->keyring_format = format;
742
743 c->keyring.data = gnutls_malloc (dlen + 1);
744 if (c->keyring.data == NULL)
745 {
746 gnutls_assert ();
747 return GNUTLS_E_MEMORY_ERROR;
748 }
749 memcpy (c->keyring.data, data, dlen);
750 c->keyring.data[dlen] = 0;
751 c->keyring.size = dlen;
752
753#endif
754}
755
756/*-
757 * _gnutls_openpgp_request_key - Receives a key from a database, key server etc
758 * @ret - a pointer to gnutls_datum_t structure.
759 * @cred - a gnutls_certificate_credentials_t structure.
760 * @key_fingerprint - The keyFingerprint
761 * @key_fingerprint_size - the size of the fingerprint
762 *
763 * Retrieves a key from a local database, keyring, or a key server. The
764 * return value is locally allocated.
765 *
766 -*/
767int
768_gnutls_openpgp_request_key (gnutls_session_t session, gnutls_datum_t * ret,
769 const gnutls_certificate_credentials_t cred,
770 opaque * key_fpr, int key_fpr_size)
771{
772 int rc = 0;
773#ifdef KEYRING_HACK
774 gnutls_openpgp_keyring_t kring;
775#endif
776
777 if (!ret || !cred || !key_fpr)
778 {
779 gnutls_assert ();
780 return GNUTLS_E_INVALID_REQUEST;
781 }
782
783 if (key_fpr_size != 16 && key_fpr_size != 20)
784 return GNUTLS_E_HASH_FAILED; /* only MD5 and SHA1 are supported */
785
786#ifndef KEYRING_HACK
787 rc = gnutls_openpgp_get_key (ret, cred->keyring, KEY_ATTR_FPR, key_fpr);
788#else
789 rc = gnutls_openpgp_keyring_init (&kring);
790 if (rc < 0)
791 {
792 gnutls_assert ();
793 return rc;
794 }
795
796 rc =
797 gnutls_openpgp_keyring_import (kring, &cred->keyring,
798 cred->keyring_format);
799 if (rc < 0)
800 {
801 gnutls_assert ();
802 gnutls_openpgp_keyring_deinit (kring);
803 return rc;
804 }
805#endif
806 if (rc >= 0) /* key was found */
807 {
808 rc = 0;
809 goto error;
810 }
811 else
812 rc = GNUTLS_E_OPENPGP_GETKEY_FAILED;
813
814 /* If the callback function was set, then try this one. */
815 if (session->internals.openpgp_recv_key_func != NULL)
816 {
817 rc = session->internals.openpgp_recv_key_func (session,
818 key_fpr,
819 key_fpr_size, ret);
820 if (rc < 0)
821 {
822 gnutls_assert ();
823 rc = GNUTLS_E_OPENPGP_GETKEY_FAILED;
824 goto error;
825 }
826 }
827
828error:
829#ifdef KEYRING_HACK
830 gnutls_openpgp_keyring_deinit (kring);
831#endif
832 return rc;
833}
834
835/**
836 * gnutls_openpgp_set_recv_key_function - Used to set a key retrieval callback for PGP keys
837 * @session: a TLS session
838 * @func: the callback
839 *
840 * This funtion will set a key retrieval function for OpenPGP keys. This
841 * callback is only useful in server side, and will be used if the peer
842 * sent a key fingerprint instead of a full key.
843 *
844 **/
845void
846gnutls_openpgp_set_recv_key_function (gnutls_session_t session,
847 gnutls_openpgp_recv_key_func func)
848{
849 session->internals.openpgp_recv_key_func = func;
850}
851
852
853/* Copies a gnutls_openpgp_privkey_t to a gnutls_privkey structure. */
854int
855_gnutls_openpgp_privkey_to_gkey (gnutls_privkey * dest,
856 gnutls_openpgp_privkey_t src)
857{
858 int i, ret;
859
860 memset (dest, 0, sizeof (gnutls_privkey));
861
862 for (i = 0; i < src->pkey.params_size; i++)
863 {
864 dest->params[i] = _gnutls_mpi_copy (src->pkey.params[i]);
865 if (dest->params[i] == NULL)
866 {
867 gnutls_assert ();
868 ret = GNUTLS_E_MEMORY_ERROR;
869 goto cleanup;
870 }
871 }
872
873 dest->pk_algorithm = src->pkey.pk_algorithm;
874 dest->params_size = src->pkey.params_size;
875
876 return 0;
877
878cleanup:
879 for (i = 0; i < src->pkey.params_size; i++)
880 _gnutls_mpi_release (&dest->params[i]);
881 return ret;
882}
883
884/* Converts a parsed gnutls_openpgp_crt_t to a gnutls_cert structure.
885 */
886int
887_gnutls_openpgp_crt_to_gcert (gnutls_cert * gcert, gnutls_openpgp_crt_t cert)
888{
889 opaque *der;
890 size_t der_size = 0;
891 gnutls_datum_t raw;
892 int ret;
893
894 memset (gcert, 0, sizeof (gnutls_cert));
895 gcert->cert_type = GNUTLS_CRT_OPENPGP;
896
897
898 ret = gnutls_openpgp_crt_export (cert, GNUTLS_OPENPGP_FMT_RAW,
899 NULL, &der_size);
900 if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
901 {
902 gnutls_assert ();
903 return ret;
904 }
905
906 der = gnutls_malloc (der_size);
907 if (der == NULL)
908 {
909 gnutls_assert ();
910 return GNUTLS_E_MEMORY_ERROR;
911 }
912
913 ret = gnutls_openpgp_crt_export (cert, GNUTLS_OPENPGP_FMT_RAW,
914 der, &der_size);
915 if (ret < 0)
916 {
917 gnutls_assert ();
918 gnutls_free (der);
919 return ret;
920 }
921
922 raw.data = der;
923 raw.size = der_size;
924
925 ret = _gnutls_openpgp_raw_key_to_gcert (gcert, &raw);
926 if (ret < 0)
927 {
928 gnutls_assert ();
929 gnutls_free (der);
930 return ret;
931 }
932
933 gnutls_free (der);
934
935 return 0;
936
937}
938
939
940/**
941 * gnutls_openpgp_privkey_sign_hash - This function will sign the given data using the private key params
942 * @key: Holds the key
943 * @hash: holds the data to be signed
944 * @signature: will contain newly allocated signature
945 *
946 * This function will sign the given hash using the private key.
947 *
948 * Return value: In case of failure a negative value will be returned,
949 * and 0 on success.
950 **/
951int
952gnutls_openpgp_privkey_sign_hash (gnutls_openpgp_privkey_t key,
953 const gnutls_datum_t * hash,
954 gnutls_datum_t * signature)
955{
956 int result;
957
958 if (key == NULL)
959 {
960 gnutls_assert ();
961 return GNUTLS_E_INVALID_REQUEST;
962 }
963
964 result = _gnutls_sign (key->pkey.pk_algorithm, key->pkey.params,
965 key->pkey.params_size, hash, signature);
966 if (result < 0)
967 {
968 gnutls_assert ();
969 return result;
970 }
971
972 return 0;
973}
diff --git a/src/daemon/https/openpgp/gnutls_openpgp.h b/src/daemon/https/openpgp/gnutls_openpgp.h
new file mode 100644
index 00000000..82e22eee
--- /dev/null
+++ b/src/daemon/https/openpgp/gnutls_openpgp.h
@@ -0,0 +1,98 @@
1#include <config.h>
2
3#ifdef ENABLE_OPENPGP
4
5#ifndef GNUTLS_OPENPGP_H
6#define GNUTLS_OPENPGP_H
7
8#include <auth_cert.h>
9#include <opencdk.h>
10
11typedef struct
12 {
13 int type;
14 size_t size;
15 uint8_t *data;
16 }keybox_blob;
17
18typedef enum
19 {
20 KBX_BLOB_FILE = 0x00,
21 KBX_BLOB_DATA = 0x01
22 }keyring_blob_types;
23
24/* OpenCDK compatible */
25typedef enum
26 {
27 KEY_ATTR_NONE = 0,
28 KEY_ATTR_SHORT_KEYID = 3,
29 KEY_ATTR_KEYID = 4,
30 KEY_ATTR_FPR = 5
31 }key_attr_t;
32
33int
34gnutls_certificate_set_openpgp_key_file (gnutls_certificate_credentials_t
35 res, const char *CERTFILE,
36 const char *KEYFILE, gnutls_openpgp_crt_fmt_t);
37
38int gnutls_openpgp_count_key_names (const gnutls_datum_t * cert);
39
40int gnutls_certificate_set_openpgp_keyring_file
41(gnutls_certificate_credentials_t c, const char *file, gnutls_openpgp_crt_fmt_t);
42
43int
44gnutls_certificate_set_openpgp_keyring_mem (gnutls_certificate_credentials_t
45 c, const opaque * data,
46 size_t dlen, gnutls_openpgp_crt_fmt_t);
47
48int gnutls_openpgp_get_key (gnutls_datum_t * key,
49 gnutls_openpgp_keyring_t keyring,
50 key_attr_t by, opaque * pattern);
51
52int gnutls_openpgp_recv_key (const char *host,
53 short port, uint32_t keyid,
54 gnutls_datum_t * key);
55
56/* internal */
57int _gnutls_openpgp_raw_key_to_gcert (gnutls_cert * cert,
58 const gnutls_datum_t * raw);
59
60extern int
61_gnutls_openpgp_raw_privkey_to_gkey (gnutls_privkey * pkey,
62 const gnutls_datum_t * raw_key,
63 gnutls_openpgp_crt_fmt_t format);
64
65int
66_gnutls_openpgp_request_key (gnutls_session_t,
67 gnutls_datum_t * ret,
68 const gnutls_certificate_credentials_t cred,
69 opaque * key_fpr, int key_fpr_size);
70
71int _gnutls_openpgp_verify_key (const gnutls_certificate_credentials_t,
72 const gnutls_datum_t * cert_list,
73 int cert_list_length, unsigned int *status);
74int _gnutls_openpgp_fingerprint (const gnutls_datum_t * cert,
75 unsigned char *fpr, size_t * fprlen);
76time_t _gnutls_openpgp_get_raw_key_creation_time (const gnutls_datum_t *
77 cert);
78time_t _gnutls_openpgp_get_raw_key_expiration_time (const gnutls_datum_t *
79 cert);
80
81int
82gnutls_openpgp_privkey_init (gnutls_openpgp_privkey_t * key);
83
84int
85gnutls_openpgp_privkey_init (gnutls_openpgp_privkey_t * key);
86
87void
88gnutls_openpgp_privkey_deinit (gnutls_openpgp_privkey_t key);
89
90int
91gnutls_openpgp_privkey_import (gnutls_openpgp_privkey_t key,
92 const gnutls_datum_t * data,
93 gnutls_openpgp_crt_fmt_t format,
94 const char *pass, unsigned int flags);
95
96#endif /*GNUTLS_OPENPGP_H */
97
98#endif /*ENABLE_OPENPGP */
diff --git a/src/daemon/https/openpgp/openpgp.h b/src/daemon/https/openpgp/openpgp.h
new file mode 100644
index 00000000..e4ea952b
--- /dev/null
+++ b/src/daemon/https/openpgp/openpgp.h
@@ -0,0 +1,182 @@
1#ifndef OPENPGP_H
2#define OPENPGP_H
3
4#include "config.h"
5
6#ifdef ENABLE_OPENPGP
7
8#ifdef __cplusplus
9extern "C"
10 {
11#endif
12
13#include <gnutls.h>
14#include <gnutls_cert.h>
15#include "opencdk.h"
16
17/* Internal context to store the OpenPGP key. */
18typedef struct gnutls_openpgp_crt_int
19 {
20 cdk_kbnode_t knode;
21 } gnutls_openpgp_crt_int;
22
23/* Internal context to store the private OpenPGP key. */
24typedef struct gnutls_openpgp_privkey_int
25 {
26 gnutls_privkey pkey;
27 } gnutls_openpgp_privkey_int;
28
29typedef struct gnutls_openpgp_keyring_int
30 {
31 cdk_keydb_hd_t db;
32 cdk_stream_t db_stream;
33 } gnutls_openpgp_keyring_int;
34
35typedef struct gnutls_openpgp_keyring_int * gnutls_openpgp_keyring_t;
36/* gnutls_openpgp_cert_t should be defined in gnutls.h */
37
38/* initializes the memory for gnutls_openpgp_crt_t struct */
39int gnutls_openpgp_crt_init(gnutls_openpgp_crt_t * key);
40/* frees all memory */
41void gnutls_openpgp_crt_deinit(gnutls_openpgp_crt_t key);
42
43int gnutls_openpgp_crt_import(gnutls_openpgp_crt_t key,
44 const gnutls_datum_t * data,
45 gnutls_openpgp_crt_fmt_t format);
46int gnutls_openpgp_crt_export(gnutls_openpgp_crt_t key,
47 gnutls_openpgp_crt_fmt_t format,
48 void *output_data,
49 size_t * output_data_size);
50
51/* The key_usage flags are defined in gnutls.h. They are
52 * the GNUTLS_KEY_* definitions.
53 */
54int gnutls_openpgp_crt_get_key_usage(gnutls_openpgp_crt_t cert,
55 unsigned int *key_usage);
56int gnutls_openpgp_crt_get_fingerprint(gnutls_openpgp_crt_t key,
57 void *fpr,
58 size_t * fprlen);
59
60int gnutls_openpgp_crt_get_name(gnutls_openpgp_crt_t key,
61 int idx,
62 char *buf,
63 size_t * sizeof_buf);
64
65gnutls_pk_algorithm_t
66 gnutls_openpgp_crt_get_pk_algorithm(gnutls_openpgp_crt_t key,
67 unsigned int *bits);
68
69int gnutls_openpgp_crt_get_version(gnutls_openpgp_crt_t key);
70
71time_t gnutls_openpgp_crt_get_creation_time(gnutls_openpgp_crt_t key);
72time_t gnutls_openpgp_crt_get_expiration_time(gnutls_openpgp_crt_t key);
73
74int gnutls_openpgp_crt_get_id(gnutls_openpgp_crt_t key,
75 unsigned char keyid[8]);
76
77int gnutls_openpgp_crt_check_hostname(gnutls_openpgp_crt_t key,
78 const char *hostname);
79
80/* privkey stuff. */
81int gnutls_openpgp_privkey_init(gnutls_openpgp_privkey_t * key);
82void gnutls_openpgp_privkey_deinit(gnutls_openpgp_privkey_t key);
83gnutls_pk_algorithm_t
84 gnutls_openpgp_privkey_get_pk_algorithm(gnutls_openpgp_privkey_t key,
85 unsigned int *bits);
86int gnutls_openpgp_privkey_import(gnutls_openpgp_privkey_t key,
87 const gnutls_datum_t * data,
88 gnutls_openpgp_crt_fmt_t format,
89 const char *pass,
90 unsigned int flags);
91int gnutls_openpgp_privkey_sign_hash(gnutls_openpgp_privkey_t key,
92 const gnutls_datum_t * hash,
93 gnutls_datum_t * signature);
94
95/* Keyring stuff. */
96
97int gnutls_openpgp_keyring_init(gnutls_openpgp_keyring_t * keyring);
98void gnutls_openpgp_keyring_deinit(gnutls_openpgp_keyring_t keyring);
99
100int gnutls_openpgp_keyring_import(gnutls_openpgp_keyring_t keyring,
101 const gnutls_datum_t * data,
102 gnutls_openpgp_crt_fmt_t format);
103
104int gnutls_openpgp_keyring_check_id(gnutls_openpgp_keyring_t ring,
105 const unsigned char keyid[8],
106 unsigned int flags);
107
108int gnutls_openpgp_crt_verify_ring(gnutls_openpgp_crt_t key,
109 gnutls_openpgp_keyring_t keyring,
110 unsigned int flags,
111 unsigned int *verify
112/* the output of the verification */);
113
114int gnutls_openpgp_crt_verify_self(gnutls_openpgp_crt_t key,
115 unsigned int flags,
116 unsigned int *verify);
117
118/* certificate authentication stuff.
119 */
120int gnutls_certificate_set_openpgp_key(gnutls_certificate_credentials_t
121 res,
122 gnutls_openpgp_crt_t key,
123 gnutls_openpgp_privkey_t pkey);
124
125#ifdef __cplusplus
126}
127#endif
128
129int _gnutls_map_cdk_rc(int rc);
130int gnutls_openpgp_crt_get_name(gnutls_openpgp_crt_t key,
131 int idx,
132 char *buf,
133 size_t * sizeof_buf);
134int gnutls_openpgp_crt_get_fingerprint(gnutls_openpgp_crt_t key,
135 void *fpr,
136 size_t * fprlen);
137gnutls_pk_algorithm_t
138 gnutls_openpgp_crt_get_pk_algorithm(gnutls_openpgp_crt_t key,
139 unsigned int *bits);
140int gnutls_openpgp_crt_get_version(gnutls_openpgp_crt_t key);
141time_t gnutls_openpgp_crt_get_creation_time(gnutls_openpgp_crt_t key);
142time_t gnutls_openpgp_crt_get_expiration_time(gnutls_openpgp_crt_t key);
143int gnutls_openpgp_crt_get_id(gnutls_openpgp_crt_t key,
144 unsigned char keyid[8]);
145
146int gnutls_openpgp_crt_init(gnutls_openpgp_crt_t * key);
147void gnutls_openpgp_crt_deinit(gnutls_openpgp_crt_t key);
148int gnutls_openpgp_crt_import(gnutls_openpgp_crt_t key,
149 const gnutls_datum_t * data,
150 gnutls_openpgp_crt_fmt_t format);
151int gnutls_openpgp_crt_export(gnutls_openpgp_crt_t key,
152 gnutls_openpgp_crt_fmt_t format,
153 void *output_data,
154 size_t * output_data_size);
155
156void gnutls_openpgp_keyring_deinit(gnutls_openpgp_keyring_t keyring);
157int gnutls_openpgp_keyring_init(gnutls_openpgp_keyring_t * keyring);
158int gnutls_openpgp_keyring_import(gnutls_openpgp_keyring_t keyring,
159 const gnutls_datum_t * data,
160 gnutls_openpgp_crt_fmt_t format);
161int gnutls_openpgp_keyring_check_id(gnutls_openpgp_keyring_t ring,
162 const unsigned char keyid[8],
163 unsigned int flags);
164
165int gnutls_openpgp_crt_verify_ring(gnutls_openpgp_crt_t key,
166 gnutls_openpgp_keyring_t keyring,
167 unsigned int flags,
168 unsigned int *verify);
169
170int gnutls_openpgp_crt_verify_self(gnutls_openpgp_crt_t key,
171 unsigned int flags,
172 unsigned int *verify);
173
174int _gnutls_openpgp_crt_to_gcert(gnutls_cert * gcert,
175 gnutls_openpgp_crt_t cert);
176int _gnutls_openpgp_privkey_to_gkey(gnutls_privkey * dest,
177 gnutls_openpgp_privkey_t src);
178
179void gnutls_openpgp_privkey_deinit(gnutls_openpgp_privkey_t key);
180
181#endif /* ENABLE_OPENPGP */
182#endif /* OPENPGP_H */
diff --git a/src/daemon/https/openpgp/pgp.c b/src/daemon/https/openpgp/pgp.c
new file mode 100644
index 00000000..fca307f5
--- /dev/null
+++ b/src/daemon/https/openpgp/pgp.c
@@ -0,0 +1,534 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation
3 *
4 * Author: Timo Schulz, Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS-EXTRA.
7 *
8 * GNUTLS-EXTRA is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * GNUTLS-EXTRA is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22/* Functions on OpenPGP key parsing
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_datum.h>
27#include <gnutls_global.h>
28#include <gnutls_errors.h>
29#include "openpgp.h"
30/* x509 */
31#include <rfc2818.h>
32
33/**
34 * gnutls_openpgp_crt_init - This function initializes a gnutls_openpgp_crt_t structure
35 * @key: The structure to be initialized
36 *
37 * This function will initialize an OpenPGP key structure.
38 *
39 * Returns 0 on success.
40 *
41 **/
42int gnutls_openpgp_crt_init(gnutls_openpgp_crt_t * key)
43{
44 *key = gnutls_calloc(1, sizeof(gnutls_openpgp_crt_int));
45
46 if (*key)
47 return 0; /* success */
48 return GNUTLS_E_MEMORY_ERROR;
49}
50
51/**
52 * gnutls_openpgp_crt_deinit - This function deinitializes memory used by a gnutls_openpgp_crt_t structure
53 * @key: The structure to be initialized
54 *
55 * This function will deinitialize a key structure.
56 **/
57void gnutls_openpgp_crt_deinit(gnutls_openpgp_crt_t key)
58{
59 if (!key)
60 return;
61
62 if (key->knode)
63 {
64 cdk_kbnode_release(key->knode);
65 key->knode = NULL;
66 }
67
68 gnutls_free(key);
69}
70
71/**
72 * gnutls_openpgp_crt_import - This function will import a RAW or BASE64 encoded key
73 * @key: The structure to store the parsed key.
74 * @data: The RAW or BASE64 encoded key.
75 * @format: One of gnutls_openpgp_crt_fmt_t elements.
76 *
77 * This function will convert the given RAW or Base64 encoded key
78 * to the native gnutls_openpgp_crt_t format. The output will be stored in 'key'.
79 *
80 * Returns 0 on success.
81 **/
82int gnutls_openpgp_crt_import(gnutls_openpgp_crt_t key,
83 const gnutls_datum_t * data,
84 gnutls_openpgp_crt_fmt_t format)
85{
86 cdk_stream_t inp;
87 int rc;
88
89 if (format == GNUTLS_OPENPGP_FMT_RAW)
90 rc = cdk_kbnode_read_from_mem(&key->knode, data->data, data->size);
91 else
92 {
93 rc = cdk_stream_tmp_from_mem(data->data, data->size, &inp);
94 if (rc)
95 {
96 rc = _gnutls_map_cdk_rc(rc);
97 gnutls_assert ();
98 return rc;
99 }
100 if (cdk_armor_filter_use(inp))
101 rc = cdk_stream_set_armor_flag(inp, 0);
102 if (!rc)
103 rc = cdk_keydb_get_keyblock(inp, &key->knode);
104 cdk_stream_close(inp);
105 if (rc)
106 {
107 rc = _gnutls_map_cdk_rc(rc);
108 gnutls_assert ();
109 return rc;
110 }
111 }
112
113 return 0;
114}
115
116/**
117 * gnutls_openpgp_crt_export - This function will export a RAW or BASE64 encoded key
118 * @key: Holds the key.
119 * @format: One of gnutls_openpgp_crt_fmt_t elements.
120 * @output_data: will contain the key base64 encoded or raw
121 * @output_data_size: holds the size of output_data (and will be replaced by the actual size of parameters)
122 *
123 * This function will convert the given key to RAW or Base64 format.
124 * If the buffer provided is not long enough to hold the output, then
125 * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
126 *
127 * Returns 0 on success.
128 *
129 **/
130int gnutls_openpgp_crt_export(gnutls_openpgp_crt_t key,
131 gnutls_openpgp_crt_fmt_t format,
132 void *output_data,
133 size_t * output_data_size)
134{
135 size_t input_data_size = *output_data_size;
136 size_t calc_size;
137 int rc;
138
139 rc = cdk_kbnode_write_to_mem(key->knode, output_data, output_data_size);
140 if (rc)
141 {
142 rc = _gnutls_map_cdk_rc(rc);
143 gnutls_assert ();
144 return rc;
145 }
146
147 /* FIXME: The first call of this function is with output_data == NULL
148 to figure out the size and the caller expects this error here. */
149 if (!output_data)
150 return GNUTLS_E_SHORT_MEMORY_BUFFER;
151
152 if (format == GNUTLS_OPENPGP_FMT_BASE64)
153 {
154 unsigned char *in = cdk_calloc(1, *output_data_size);
155 memcpy(in, output_data, *output_data_size);
156
157 /* Calculate the size of the encoded data and check if the provided
158 buffer is large enough. */
159 rc = cdk_armor_encode_buffer(in, input_data_size,
160 NULL, 0, &calc_size, CDK_ARMOR_PUBKEY);
161 if (rc || calc_size > input_data_size)
162 {
163 cdk_free(in);
164 *output_data_size = calc_size;
165 rc = _gnutls_map_cdk_rc(CDK_Too_Short);
166 gnutls_assert ();
167 return rc;
168 }
169
170 rc = cdk_armor_encode_buffer(in, input_data_size, output_data,
171 input_data_size, &calc_size,
172 CDK_ARMOR_PUBKEY);
173 cdk_free(in);
174 *output_data_size = calc_size;
175 }
176
177 return 0;
178}
179
180/**
181 * gnutls_openpgp_crt_get_fingerprint - Gets the fingerprint
182 * @key: the raw data that contains the OpenPGP public key.
183 * @fpr: the buffer to save the fingerprint, must hold at least 20 bytes.
184 * @fprlen: the integer to save the length of the fingerprint.
185 *
186 * Returns the fingerprint of the OpenPGP key. Depends on the algorithm,
187 * the fingerprint can be 16 or 20 bytes.
188 **/
189int gnutls_openpgp_crt_get_fingerprint(gnutls_openpgp_crt_t key,
190 void *fpr,
191 size_t * fprlen)
192{
193 cdk_packet_t pkt;
194 cdk_pkt_pubkey_t pk= NULL;
195
196 if (!fpr || !fprlen)
197 {
198 gnutls_assert ();
199 return GNUTLS_E_INVALID_REQUEST;
200 }
201
202 *fprlen = 0;
203
204 pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY);
205 if (!pkt)
206 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
207
208 pk = pkt->pkt.public_key;
209 *fprlen = 20;
210
211 /* FIXME: Check if the draft allows old PGP keys. */
212 if (is_RSA (pk->pubkey_algo) && pk->version < 4)
213 *fprlen = 16;
214 cdk_pk_get_fingerprint(pk, fpr);
215
216 return 0;
217}
218
219int _gnutls_openpgp_count_key_names(gnutls_openpgp_crt_t key)
220{
221 cdk_kbnode_t p, ctx;
222 cdk_packet_t pkt;
223 int nuids;
224
225 if (key == NULL)
226 {
227 gnutls_assert ();
228 return 0;
229 }
230
231 ctx = NULL;
232 nuids = 0;
233 while ((p = cdk_kbnode_walk(key->knode, &ctx, 0)))
234 {
235 pkt = cdk_kbnode_get_packet(p);
236 if (pkt->pkttype == CDK_PKT_USER_ID)
237 nuids++;
238 }
239
240 return nuids;
241}
242
243/**
244 * gnutls_openpgp_crt_get_name - Extracts the userID
245 * @key: the structure that contains the OpenPGP public key.
246 * @idx: the index of the ID to extract
247 * @buf: a pointer to a structure to hold the name
248 * @sizeof_buf: holds the maximum size of @buf, on return hold the
249 * actual/required size of @buf.
250 *
251 * Extracts the userID from the parsed OpenPGP key.
252 *
253 * Returns 0 on success, and GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
254 * if the index of the ID does not exist.
255 *
256 **/
257int gnutls_openpgp_crt_get_name(gnutls_openpgp_crt_t key,
258 int idx,
259 char *buf,
260 size_t * sizeof_buf)
261{
262 cdk_kbnode_t ctx= NULL, p;
263 cdk_packet_t pkt= NULL;
264 cdk_pkt_userid_t uid= NULL;
265 int pos = 0;
266
267 if (!key || !buf)
268 {
269 gnutls_assert ();
270 return GNUTLS_E_INVALID_REQUEST;
271 }
272
273 if (idx < 0 || idx > _gnutls_openpgp_count_key_names(key))
274 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
275
276 if (!idx)
277 pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_USER_ID);
278 else
279 {
280 pos = 0;
281 while ((p = cdk_kbnode_walk(key->knode, &ctx, 0)))
282 {
283 pkt = cdk_kbnode_get_packet(p);
284 if (pkt->pkttype == CDK_PKT_USER_ID && ++pos == idx)
285 break;
286 }
287 }
288
289 if (!pkt)
290 {
291 gnutls_assert ();
292 return GNUTLS_E_INTERNAL_ERROR;
293 }
294
295 uid = pkt->pkt.user_id;
296 if (uid->len >= *sizeof_buf)
297 {
298 gnutls_assert ();
299 *sizeof_buf = uid->len + 1;
300 return GNUTLS_E_SHORT_MEMORY_BUFFER;
301 }
302
303 memcpy(buf, uid->name, uid->len);
304 buf[uid->len] = '\0'; /* make sure it's a string */
305 *sizeof_buf = uid->len + 1;
306
307 if (uid->is_revoked)
308 return GNUTLS_E_OPENPGP_UID_REVOKED;
309
310 return 0;
311}
312
313/**
314 * gnutls_openpgp_crt_get_pk_algorithm - This function returns the key's PublicKey algorithm
315 * @key: is an OpenPGP key
316 * @bits: if bits is non null it will hold the size of the parameters' in bits
317 *
318 * This function will return the public key algorithm of an OpenPGP
319 * certificate.
320 *
321 * If bits is non null, it should have enough size to hold the parameters
322 * size in bits. For RSA the bits returned is the modulus.
323 * For DSA the bits returned are of the public exponent.
324 *
325 * Returns a member of the GNUTLS_PKAlgorithm enumeration on success,
326 * or a negative value on error.
327 *
328 **/
329gnutls_pk_algorithm_t gnutls_openpgp_crt_get_pk_algorithm(gnutls_openpgp_crt_t key,
330 unsigned int *bits)
331{
332 cdk_packet_t pkt;
333 int algo;
334
335 if (!key)
336 return GNUTLS_PK_UNKNOWN;
337
338 algo = 0;
339 pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY);
340 if (pkt && pkt->pkttype == CDK_PKT_PUBLIC_KEY)
341 {
342 if (bits)
343 *bits = cdk_pk_get_nbits(pkt->pkt.public_key);
344 algo = pkt->pkt.public_key->pubkey_algo;
345 if (is_RSA (algo))
346 algo = GNUTLS_PK_RSA;
347 else
348 algo = GNUTLS_E_UNKNOWN_PK_ALGORITHM;
349 }
350
351 return algo;
352}
353
354/**
355 * gnutls_openpgp_crt_get_version - Extracts the version of the key.
356 * @key: the structure that contains the OpenPGP public key.
357 *
358 * Extract the version of the OpenPGP key.
359 **/
360int gnutls_openpgp_crt_get_version(gnutls_openpgp_crt_t key)
361{
362 cdk_packet_t pkt;
363 int version;
364
365 if (!key)
366 return -1;
367
368 pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY);
369 if (pkt)
370 version = pkt->pkt.public_key->version;
371 else
372 version = 0;
373
374 return version;
375}
376
377/**
378 * gnutls_openpgp_crt_get_creation_time - Extract the timestamp
379 * @key: the structure that contains the OpenPGP public key.
380 *
381 * Returns the timestamp when the OpenPGP key was created.
382 **/
383time_t gnutls_openpgp_crt_get_creation_time(gnutls_openpgp_crt_t key)
384{
385 cdk_packet_t pkt;
386 time_t timestamp;
387
388 if (!key)
389 return (time_t) - 1;
390
391 pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY);
392 if (pkt)
393 timestamp = pkt->pkt.public_key->timestamp;
394 else
395 timestamp = 0;
396
397 return timestamp;
398}
399
400/**
401 * gnutls_openpgp_crt_get_expiration_time - Extract the expire date
402 * @key: the structure that contains the OpenPGP public key.
403 *
404 * Returns the time when the OpenPGP key expires. A value of '0' means
405 * that the key doesn't expire at all.
406 **/
407time_t gnutls_openpgp_crt_get_expiration_time(gnutls_openpgp_crt_t key)
408{
409 cdk_packet_t pkt;
410 time_t expiredate;
411
412 if (!key)
413 return (time_t) - 1;
414
415 pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY);
416 if (pkt)
417 expiredate = pkt->pkt.public_key->expiredate;
418 else
419 expiredate = 0;
420
421 return expiredate;
422}
423
424/**
425 * gnutls_openpgp_crt_get_id - Gets the keyID
426 * @key: the structure that contains the OpenPGP public key.
427 * @keyid: the buffer to save the keyid.
428 *
429 * Returns the 64-bit keyID of the OpenPGP key.
430 **/
431int gnutls_openpgp_crt_get_id(gnutls_openpgp_crt_t key,
432 unsigned char keyid[8])
433{
434 cdk_packet_t pkt;
435 uint32_t kid[2];
436
437 if (!key || !keyid)
438 {
439 gnutls_assert ();
440 return GNUTLS_E_INVALID_REQUEST;
441 }
442
443 pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY);
444 if (!pkt)
445 return GNUTLS_E_OPENPGP_GETKEY_FAILED;
446
447 cdk_pk_get_keyid(pkt->pkt.public_key, kid);
448 keyid[0] = kid[0] >> 24;
449 keyid[1] = kid[0] >> 16;
450 keyid[2] = kid[0] >> 8;
451 keyid[3] = kid[0];
452 keyid[4] = kid[1] >> 24;
453 keyid[5] = kid[1] >> 16;
454 keyid[6] = kid[1] >> 8;
455 keyid[7] = kid[1];
456
457 return 0;
458}
459
460/**
461 * gnutls_openpgp_crt_check_hostname - This function compares the given hostname with the hostname in the key
462 * @key: should contain an gnutls_openpgp_crt_t structure
463 * @hostname: A null terminated string that contains a DNS name
464 *
465 * This function will check if the given key's owner matches
466 * the given hostname. This is a basic implementation of the matching
467 * described in RFC2818 (HTTPS), which takes into account wildcards.
468 *
469 * Returns non zero on success, and zero on failure.
470 *
471 **/
472int gnutls_openpgp_crt_check_hostname(gnutls_openpgp_crt_t key,
473 const char *hostname)
474{
475 char dnsname[MAX_CN];
476 size_t dnsnamesize;
477 int ret;
478 int i;
479
480 /* Check through all included names. */
481 for (i = 0; !(ret < 0); i++)
482 {
483 dnsnamesize = sizeof (dnsname);
484 ret = gnutls_openpgp_crt_get_name(key, i, dnsname, &dnsnamesize);
485 /* FIXME: ret is not used */
486 if (_gnutls_hostname_compare(dnsname, hostname))
487 return 1;
488 }
489
490 /* not found a matching name */
491 return 0;
492}
493
494/**
495 * gnutls_openpgp_crt_get_key_usage - This function returns the key's usage
496 * @key: should contain a gnutls_openpgp_crt_t structure
497 * @key_usage: where the key usage bits will be stored
498 *
499 * This function will return certificate's key usage, by checking the
500 * key algorithm. The key usage value will ORed values of the:
501 * GNUTLS_KEY_DIGITAL_SIGNATURE, GNUTLS_KEY_KEY_ENCIPHERMENT.
502 *
503 * A negative value may be returned in case of parsing error.
504 *
505 */
506int gnutls_openpgp_crt_get_key_usage(gnutls_openpgp_crt_t key,
507 unsigned int *key_usage)
508{
509 cdk_packet_t pkt;
510 int algo = 0;
511
512 if (!key)
513 return GNUTLS_E_INVALID_REQUEST;
514
515 *key_usage = 0;
516
517 pkt = cdk_kbnode_find_packet(key->knode, CDK_PKT_PUBLIC_KEY);
518 if (pkt && pkt->pkttype == CDK_PKT_PUBLIC_KEY)
519 {
520 algo = pkt->pkt.public_key->pubkey_algo;
521
522 /* FIXME: We need to take a look at the key flags because
523 RSA-E and RSA-S are obsolete. Only RSA is used
524 and the flags are used to set the capabilities. */
525 if (is_DSA (algo) || algo == GCRY_PK_RSA_S)
526 *key_usage |= KEY_DIGITAL_SIGNATURE;
527 else if (algo == GCRY_PK_RSA_E)
528 *key_usage |= KEY_KEY_ENCIPHERMENT;
529 else if (algo == GCRY_PK_RSA)
530 *key_usage |= KEY_DIGITAL_SIGNATURE | KEY_KEY_ENCIPHERMENT;
531 }
532
533 return 0;
534}
diff --git a/src/daemon/https/openpgp/pgp_privkey.c b/src/daemon/https/openpgp/pgp_privkey.c
new file mode 100644
index 00000000..e09697eb
--- /dev/null
+++ b/src/daemon/https/openpgp/pgp_privkey.c
@@ -0,0 +1,134 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS-EXTRA.
7 *
8 * GNUTLS-EXTRA is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * GNUTLS-EXTRA is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22/* Functions on OpenPGP privkey parsing
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_datum.h>
27#include <gnutls_global.h>
28#include <gnutls_errors.h>
29#include "openpgp.h"
30#include <gnutls_openpgp.h>
31#include <gnutls_cert.h>
32/* x509 */
33#include <rfc2818.h>
34
35/**
36 * gnutls_openpgp_privkey_init - This function initializes a gnutls_openpgp_privkey_t structure
37 * @key: The structure to be initialized
38 *
39 * This function will initialize an OpenPGP key structure.
40 *
41 * Returns 0 on success.
42 *
43 **/
44int
45gnutls_openpgp_privkey_init (gnutls_openpgp_privkey_t * key)
46{
47 *key = gnutls_calloc (1, sizeof (gnutls_openpgp_privkey_int));
48
49 if (*key)
50 return 0; /* success */
51 return GNUTLS_E_MEMORY_ERROR;
52}
53
54/**
55 * gnutls_openpgp_privkey_deinit - This function deinitializes memory used by a gnutls_openpgp_privkey_t structure
56 * @key: The structure to be initialized
57 *
58 * This function will deinitialize a key structure.
59 *
60 **/
61void
62gnutls_openpgp_privkey_deinit (gnutls_openpgp_privkey_t key)
63{
64 if (!key)
65 return;
66
67 _gnutls_gkey_deinit (&key->pkey);
68 gnutls_free (key);
69}
70
71/**
72 * gnutls_openpgp_privkey_import - This function will import a RAW or BASE64 encoded key
73 * @key: The structure to store the parsed key.
74 * @data: The RAW or BASE64 encoded key.
75 * @format: One of gnutls_openpgp_crt_fmt_t elements.
76 * @pass: Unused for now
77 * @flags: should be zero
78 *
79 * This function will convert the given RAW or Base64 encoded key
80 * to the native gnutls_openpgp_privkey_t format. The output will be stored in 'key'.
81 *
82 * Returns 0 on success.
83 *
84 **/
85int
86gnutls_openpgp_privkey_import (gnutls_openpgp_privkey_t key,
87 const gnutls_datum_t * data,
88 gnutls_openpgp_crt_fmt_t format,
89 const char *pass, unsigned int flags)
90{
91 int rc;
92
93 rc = _gnutls_openpgp_raw_privkey_to_gkey (&key->pkey, data, format);
94 if (rc)
95 {
96 gnutls_assert ();
97 return rc;
98 }
99
100 return 0;
101}
102
103
104/**
105 * gnutls_openpgp_privkey_get_pk_algorithm - This function returns the key's PublicKey algorithm
106 * @key: is an OpenPGP key
107 * @bits: if bits is non null it will hold the size of the parameters' in bits
108 *
109 * This function will return the public key algorithm of an OpenPGP
110 * certificate.
111 *
112 * If bits is non null, it should have enough size to hold the parameters
113 * size in bits. For RSA the bits returned is the modulus.
114 * For DSA the bits returned are of the public exponent.
115 *
116 * Returns a member of the GNUTLS_PKAlgorithm enumeration on success,
117 * or a negative value on error.
118 *
119 **/
120gnutls_pk_algorithm_t
121gnutls_openpgp_privkey_get_pk_algorithm (gnutls_openpgp_privkey_t key,
122 unsigned int *bits)
123{
124 int pk = key->pkey.pk_algorithm;
125
126 if (bits)
127 {
128 *bits = 0;
129 if (pk == GNUTLS_PK_RSA)
130 *bits = _gnutls_mpi_get_nbits (key->pkey.params[0]);
131 }
132
133 return pk;
134}
diff --git a/src/daemon/https/openpgp/pgp_verify.c b/src/daemon/https/openpgp/pgp_verify.c
new file mode 100644
index 00000000..cfa29b69
--- /dev/null
+++ b/src/daemon/https/openpgp/pgp_verify.c
@@ -0,0 +1,144 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Timo Schulz, Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS-EXTRA.
7 *
8 * GNUTLS-EXTRA is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * GNUTLS-EXTRA is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22/* Functions on OpenPGP key parsing
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_errors.h>
27#include <gnutls_openpgp.h>
28#include <gnutls_num.h>
29#include "openpgp.h"
30/* x509 */
31#include <verify.h> /* lib/x509/verify.h */
32
33
34/**
35 * gnutls_openpgp_crt_verify_ring - Verify all signatures in the key
36 * @key: the structure that holds the key.
37 * @keyring: holds the keyring to check against
38 * @flags: unused (should be 0)
39 * @verify: will hold the certificate verification output.
40 *
41 * Verify all signatures in the key, using the given set of keys (keyring).
42 *
43 * The key verification output will be put in @verify and will be
44 * one or more of the gnutls_certificate_status_t enumerated elements bitwise or'd.
45 *
46 * GNUTLS_CERT_INVALID: A signature on the key is invalid.
47 *
48 * GNUTLS_CERT_REVOKED: The key has been revoked.
49 *
50 * Note that this function does not verify using any "web of
51 * trust". You may use GnuPG for that purpose, or any other external
52 * PGP application.
53 *
54 * Returns 0 on success.
55 **/
56int
57gnutls_openpgp_crt_verify_ring (gnutls_openpgp_crt_t key,
58 gnutls_openpgp_keyring_t keyring,
59 unsigned int flags, unsigned int *verify)
60{
61 opaque id[8];
62 cdk_error_t rc;
63 int status;
64
65 if (!key || !keyring)
66 {
67 gnutls_assert ();
68 return GNUTLS_E_NO_CERTIFICATE_FOUND;
69 }
70
71 *verify = 0;
72
73 rc = cdk_pk_check_sigs (key->knode, keyring->db, &status);
74 if (rc == CDK_Error_No_Key)
75 {
76 rc = GNUTLS_E_NO_CERTIFICATE_FOUND;
77 gnutls_assert ();
78 return rc;
79 }
80 else if (rc != CDK_Success)
81 {
82 _gnutls_x509_log ("cdk_pk_check_sigs: error %d\n", rc);
83 rc = _gnutls_map_cdk_rc (rc);
84 gnutls_assert ();
85 return rc;
86 }
87 _gnutls_x509_log ("status: %x\n", status);
88
89 if (status & CDK_KEY_INVALID)
90 *verify |= GNUTLS_CERT_INVALID;
91 if (status & CDK_KEY_REVOKED)
92 *verify |= GNUTLS_CERT_REVOKED;
93 if (status & CDK_KEY_NOSIGNER)
94 *verify |= GNUTLS_CERT_SIGNER_NOT_FOUND;
95
96 /* Check if the key is included in the ring. */
97 if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_SAME))
98 {
99 rc = gnutls_openpgp_crt_get_id (key, id);
100 if (rc < 0)
101 {
102 gnutls_assert ();
103 return rc;
104 }
105
106 rc = gnutls_openpgp_keyring_check_id (keyring, id, 0);
107 /* If it exists in the keyring don't treat it as unknown. */
108 if (rc == 0 && *verify & GNUTLS_CERT_SIGNER_NOT_FOUND)
109 *verify ^= GNUTLS_CERT_SIGNER_NOT_FOUND;
110 }
111
112 return 0;
113}
114
115
116/**
117 * gnutls_openpgp_crt_verify_self - Verify the self signature on the key
118 * @key: the structure that holds the key.
119 * @flags: unused (should be 0)
120 * @verify: will hold the key verification output.
121 *
122 * Verifies the self signature in the key.
123 * The key verification output will be put in @verify and will be
124 * one or more of the gnutls_certificate_status_t enumerated elements bitwise or'd.
125 *
126 * GNUTLS_CERT_INVALID: The self signature on the key is invalid.
127 *
128 * Returns 0 on success.
129 **/
130int
131gnutls_openpgp_crt_verify_self (gnutls_openpgp_crt_t key,
132 unsigned int flags, unsigned int *verify)
133{
134 int status;
135 cdk_error_t rc;
136
137 rc = cdk_pk_check_self_sig (key->knode, &status);
138 if (rc || status != CDK_KEY_VALID)
139 *verify |= GNUTLS_CERT_INVALID;
140 else
141 *verify = 0;
142
143 return 0;
144}
diff --git a/src/daemon/https/tests.c b/src/daemon/https/tests.c
new file mode 100644
index 00000000..35fc70e9
--- /dev/null
+++ b/src/daemon/https/tests.c
@@ -0,0 +1,1160 @@
1/*
2 * Copyright (C) 2004, 2006, 2007 Free Software Foundation
3 * Copyright (C) 2000,2001,2002,2003 Nikos Mavrogiannopoulos
4 *
5 * This file is part of GNUTLS.
6 *
7 * GNUTLS is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * GNUTLS is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <config.h>
22#include <gnutls.h>
23#include <extra.h>
24#include <x509.h>
25
26#ifndef _WIN32
27# include <unistd.h>
28# include <signal.h>
29#else
30# include <errno.h>
31#endif
32
33#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
36#include <common.h>
37#include <tests.h>
38
39extern gnutls_srp_client_credentials_t srp_cred;
40extern gnutls_anon_client_credentials_t anon_cred;
41extern gnutls_certificate_credentials_t xcred;
42
43extern int verbose;
44
45int tls1_ok = 0;
46int ssl3_ok = 0;
47int tls1_1_ok = 0;
48
49/* keep session info */
50static char *session_data = NULL;
51static char session_id[32];
52static size_t session_data_size = 0, session_id_size = 0;
53static int sfree = 0;
54static int handshake_output = 0;
55
56int
57do_handshake (gnutls_session_t session)
58{
59 int ret, alert;
60
61 do
62 {
63 ret = gnutls_handshake (session);
64 }
65 while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN);
66
67 handshake_output = ret;
68
69 if (ret < 0 && verbose > 1)
70 {
71 if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED
72 || ret == GNUTLS_E_FATAL_ALERT_RECEIVED)
73 {
74 alert = gnutls_alert_get (session);
75 printf ("\n");
76 printf ("*** Received alert [%d]: %s\n",
77 alert, gnutls_alert_get_name (alert));
78 }
79 }
80
81 if (ret < 0)
82 return TEST_FAILED;
83
84 gnutls_session_get_data (session, NULL, &session_data_size);
85
86 if (sfree != 0)
87 {
88 free (session_data);
89 sfree = 0;
90 }
91 session_data = malloc (session_data_size);
92 sfree = 1;
93 if (session_data == NULL)
94 {
95 fprintf (stderr, "Memory error\n");
96 exit (1);
97 }
98 gnutls_session_get_data (session, session_data, &session_data_size);
99
100 session_id_size = sizeof (session_id);
101 gnutls_session_get_id (session, session_id, &session_id_size);
102
103 return TEST_SUCCEED;
104}
105
106static int protocol_priority[16] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
107static const int kx_priority[16] =
108 { GNUTLS_KX_RSA, GNUTLS_KX_DHE_DSS, GNUTLS_KX_DHE_RSA,
109 GNUTLS_KX_ANON_DH,
110 GNUTLS_KX_RSA_EXPORT, 0
111};
112static const int cipher_priority[16] =
113 { GNUTLS_CIPHER_3DES_CBC, GNUTLS_CIPHER_ARCFOUR_128,
114 GNUTLS_CIPHER_ARCFOUR_40, 0
115};
116static const int comp_priority[16] = { GNUTLS_COMP_NULL, 0 };
117static const int mac_priority[16] = { GNUTLS_MAC_SHA1, GNUTLS_MAC_MD5, 0 };
118static const int cert_type_priority[16] = { GNUTLS_CRT_X509, 0 };
119
120#define ADD_ALL_CIPHERS(session) gnutls_cipher_set_priority(session, cipher_priority)
121#define ADD_ALL_COMP(session) gnutls_compression_set_priority(session, comp_priority)
122#define ADD_ALL_MACS(session) gnutls_mac_set_priority(session, mac_priority)
123#define ADD_ALL_KX(session) gnutls_kx_set_priority(session, kx_priority)
124#define ADD_ALL_PROTOCOLS(session) gnutls_protocol_set_priority(session, protocol_priority)
125#define ADD_ALL_CERTTYPES(session) gnutls_certificate_type_set_priority(session, cert_type_priority)
126
127static void
128ADD_KX (gnutls_session_t session, int kx)
129{
130 static int _kx_priority[] = { 0, 0 };
131 _kx_priority[0] = kx;
132
133 gnutls_kx_set_priority (session, _kx_priority);
134}
135
136static void
137ADD_KX2 (gnutls_session_t session, int kx1, int kx2)
138{
139 static int _kx_priority[] = { 0, 0, 0 };
140 _kx_priority[0] = kx1;
141 _kx_priority[1] = kx2;
142
143 gnutls_kx_set_priority (session, _kx_priority);
144}
145
146static void
147ADD_CIPHER (gnutls_session_t session, int cipher)
148{
149 static int _cipher_priority[] = { 0, 0 };
150 _cipher_priority[0] = cipher;
151
152 gnutls_cipher_set_priority (session, _cipher_priority);
153}
154
155static void
156ADD_CIPHER4 (gnutls_session_t session, int cipher1, int cipher2, int cipher3,
157 int cipher4)
158{
159 static int _cipher_priority[] = { 0, 0, 0, 0, 0 };
160 _cipher_priority[0] = cipher1;
161 _cipher_priority[1] = cipher2;
162 _cipher_priority[2] = cipher3;
163 _cipher_priority[3] = cipher4;
164
165 gnutls_cipher_set_priority (session, _cipher_priority);
166}
167
168static void
169ADD_MAC (gnutls_session_t session, int mac)
170{
171 static int _mac_priority[] = { 0, 0 };
172 _mac_priority[0] = mac;
173
174 gnutls_mac_set_priority (session, _mac_priority);
175}
176
177static void
178ADD_COMP (gnutls_session_t session, int c)
179{
180 static int _comp_priority[] = { 0, 0 };
181 _comp_priority[0] = c;
182
183 gnutls_compression_set_priority (session, _comp_priority);
184}
185
186static void
187ADD_CERTTYPE (gnutls_session_t session, int ctype)
188{
189 static int _ct_priority[] = { 0, 0 };
190 _ct_priority[0] = ctype;
191
192 gnutls_certificate_type_set_priority (session, _ct_priority);
193}
194
195static void
196ADD_PROTOCOL (gnutls_session_t session, int protocol)
197{
198 static int _proto_priority[] = { 0, 0 };
199 _proto_priority[0] = protocol;
200
201 gnutls_protocol_set_priority (session, _proto_priority);
202}
203
204static void
205ADD_PROTOCOL3 (gnutls_session_t session, int p1, int p2, int p3)
206{
207 static int _proto_priority[] = { 0, 0, 0, 0 };
208 _proto_priority[0] = p1;
209 _proto_priority[1] = p2;
210 _proto_priority[2] = p3;
211
212 gnutls_protocol_set_priority (session, _proto_priority);
213}
214
215#ifdef ENABLE_SRP
216static int srp_detected;
217
218int
219_test_srp_username_callback (gnutls_session_t session,
220 char **username, char **password)
221{
222 srp_detected = 1;
223
224 return -1;
225}
226
227test_code_t
228test_srp (gnutls_session_t session)
229{
230 int ret;
231
232 ADD_ALL_CIPHERS (session);
233 ADD_ALL_COMP (session);
234 ADD_ALL_CERTTYPES (session);
235 ADD_ALL_PROTOCOLS (session);
236 ADD_ALL_MACS (session);
237
238 ADD_KX (session, GNUTLS_KX_SRP);
239 srp_detected = 0;
240
241 gnutls_srp_set_client_credentials_function (srp_cred,
242 _test_srp_username_callback);
243
244 gnutls_credentials_set (session, GNUTLS_CRD_SRP, srp_cred);
245
246 ret = do_handshake (session);
247
248 gnutls_srp_set_client_credentials_function (srp_cred, NULL);
249
250 if (srp_detected != 0)
251 return TEST_SUCCEED;
252 else
253 return TEST_FAILED;
254}
255#endif
256
257test_code_t
258test_server (gnutls_session_t session)
259{
260 int ret, i = 0;
261 char buf[5 * 1024];
262 char *p;
263 const char snd_buf[] = "GET / HTTP/1.0\n\n";
264
265 if (verbose == 0)
266 return TEST_UNSURE;
267
268 buf[sizeof (buf) - 1] = 0;
269
270 ADD_ALL_CIPHERS (session);
271 ADD_ALL_COMP (session);
272 ADD_ALL_CERTTYPES (session);
273 ADD_ALL_PROTOCOLS (session);
274 ADD_ALL_MACS (session);
275 ADD_ALL_KX (session);
276
277 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
278
279 ret = do_handshake (session);
280 if (ret != TEST_SUCCEED)
281 return TEST_FAILED;
282
283 gnutls_record_send (session, snd_buf, sizeof (snd_buf) - 1);
284 ret = gnutls_record_recv (session, buf, sizeof (buf) - 1);
285 if (ret < 0)
286 return TEST_FAILED;
287
288 p = strstr (buf, "Server:");
289 if (p != NULL)
290 p = strchr (p, ':');
291 if (p != NULL)
292 {
293 p++;
294 while (*p != 0 && *p != '\r' && *p != '\n')
295 {
296 putc (*p, stdout);
297 p++;
298 i++;
299 if (i > 128)
300 break;
301 }
302 }
303
304 return TEST_SUCCEED;
305}
306
307
308static int export_true = 0;
309static gnutls_datum_t exp = { NULL, 0 }, mod =
310
311{
312NULL, 0};
313
314test_code_t
315test_export (gnutls_session_t session)
316{
317 int ret;
318
319 ADD_ALL_COMP (session);
320 ADD_ALL_CERTTYPES (session);
321 ADD_ALL_PROTOCOLS (session);
322 ADD_ALL_MACS (session);
323
324 ADD_KX (session, GNUTLS_KX_RSA_EXPORT);
325 ADD_CIPHER (session, GNUTLS_CIPHER_ARCFOUR_40);
326 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
327
328 ret = do_handshake (session);
329
330 if (ret == TEST_SUCCEED)
331 {
332 export_true = 1;
333 gnutls_rsa_export_get_pubkey (session, &exp, &mod);
334 }
335
336 return ret;
337}
338
339test_code_t
340test_export_info (gnutls_session_t session)
341{
342 int ret2, ret;
343 gnutls_datum_t exp2, mod2;
344 const char *print;
345
346 if (verbose == 0 || export_true == 0)
347 return TEST_IGNORE;
348
349 ADD_ALL_COMP (session);
350 ADD_ALL_CERTTYPES (session);
351 ADD_ALL_PROTOCOLS (session);
352 ADD_ALL_MACS (session);
353
354 ADD_KX (session, GNUTLS_KX_RSA_EXPORT);
355 ADD_CIPHER (session, GNUTLS_CIPHER_ARCFOUR_40);
356 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
357
358 ret = do_handshake (session);
359
360 if (ret == TEST_SUCCEED)
361 {
362 ret2 = gnutls_rsa_export_get_pubkey (session, &exp2, &mod2);
363 if (ret2 >= 0)
364 {
365 printf ("\n");
366
367 print = raw_to_string (exp2.data, exp2.size);
368 if (print)
369 printf (" Exponent [%d bits]: %s\n", exp2.size * 8, print);
370
371 print = raw_to_string (mod2.data, mod2.size);
372 if (print)
373 printf (" Modulus [%d bits]: %s\n", mod2.size * 8, print);
374
375 if (mod2.size != mod.size || exp2.size != exp.size ||
376 memcmp (mod2.data, mod.data, mod.size) != 0 ||
377 memcmp (exp2.data, exp.data, exp.size) != 0)
378 {
379 printf
380 (" (server uses different public keys per connection)\n");
381 }
382 }
383 }
384
385 return ret;
386
387}
388
389static gnutls_datum_t pubkey = { NULL, 0 };
390
391test_code_t
392test_dhe (gnutls_session_t session)
393{
394 int ret;
395
396 ADD_ALL_CIPHERS (session);
397 ADD_ALL_COMP (session);
398 ADD_ALL_CERTTYPES (session);
399 ADD_ALL_PROTOCOLS (session);
400 ADD_ALL_MACS (session);
401
402 ADD_KX2 (session, GNUTLS_KX_DHE_RSA, GNUTLS_KX_DHE_DSS);
403 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
404
405 ret = do_handshake (session);
406
407 gnutls_dh_get_pubkey (session, &pubkey);
408
409 return ret;
410}
411
412test_code_t
413test_dhe_group (gnutls_session_t session)
414{
415 int ret, ret2;
416 gnutls_datum_t gen, prime, pubkey2;
417 const char *print;
418
419 if (verbose == 0 || pubkey.data == NULL)
420 return TEST_IGNORE;
421
422 ADD_ALL_CIPHERS (session);
423 ADD_ALL_COMP (session);
424 ADD_ALL_CERTTYPES (session);
425 ADD_ALL_PROTOCOLS (session);
426 ADD_ALL_MACS (session);
427
428 ADD_KX2 (session, GNUTLS_KX_DHE_RSA, GNUTLS_KX_DHE_DSS);
429 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
430
431 ret = do_handshake (session);
432
433 ret2 = gnutls_dh_get_group (session, &gen, &prime);
434 if (ret2 >= 0)
435 {
436 printf ("\n");
437
438 print = raw_to_string (gen.data, gen.size);
439 if (print)
440 printf (" Generator [%d bits]: %s\n", gen.size * 8, print);
441
442 print = raw_to_string (prime.data, prime.size);
443 if (print)
444 printf (" Prime [%d bits]: %s\n", prime.size * 8, print);
445
446 gnutls_dh_get_pubkey (session, &pubkey2);
447 print = raw_to_string (pubkey2.data, pubkey2.size);
448 if (print)
449 printf (" Pubkey [%d bits]: %s\n", pubkey2.size * 8, print);
450
451 if (pubkey2.data && pubkey2.size == pubkey.size &&
452 memcmp (pubkey.data, pubkey2.data, pubkey.size) == 0)
453 {
454 printf (" (public key seems to be static among sessions)\n");
455 }
456 }
457 return ret;
458}
459
460test_code_t
461test_ssl3 (gnutls_session_t session)
462{
463 int ret;
464 ADD_ALL_CIPHERS (session);
465 ADD_ALL_COMP (session);
466 ADD_ALL_CERTTYPES (session);
467 ADD_PROTOCOL (session, GNUTLS_SSL3);
468 ADD_ALL_MACS (session);
469 ADD_ALL_KX (session);
470 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
471
472 ret = do_handshake (session);
473 if (ret == TEST_SUCCEED)
474 ssl3_ok = 1;
475
476 return ret;
477}
478
479static int alrm = 0;
480void
481got_alarm (int k)
482{
483 alrm = 1;
484}
485
486test_code_t
487test_bye (gnutls_session_t session)
488{
489 int ret;
490 char data[20];
491 int old, secs = 6;
492
493#ifndef _WIN32
494 signal (SIGALRM, got_alarm);
495#endif
496
497 ADD_ALL_CIPHERS (session);
498 ADD_ALL_COMP (session);
499 ADD_ALL_CERTTYPES (session);
500 ADD_ALL_PROTOCOLS (session);
501 ADD_ALL_MACS (session);
502 ADD_ALL_KX (session);
503 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
504
505 ret = do_handshake (session);
506 if (ret == TEST_FAILED)
507 return ret;
508
509 ret = gnutls_bye (session, GNUTLS_SHUT_WR);
510 if (ret < 0)
511 return TEST_FAILED;
512
513#ifndef _WIN32
514 old = siginterrupt (SIGALRM, 1);
515 alarm (secs);
516#else
517 setsockopt (gnutls_transport_get_ptr (session), SOL_SOCKET, SO_RCVTIMEO,
518 (char *) &secs, sizeof (int));
519#endif
520
521 do
522 {
523 ret = gnutls_record_recv (session, data, sizeof (data));
524 }
525 while (ret > 0);
526
527#ifndef _WIN32
528 siginterrupt (SIGALRM, old);
529#else
530 if (WSAGetLastError () == WSAETIMEDOUT ||
531 WSAGetLastError () == WSAECONNABORTED)
532 alrm = 1;
533#endif
534 if (ret == 0)
535 return TEST_SUCCEED;
536
537 if (alrm == 0)
538 return TEST_UNSURE;
539
540 return TEST_FAILED;
541}
542
543
544
545test_code_t
546test_aes (gnutls_session_t session)
547{
548 int ret;
549 ADD_CIPHER (session, GNUTLS_CIPHER_AES_128_CBC);
550 ADD_ALL_COMP (session);
551 ADD_ALL_CERTTYPES (session);
552 ADD_ALL_PROTOCOLS (session);
553 ADD_ALL_MACS (session);
554 ADD_ALL_KX (session);
555 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
556
557 ret = do_handshake (session);
558 return ret;
559}
560
561#ifdef ENABLE_CAMELLIA
562test_code_t
563test_camellia (gnutls_session_t session)
564{
565 int ret;
566 ADD_CIPHER (session, GNUTLS_CIPHER_CAMELLIA_128_CBC);
567 ADD_ALL_COMP (session);
568 ADD_ALL_CERTTYPES (session);
569 ADD_ALL_PROTOCOLS (session);
570 ADD_ALL_MACS (session);
571 ADD_ALL_KX (session);
572 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
573
574 ret = do_handshake (session);
575 return ret;
576}
577#endif
578
579test_code_t
580test_openpgp1 (gnutls_session_t session)
581{
582 int ret;
583 ADD_ALL_CIPHERS (session);
584 ADD_ALL_COMP (session);
585 ADD_CERTTYPE (session, GNUTLS_CRT_OPENPGP);
586 ADD_ALL_PROTOCOLS (session);
587 ADD_ALL_MACS (session);
588 ADD_ALL_KX (session);
589 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
590
591 ret = do_handshake (session);
592 if (ret == TEST_FAILED)
593 return ret;
594
595 if (gnutls_certificate_type_get (session) == GNUTLS_CRT_OPENPGP)
596 return TEST_SUCCEED;
597
598 return TEST_FAILED;
599}
600
601test_code_t
602test_unknown_ciphersuites (gnutls_session_t session)
603{
604 int ret;
605#ifdef ENABLE_CAMELLIA
606 ADD_CIPHER4 (session, GNUTLS_CIPHER_AES_128_CBC, GNUTLS_CIPHER_3DES_CBC,
607 GNUTLS_CIPHER_CAMELLIA_128_CBC, GNUTLS_CIPHER_ARCFOUR_128);
608#else
609 ADD_CIPHER4 (session, GNUTLS_CIPHER_AES_128_CBC, GNUTLS_CIPHER_3DES_CBC,
610 GNUTLS_CIPHER_ARCFOUR_128, 0);
611#endif
612 ADD_ALL_COMP (session);
613 ADD_ALL_CERTTYPES (session);
614 ADD_ALL_PROTOCOLS (session);
615 ADD_ALL_MACS (session);
616 ADD_ALL_KX (session);
617 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
618
619 ret = do_handshake (session);
620 return ret;
621}
622
623test_code_t
624test_md5 (gnutls_session_t session)
625{
626 int ret;
627 ADD_ALL_CIPHERS (session);
628 ADD_ALL_COMP (session);
629 ADD_ALL_CERTTYPES (session);
630 ADD_ALL_PROTOCOLS (session);
631 ADD_MAC (session, GNUTLS_MAC_MD5);
632 ADD_ALL_KX (session);
633 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
634
635 ret = do_handshake (session);
636 return ret;
637}
638
639#ifdef HAVE_LIBZ
640test_code_t
641test_zlib (gnutls_session_t session)
642{
643 int ret;
644 ADD_ALL_CIPHERS (session);
645 ADD_COMP (session, GNUTLS_COMP_ZLIB);
646 ADD_ALL_CERTTYPES (session);
647 ADD_ALL_PROTOCOLS (session);
648 ADD_ALL_MACS (session);
649 ADD_ALL_KX (session);
650 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
651
652 ret = do_handshake (session);
653 return ret;
654}
655#endif
656
657test_code_t
658test_lzo (gnutls_session_t session)
659{
660 int ret;
661 gnutls_handshake_set_private_extensions (session, 1);
662
663 ADD_ALL_CIPHERS (session);
664 ADD_COMP (session, GNUTLS_COMP_LZO);
665 ADD_ALL_CERTTYPES (session);
666 ADD_ALL_PROTOCOLS (session);
667 ADD_ALL_MACS (session);
668 ADD_ALL_KX (session);
669 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
670
671 ret = do_handshake (session);
672
673 return ret;
674}
675
676test_code_t
677test_sha (gnutls_session_t session)
678{
679 int ret;
680 ADD_ALL_CIPHERS (session);
681 ADD_ALL_COMP (session);
682 ADD_ALL_CERTTYPES (session);
683 ADD_ALL_PROTOCOLS (session);
684 ADD_MAC (session, GNUTLS_MAC_SHA1);
685 ADD_ALL_KX (session);
686 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
687
688 ret = do_handshake (session);
689 return ret;
690}
691
692test_code_t
693test_3des (gnutls_session_t session)
694{
695 int ret;
696 ADD_CIPHER (session, GNUTLS_CIPHER_3DES_CBC);
697 ADD_ALL_COMP (session);
698 ADD_ALL_CERTTYPES (session);
699 ADD_ALL_PROTOCOLS (session);
700 ADD_ALL_MACS (session);
701 ADD_ALL_KX (session);
702 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
703
704 ret = do_handshake (session);
705 return ret;
706}
707
708test_code_t
709test_arcfour (gnutls_session_t session)
710{
711 int ret;
712 ADD_CIPHER (session, GNUTLS_CIPHER_ARCFOUR_128);
713 ADD_ALL_COMP (session);
714 ADD_ALL_CERTTYPES (session);
715 ADD_ALL_PROTOCOLS (session);
716 ADD_ALL_MACS (session);
717 ADD_ALL_KX (session);
718 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
719
720 ret = do_handshake (session);
721 return ret;
722}
723
724test_code_t
725test_arcfour_40 (gnutls_session_t session)
726{
727 int ret;
728 ADD_CIPHER (session, GNUTLS_CIPHER_ARCFOUR_40);
729 ADD_ALL_COMP (session);
730 ADD_ALL_CERTTYPES (session);
731 ADD_ALL_PROTOCOLS (session);
732 ADD_ALL_MACS (session);
733 ADD_ALL_KX (session);
734 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
735
736 ret = do_handshake (session);
737 return ret;
738}
739
740test_code_t
741test_tls1 (gnutls_session_t session)
742{
743 int ret;
744 ADD_ALL_CIPHERS (session);
745 ADD_ALL_COMP (session);
746 ADD_ALL_CERTTYPES (session);
747 ADD_PROTOCOL (session, GNUTLS_TLS1);
748 ADD_ALL_MACS (session);
749 ADD_ALL_KX (session);
750 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
751
752 ret = do_handshake (session);
753 if (ret == TEST_SUCCEED)
754 tls1_ok = 1;
755
756 return ret;
757
758}
759
760test_code_t
761test_tls1_1 (gnutls_session_t session)
762{
763 int ret;
764 ADD_ALL_CIPHERS (session);
765 ADD_ALL_COMP (session);
766 ADD_ALL_CERTTYPES (session);
767 ADD_PROTOCOL (session, GNUTLS_TLS1_1);
768 ADD_ALL_MACS (session);
769 ADD_ALL_KX (session);
770 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
771
772 ret = do_handshake (session);
773 if (ret == TEST_SUCCEED)
774 tls1_1_ok = 1;
775
776 return ret;
777
778}
779
780test_code_t
781test_tls1_1_fallback (gnutls_session_t session)
782{
783 int ret;
784 if (tls1_1_ok)
785 return TEST_IGNORE;
786
787 ADD_ALL_CIPHERS (session);
788 ADD_ALL_COMP (session);
789 ADD_ALL_CERTTYPES (session);
790 ADD_PROTOCOL3 (session, GNUTLS_TLS1_1, GNUTLS_TLS1, GNUTLS_SSL3);
791 ADD_ALL_MACS (session);
792 ADD_ALL_KX (session);
793 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
794
795 ret = do_handshake (session);
796 if (ret != TEST_SUCCEED)
797 return TEST_FAILED;
798
799 if (gnutls_protocol_get_version (session) == GNUTLS_TLS1)
800 return TEST_SUCCEED;
801 else if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
802 return TEST_UNSURE;
803
804 return TEST_FAILED;
805
806}
807
808/* Advertize both TLS 1.0 and SSL 3.0. If the connection fails,
809 * but the previous SSL 3.0 test succeeded then disable TLS 1.0.
810 */
811test_code_t
812test_tls_disable (gnutls_session_t session)
813{
814 int ret;
815 if (tls1_ok != 0)
816 return TEST_IGNORE;
817
818 ADD_ALL_CIPHERS (session);
819 ADD_ALL_COMP (session);
820 ADD_ALL_CERTTYPES (session);
821 ADD_ALL_PROTOCOLS (session);
822 ADD_ALL_MACS (session);
823 ADD_ALL_KX (session);
824 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
825
826 ret = do_handshake (session);
827 if (ret == TEST_FAILED)
828 {
829 /* disable TLS 1.0 */
830 if (ssl3_ok != 0)
831 {
832 protocol_priority[0] = GNUTLS_SSL3;
833 protocol_priority[1] = 0;
834 }
835 }
836 return ret;
837
838}
839
840test_code_t
841test_rsa_pms (gnutls_session_t session)
842{
843 int ret;
844
845 /* here we enable both SSL 3.0 and TLS 1.0
846 * and try to connect and use rsa authentication.
847 * If the server is old, buggy and only supports
848 * SSL 3.0 then the handshake will fail.
849 */
850 ADD_ALL_CIPHERS (session);
851 ADD_ALL_COMP (session);
852 ADD_ALL_CERTTYPES (session);
853 ADD_ALL_PROTOCOLS (session);
854 ADD_ALL_MACS (session);
855 ADD_KX (session, GNUTLS_KX_RSA);
856 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
857
858 ret = do_handshake (session);
859 if (ret == TEST_FAILED)
860 return TEST_FAILED;
861
862 if (gnutls_protocol_get_version (session) == GNUTLS_TLS1)
863 return TEST_SUCCEED;
864 return TEST_UNSURE;
865}
866
867test_code_t
868test_max_record_size (gnutls_session_t session)
869{
870 int ret;
871 ADD_ALL_CIPHERS (session);
872 ADD_ALL_COMP (session);
873 ADD_ALL_CERTTYPES (session);
874 ADD_ALL_PROTOCOLS (session);
875 ADD_ALL_MACS (session);
876 ADD_ALL_KX (session);
877 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
878 gnutls_record_set_max_size (session, 512);
879
880 ret = do_handshake (session);
881 if (ret == TEST_FAILED)
882 return ret;
883
884 ret = gnutls_record_get_max_size (session);
885 if (ret == 512)
886 return TEST_SUCCEED;
887
888 return TEST_FAILED;
889}
890
891test_code_t
892test_hello_extension (gnutls_session_t session)
893{
894 int ret;
895 ADD_ALL_CIPHERS (session);
896 ADD_ALL_COMP (session);
897 ADD_ALL_CERTTYPES (session);
898 ADD_ALL_PROTOCOLS (session);
899 ADD_ALL_MACS (session);
900 ADD_ALL_KX (session);
901 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
902 gnutls_record_set_max_size (session, 512);
903
904 ret = do_handshake (session);
905 return ret;
906}
907
908void _gnutls_record_set_default_version (gnutls_session_t session,
909 unsigned char major,
910 unsigned char minor);
911
912test_code_t
913test_version_rollback (gnutls_session_t session)
914{
915 int ret;
916 if (tls1_ok == 0)
917 return TEST_IGNORE;
918
919 /* here we enable both SSL 3.0 and TLS 1.0
920 * and we connect using a 3.1 client hello version,
921 * and a 3.0 record version. Some implementations
922 * are buggy (and vulnerable to man in the middle
923 * attacks which allow a version downgrade) and this
924 * connection will fail.
925 */
926 ADD_ALL_CIPHERS (session);
927 ADD_ALL_COMP (session);
928 ADD_ALL_CERTTYPES (session);
929 ADD_ALL_PROTOCOLS (session);
930 ADD_ALL_MACS (session);
931 ADD_ALL_KX (session);
932 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
933 _gnutls_record_set_default_version (session, 3, 0);
934
935 ret = do_handshake (session);
936 if (ret != TEST_SUCCEED)
937 return ret;
938
939 if (tls1_ok != 0 && gnutls_protocol_get_version (session) == GNUTLS_SSL3)
940 return TEST_FAILED;
941
942 return TEST_SUCCEED;
943}
944
945/* See if the server tolerates out of bounds
946 * record layer versions in the first client hello
947 * message.
948 */
949test_code_t
950test_version_oob (gnutls_session_t session)
951{
952 int ret;
953 /* here we enable both SSL 3.0 and TLS 1.0
954 * and we connect using a 5.5 record version.
955 */
956 ADD_ALL_CIPHERS (session);
957 ADD_ALL_COMP (session);
958 ADD_ALL_CERTTYPES (session);
959 ADD_ALL_PROTOCOLS (session);
960 ADD_ALL_MACS (session);
961 ADD_ALL_KX (session);
962 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
963 _gnutls_record_set_default_version (session, 5, 5);
964
965 ret = do_handshake (session);
966 return ret;
967}
968
969void _gnutls_rsa_pms_set_version (gnutls_session_t session,
970 unsigned char major, unsigned char minor);
971
972test_code_t
973test_rsa_pms_version_check (gnutls_session_t session)
974{
975 int ret;
976 /* here we use an arbitary version in the RSA PMS
977 * to see whether to server will check this version.
978 *
979 * A normal server would abort this handshake.
980 */
981 ADD_ALL_CIPHERS (session);
982 ADD_ALL_COMP (session);
983 ADD_ALL_CERTTYPES (session);
984 ADD_ALL_PROTOCOLS (session);
985 ADD_ALL_MACS (session);
986 ADD_ALL_KX (session);
987 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
988 _gnutls_rsa_pms_set_version (session, 5, 5); /* use SSL 5.5 version */
989
990 ret = do_handshake (session);
991 return ret;
992
993}
994
995#ifdef ENABLE_ANON
996test_code_t
997test_anonymous (gnutls_session_t session)
998{
999 int ret;
1000
1001 ADD_ALL_CIPHERS (session);
1002 ADD_ALL_COMP (session);
1003 ADD_ALL_CERTTYPES (session);
1004 ADD_ALL_PROTOCOLS (session);
1005 ADD_ALL_MACS (session);
1006 ADD_KX (session, GNUTLS_KX_ANON_DH);
1007 gnutls_credentials_set (session, GNUTLS_CRD_ANON, anon_cred);
1008
1009 ret = do_handshake (session);
1010
1011 if (ret == TEST_SUCCEED)
1012 gnutls_dh_get_pubkey (session, &pubkey);
1013
1014 return ret;
1015}
1016#endif
1017
1018test_code_t
1019test_session_resume2 (gnutls_session_t session)
1020{
1021 int ret;
1022 char tmp_session_id[32];
1023 int tmp_session_id_size;
1024
1025 if (session == NULL)
1026 return TEST_IGNORE;
1027
1028 ADD_ALL_CIPHERS (session);
1029 ADD_ALL_COMP (session);
1030 ADD_ALL_CERTTYPES (session);
1031 ADD_ALL_PROTOCOLS (session);
1032 ADD_ALL_MACS (session);
1033 ADD_ALL_KX (session);
1034
1035 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
1036 gnutls_credentials_set (session, GNUTLS_CRD_ANON, anon_cred);
1037
1038 gnutls_session_set_data (session, session_data, session_data_size);
1039
1040 memcpy (tmp_session_id, session_id, session_id_size);
1041 tmp_session_id_size = session_id_size;
1042
1043 ret = do_handshake (session);
1044 if (ret == TEST_FAILED)
1045 return ret;
1046
1047 /* check if we actually resumed the previous session */
1048
1049 session_id_size = sizeof (session_id);
1050 gnutls_session_get_id (session, session_id, &session_id_size);
1051
1052 if (session_id_size == 0)
1053 return TEST_FAILED;
1054
1055 if (gnutls_session_is_resumed (session))
1056 return TEST_SUCCEED;
1057
1058 if (tmp_session_id_size == session_id_size &&
1059 memcmp (tmp_session_id, session_id, tmp_session_id_size) == 0)
1060 return TEST_SUCCEED;
1061 else
1062 return TEST_FAILED;
1063}
1064
1065extern char *hostname;
1066
1067test_code_t
1068test_certificate (gnutls_session_t session)
1069{
1070 int ret;
1071
1072 if (verbose == 0)
1073 return TEST_IGNORE;
1074
1075 ADD_ALL_CIPHERS (session);
1076 ADD_ALL_COMP (session);
1077 ADD_ALL_CERTTYPES (session);
1078 ADD_ALL_PROTOCOLS (session);
1079 ADD_ALL_MACS (session);
1080 ADD_ALL_KX (session);
1081
1082 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
1083
1084 ret = do_handshake (session);
1085 if (ret == TEST_FAILED)
1086 return ret;
1087
1088 printf ("\n");
1089 print_cert_info (session, hostname);
1090
1091 return TEST_SUCCEED;
1092}
1093
1094/* A callback function to be used at the certificate selection time.
1095 */
1096static int
1097cert_callback (gnutls_session_t session,
1098 const gnutls_datum_t * req_ca_rdn, int nreqs,
1099 const gnutls_pk_algorithm_t * sign_algos,
1100 int sign_algos_length, gnutls_retr_st * st)
1101{
1102 char issuer_dn[256];
1103 int i, ret;
1104 size_t len;
1105
1106 if (verbose == 0)
1107 return -1;
1108
1109 /* Print the server's trusted CAs
1110 */
1111 printf ("\n");
1112 if (nreqs > 0)
1113 printf ("- Server's trusted authorities:\n");
1114 else
1115 printf ("- Server did not send us any trusted authorities names.\n");
1116
1117 /* print the names (if any) */
1118 for (i = 0; i < nreqs; i++)
1119 {
1120 len = sizeof (issuer_dn);
1121 ret = gnutls_x509_rdn_get (&req_ca_rdn[i], issuer_dn, &len);
1122 if (ret >= 0)
1123 {
1124 printf (" [%d]: ", i);
1125 printf ("%s\n", issuer_dn);
1126 }
1127 }
1128
1129 return -1;
1130
1131}
1132
1133/* Prints the trusted server's CAs. This is only
1134 * if the server sends a certificate request packet.
1135 */
1136test_code_t
1137test_server_cas (gnutls_session_t session)
1138{
1139 int ret;
1140
1141 if (verbose == 0)
1142 return TEST_IGNORE;
1143
1144 ADD_ALL_CIPHERS (session);
1145 ADD_ALL_COMP (session);
1146 ADD_ALL_CERTTYPES (session);
1147 ADD_ALL_PROTOCOLS (session);
1148 ADD_ALL_MACS (session);
1149 ADD_ALL_KX (session);
1150
1151 gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);
1152 gnutls_certificate_client_set_retrieve_function (xcred, cert_callback);
1153
1154 ret = do_handshake (session);
1155 gnutls_certificate_client_set_retrieve_function (xcred, NULL);
1156
1157 if (ret == TEST_FAILED)
1158 return ret;
1159 return TEST_SUCCEED;
1160}
diff --git a/src/daemon/https/tests.h b/src/daemon/https/tests.h
new file mode 100644
index 00000000..2f27f850
--- /dev/null
+++ b/src/daemon/https/tests.h
@@ -0,0 +1,42 @@
1typedef enum
2{
3 TEST_SUCCEED, TEST_FAILED, TEST_UNSURE, TEST_IGNORE
4} test_code_t;
5
6test_code_t test_srp (gnutls_session_t state);
7test_code_t test_server (gnutls_session_t state);
8test_code_t test_export (gnutls_session_t state);
9test_code_t test_export_info (gnutls_session_t state);
10test_code_t test_hello_extension (gnutls_session_t state);
11test_code_t test_dhe (gnutls_session_t state);
12test_code_t test_dhe_group (gnutls_session_t state);
13test_code_t test_ssl3 (gnutls_session_t state);
14test_code_t test_aes (gnutls_session_t state);
15#ifdef ENABLE_CAMELLIA
16test_code_t test_camellia (gnutls_session_t state);
17#endif
18test_code_t test_md5 (gnutls_session_t state);
19test_code_t test_sha (gnutls_session_t state);
20test_code_t test_3des (gnutls_session_t state);
21test_code_t test_arcfour (gnutls_session_t state);
22test_code_t test_arcfour_40 (gnutls_session_t state);
23test_code_t test_tls1 (gnutls_session_t state);
24test_code_t test_tls1_1 (gnutls_session_t state);
25test_code_t test_tls1_1_fallback (gnutls_session_t state);
26test_code_t test_tls_disable (gnutls_session_t state);
27test_code_t test_rsa_pms (gnutls_session_t state);
28test_code_t test_max_record_size (gnutls_session_t state);
29test_code_t test_version_rollback (gnutls_session_t state);
30test_code_t test_anonymous (gnutls_session_t state);
31test_code_t test_unknown_ciphersuites (gnutls_session_t state);
32test_code_t test_openpgp1 (gnutls_session_t state);
33test_code_t test_bye (gnutls_session_t state);
34test_code_t test_certificate (gnutls_session_t state);
35test_code_t test_server_cas (gnutls_session_t state);
36test_code_t test_session_resume2 (gnutls_session_t state);
37test_code_t test_rsa_pms_version_check (gnutls_session_t session);
38test_code_t test_version_oob (gnutls_session_t session);
39test_code_t test_zlib (gnutls_session_t session);
40test_code_t test_lzo (gnutls_session_t session);
41int _test_srp_username_callback (gnutls_session_t session,
42 char **username, char **password);
diff --git a/src/daemon/https/tls/Makefile.am b/src/daemon/https/tls/Makefile.am
new file mode 100644
index 00000000..309080ea
--- /dev/null
+++ b/src/daemon/https/tls/Makefile.am
@@ -0,0 +1,73 @@
1SUBDIRS = .
2
3AM_CPPFLAGS = \
4-I$(top_srcdir)/src/daemon/https/includes \
5-I$(top_srcdir)/src/daemon/https/lgl \
6-I$(top_srcdir)/src/daemon/https/x509 \
7-I$(top_srcdir)/src/daemon/https/tls \
8-I$(top_srcdir)/src/daemon/https/openpgp \
9-I$(top_srcdir)/src/daemon/https/opencdk \
10-I$(GCRYPT_CPPFLAGS)
11
12noinst_LTLIBRARIES = libtls.la
13
14libtls_la_LDFLAGS = \
15 -L$(GCRYPT_LIB_PATH)
16
17libtls_la_SOURCES = \
18auth_anon.c \
19auth_cert.c \
20auth_dh_common.c \
21auth_dhe.c \
22auth_rsa.c \
23auth_rsa_export.c \
24debug.c \
25ext_cert_type.c \
26ext_inner_application.c \
27ext_max_record.c \
28ext_oprfi.c \
29ext_server_name.c \
30gnutls_alert.c \
31gnutls_algorithms.c \
32gnutls_anon_cred.c \
33gnutls_asn1_tab.c \
34gnutls_auth.c \
35gnutls_buffers.c \
36gnutls_cert.c \
37gnutls_cipher.c \
38gnutls_cipher_int.c \
39gnutls_compress.c \
40gnutls_compress_int.c \
41gnutls_constate.c \
42gnutls_datum.c \
43gnutls_db.c \
44gnutls_dh.c \
45gnutls_dh_primes.c \
46gnutls_errors.c \
47gnutls_extensions.c \
48gnutls_extra_hooks.c \
49gnutls_global.c \
50gnutls_handshake.c \
51gnutls_hash_int.c \
52gnutls_kx.c \
53gnutls_mem.c \
54gnutls_mpi.c \
55gnutls_num.c \
56gnutls_pk.c \
57gnutls_priority.c \
58gnutls_record.c \
59gnutls_rsa_export.c \
60gnutls_session.c \
61gnutls_session_pack.c \
62gnutls_sig.c \
63gnutls_state.c \
64gnutls_str.c \
65gnutls_supplemental.c \
66gnutls_ui.c \
67gnutls_v2_compat.c \
68gnutls_x509.c \
69pkix_asn1_tab.c \
70x509_b64.c
71
72# gnutlsxx.cpp
73
diff --git a/src/daemon/https/tls/auth_anon.c b/src/daemon/https/tls/auth_anon.c
new file mode 100644
index 00000000..18cad200
--- /dev/null
+++ b/src/daemon/https/tls/auth_anon.c
@@ -0,0 +1,178 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file contains the Anonymous Diffie Hellman key exchange part of
26 * the anonymous authentication. The functions here are used in the
27 * handshake.
28 */
29
30#include <gnutls_int.h>
31
32#ifdef ENABLE_ANON
33
34#include "gnutls_auth_int.h"
35#include "gnutls_errors.h"
36#include "gnutls_dh.h"
37#include "auth_anon.h"
38#include "gnutls_num.h"
39#include "gnutls_mpi.h"
40#include <gnutls_state.h>
41#include <auth_dh_common.h>
42
43static int gen_anon_server_kx (gnutls_session_t, opaque **);
44static int proc_anon_client_kx (gnutls_session_t, opaque *, size_t);
45static int proc_anon_server_kx (gnutls_session_t, opaque *, size_t);
46
47const mod_auth_st anon_auth_struct = {
48 "ANON",
49 NULL,
50 NULL,
51 gen_anon_server_kx,
52 _gnutls_gen_dh_common_client_kx, /* this can be shared */
53 NULL,
54 NULL,
55
56 NULL,
57 NULL, /* certificate */
58 proc_anon_server_kx,
59 proc_anon_client_kx,
60 NULL,
61 NULL
62};
63
64static int
65gen_anon_server_kx (gnutls_session_t session, opaque ** data)
66{
67 mpi_t g, p;
68 const mpi_t *mpis;
69 int ret;
70 gnutls_dh_params_t dh_params;
71 gnutls_anon_server_credentials_t cred;
72
73 cred = (gnutls_anon_server_credentials_t)
74 _gnutls_get_cred (session->key, GNUTLS_CRD_ANON, NULL);
75 if (cred == NULL)
76 {
77 gnutls_assert ();
78 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
79 }
80
81 dh_params =
82 _gnutls_get_dh_params (cred->dh_params, cred->params_func, session);
83 mpis = _gnutls_dh_params_to_mpi (dh_params);
84 if (mpis == NULL)
85 {
86 gnutls_assert ();
87 return GNUTLS_E_NO_TEMPORARY_DH_PARAMS;
88 }
89
90 p = mpis[0];
91 g = mpis[1];
92
93 if ((ret =
94 _gnutls_auth_info_set (session, GNUTLS_CRD_ANON,
95 sizeof (anon_auth_info_st), 1)) < 0)
96 {
97 gnutls_assert ();
98 return ret;
99 }
100
101 _gnutls_dh_set_group (session, g, p);
102
103 ret = _gnutls_dh_common_print_server_kx (session, g, p, data, 0);
104 if (ret < 0)
105 {
106 gnutls_assert ();
107 }
108
109 return ret;
110}
111
112
113static int
114proc_anon_client_kx (gnutls_session_t session, opaque * data,
115 size_t _data_size)
116{
117 gnutls_anon_server_credentials_t cred;
118 int bits;
119 int ret;
120 mpi_t p, g;
121 gnutls_dh_params_t dh_params;
122 const mpi_t *mpis;
123
124 bits = _gnutls_dh_get_allowed_prime_bits (session);
125
126 cred = (gnutls_anon_server_credentials_t)
127 _gnutls_get_cred (session->key, GNUTLS_CRD_ANON, NULL);
128 if (cred == NULL)
129 {
130 gnutls_assert ();
131 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
132 }
133
134 dh_params =
135 _gnutls_get_dh_params (cred->dh_params, cred->params_func, session);
136 mpis = _gnutls_dh_params_to_mpi (dh_params);
137 if (mpis == NULL)
138 {
139 gnutls_assert ();
140 return GNUTLS_E_NO_TEMPORARY_DH_PARAMS;
141 }
142
143 p = mpis[0];
144 g = mpis[1];
145
146 ret = _gnutls_proc_dh_common_client_kx (session, data, _data_size, g, p);
147
148 return ret;
149
150}
151
152int
153proc_anon_server_kx (gnutls_session_t session, opaque * data,
154 size_t _data_size)
155{
156
157 int ret;
158
159 /* set auth_info */
160 if ((ret =
161 _gnutls_auth_info_set (session, GNUTLS_CRD_ANON,
162 sizeof (anon_auth_info_st), 1)) < 0)
163 {
164 gnutls_assert ();
165 return ret;
166 }
167
168 ret = _gnutls_proc_dh_common_server_kx (session, data, _data_size, 0);
169 if (ret < 0)
170 {
171 gnutls_assert ();
172 return ret;
173 }
174
175 return 0;
176}
177
178#endif /* ENABLE_ANON */
diff --git a/src/daemon/https/tls/auth_anon.h b/src/daemon/https/tls/auth_anon.h
new file mode 100644
index 00000000..b1705f85
--- /dev/null
+++ b/src/daemon/https/tls/auth_anon.h
@@ -0,0 +1,48 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* this is not to be included by gnutls_anon.c */
26#include <gnutls_auth.h>
27#include <auth_dh_common.h>
28
29typedef struct gnutls_anon_server_credentials_st
30{
31 gnutls_dh_params_t dh_params;
32 /* this callback is used to retrieve the DH or RSA
33 * parameters.
34 */
35 gnutls_params_function *params_func;
36} anon_server_credentials_st;
37
38typedef struct gnutls_anon_client_credentials_st
39{
40 int dummy;
41} anon_client_credentials_st;
42
43typedef struct anon_auth_info_st
44{
45 dh_info_st dh;
46} *anon_auth_info_t;
47
48typedef struct anon_auth_info_st anon_auth_info_st;
diff --git a/src/daemon/https/tls/auth_cert.c b/src/daemon/https/tls/auth_cert.c
new file mode 100644
index 00000000..43dcb777
--- /dev/null
+++ b/src/daemon/https/tls/auth_cert.c
@@ -0,0 +1,1781 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* The certificate authentication functions which are needed in the handshake,
26 * and are common to RSA and DHE key exchange, are in this file.
27 */
28
29#include <gnutls_int.h>
30#include "gnutls_auth_int.h"
31#include "gnutls_errors.h"
32#include <gnutls_cert.h>
33#include <auth_cert.h>
34#include "gnutls_dh.h"
35#include "gnutls_num.h"
36#include "libtasn1.h"
37#include "gnutls_datum.h"
38#include <gnutls_pk.h>
39#include <gnutls_algorithms.h>
40#include <gnutls_global.h>
41#include <gnutls_record.h>
42#include <gnutls_sig.h>
43#include <gnutls_state.h>
44#include <gnutls_pk.h>
45#include <gnutls_x509.h>
46#include <gnutls_extra_hooks.h>
47#include "debug.h"
48
49static gnutls_cert *alloc_and_load_x509_certs (gnutls_x509_crt_t * certs,
50 unsigned);
51static gnutls_privkey *alloc_and_load_x509_key (gnutls_x509_privkey_t key);
52static gnutls_cert *alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert);
53static gnutls_privkey *alloc_and_load_pgp_key (const gnutls_openpgp_privkey_t
54 key);
55
56
57/* Copies data from a internal certificate struct (gnutls_cert) to
58 * exported certificate struct (cert_auth_info_t)
59 */
60static int
61_gnutls_copy_certificate_auth_info (cert_auth_info_t info,
62 gnutls_cert * cert, int ncerts)
63{
64 /* Copy peer's information to auth_info_t
65 */
66 int ret, i, j;
67
68 if (ncerts == 0)
69 {
70 info->raw_certificate_list = NULL;
71 info->ncerts = 0;
72 return 0;
73 }
74
75 info->raw_certificate_list =
76 gnutls_calloc (1, sizeof (gnutls_datum_t) * ncerts);
77 if (info->raw_certificate_list == NULL)
78 {
79 gnutls_assert ();
80 return GNUTLS_E_MEMORY_ERROR;
81 }
82
83 for (i = 0; i < ncerts; i++)
84 {
85 if (cert->raw.size > 0)
86 {
87 ret =
88 _gnutls_set_datum (&info->
89 raw_certificate_list[i],
90 cert[i].raw.data, cert[i].raw.size);
91 if (ret < 0)
92 {
93 gnutls_assert ();
94 goto clear;
95 }
96 }
97 }
98 info->ncerts = ncerts;
99
100 return 0;
101
102clear:
103
104 for (j = 0; j < i; j++)
105 _gnutls_free_datum (&info->raw_certificate_list[j]);
106
107 gnutls_free (info->raw_certificate_list);
108 info->raw_certificate_list = NULL;
109
110 return ret;
111}
112
113
114
115
116/* returns 0 if the algo_to-check exists in the pk_algos list,
117 * -1 otherwise.
118 */
119inline static int
120_gnutls_check_pk_algo_in_list (const gnutls_pk_algorithm_t *
121 pk_algos, int pk_algos_length,
122 gnutls_pk_algorithm_t algo_to_check)
123{
124 int i;
125 for (i = 0; i < pk_algos_length; i++)
126 {
127 if (algo_to_check == pk_algos[i])
128 {
129 return 0;
130 }
131 }
132 return -1;
133}
134
135
136/* Returns the issuer's Distinguished name in odn, of the certificate
137 * specified in cert.
138 */
139static int
140_gnutls_cert_get_issuer_dn (gnutls_cert * cert, gnutls_datum_t * odn)
141{
142 ASN1_TYPE dn;
143 int len, result;
144 int start, end;
145
146 if ((result = asn1_create_element
147 (_gnutls_get_pkix (), "PKIX1.Certificate", &dn)) != ASN1_SUCCESS)
148 {
149 gnutls_assert ();
150 return _gnutls_asn2err (result);
151 }
152
153 result = asn1_der_decoding (&dn, cert->raw.data, cert->raw.size, NULL);
154 if (result != ASN1_SUCCESS)
155 {
156 /* couldn't decode DER */
157 gnutls_assert ();
158 asn1_delete_structure (&dn);
159 return _gnutls_asn2err (result);
160 }
161
162 result = asn1_der_decoding_startEnd (dn, cert->raw.data, cert->raw.size,
163 "tbsCertificate.issuer", &start, &end);
164
165 if (result != ASN1_SUCCESS)
166 {
167 /* couldn't decode DER */
168 gnutls_assert ();
169 asn1_delete_structure (&dn);
170 return _gnutls_asn2err (result);
171 }
172 asn1_delete_structure (&dn);
173
174 len = end - start + 1;
175
176 odn->size = len;
177 odn->data = &cert->raw.data[start];
178
179 return 0;
180}
181
182
183/* Locates the most appropriate x509 certificate using the
184 * given DN. If indx == -1 then no certificate was found.
185 *
186 * That is to guess which certificate to use, based on the
187 * CAs and sign algorithms supported by the peer server.
188 */
189static int
190_find_x509_cert (const gnutls_certificate_credentials_t cred,
191 opaque * _data, size_t _data_size,
192 const gnutls_pk_algorithm_t * pk_algos,
193 int pk_algos_length, int *indx)
194{
195 unsigned size;
196 gnutls_datum_t odn;
197 opaque *data = _data;
198 ssize_t data_size = _data_size;
199 unsigned i, j;
200 int result, cert_pk;
201
202 *indx = -1;
203
204 do
205 {
206
207 DECR_LENGTH_RET (data_size, 2, 0);
208 size = _gnutls_read_uint16 (data);
209 DECR_LENGTH_RET (data_size, size, 0);
210 data += 2;
211
212 for (i = 0; i < cred->ncerts; i++)
213 {
214 for (j = 0; j < cred->cert_list_length[i]; j++)
215 {
216 if ((result =
217 _gnutls_cert_get_issuer_dn (&cred->
218 cert_list[i][j], &odn)) < 0)
219 {
220 gnutls_assert ();
221 return result;
222 }
223
224 if (odn.size != size)
225 continue;
226
227 /* If the DN matches and
228 * the *_SIGN algorithm matches
229 * the cert is our cert!
230 */
231 cert_pk = cred->cert_list[i][0].subject_pk_algorithm;
232
233 if ((memcmp (odn.data, data, size) == 0) &&
234 (_gnutls_check_pk_algo_in_list
235 (pk_algos, pk_algos_length, cert_pk) == 0))
236 {
237 *indx = i;
238 break;
239 }
240 }
241 if (*indx != -1)
242 break;
243 }
244
245 if (*indx != -1)
246 break;
247
248 /* move to next record */
249 data += size;
250
251 }
252 while (1);
253
254 return 0;
255
256}
257
258/* Locates the most appropriate openpgp cert
259 */
260static int
261_find_openpgp_cert (const gnutls_certificate_credentials_t cred,
262 gnutls_pk_algorithm_t * pk_algos,
263 int pk_algos_length, int *indx)
264{
265 unsigned i, j;
266
267 *indx = -1;
268
269 for (i = 0; i < cred->ncerts; i++)
270 {
271 for (j = 0; j < cred->cert_list_length[i]; j++)
272 {
273
274 /* If the *_SIGN algorithm matches
275 * the cert is our cert!
276 */
277 if ((_gnutls_check_pk_algo_in_list
278 (pk_algos, pk_algos_length,
279 cred->cert_list[i][0].subject_pk_algorithm) == 0)
280 && (cred->cert_list[i][0].cert_type == GNUTLS_CRT_OPENPGP))
281 {
282 *indx = i;
283 break;
284 }
285 }
286 if (*indx != -1)
287 break;
288 }
289
290 return 0;
291}
292
293/* Returns the number of issuers in the server's
294 * certificate request packet.
295 */
296static int
297get_issuers_num (gnutls_session_t session, opaque * data, ssize_t data_size)
298{
299 int issuers_dn_len = 0, result;
300 unsigned size;
301
302 /* Count the number of the given issuers;
303 * This is used to allocate the issuers_dn without
304 * using realloc().
305 */
306
307 if (data_size == 0 || data == NULL)
308 return 0;
309
310 if (data_size > 0)
311 do
312 {
313 /* This works like DECR_LEN()
314 */
315 result = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
316 DECR_LENGTH_COM (data_size, 2, goto error);
317 size = _gnutls_read_uint16 (data);
318
319 result = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
320 DECR_LENGTH_COM (data_size, size, goto error);
321
322 data += 2;
323
324 if (size > 0)
325 {
326 issuers_dn_len++;
327 data += size;
328 }
329
330 if (data_size == 0)
331 break;
332
333 }
334 while (1);
335
336 return issuers_dn_len;
337
338error:
339 return result;
340}
341
342/* Returns the issuers in the server's certificate request
343 * packet.
344 */
345static int
346get_issuers (gnutls_session_t session,
347 gnutls_datum_t * issuers_dn, int issuers_len,
348 opaque * data, size_t data_size)
349{
350 int i;
351 unsigned size;
352
353 if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509)
354 return 0;
355
356 /* put the requested DNs to req_dn, only in case
357 * of X509 certificates.
358 */
359 if (issuers_len > 0)
360 {
361
362 for (i = 0; i < issuers_len; i++)
363 {
364 /* The checks here for the buffer boundaries
365 * are not needed since the buffer has been
366 * parsed above.
367 */
368 data_size -= 2;
369
370 size = _gnutls_read_uint16 (data);
371
372 data += 2;
373
374 issuers_dn[i].data = data;
375 issuers_dn[i].size = size;
376
377 data += size;
378 }
379 }
380
381 return 0;
382}
383
384/* Calls the client get callback.
385 */
386static int
387call_get_cert_callback (gnutls_session_t session,
388 gnutls_datum_t * issuers_dn,
389 int issuers_dn_length,
390 gnutls_pk_algorithm_t * pk_algos, int pk_algos_length)
391{
392 unsigned i;
393 gnutls_cert *local_certs = NULL;
394 gnutls_privkey *local_key = NULL;
395 gnutls_retr_st st;
396 int ret;
397 gnutls_certificate_type_t type = gnutls_certificate_type_get (session);
398 gnutls_certificate_credentials_t cred;
399
400 cred = (gnutls_certificate_credentials_t)
401 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
402 if (cred == NULL)
403 {
404 gnutls_assert ();
405 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
406 }
407
408 memset (&st, 0, sizeof (st));
409
410 if (session->security_parameters.entity == GNUTLS_SERVER)
411 {
412 ret = cred->server_get_cert_callback (session, &st);
413 }
414 else
415 { /* CLIENT */
416 ret =
417 cred->client_get_cert_callback (session,
418 issuers_dn, issuers_dn_length,
419 pk_algos, pk_algos_length, &st);
420 }
421
422 if (ret < 0)
423 {
424 gnutls_assert ();
425 return GNUTLS_E_INTERNAL_ERROR;
426 }
427
428 if (st.ncerts == 0)
429 return 0; /* no certificate was selected */
430
431 if (type != st.type)
432 {
433 gnutls_assert ();
434 ret = GNUTLS_E_INVALID_REQUEST;
435 goto cleanup;
436 }
437
438 if (type == GNUTLS_CRT_X509)
439 {
440 local_certs = alloc_and_load_x509_certs (st.cert.x509, st.ncerts);
441 if (local_certs != NULL)
442 local_key = alloc_and_load_x509_key (st.key.x509);
443
444 }
445 else
446 { /* PGP */
447 if (st.ncerts > 1)
448 {
449 gnutls_assert ();
450 ret = GNUTLS_E_INVALID_REQUEST;
451 goto cleanup;
452 }
453
454 local_certs = alloc_and_load_pgp_certs (st.cert.pgp);
455 if (local_certs != NULL)
456 local_key = alloc_and_load_pgp_key (st.key.pgp);
457
458 }
459
460 _gnutls_selected_certs_set (session, local_certs,
461 (local_certs != NULL) ? st.ncerts : 0,
462 local_key, 1);
463
464 ret = 0;
465
466cleanup:
467
468 if (st.type == GNUTLS_CRT_X509)
469 {
470 if (st.deinit_all)
471 {
472 for (i = 0; i < st.ncerts; i++)
473 {
474 gnutls_x509_crt_deinit (st.cert.x509[i]);
475 }
476 gnutls_free (st.cert.x509);
477 gnutls_x509_privkey_deinit (st.key.x509);
478 }
479 }
480 else
481 {
482 if (st.deinit_all)
483 {
484 if (_E_gnutls_openpgp_crt_deinit == NULL ||
485 _E_gnutls_openpgp_privkey_deinit == NULL)
486 {
487 gnutls_assert ();
488 return GNUTLS_E_INIT_LIBEXTRA;
489 }
490
491 _E_gnutls_openpgp_crt_deinit (st.cert.pgp);
492 _E_gnutls_openpgp_privkey_deinit (st.key.pgp);
493 }
494 }
495
496 return ret;
497}
498
499/* Finds the appropriate certificate depending on the cA Distinguished name
500 * advertized by the server. If none matches then returns 0 and -1 as index.
501 * In case of an error a negative value, is returned.
502 *
503 * 20020128: added ability to select a certificate depending on the SIGN
504 * algorithm (only in automatic mode).
505 */
506static int
507_select_client_cert (gnutls_session_t session,
508 opaque * _data, size_t _data_size,
509 gnutls_pk_algorithm_t * pk_algos, int pk_algos_length)
510{
511 int result;
512 int indx = -1;
513 gnutls_certificate_credentials_t cred;
514 opaque *data = _data;
515 ssize_t data_size = _data_size;
516 int issuers_dn_length;
517 gnutls_datum_t *issuers_dn = NULL;
518
519 cred = (gnutls_certificate_credentials_t)
520 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
521 if (cred == NULL)
522 {
523 gnutls_assert ();
524 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
525 }
526
527 if (cred->client_get_cert_callback != NULL)
528 {
529
530 /* use a callback to get certificate
531 */
532 if (session->security_parameters.cert_type != GNUTLS_CRT_X509)
533 issuers_dn_length = 0;
534 else
535 {
536 issuers_dn_length = get_issuers_num (session, data, data_size);
537 if (issuers_dn_length < 0)
538 {
539 gnutls_assert ();
540 return issuers_dn_length;
541 }
542
543 if (issuers_dn_length > 0)
544 {
545 issuers_dn =
546 gnutls_malloc (sizeof (gnutls_datum_t) * issuers_dn_length);
547 if (issuers_dn == NULL)
548 {
549 gnutls_assert ();
550 return GNUTLS_E_MEMORY_ERROR;
551 }
552
553 result =
554 get_issuers (session, issuers_dn, issuers_dn_length,
555 data, data_size);
556 if (result < 0)
557 {
558 gnutls_assert ();
559 goto cleanup;
560 }
561 }
562 }
563
564 result =
565 call_get_cert_callback (session, issuers_dn, issuers_dn_length,
566 pk_algos, pk_algos_length);
567 goto cleanup;
568
569 }
570 else
571 {
572 /* If we have no callbacks, try to guess.
573 */
574 result = 0;
575
576 if (session->security_parameters.cert_type == GNUTLS_CRT_X509)
577 result =
578 _find_x509_cert (cred, _data, _data_size,
579 pk_algos, pk_algos_length, &indx);
580
581 if (session->security_parameters.cert_type == GNUTLS_CRT_OPENPGP)
582 result = _find_openpgp_cert (cred, pk_algos, pk_algos_length, &indx);
583
584
585 if (result < 0)
586 {
587 gnutls_assert ();
588 return result;
589 }
590
591 if (indx >= 0)
592 {
593 _gnutls_selected_certs_set (session,
594 &cred->cert_list[indx][0],
595 cred->cert_list_length[indx],
596 &cred->pkey[indx], 0);
597 }
598 else
599 {
600 _gnutls_selected_certs_set (session, NULL, 0, NULL, 0);
601 }
602
603 result = 0;
604 }
605
606cleanup:
607 gnutls_free (issuers_dn);
608 return result;
609
610}
611
612/* Generate client certificate
613 */
614
615int
616_gnutls_gen_x509_crt (gnutls_session_t session, opaque ** data)
617{
618 int ret, i;
619 opaque *pdata;
620 gnutls_cert *apr_cert_list;
621 gnutls_privkey *apr_pkey;
622 int apr_cert_list_length;
623
624 /* find the appropriate certificate
625 */
626 if ((ret =
627 _gnutls_get_selected_cert (session, &apr_cert_list,
628 &apr_cert_list_length, &apr_pkey)) < 0)
629 {
630 gnutls_assert ();
631 return ret;
632 }
633
634 ret = 3;
635 for (i = 0; i < apr_cert_list_length; i++)
636 {
637 ret += apr_cert_list[i].raw.size + 3;
638 /* hold size
639 * for uint24 */
640 }
641
642 /* if no certificates were found then send:
643 * 0B 00 00 03 00 00 00 // Certificate with no certs
644 * instead of:
645 * 0B 00 00 00 // empty certificate handshake
646 *
647 * ( the above is the whole handshake message, not
648 * the one produced here )
649 */
650
651 (*data) = gnutls_malloc (ret);
652 pdata = (*data);
653
654 if (pdata == NULL)
655 {
656 gnutls_assert ();
657 return GNUTLS_E_MEMORY_ERROR;
658 }
659 _gnutls_write_uint24 (ret - 3, pdata);
660 pdata += 3;
661 for (i = 0; i < apr_cert_list_length; i++)
662 {
663 _gnutls_write_datum24 (pdata, apr_cert_list[i].raw);
664 pdata += (3 + apr_cert_list[i].raw.size);
665 }
666
667 return ret;
668}
669
670enum PGPKeyDescriptorType
671{ PGP_KEY_FINGERPRINT, PGP_KEY };
672
673int
674_gnutls_gen_openpgp_certificate (gnutls_session_t session, opaque ** data)
675{
676 int ret;
677 opaque *pdata;
678 gnutls_cert *apr_cert_list;
679 gnutls_privkey *apr_pkey;
680 int apr_cert_list_length;
681
682 /* find the appropriate certificate */
683 if ((ret =
684 _gnutls_get_selected_cert (session, &apr_cert_list,
685 &apr_cert_list_length, &apr_pkey)) < 0)
686 {
687 gnutls_assert ();
688 return ret;
689 }
690
691 ret = 3 + 1 + 3;
692
693 if (apr_cert_list_length > 0)
694 ret += apr_cert_list[0].raw.size;
695
696 (*data) = gnutls_malloc (ret);
697 pdata = (*data);
698
699 if (pdata == NULL)
700 {
701 gnutls_assert ();
702 return GNUTLS_E_MEMORY_ERROR;
703 }
704
705 _gnutls_write_uint24 (ret - 3, pdata);
706 pdata += 3;
707
708 *pdata = PGP_KEY; /* whole key */
709 pdata++;
710
711 if (apr_cert_list_length > 0)
712 {
713 _gnutls_write_datum24 (pdata, apr_cert_list[0].raw);
714 pdata += (3 + apr_cert_list[0].raw.size);
715 }
716 else /* empty - no certificate */
717 _gnutls_write_uint24 (0, pdata);
718
719 return ret;
720}
721
722int
723_gnutls_gen_openpgp_certificate_fpr (gnutls_session_t session, opaque ** data)
724{
725 int ret, packet_size;
726 size_t fpr_size;
727 opaque *pdata;
728 gnutls_cert *apr_cert_list;
729 gnutls_privkey *apr_pkey;
730 int apr_cert_list_length;
731
732 /* find the appropriate certificate */
733 if ((ret =
734 _gnutls_get_selected_cert (session, &apr_cert_list,
735 &apr_cert_list_length, &apr_pkey)) < 0)
736 {
737 gnutls_assert ();
738 return ret;
739 }
740
741 packet_size = 3 + 1;
742
743 /* Only v4 fingerprints are sent
744 */
745 if (apr_cert_list_length > 0 && apr_cert_list[0].version == 4)
746 packet_size += 20 + 1;
747 else /* empty certificate case */
748 return _gnutls_gen_openpgp_certificate (session, data);
749
750 (*data) = gnutls_malloc (packet_size);
751 pdata = (*data);
752
753 if (pdata == NULL)
754 {
755 gnutls_assert ();
756 return GNUTLS_E_MEMORY_ERROR;
757 }
758
759 _gnutls_write_uint24 (packet_size - 3, pdata);
760 pdata += 3;
761
762 *pdata = PGP_KEY_FINGERPRINT; /* key fingerprint */
763 pdata++;
764
765 *pdata = 20;
766 pdata++;
767
768 fpr_size = 20;
769
770 if (_E_gnutls_openpgp_fingerprint == NULL)
771 {
772 gnutls_assert ();
773 return GNUTLS_E_INIT_LIBEXTRA;
774 }
775
776 if ((ret =
777 _E_gnutls_openpgp_fingerprint (&apr_cert_list[0].raw, pdata,
778 &fpr_size)) < 0)
779 {
780 gnutls_assert ();
781 return ret;
782 }
783
784 return packet_size;
785}
786
787
788
789int
790_gnutls_gen_cert_client_certificate (gnutls_session_t session, opaque ** data)
791{
792 switch (session->security_parameters.cert_type)
793 {
794 case GNUTLS_CRT_OPENPGP:
795 if (_gnutls_openpgp_send_fingerprint (session) == 0)
796 return _gnutls_gen_openpgp_certificate (session, data);
797 else
798 return _gnutls_gen_openpgp_certificate_fpr (session, data);
799
800 case GNUTLS_CRT_X509:
801 return _gnutls_gen_x509_crt (session, data);
802
803 default:
804 gnutls_assert ();
805 return GNUTLS_E_INTERNAL_ERROR;
806 }
807}
808
809int
810_gnutls_gen_cert_server_certificate (gnutls_session_t session, opaque ** data)
811{
812 switch (session->security_parameters.cert_type)
813 {
814 case GNUTLS_CRT_OPENPGP:
815 return _gnutls_gen_openpgp_certificate (session, data);
816 case GNUTLS_CRT_X509:
817 return _gnutls_gen_x509_crt (session, data);
818 default:
819 gnutls_assert ();
820 return GNUTLS_E_INTERNAL_ERROR;
821 }
822}
823
824/* Process server certificate
825 */
826
827#define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_gcert_deinit(&peer_certificate_list[x])
828int
829_gnutls_proc_x509_server_certificate (gnutls_session_t session,
830 opaque * data, size_t data_size)
831{
832 int size, len, ret;
833 opaque *p = data;
834 cert_auth_info_t info;
835 gnutls_certificate_credentials_t cred;
836 ssize_t dsize = data_size;
837 int i, j, x;
838 gnutls_cert *peer_certificate_list;
839 int peer_certificate_list_size = 0;
840 gnutls_datum_t tmp;
841
842 cred = (gnutls_certificate_credentials_t)
843 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
844 if (cred == NULL)
845 {
846 gnutls_assert ();
847 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
848 }
849
850
851 if ((ret =
852 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
853 sizeof (cert_auth_info_st), 1)) < 0)
854 {
855 gnutls_assert ();
856 return ret;
857 }
858
859 info = _gnutls_get_auth_info (session);
860
861 if (data == NULL || data_size == 0)
862 {
863 gnutls_assert ();
864 /* no certificate was sent */
865 return GNUTLS_E_NO_CERTIFICATE_FOUND;
866 }
867
868 DECR_LEN (dsize, 3);
869 size = _gnutls_read_uint24 (p);
870 p += 3;
871
872 /* some implementations send 0B 00 00 06 00 00 03 00 00 00
873 * instead of just 0B 00 00 03 00 00 00 as an empty certificate message.
874 */
875 if (size == 0 || size == 3)
876 {
877 gnutls_assert ();
878 /* no certificate was sent */
879 return GNUTLS_E_NO_CERTIFICATE_FOUND;
880 }
881
882 i = dsize;
883 while (i > 0)
884 {
885 DECR_LEN (dsize, 3);
886 len = _gnutls_read_uint24 (p);
887 p += 3;
888 DECR_LEN (dsize, len);
889 peer_certificate_list_size++;
890 p += len;
891 i -= len + 3;
892 }
893
894 if (peer_certificate_list_size == 0)
895 {
896 gnutls_assert ();
897 return GNUTLS_E_NO_CERTIFICATE_FOUND;
898 }
899
900 /* Ok we now allocate the memory to hold the
901 * certificate list
902 */
903
904 peer_certificate_list =
905 gnutls_malloc (sizeof (gnutls_cert) * (peer_certificate_list_size));
906
907 if (peer_certificate_list == NULL)
908 {
909 gnutls_assert ();
910 return GNUTLS_E_MEMORY_ERROR;
911 }
912 memset (peer_certificate_list, 0, sizeof (gnutls_cert) *
913 peer_certificate_list_size);
914
915 p = data + 3;
916
917 /* Now we start parsing the list (again).
918 * We don't use DECR_LEN since the list has
919 * been parsed before.
920 */
921
922 for (j = 0; j < peer_certificate_list_size; j++)
923 {
924 len = _gnutls_read_uint24 (p);
925 p += 3;
926
927 tmp.size = len;
928 tmp.data = p;
929
930 if ((ret =
931 _gnutls_x509_raw_cert_to_gcert (&peer_certificate_list
932 [j], &tmp,
933 CERT_ONLY_EXTENSIONS)) < 0)
934 {
935 gnutls_assert ();
936 goto cleanup;
937 }
938
939 p += len;
940 }
941
942
943 if ((ret =
944 _gnutls_copy_certificate_auth_info (info,
945 peer_certificate_list,
946 peer_certificate_list_size)) < 0)
947 {
948 gnutls_assert ();
949 goto cleanup;
950 }
951
952 if ((ret =
953 _gnutls_check_key_usage (&peer_certificate_list[0],
954 gnutls_kx_get (session))) < 0)
955 {
956 gnutls_assert ();
957 goto cleanup;
958 }
959
960 ret = 0;
961
962cleanup:
963 CLEAR_CERTS;
964 gnutls_free (peer_certificate_list);
965 return ret;
966
967}
968
969#define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) _gnutls_gcert_deinit(&peer_certificate_list[x])
970int
971_gnutls_proc_openpgp_server_certificate (gnutls_session_t session,
972 opaque * data, size_t data_size)
973{
974 int size, ret, len;
975 opaque *p = data;
976 cert_auth_info_t info;
977 gnutls_certificate_credentials_t cred;
978 ssize_t dsize = data_size;
979 int i, x;
980 gnutls_cert *peer_certificate_list = NULL;
981 int peer_certificate_list_size = 0;
982 gnutls_datum_t tmp, akey = { NULL, 0 };
983
984 cred = (gnutls_certificate_credentials_t)
985 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
986 if (cred == NULL)
987 {
988 gnutls_assert ();
989 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
990 }
991
992 if ((ret =
993 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
994 sizeof (cert_auth_info_st), 1)) < 0)
995 {
996 gnutls_assert ();
997 return ret;
998 }
999
1000 info = _gnutls_get_auth_info (session);
1001
1002 if (data == NULL || data_size == 0)
1003 {
1004 gnutls_assert ();
1005 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1006 }
1007
1008 DECR_LEN (dsize, 3);
1009 size = _gnutls_read_uint24 (p);
1010 p += 3;
1011
1012 if (size == 0)
1013 {
1014 gnutls_assert ();
1015 /* no certificate was sent */
1016 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1017 }
1018 i = dsize;
1019
1020 /* Read PGPKeyDescriptor */
1021 DECR_LEN (dsize, 1);
1022 if (*p == PGP_KEY_FINGERPRINT)
1023 { /* the fingerprint */
1024 p++;
1025
1026 DECR_LEN (dsize, 1);
1027 len = (uint8_t) * p;
1028 p++;
1029
1030 if (len != 20)
1031 {
1032 gnutls_assert ();
1033 return GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED;
1034 }
1035
1036 DECR_LEN (dsize, 20);
1037
1038 /* request the actual key from our database, or
1039 * a key server or anything.
1040 */
1041 if (_E_gnutls_openpgp_request_key == NULL)
1042 {
1043 gnutls_assert ();
1044 return GNUTLS_E_INIT_LIBEXTRA;
1045 }
1046 if ((ret =
1047 _E_gnutls_openpgp_request_key (session, &akey, cred, p, 20)) < 0)
1048 {
1049 gnutls_assert ();
1050 return ret;
1051 }
1052 tmp = akey;
1053 peer_certificate_list_size++;
1054
1055 }
1056 else if (*p == PGP_KEY)
1057 { /* the whole key */
1058
1059 p++;
1060
1061 /* Read the actual certificate */
1062 DECR_LEN (dsize, 3);
1063 len = _gnutls_read_uint24 (p);
1064 p += 3;
1065
1066 if (len == 0)
1067 {
1068 gnutls_assert ();
1069 /* no certificate was sent */
1070 return GNUTLS_E_NO_CERTIFICATE_FOUND;
1071 }
1072
1073 DECR_LEN (dsize, len);
1074 peer_certificate_list_size++;
1075
1076 tmp.size = len;
1077 tmp.data = p;
1078
1079 }
1080 else
1081 {
1082 gnutls_assert ();
1083 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
1084 }
1085
1086 /* ok we now have the peer's key in tmp datum
1087 */
1088
1089 if (peer_certificate_list_size == 0)
1090 {
1091 gnutls_assert ();
1092 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1093 }
1094
1095 peer_certificate_list =
1096 gnutls_alloca (sizeof (gnutls_cert) * (peer_certificate_list_size));
1097 if (peer_certificate_list == NULL)
1098 {
1099 gnutls_assert ();
1100 ret = GNUTLS_E_MEMORY_ERROR;
1101 goto cleanup;
1102 }
1103 memset (peer_certificate_list, 0, sizeof (gnutls_cert) *
1104 peer_certificate_list_size);
1105
1106 if (_E_gnutls_openpgp_raw_key_to_gcert == NULL)
1107 {
1108 gnutls_assert ();
1109 ret = GNUTLS_E_INIT_LIBEXTRA;
1110 goto cleanup;
1111 }
1112
1113 if ((ret =
1114 _E_gnutls_openpgp_raw_key_to_gcert (&peer_certificate_list[0],
1115 &tmp)) < 0)
1116 {
1117 gnutls_assert ();
1118 goto cleanup;
1119 }
1120
1121 if ((ret =
1122 _gnutls_copy_certificate_auth_info (info,
1123 peer_certificate_list,
1124 peer_certificate_list_size)) < 0)
1125 {
1126 gnutls_assert ();
1127 goto cleanup;
1128 }
1129
1130 if ((ret =
1131 _gnutls_check_key_usage (&peer_certificate_list[0],
1132 gnutls_kx_get (session))) < 0)
1133 {
1134 gnutls_assert ();
1135 goto cleanup;
1136 }
1137
1138 ret = 0;
1139
1140cleanup:
1141
1142 _gnutls_free_datum (&akey);
1143 CLEAR_CERTS;
1144 gnutls_afree (peer_certificate_list);
1145 return ret;
1146
1147}
1148
1149int
1150_gnutls_proc_cert_server_certificate (gnutls_session_t session,
1151 opaque * data, size_t data_size)
1152{
1153 switch (session->security_parameters.cert_type)
1154 {
1155 case GNUTLS_CRT_OPENPGP:
1156 return _gnutls_proc_openpgp_server_certificate (session,
1157 data, data_size);
1158 case GNUTLS_CRT_X509:
1159 return _gnutls_proc_x509_server_certificate (session, data, data_size);
1160 default:
1161 gnutls_assert ();
1162 return GNUTLS_E_INTERNAL_ERROR;
1163 }
1164}
1165
1166#define MAX_SIGN_ALGOS 2
1167typedef enum CertificateSigType
1168{ RSA_SIGN = 1, DSA_SIGN
1169} CertificateSigType;
1170
1171/* Checks if we support the given signature algorithm
1172 * (RSA or DSA). Returns the corresponding gnutls_pk_algorithm_t
1173 * if true;
1174 */
1175inline static int
1176_gnutls_check_supported_sign_algo (CertificateSigType algo)
1177{
1178 switch (algo)
1179 {
1180 case RSA_SIGN:
1181 return GNUTLS_PK_RSA;
1182 }
1183
1184 return -1;
1185}
1186
1187int
1188_gnutls_proc_cert_cert_req (gnutls_session_t session, opaque * data,
1189 size_t data_size)
1190{
1191 int size, ret;
1192 opaque *p;
1193 gnutls_certificate_credentials_t cred;
1194 cert_auth_info_t info;
1195 ssize_t dsize;
1196 int i, j;
1197 gnutls_pk_algorithm_t pk_algos[MAX_SIGN_ALGOS];
1198 int pk_algos_length;
1199 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1200
1201 cred = (gnutls_certificate_credentials_t)
1202 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1203 if (cred == NULL)
1204 {
1205 gnutls_assert ();
1206 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1207 }
1208
1209 if ((ret =
1210 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
1211 sizeof (cert_auth_info_st), 0)) < 0)
1212 {
1213 gnutls_assert ();
1214 return ret;
1215 }
1216
1217 info = _gnutls_get_auth_info (session);
1218
1219 p = data;
1220 dsize = data_size;
1221
1222 DECR_LEN (dsize, 1);
1223 size = p[0];
1224 p++;
1225 /* check if the sign algorithm is supported.
1226 */
1227 pk_algos_length = j = 0;
1228 for (i = 0; i < size; i++, p++)
1229 {
1230 DECR_LEN (dsize, 1);
1231 if ((ret = _gnutls_check_supported_sign_algo (*p)) > 0)
1232 {
1233 if (j < MAX_SIGN_ALGOS)
1234 {
1235 pk_algos[j++] = ret;
1236 pk_algos_length++;
1237 }
1238 }
1239 }
1240
1241 if (pk_algos_length == 0)
1242 {
1243 gnutls_assert ();
1244 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
1245 }
1246
1247 if (ver == GNUTLS_TLS1_2)
1248 {
1249 /* read supported hashes */
1250 int hash_num;
1251 DECR_LEN (dsize, 1);
1252
1253 hash_num = p[0] & 0xFF;
1254 p++;
1255
1256 DECR_LEN (dsize, hash_num);
1257 p += hash_num;
1258 }
1259
1260 /* read the certificate authorities */
1261 DECR_LEN (dsize, 2);
1262 size = _gnutls_read_uint16 (p);
1263 p += 2;
1264
1265 if (session->security_parameters.cert_type == GNUTLS_CRT_OPENPGP
1266 && size != 0)
1267 {
1268 gnutls_assert (); // size should be zero
1269 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1270 }
1271
1272 DECR_LEN (dsize, size);
1273
1274 /* now we ask the user to tell which one
1275 * he wants to use.
1276 */
1277 if ((ret =
1278 _select_client_cert (session, p, size, pk_algos, pk_algos_length)) < 0)
1279 {
1280 gnutls_assert ();
1281 return ret;
1282 }
1283
1284 /* We should reply with a certificate message,
1285 * even if we have no certificate to send.
1286 */
1287 session->key->certificate_requested = 1;
1288
1289 return 0;
1290}
1291
1292int
1293_gnutls_gen_cert_client_cert_vrfy (gnutls_session_t session, opaque ** data)
1294{
1295 int ret;
1296 gnutls_cert *apr_cert_list;
1297 gnutls_privkey *apr_pkey;
1298 int apr_cert_list_length, size;
1299 gnutls_datum_t signature;
1300
1301 *data = NULL;
1302
1303 /* find the appropriate certificate */
1304 if ((ret =
1305 _gnutls_get_selected_cert (session, &apr_cert_list,
1306 &apr_cert_list_length, &apr_pkey)) < 0)
1307 {
1308 gnutls_assert ();
1309 return ret;
1310 }
1311
1312 if (apr_cert_list_length > 0)
1313 {
1314 if ((ret =
1315 _gnutls_tls_sign_hdata (session,
1316 &apr_cert_list[0],
1317 apr_pkey, &signature)) < 0)
1318 {
1319 gnutls_assert ();
1320 return ret;
1321 }
1322 }
1323 else
1324 {
1325 return 0;
1326 }
1327
1328 *data = gnutls_malloc (signature.size + 2);
1329 if (*data == NULL)
1330 {
1331 _gnutls_free_datum (&signature);
1332 return GNUTLS_E_MEMORY_ERROR;
1333 }
1334 size = signature.size;
1335 _gnutls_write_uint16 (size, *data);
1336
1337 memcpy (&(*data)[2], signature.data, size);
1338
1339 _gnutls_free_datum (&signature);
1340
1341 return size + 2;
1342}
1343
1344int
1345_gnutls_proc_cert_client_cert_vrfy (gnutls_session_t session,
1346 opaque * data, size_t data_size)
1347{
1348 int size, ret;
1349 ssize_t dsize = data_size;
1350 opaque *pdata = data;
1351 gnutls_datum_t sig;
1352 cert_auth_info_t info = _gnutls_get_auth_info (session);
1353 gnutls_cert peer_cert;
1354
1355 if (info == NULL || info->ncerts == 0)
1356 {
1357 gnutls_assert ();
1358 /* we need this in order to get peer's certificate */
1359 return GNUTLS_E_INTERNAL_ERROR;
1360 }
1361
1362 DECR_LEN (dsize, 2);
1363 size = _gnutls_read_uint16 (pdata);
1364 pdata += 2;
1365
1366 DECR_LEN (dsize, size);
1367
1368 sig.data = pdata;
1369 sig.size = size;
1370
1371 ret = _gnutls_raw_cert_to_gcert (&peer_cert,
1372 session->security_parameters.cert_type,
1373 &info->raw_certificate_list[0],
1374 CERT_NO_COPY);
1375
1376 if (ret < 0)
1377 {
1378 gnutls_assert ();
1379 return ret;
1380 }
1381
1382 if ((ret = _gnutls_verify_sig_hdata (session, &peer_cert, &sig)) < 0)
1383 {
1384 gnutls_assert ();
1385 _gnutls_gcert_deinit (&peer_cert);
1386 return ret;
1387 }
1388 _gnutls_gcert_deinit (&peer_cert);
1389
1390 return 0;
1391}
1392
1393#define CERTTYPE_SIZE 3
1394int
1395_gnutls_gen_cert_server_cert_req (gnutls_session_t session, opaque ** data)
1396{
1397 gnutls_certificate_credentials_t cred;
1398 int size;
1399 opaque *pdata;
1400 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
1401
1402 /* Now we need to generate the RDN sequence. This is
1403 * already in the CERTIFICATE_CRED structure, to improve
1404 * performance.
1405 */
1406
1407 cred = (gnutls_certificate_credentials_t)
1408 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1409 if (cred == NULL)
1410 {
1411 gnutls_assert ();
1412 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1413 }
1414
1415 size = CERTTYPE_SIZE + 2; /* 2 for gnutls_certificate_type_t + 2 for size of rdn_seq
1416 */
1417
1418 if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
1419 session->internals.ignore_rdn_sequence == 0)
1420 size += cred->x509_rdn_sequence.size;
1421
1422 if (ver == GNUTLS_TLS1_2)
1423 /* Need at least one byte to announce the number of supported hash
1424 functions (see below). */
1425 size += 1;
1426
1427 (*data) = gnutls_malloc (size);
1428 pdata = (*data);
1429
1430 if (pdata == NULL)
1431 {
1432 gnutls_assert ();
1433 return GNUTLS_E_MEMORY_ERROR;
1434 }
1435
1436 pdata[0] = CERTTYPE_SIZE - 1;
1437
1438 pdata[1] = RSA_SIGN;
1439 pdata[2] = DSA_SIGN; /* only these for now */
1440 pdata += CERTTYPE_SIZE;
1441
1442 if (ver == GNUTLS_TLS1_2)
1443 {
1444 /* Supported hashes (nothing for now -- FIXME). */
1445 *pdata = 0;
1446 pdata++;
1447 }
1448
1449 if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
1450 session->internals.ignore_rdn_sequence == 0)
1451 {
1452 _gnutls_write_datum16 (pdata, cred->x509_rdn_sequence);
1453 /* pdata += cred->x509_rdn_sequence.size + 2; */
1454 }
1455 else
1456 {
1457 _gnutls_write_uint16 (0, pdata);
1458 /* pdata+=2; */
1459 }
1460
1461 return size;
1462}
1463
1464
1465/* This function will return the appropriate certificate to use.
1466 * Fills in the apr_cert_list, apr_cert_list_length and apr_pkey.
1467 * The return value is a negative value on error.
1468 *
1469 * It is normal to return 0 with no certificates in client side.
1470 *
1471 */
1472int
1473_gnutls_get_selected_cert (gnutls_session_t session,
1474 gnutls_cert ** apr_cert_list,
1475 int *apr_cert_list_length,
1476 gnutls_privkey ** apr_pkey)
1477{
1478 if (session->security_parameters.entity == GNUTLS_SERVER)
1479 {
1480
1481 /* select_client_cert() has been called before.
1482 */
1483
1484 *apr_cert_list = session->internals.selected_cert_list;
1485 *apr_pkey = session->internals.selected_key;
1486 *apr_cert_list_length = session->internals.selected_cert_list_length;
1487
1488 if (*apr_cert_list_length == 0 || *apr_cert_list == NULL)
1489 {
1490 gnutls_assert ();
1491 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1492 }
1493
1494 }
1495 else
1496 { /* CLIENT SIDE
1497 */
1498
1499 /* we have already decided which certificate
1500 * to send.
1501 */
1502 *apr_cert_list = session->internals.selected_cert_list;
1503 *apr_cert_list_length = session->internals.selected_cert_list_length;
1504 *apr_pkey = session->internals.selected_key;
1505
1506 }
1507
1508 return 0;
1509}
1510
1511/* converts the given x509 certificate to gnutls_cert* and allocates
1512 * space for them.
1513 */
1514static gnutls_cert *
1515alloc_and_load_x509_certs (gnutls_x509_crt_t * certs, unsigned ncerts)
1516{
1517 gnutls_cert *local_certs;
1518 int ret = 0;
1519 unsigned i, j;
1520
1521 if (certs == NULL)
1522 return NULL;
1523
1524 local_certs = gnutls_malloc (sizeof (gnutls_cert) * ncerts);
1525 if (local_certs == NULL)
1526 {
1527 gnutls_assert ();
1528 return NULL;
1529 }
1530
1531 for (i = 0; i < ncerts; i++)
1532 {
1533 ret = _gnutls_x509_crt_to_gcert (&local_certs[i], certs[i], 0);
1534 if (ret < 0)
1535 break;
1536 }
1537
1538 if (ret < 0)
1539 {
1540 gnutls_assert ();
1541 for (j = 0; j < i; j++)
1542 {
1543 _gnutls_gcert_deinit (&local_certs[j]);
1544 }
1545 gnutls_free (local_certs);
1546 return NULL;
1547 }
1548
1549 return local_certs;
1550}
1551
1552/* converts the given x509 key to gnutls_privkey* and allocates
1553 * space for it.
1554 */
1555static gnutls_privkey *
1556alloc_and_load_x509_key (gnutls_x509_privkey_t key)
1557{
1558 gnutls_privkey *local_key;
1559 int ret = 0;
1560
1561 if (key == NULL)
1562 return NULL;
1563
1564 local_key = gnutls_malloc (sizeof (gnutls_privkey));
1565 if (local_key == NULL)
1566 {
1567 gnutls_assert ();
1568 return NULL;
1569 }
1570
1571 ret = _gnutls_x509_privkey_to_gkey (local_key, key);
1572 if (ret < 0)
1573 {
1574 gnutls_assert ();
1575 return NULL;
1576 }
1577
1578 return local_key;
1579}
1580
1581/* converts the given pgp certificate to gnutls_cert* and allocates
1582 * space for them.
1583 */
1584static gnutls_cert *
1585alloc_and_load_pgp_certs (gnutls_openpgp_crt_t cert)
1586{
1587 gnutls_cert *local_certs;
1588 int ret = 0;
1589
1590 if (cert == NULL)
1591 return NULL;
1592
1593 local_certs = gnutls_malloc (sizeof (gnutls_cert));
1594 if (local_certs == NULL)
1595 {
1596 gnutls_assert ();
1597 return NULL;
1598 }
1599
1600 if (_E_gnutls_openpgp_crt_to_gcert == NULL)
1601 {
1602 gnutls_assert ();
1603 return NULL;
1604 }
1605
1606 ret = _E_gnutls_openpgp_crt_to_gcert (local_certs, cert);
1607 if (ret < 0)
1608 {
1609 gnutls_assert ();
1610 return NULL;
1611 }
1612
1613 if (ret < 0)
1614 {
1615 gnutls_assert ();
1616 _gnutls_gcert_deinit (local_certs);
1617 gnutls_free (local_certs);
1618 return NULL;
1619 }
1620
1621 return local_certs;
1622}
1623
1624/* converts the given raw key to gnutls_privkey* and allocates
1625 * space for it.
1626 */
1627static gnutls_privkey *
1628alloc_and_load_pgp_key (const gnutls_openpgp_privkey_t key)
1629{
1630 gnutls_privkey *local_key;
1631 int ret = 0;
1632
1633 if (key == NULL)
1634 return NULL;
1635
1636 local_key = gnutls_malloc (sizeof (gnutls_privkey));
1637 if (local_key == NULL)
1638 {
1639 gnutls_assert ();
1640 return NULL;
1641 }
1642
1643 if (_E_gnutls_openpgp_privkey_to_gkey == NULL)
1644 {
1645 gnutls_assert ();
1646 return NULL;
1647 }
1648
1649 ret = _E_gnutls_openpgp_privkey_to_gkey (local_key, key);
1650 if (ret < 0)
1651 {
1652 gnutls_assert ();
1653 return NULL;
1654 }
1655
1656 return local_key;
1657}
1658
1659
1660void
1661_gnutls_selected_certs_deinit (gnutls_session_t session)
1662{
1663 if (session->internals.selected_need_free != 0)
1664 {
1665 int i;
1666
1667 for (i = 0; i < session->internals.selected_cert_list_length; i++)
1668 {
1669 _gnutls_gcert_deinit (&session->internals.selected_cert_list[i]);
1670 }
1671 gnutls_free (session->internals.selected_cert_list);
1672 session->internals.selected_cert_list = NULL;
1673 session->internals.selected_cert_list_length = 0;
1674
1675 _gnutls_gkey_deinit (session->internals.selected_key);
1676 if (session->internals.selected_key)
1677 {
1678 gnutls_free (session->internals.selected_key);
1679 session->internals.selected_key = NULL;
1680 }
1681 }
1682
1683 return;
1684}
1685
1686void
1687_gnutls_selected_certs_set (gnutls_session_t session,
1688 gnutls_cert * certs, int ncerts,
1689 gnutls_privkey * key, int need_free)
1690{
1691 _gnutls_selected_certs_deinit (session);
1692
1693 session->internals.selected_cert_list = certs;
1694 session->internals.selected_cert_list_length = ncerts;
1695 session->internals.selected_key = key;
1696 session->internals.selected_need_free = need_free;
1697
1698}
1699
1700
1701/* finds the most appropriate certificate in the cert list.
1702 * The 'appropriate' is defined by the user.
1703 *
1704 * requested_algo holds the parameters required by the peer (RSA, DSA
1705 * or -1 for any).
1706 *
1707 * Returns 0 on success and a negative value on error. The
1708 * selected certificate will be in session->internals.selected_*.
1709 *
1710 */
1711int
1712_gnutls_server_select_cert (gnutls_session_t session,
1713 gnutls_pk_algorithm_t requested_algo)
1714{
1715 unsigned i;
1716 int idx, ret;
1717 gnutls_certificate_credentials_t cred;
1718
1719 cred = (gnutls_certificate_credentials_t)
1720 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
1721 if (cred == NULL)
1722 {
1723 gnutls_assert ();
1724 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1725 }
1726
1727 /* If the callback which retrieves certificate has been set,
1728 * use it and leave.
1729 */
1730 if (cred->server_get_cert_callback != NULL)
1731 return call_get_cert_callback (session, NULL, 0, NULL, 0);
1732
1733 /* Otherwise... */
1734
1735 ret = 0;
1736 idx = -1; /* default is use no certificate */
1737
1738
1739 for (i = 0; i < cred->ncerts; i++)
1740 {
1741 /* find one compatible certificate
1742 */
1743 if (requested_algo == GNUTLS_PK_ANY ||
1744 requested_algo == cred->cert_list[i][0].subject_pk_algorithm)
1745 {
1746 /* if cert type matches
1747 */
1748 if (session->security_parameters.cert_type ==
1749 cred->cert_list[i][0].cert_type)
1750 {
1751 idx = i;
1752 break;
1753 }
1754 }
1755 }
1756
1757 /* store the certificate pointer for future use, in the handshake.
1758 * (This will allow not calling this callback again.)
1759 */
1760 if (idx >= 0 && ret == 0)
1761 {
1762 _gnutls_selected_certs_set (session,
1763 &cred->cert_list[idx][0],
1764 cred->cert_list_length[idx],
1765 &cred->pkey[idx], 0);
1766 }
1767 else
1768 /* Certificate does not support REQUESTED_ALGO. */
1769 ret = GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1770
1771 return ret;
1772}
1773
1774/* Frees the rsa_info_st structure.
1775 */
1776void
1777_gnutls_free_rsa_info (rsa_info_st * rsa)
1778{
1779 _gnutls_free_datum (&rsa->modulus);
1780 _gnutls_free_datum (&rsa->exponent);
1781}
diff --git a/src/daemon/https/tls/auth_cert.h b/src/daemon/https/tls/auth_cert.h
new file mode 100644
index 00000000..86e0230f
--- /dev/null
+++ b/src/daemon/https/tls/auth_cert.h
@@ -0,0 +1,158 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#ifndef AUTH_CERT_H
26# define AUTH_CERT_H
27
28# include "gnutls_cert.h"
29# include "gnutls_auth.h"
30# include "auth_dh_common.h"
31# include "x509.h"
32# include "openpgp.h"
33
34/* This structure may be complex, but it's the only way to
35 * support a server that has multiple certificates
36 */
37typedef struct gnutls_certificate_credentials_st
38{
39 gnutls_dh_params_t dh_params;
40 gnutls_rsa_params_t rsa_params;
41 /* this callback is used to retrieve the DH or RSA
42 * parameters.
43 */
44 gnutls_params_function *params_func;
45
46 gnutls_cert **cert_list;
47 /* contains a list of a list of certificates.
48 * eg (X509): [0] certificate1, certificate11, certificate111
49 * (if more than one, one certificate certifies the one before)
50 * [1] certificate2, certificate22, ...
51 */
52 unsigned *cert_list_length;
53 /* contains the number of the certificates in a
54 * row (should be 1 for OpenPGP keys).
55 */
56 unsigned ncerts; /* contains the number of columns in cert_list.
57 * This is the same with the number of pkeys.
58 */
59
60 gnutls_privkey *pkey;
61 /* private keys. It contains ncerts private
62 * keys. pkey[i] corresponds to certificate in
63 * cert_list[i][0].
64 */
65
66 /* OpenPGP specific stuff */
67
68#ifndef KEYRING_HACK
69 gnutls_openpgp_keyring_t keyring;
70#else
71 gnutls_datum_t keyring;
72 int keyring_format;
73#endif
74
75 /* X509 specific stuff */
76
77 gnutls_x509_crt_t *x509_ca_list;
78 unsigned x509_ncas; /* number of CAs in the ca_list
79 */
80
81 gnutls_x509_crl_t *x509_crl_list;
82 unsigned x509_ncrls; /* number of CRLs in the crl_list
83 */
84
85 unsigned int verify_flags; /* flags to be used at
86 * certificate verification.
87 */
88 unsigned int verify_depth;
89 unsigned int verify_bits;
90
91 /* holds a sequence of the
92 * RDNs of the CAs above.
93 * This is better than
94 * generating on every handshake.
95 */
96 gnutls_datum_t x509_rdn_sequence;
97
98 gnutls_certificate_client_retrieve_function *client_get_cert_callback;
99 gnutls_certificate_server_retrieve_function *server_get_cert_callback;
100} certificate_credentials_st;
101
102typedef struct rsa_info_st
103{
104 gnutls_datum_t modulus;
105 gnutls_datum_t exponent;
106} rsa_info_st;
107
108typedef struct cert_auth_info_st
109{
110 int certificate_requested; /* if the peer requested certificate
111 * this is non zero;
112 */
113
114 /* These (dh/rsa) are just copies from the credentials_t structure.
115 * They must be freed.
116 */
117 dh_info_st dh;
118 rsa_info_st rsa_export;
119
120 gnutls_datum_t *raw_certificate_list; /* holds the raw certificate of the
121 * peer.
122 */
123 unsigned int ncerts; /* holds the size of the list above */
124} *cert_auth_info_t;
125
126typedef struct cert_auth_info_st cert_auth_info_st;
127
128void _gnutls_free_rsa_info (rsa_info_st * rsa);
129
130/* AUTH X509 functions */
131int _gnutls_gen_cert_server_certificate (gnutls_session_t, opaque **);
132int _gnutls_gen_cert_client_certificate (gnutls_session_t, opaque **);
133int _gnutls_gen_cert_client_cert_vrfy (gnutls_session_t, opaque **);
134int _gnutls_gen_cert_server_cert_req (gnutls_session_t, opaque **);
135int _gnutls_proc_cert_cert_req (gnutls_session_t, opaque *, size_t);
136int _gnutls_proc_cert_client_cert_vrfy (gnutls_session_t, opaque *, size_t);
137int _gnutls_proc_cert_server_certificate (gnutls_session_t, opaque *, size_t);
138int _gnutls_get_selected_cert (gnutls_session_t session,
139 gnutls_cert ** apr_cert_list,
140 int *apr_cert_list_length,
141 gnutls_privkey ** apr_pkey);
142
143int _gnutls_server_select_cert (struct gnutls_session_int *,
144 gnutls_pk_algorithm_t);
145void _gnutls_selected_certs_deinit (gnutls_session_t session);
146void _gnutls_selected_certs_set (gnutls_session_t session,
147 gnutls_cert * certs, int ncerts,
148 gnutls_privkey * key, int need_free);
149
150#define _gnutls_proc_cert_client_certificate _gnutls_proc_cert_server_certificate
151
152gnutls_rsa_params_t _gnutls_certificate_get_rsa_params (gnutls_rsa_params_t
153 rsa_params,
154 gnutls_params_function
155 * func,
156 gnutls_session_t);
157
158#endif
diff --git a/src/daemon/https/tls/auth_dh_common.c b/src/daemon/https/tls/auth_dh_common.c
new file mode 100644
index 00000000..f1b82bf9
--- /dev/null
+++ b/src/daemon/https/tls/auth_dh_common.c
@@ -0,0 +1,369 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file contains common stuff in Ephemeral Diffie Hellman (DHE) and
26 * Anonymous DH key exchange(DHA). These are used in the handshake procedure
27 * of the certificate and anoymous authentication.
28 */
29
30#include "gnutls_int.h"
31#include "gnutls_auth_int.h"
32#include "gnutls_errors.h"
33#include "gnutls_dh.h"
34#include "gnutls_num.h"
35#include "gnutls_sig.h"
36#include <gnutls_datum.h>
37#include <gnutls_x509.h>
38#include <gnutls_state.h>
39#include <auth_dh_common.h>
40#include <gnutls_algorithms.h>
41
42/* Frees the dh_info_st structure.
43 */
44void
45_gnutls_free_dh_info (dh_info_st * dh)
46{
47 dh->secret_bits = 0;
48 _gnutls_free_datum (&dh->prime);
49 _gnutls_free_datum (&dh->generator);
50 _gnutls_free_datum (&dh->public_key);
51}
52
53int
54_gnutls_proc_dh_common_client_kx (gnutls_session_t session,
55 opaque * data, size_t _data_size,
56 mpi_t g, mpi_t p)
57{
58 uint16_t n_Y;
59 size_t _n_Y;
60 int ret;
61 ssize_t data_size = _data_size;
62
63
64 DECR_LEN (data_size, 2);
65 n_Y = _gnutls_read_uint16 (&data[0]);
66 _n_Y = n_Y;
67
68 DECR_LEN (data_size, n_Y);
69 if (_gnutls_mpi_scan_nz (&session->key->client_Y, &data[2], &_n_Y))
70 {
71 gnutls_assert ();
72 return GNUTLS_E_MPI_SCAN_FAILED;
73 }
74
75 _gnutls_dh_set_peer_public (session, session->key->client_Y);
76
77 session->key->KEY =
78 gnutls_calc_dh_key (session->key->client_Y, session->key->dh_secret, p);
79
80 if (session->key->KEY == NULL)
81 {
82 gnutls_assert ();
83 return GNUTLS_E_MEMORY_ERROR;
84 }
85
86 _gnutls_mpi_release (&session->key->client_Y);
87 _gnutls_mpi_release (&session->key->dh_secret);
88
89
90 if (_gnutls_cipher_suite_get_kx_algo
91 (&session->security_parameters.current_cipher_suite)
92 != GNUTLS_KX_DHE_PSK)
93 {
94 ret = _gnutls_mpi_dprint (&session->key->key, session->key->KEY);
95 }
96 /* In DHE_PSK the key is set differently
97 else
98 {
99 gnutls_datum_t tmp_dh_key;
100 ret = _gnutls_mpi_dprint (&tmp_dh_key, session->key->KEY);
101 if (ret < 0)
102 {
103 gnutls_assert ();
104 return ret;
105 }
106
107 ret = _gnutls_set_psk_session_key (session, &tmp_dh_key);
108 _gnutls_free_datum (&tmp_dh_key);
109
110 }
111 */
112
113 _gnutls_mpi_release (&session->key->KEY);
114
115 if (ret < 0)
116 {
117 return ret;
118 }
119
120 return 0;
121}
122
123int
124_gnutls_gen_dh_common_client_kx (gnutls_session_t session, opaque ** data)
125{
126 mpi_t x = NULL, X = NULL;
127 size_t n_X;
128 int ret;
129
130 *data = NULL;
131
132 X = gnutls_calc_dh_secret (&x, session->key->client_g,
133 session->key->client_p);
134 if (X == NULL || x == NULL)
135 {
136 gnutls_assert ();
137 ret = GNUTLS_E_MEMORY_ERROR;
138 goto error;
139 }
140
141 _gnutls_dh_set_secret_bits (session, _gnutls_mpi_get_nbits (x));
142
143 _gnutls_mpi_print (NULL, &n_X, X);
144 (*data) = gnutls_malloc (n_X + 2);
145 if (*data == NULL)
146 {
147 ret = GNUTLS_E_MEMORY_ERROR;
148 goto error;
149 }
150
151 _gnutls_mpi_print (&(*data)[2], &n_X, X);
152 _gnutls_mpi_release (&X);
153
154 _gnutls_write_uint16 (n_X, &(*data)[0]);
155
156 /* calculate the key after calculating the message */
157 session->key->KEY =
158 gnutls_calc_dh_key (session->key->client_Y, x, session->key->client_p);
159
160 _gnutls_mpi_release (&x);
161 if (session->key->KEY == NULL)
162 {
163 gnutls_assert ();
164 ret = GNUTLS_E_MEMORY_ERROR;
165 goto error;
166 }
167
168 /* THESE SHOULD BE DISCARDED */
169 _gnutls_mpi_release (&session->key->client_Y);
170 _gnutls_mpi_release (&session->key->client_p);
171 _gnutls_mpi_release (&session->key->client_g);
172
173 if (_gnutls_cipher_suite_get_kx_algo
174 (&session->security_parameters.current_cipher_suite)
175 != GNUTLS_KX_DHE_PSK)
176 {
177 ret = _gnutls_mpi_dprint (&session->key->key, session->key->KEY);
178 }
179 /* In DHE_PSK the key is set differently
180 else
181 {
182 gnutls_datum_t tmp_dh_key;
183 ret = _gnutls_mpi_dprint (&tmp_dh_key, session->key->KEY);
184 if (ret < 0)
185 {
186 gnutls_assert ();
187 goto error;
188 }
189
190 ret = _gnutls_set_psk_session_key (session, &tmp_dh_key);
191 _gnutls_free_datum (&tmp_dh_key);
192
193 }*/
194
195 _gnutls_mpi_release (&session->key->KEY);
196
197 if (ret < 0)
198 {
199 gnutls_assert ();
200 goto error;
201 }
202
203 return n_X + 2;
204
205error:
206 _gnutls_mpi_release (&x);
207 _gnutls_mpi_release (&X);
208 gnutls_free (*data);
209 *data = NULL;
210 return ret;
211}
212
213int
214_gnutls_proc_dh_common_server_kx (gnutls_session_t session,
215 opaque * data, size_t _data_size, int psk)
216{
217 uint16_t n_Y, n_g, n_p;
218 size_t _n_Y, _n_g, _n_p;
219 uint8_t *data_p;
220 uint8_t *data_g;
221 uint8_t *data_Y;
222 int i, bits, psk_size, ret;
223 ssize_t data_size = _data_size;
224
225 i = 0;
226
227 if (psk != 0)
228 {
229 DECR_LEN (data_size, 2);
230 psk_size = _gnutls_read_uint16 (&data[i]);
231 DECR_LEN (data_size, psk_size);
232 i += 2 + psk_size;
233 }
234
235 DECR_LEN (data_size, 2);
236 n_p = _gnutls_read_uint16 (&data[i]);
237 i += 2;
238
239 DECR_LEN (data_size, n_p);
240 data_p = &data[i];
241 i += n_p;
242
243 DECR_LEN (data_size, 2);
244 n_g = _gnutls_read_uint16 (&data[i]);
245 i += 2;
246
247 DECR_LEN (data_size, n_g);
248 data_g = &data[i];
249 i += n_g;
250
251 DECR_LEN (data_size, 2);
252 n_Y = _gnutls_read_uint16 (&data[i]);
253 i += 2;
254
255 DECR_LEN (data_size, n_Y);
256 data_Y = &data[i];
257 i += n_Y;
258
259 _n_Y = n_Y;
260 _n_g = n_g;
261 _n_p = n_p;
262
263 if (_gnutls_mpi_scan_nz (&session->key->client_Y, data_Y, &_n_Y) != 0)
264 {
265 gnutls_assert ();
266 return GNUTLS_E_MPI_SCAN_FAILED;
267 }
268
269 if (_gnutls_mpi_scan_nz (&session->key->client_g, data_g, &_n_g) != 0)
270 {
271 gnutls_assert ();
272 return GNUTLS_E_MPI_SCAN_FAILED;
273 }
274 if (_gnutls_mpi_scan_nz (&session->key->client_p, data_p, &_n_p) != 0)
275 {
276 gnutls_assert ();
277 return GNUTLS_E_MPI_SCAN_FAILED;
278 }
279
280 bits = _gnutls_dh_get_allowed_prime_bits (session);
281 if (bits < 0)
282 {
283 gnutls_assert ();
284 return bits;
285 }
286
287 if (_gnutls_mpi_get_nbits (session->key->client_p) < (size_t) bits)
288 {
289 /* the prime used by the peer is not acceptable
290 */
291 gnutls_assert ();
292 return GNUTLS_E_DH_PRIME_UNACCEPTABLE;
293 }
294
295 _gnutls_dh_set_group (session, session->key->client_g,
296 session->key->client_p);
297 _gnutls_dh_set_peer_public (session, session->key->client_Y);
298
299 ret = n_Y + n_p + n_g + 6;
300 if (psk != 0)
301 ret += 2;
302
303 return ret;
304}
305
306/* If the psk flag is set, then an empty psk_identity_hint will
307 * be inserted */
308int
309_gnutls_dh_common_print_server_kx (gnutls_session_t session,
310 mpi_t g, mpi_t p, opaque ** data, int psk)
311{
312 mpi_t x, X;
313 size_t n_X, n_g, n_p;
314 int ret, data_size, pos;
315 uint8_t *pdata;
316
317 X = gnutls_calc_dh_secret (&x, g, p);
318 if (X == NULL || x == NULL)
319 {
320 gnutls_assert ();
321 return GNUTLS_E_MEMORY_ERROR;
322 }
323
324 session->key->dh_secret = x;
325 _gnutls_dh_set_secret_bits (session, _gnutls_mpi_get_nbits (x));
326
327 _gnutls_mpi_print (NULL, &n_g, g);
328 _gnutls_mpi_print (NULL, &n_p, p);
329 _gnutls_mpi_print (NULL, &n_X, X);
330
331 data_size = n_g + n_p + n_X + 6;
332 if (psk != 0)
333 data_size += 2;
334
335 (*data) = gnutls_malloc (data_size);
336 if (*data == NULL)
337 {
338 _gnutls_mpi_release (&X);
339 return GNUTLS_E_MEMORY_ERROR;
340 }
341
342 pos = 0;
343 pdata = *data;
344
345 if (psk != 0)
346 {
347 _gnutls_write_uint16 (0, &pdata[pos]);
348 pos += 2;
349 }
350
351 _gnutls_mpi_print (&pdata[pos + 2], &n_p, p);
352 _gnutls_write_uint16 (n_p, &pdata[pos]);
353
354 pos += n_p + 2;
355
356 _gnutls_mpi_print (&pdata[pos + 2], &n_g, g);
357 _gnutls_write_uint16 (n_g, &pdata[pos]);
358
359 pos += n_g + 2;
360
361 _gnutls_mpi_print (&pdata[pos + 2], &n_X, X);
362 _gnutls_mpi_release (&X);
363
364 _gnutls_write_uint16 (n_X, &pdata[pos]);
365
366 ret = data_size;
367
368 return ret;
369}
diff --git a/src/daemon/https/tls/auth_dh_common.h b/src/daemon/https/tls/auth_dh_common.h
new file mode 100644
index 00000000..be0ad066
--- /dev/null
+++ b/src/daemon/https/tls/auth_dh_common.h
@@ -0,0 +1,48 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#ifndef AUTH_DH_COMMON
26# define AUTH_DH_COMMON
27
28typedef struct
29{
30 int secret_bits;
31
32 gnutls_datum_t prime;
33 gnutls_datum_t generator;
34 gnutls_datum_t public_key;
35} dh_info_st;
36
37void _gnutls_free_dh_info (dh_info_st * dh);
38int _gnutls_gen_dh_common_client_kx (gnutls_session_t, opaque **);
39int _gnutls_proc_dh_common_client_kx (gnutls_session_t session,
40 opaque * data, size_t _data_size,
41 mpi_t p, mpi_t g);
42int _gnutls_dh_common_print_server_kx (gnutls_session_t, mpi_t g, mpi_t p,
43 opaque ** data, int psk);
44int _gnutls_proc_dh_common_server_kx (gnutls_session_t session,
45 opaque * data, size_t _data_size,
46 int psk);
47
48#endif
diff --git a/src/daemon/https/tls/auth_dhe.c b/src/daemon/https/tls/auth_dhe.c
new file mode 100644
index 00000000..0262bda3
--- /dev/null
+++ b/src/daemon/https/tls/auth_dhe.c
@@ -0,0 +1,276 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file contains everything for the Ephemeral Diffie Hellman (DHE)
26 * key exchange. This is used in the handshake procedure of the certificate
27 * authentication.
28 */
29
30#include "gnutls_int.h"
31#include "gnutls_auth_int.h"
32#include "gnutls_errors.h"
33#include "gnutls_dh.h"
34#include "gnutls_num.h"
35#include "gnutls_sig.h"
36#include <gnutls_datum.h>
37#include <auth_cert.h>
38#include <gnutls_x509.h>
39#include <gnutls_state.h>
40#include <auth_dh_common.h>
41
42static int gen_dhe_server_kx (gnutls_session_t, opaque **);
43static int proc_dhe_server_kx (gnutls_session_t, opaque *, size_t);
44static int proc_dhe_client_kx (gnutls_session_t, opaque *, size_t);
45
46const mod_auth_st dhe_rsa_auth_struct = {
47 "DHE_RSA",
48 _gnutls_gen_cert_server_certificate,
49 _gnutls_gen_cert_client_certificate,
50 gen_dhe_server_kx,
51 _gnutls_gen_dh_common_client_kx,
52 _gnutls_gen_cert_client_cert_vrfy, /* gen client cert vrfy */
53 _gnutls_gen_cert_server_cert_req, /* server cert request */
54
55 _gnutls_proc_cert_server_certificate,
56 _gnutls_proc_cert_client_certificate,
57 proc_dhe_server_kx,
58 proc_dhe_client_kx,
59 _gnutls_proc_cert_client_cert_vrfy, /* proc client cert vrfy */
60 _gnutls_proc_cert_cert_req /* proc server cert request */
61};
62
63const mod_auth_st dhe_dss_auth_struct = {
64 "DHE_DSS",
65 _gnutls_gen_cert_server_certificate,
66 _gnutls_gen_cert_client_certificate,
67 gen_dhe_server_kx,
68 _gnutls_gen_dh_common_client_kx,
69 _gnutls_gen_cert_client_cert_vrfy, /* gen client cert vrfy */
70 _gnutls_gen_cert_server_cert_req, /* server cert request */
71
72 _gnutls_proc_cert_server_certificate,
73 _gnutls_proc_cert_client_certificate,
74 proc_dhe_server_kx,
75 proc_dhe_client_kx,
76 _gnutls_proc_cert_client_cert_vrfy, /* proc client cert vrfy */
77 _gnutls_proc_cert_cert_req /* proc server cert request */
78};
79
80
81static int
82gen_dhe_server_kx (gnutls_session_t session, opaque ** data)
83{
84 mpi_t g, p;
85 const mpi_t *mpis;
86 int ret = 0, data_size;
87 int bits;
88 gnutls_cert *apr_cert_list;
89 gnutls_privkey *apr_pkey;
90 int apr_cert_list_length;
91 gnutls_datum_t signature, ddata;
92 gnutls_certificate_credentials_t cred;
93 gnutls_dh_params_t dh_params;
94
95 cred = (gnutls_certificate_credentials_t)
96 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
97 if (cred == NULL)
98 {
99 gnutls_assert ();
100 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
101 }
102
103 bits = _gnutls_dh_get_allowed_prime_bits (session);
104
105 /* find the appropriate certificate */
106 if ((ret =
107 _gnutls_get_selected_cert (session, &apr_cert_list,
108 &apr_cert_list_length, &apr_pkey)) < 0)
109 {
110 gnutls_assert ();
111 return ret;
112 }
113
114 dh_params =
115 _gnutls_get_dh_params (cred->dh_params, cred->params_func, session);
116 mpis = _gnutls_dh_params_to_mpi (dh_params);
117 if (mpis == NULL)
118 {
119 gnutls_assert ();
120 return GNUTLS_E_NO_TEMPORARY_DH_PARAMS;
121 }
122
123 p = mpis[0];
124 g = mpis[1];
125
126 if ((ret = _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
127 sizeof (cert_auth_info_st), 0)) < 0)
128 {
129 gnutls_assert ();
130 return ret;
131 }
132
133 _gnutls_dh_set_group (session, g, p);
134
135 ret = _gnutls_dh_common_print_server_kx (session, g, p, data, 0);
136 if (ret < 0)
137 {
138 gnutls_assert ();
139 return ret;
140 }
141 data_size = ret;
142
143 /* Generate the signature. */
144
145 ddata.data = *data;
146 ddata.size = data_size;
147
148 if (apr_cert_list_length > 0)
149 {
150 if ((ret =
151 _gnutls_tls_sign_params (session, &apr_cert_list[0],
152 apr_pkey, &ddata, &signature)) < 0)
153 {
154 gnutls_assert ();
155 gnutls_free (*data);
156 return ret;
157 }
158 }
159 else
160 {
161 gnutls_assert ();
162 return data_size; /* do not put a signature - ILLEGAL! */
163 }
164
165 *data = gnutls_realloc_fast (*data, data_size + signature.size + 2);
166 if (*data == NULL)
167 {
168 _gnutls_free_datum (&signature);
169 gnutls_assert ();
170 return GNUTLS_E_MEMORY_ERROR;
171 }
172
173 _gnutls_write_datum16 (&(*data)[data_size], signature);
174 data_size += signature.size + 2;
175
176 _gnutls_free_datum (&signature);
177
178 return data_size;
179}
180
181static int
182proc_dhe_server_kx (gnutls_session_t session, opaque * data,
183 size_t _data_size)
184{
185 int sigsize;
186 gnutls_datum_t vparams, signature;
187 int ret;
188 cert_auth_info_t info = _gnutls_get_auth_info (session);
189 ssize_t data_size = _data_size;
190 gnutls_cert peer_cert;
191
192 if (info == NULL || info->ncerts == 0)
193 {
194 gnutls_assert ();
195 /* we need this in order to get peer's certificate */
196 return GNUTLS_E_INTERNAL_ERROR;
197 }
198
199 ret = _gnutls_proc_dh_common_server_kx (session, data, _data_size, 0);
200 if (ret < 0)
201 {
202 gnutls_assert ();
203 return ret;
204 }
205
206 /* VERIFY SIGNATURE */
207
208 vparams.size = ret;
209 vparams.data = data;
210
211 DECR_LEN (data_size, 2);
212 sigsize = _gnutls_read_uint16 (&data[vparams.size]);
213
214 DECR_LEN (data_size, sigsize);
215 signature.data = &data[vparams.size + 2];
216 signature.size = sigsize;
217
218 if ((ret =
219 _gnutls_raw_cert_to_gcert (&peer_cert,
220 session->security_parameters.cert_type,
221 &info->raw_certificate_list[0],
222 CERT_NO_COPY)) < 0)
223 {
224 gnutls_assert ();
225 return ret;
226 }
227
228 ret = _gnutls_verify_sig_params (session, &peer_cert, &vparams, &signature);
229
230 _gnutls_gcert_deinit (&peer_cert);
231 if (ret < 0)
232 {
233 gnutls_assert ();
234 return ret;
235 }
236
237 return ret;
238}
239
240
241
242static int
243proc_dhe_client_kx (gnutls_session_t session, opaque * data,
244 size_t _data_size)
245{
246 gnutls_certificate_credentials_t cred;
247 int ret;
248 mpi_t p, g;
249 const mpi_t *mpis;
250 gnutls_dh_params_t dh_params;
251
252 cred = (gnutls_certificate_credentials_t)
253 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
254 if (cred == NULL)
255 {
256 gnutls_assert ();
257 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
258 }
259
260 dh_params =
261 _gnutls_get_dh_params (cred->dh_params, cred->params_func, session);
262 mpis = _gnutls_dh_params_to_mpi (dh_params);
263 if (mpis == NULL)
264 {
265 gnutls_assert ();
266 return GNUTLS_E_NO_TEMPORARY_DH_PARAMS;
267 }
268
269 p = mpis[0];
270 g = mpis[1];
271
272 ret = _gnutls_proc_dh_common_client_kx (session, data, _data_size, g, p);
273
274 return ret;
275
276}
diff --git a/src/daemon/https/tls/auth_rsa.c b/src/daemon/https/tls/auth_rsa.c
new file mode 100644
index 00000000..4430009d
--- /dev/null
+++ b/src/daemon/https/tls/auth_rsa.c
@@ -0,0 +1,408 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file contains the RSA key exchange part of the certificate
26 * authentication.
27 */
28
29#include "gnutls_int.h"
30#include "gnutls_auth_int.h"
31#include "gnutls_errors.h"
32#include "gnutls_dh.h"
33#include "gnutls_num.h"
34#include "libtasn1.h"
35#include "gnutls_datum.h"
36#include "auth_cert.h"
37#include <gnutls_pk.h>
38#include <gnutls_algorithms.h>
39#include <gnutls_global.h>
40#include "debug.h"
41#include <gnutls_sig.h>
42#include <gnutls_x509.h>
43#include <gc.h>
44
45int _gnutls_gen_rsa_client_kx (gnutls_session_t, opaque **);
46int _gnutls_proc_rsa_client_kx (gnutls_session_t, opaque *, size_t);
47
48const mod_auth_st rsa_auth_struct = {
49 "RSA",
50 _gnutls_gen_cert_server_certificate,
51 _gnutls_gen_cert_client_certificate,
52 NULL, /* gen server kx */
53 _gnutls_gen_rsa_client_kx,
54 _gnutls_gen_cert_client_cert_vrfy, /* gen client cert vrfy */
55 _gnutls_gen_cert_server_cert_req, /* server cert request */
56
57 _gnutls_proc_cert_server_certificate,
58 _gnutls_proc_cert_client_certificate,
59 NULL, /* proc server kx */
60 _gnutls_proc_rsa_client_kx, /* proc client kx */
61 _gnutls_proc_cert_client_cert_vrfy, /* proc client cert vrfy */
62 _gnutls_proc_cert_cert_req /* proc server cert request */
63};
64
65/* This function reads the RSA parameters from peer's certificate;
66 */
67int
68_gnutls_get_public_rsa_params (gnutls_session_t session,
69 mpi_t params[MAX_PUBLIC_PARAMS_SIZE],
70 int *params_len)
71{
72 int ret;
73 cert_auth_info_t info;
74 gnutls_cert peer_cert;
75 int i;
76
77 /* normal non export case */
78
79 info = _gnutls_get_auth_info (session);
80
81 if (info == NULL || info->ncerts == 0)
82 {
83 gnutls_assert ();
84 return GNUTLS_E_INTERNAL_ERROR;
85 }
86
87 ret =
88 _gnutls_raw_cert_to_gcert (&peer_cert,
89 session->security_parameters.cert_type,
90 &info->raw_certificate_list[0],
91 CERT_ONLY_PUBKEY | CERT_NO_COPY);
92
93 if (ret < 0)
94 {
95 gnutls_assert ();
96 return ret;
97 }
98
99
100 /* EXPORT case: */
101 if (_gnutls_cipher_suite_get_kx_algo
102 (&session->security_parameters.current_cipher_suite)
103 == GNUTLS_KX_RSA_EXPORT
104 && _gnutls_mpi_get_nbits (peer_cert.params[0]) > 512)
105 {
106
107 _gnutls_gcert_deinit (&peer_cert);
108
109 if (session->key->rsa[0] == NULL || session->key->rsa[1] == NULL)
110 {
111 gnutls_assert ();
112 return GNUTLS_E_INTERNAL_ERROR;
113 }
114
115 if (*params_len < 2)
116 {
117 gnutls_assert ();
118 return GNUTLS_E_INTERNAL_ERROR;
119 }
120 *params_len = 2;
121 for (i = 0; i < *params_len; i++)
122 {
123 params[i] = _gnutls_mpi_copy (session->key->rsa[i]);
124 }
125
126 return 0;
127 }
128
129 /* end of export case */
130
131 if (*params_len < peer_cert.params_size)
132 {
133 gnutls_assert ();
134 return GNUTLS_E_INTERNAL_ERROR;
135 }
136 *params_len = peer_cert.params_size;
137
138 for (i = 0; i < *params_len; i++)
139 {
140 params[i] = _gnutls_mpi_copy (peer_cert.params[i]);
141 }
142 _gnutls_gcert_deinit (&peer_cert);
143
144 return 0;
145}
146
147/* This function reads the RSA parameters from the private key
148 */
149int
150_gnutls_get_private_rsa_params (gnutls_session_t session,
151 mpi_t ** params, int *params_size)
152{
153 int bits;
154 gnutls_certificate_credentials_t cred;
155 gnutls_rsa_params_t rsa_params;
156
157 cred = (gnutls_certificate_credentials_t)
158 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
159 if (cred == NULL)
160 {
161 gnutls_assert ();
162 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
163 }
164
165 if (session->internals.selected_cert_list == NULL)
166 {
167 gnutls_assert ();
168 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
169 }
170
171 bits =
172 _gnutls_mpi_get_nbits (session->internals.selected_cert_list[0].
173 params[0]);
174
175 if (_gnutls_cipher_suite_get_kx_algo
176 (&session->security_parameters.current_cipher_suite)
177 == GNUTLS_KX_RSA_EXPORT && bits > 512)
178 {
179
180 rsa_params =
181 _gnutls_certificate_get_rsa_params (cred->rsa_params,
182 cred->params_func, session);
183 /* EXPORT case: */
184 if (rsa_params == NULL)
185 {
186 gnutls_assert ();
187 return GNUTLS_E_NO_TEMPORARY_RSA_PARAMS;
188 }
189
190 /* In the export case, we do use temporary RSA params
191 * of 512 bits size. The params in the certificate are
192 * used to sign this temporary stuff.
193 */
194 *params_size = RSA_PRIVATE_PARAMS;
195 *params = rsa_params->params;
196
197 return 0;
198 }
199
200 /* non export cipher suites. */
201
202 *params_size = session->internals.selected_key->params_size;
203 *params = session->internals.selected_key->params;
204
205 return 0;
206}
207
208int
209_gnutls_proc_rsa_client_kx (gnutls_session_t session, opaque * data,
210 size_t _data_size)
211{
212 gnutls_datum_t plaintext;
213 gnutls_datum_t ciphertext;
214 int ret, dsize;
215 mpi_t *params;
216 int params_len;
217 int randomize_key = 0;
218 ssize_t data_size = _data_size;
219
220 if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
221 {
222 /* SSL 3.0
223 */
224 ciphertext.data = data;
225 ciphertext.size = data_size;
226 }
227 else
228 {
229 /* TLS 1.0
230 */
231 DECR_LEN (data_size, 2);
232 ciphertext.data = &data[2];
233 dsize = _gnutls_read_uint16 (data);
234
235 if (dsize != data_size)
236 {
237 gnutls_assert ();
238 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
239 }
240 ciphertext.size = dsize;
241 }
242
243 ret = _gnutls_get_private_rsa_params (session, &params, &params_len);
244 if (ret < 0)
245 {
246 gnutls_assert ();
247 return ret;
248 }
249
250 ret = _gnutls_pkcs1_rsa_decrypt (&plaintext, &ciphertext, params, params_len, 2); /* btype==2 */
251
252 if (ret < 0 || plaintext.size != TLS_MASTER_SIZE)
253 {
254 /* In case decryption fails then don't inform
255 * the peer. Just use a random key. (in order to avoid
256 * attack against pkcs-1 formating).
257 */
258 gnutls_assert ();
259 _gnutls_x509_log ("auth_rsa: Possible PKCS #1 format attack\n");
260 randomize_key = 1;
261 }
262 else
263 {
264 /* If the secret was properly formatted, then
265 * check the version number.
266 */
267 if (_gnutls_get_adv_version_major (session) != plaintext.data[0]
268 || _gnutls_get_adv_version_minor (session) != plaintext.data[1])
269 {
270 /* No error is returned here, if the version number check
271 * fails. We proceed normally.
272 * That is to defend against the attack described in the paper
273 * "Attacking RSA-based sessions in SSL/TLS" by Vlastimil Klima,
274 * Ondej Pokorny and Tomas Rosa.
275 */
276 gnutls_assert ();
277 _gnutls_x509_log
278 ("auth_rsa: Possible PKCS #1 version check format attack\n");
279 }
280 }
281
282 if (randomize_key != 0)
283 {
284 session->key->key.size = TLS_MASTER_SIZE;
285 session->key->key.data = gnutls_malloc (session->key->key.size);
286 if (session->key->key.data == NULL)
287 {
288 gnutls_assert ();
289 return GNUTLS_E_MEMORY_ERROR;
290 }
291
292 /* we do not need strong random numbers here.
293 */
294 if (gc_nonce (session->key->key.data, session->key->key.size) != GC_OK)
295 {
296 gnutls_assert ();
297 return GNUTLS_E_RANDOM_FAILED;
298 }
299
300 }
301 else
302 {
303 session->key->key.data = plaintext.data;
304 session->key->key.size = plaintext.size;
305 }
306
307 /* This is here to avoid the version check attack
308 * discussed above.
309 */
310 session->key->key.data[0] = _gnutls_get_adv_version_major (session);
311 session->key->key.data[1] = _gnutls_get_adv_version_minor (session);
312
313 return 0;
314}
315
316
317
318/* return RSA(random) using the peers public key
319 */
320int
321_gnutls_gen_rsa_client_kx (gnutls_session_t session, opaque ** data)
322{
323 cert_auth_info_t auth = session->key->auth_info;
324 gnutls_datum_t sdata; /* data to send */
325 mpi_t params[MAX_PUBLIC_PARAMS_SIZE];
326 int params_len = MAX_PUBLIC_PARAMS_SIZE;
327 int ret, i;
328 gnutls_protocol_t ver;
329
330 if (auth == NULL)
331 {
332 /* this shouldn't have happened. The proc_certificate
333 * function should have detected that.
334 */
335 gnutls_assert ();
336 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
337 }
338
339 session->key->key.size = TLS_MASTER_SIZE;
340 session->key->key.data = gnutls_secure_malloc (session->key->key.size);
341
342 if (session->key->key.data == NULL)
343 {
344 gnutls_assert ();
345 return GNUTLS_E_MEMORY_ERROR;
346 }
347
348 if (gc_pseudo_random (session->key->key.data,
349 session->key->key.size) != GC_OK)
350 {
351 gnutls_assert ();
352 return GNUTLS_E_RANDOM_FAILED;
353 }
354
355 ver = _gnutls_get_adv_version (session);
356
357 if (session->internals.rsa_pms_version[0] == 0)
358 {
359 session->key->key.data[0] = _gnutls_version_get_major (ver);
360 session->key->key.data[1] = _gnutls_version_get_minor (ver);
361 }
362 else
363 { /* use the version provided */
364 session->key->key.data[0] = session->internals.rsa_pms_version[0];
365 session->key->key.data[1] = session->internals.rsa_pms_version[1];
366 }
367
368 /* move RSA parameters to key (session).
369 */
370 if ((ret =
371 _gnutls_get_public_rsa_params (session, params, &params_len)) < 0)
372 {
373 gnutls_assert ();
374 return ret;
375 }
376
377 if ((ret =
378 _gnutls_pkcs1_rsa_encrypt (&sdata, &session->key->key,
379 params, params_len, 2)) < 0)
380 {
381 gnutls_assert ();
382 return ret;
383 }
384
385 for (i = 0; i < params_len; i++)
386 _gnutls_mpi_release (&params[i]);
387
388 if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
389 {
390 /* SSL 3.0 */
391 *data = sdata.data;
392 return sdata.size;
393 }
394 else
395 { /* TLS 1 */
396 *data = gnutls_malloc (sdata.size + 2);
397 if (*data == NULL)
398 {
399 _gnutls_free_datum (&sdata);
400 return GNUTLS_E_MEMORY_ERROR;
401 }
402 _gnutls_write_datum16 (*data, sdata);
403 ret = sdata.size + 2;
404 _gnutls_free_datum (&sdata);
405 return ret;
406 }
407
408}
diff --git a/src/daemon/https/tls/auth_rsa_export.c b/src/daemon/https/tls/auth_rsa_export.c
new file mode 100644
index 00000000..3c84121d
--- /dev/null
+++ b/src/daemon/https/tls/auth_rsa_export.c
@@ -0,0 +1,325 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file contains the RSA key exchange part of the certificate
26 * authentication.
27 */
28
29#include "gnutls_int.h"
30#include "gnutls_auth_int.h"
31#include "gnutls_errors.h"
32#include "gnutls_dh.h"
33#include "gnutls_num.h"
34#include "libtasn1.h"
35#include "gnutls_datum.h"
36#include "auth_cert.h"
37#include <gnutls_pk.h>
38#include <gnutls_algorithms.h>
39#include <gnutls_global.h>
40#include "debug.h"
41#include <gnutls_sig.h>
42#include <gnutls_x509.h>
43#include <gnutls_rsa_export.h>
44#include <gnutls_state.h>
45
46int _gnutls_gen_rsa_client_kx (gnutls_session_t, opaque **);
47int _gnutls_proc_rsa_client_kx (gnutls_session_t, opaque *, size_t);
48static int gen_rsa_export_server_kx (gnutls_session_t, opaque **);
49static int proc_rsa_export_server_kx (gnutls_session_t, opaque *, size_t);
50
51const mod_auth_st rsa_export_auth_struct = {
52 "RSA EXPORT",
53 _gnutls_gen_cert_server_certificate,
54 _gnutls_gen_cert_client_certificate,
55 gen_rsa_export_server_kx,
56 _gnutls_gen_rsa_client_kx,
57 _gnutls_gen_cert_client_cert_vrfy, /* gen client cert vrfy */
58 _gnutls_gen_cert_server_cert_req, /* server cert request */
59
60 _gnutls_proc_cert_server_certificate,
61 _gnutls_proc_cert_client_certificate,
62 proc_rsa_export_server_kx,
63 _gnutls_proc_rsa_client_kx, /* proc client kx */
64 _gnutls_proc_cert_client_cert_vrfy, /* proc client cert vrfy */
65 _gnutls_proc_cert_cert_req /* proc server cert request */
66};
67
68static int
69gen_rsa_export_server_kx (gnutls_session_t session, opaque ** data)
70{
71 gnutls_rsa_params_t rsa_params;
72 const mpi_t *rsa_mpis;
73 size_t n_e, n_m;
74 uint8_t *data_e, *data_m;
75 int ret = 0, data_size;
76 gnutls_cert *apr_cert_list;
77 gnutls_privkey *apr_pkey;
78 int apr_cert_list_length;
79 gnutls_datum_t signature, ddata;
80 cert_auth_info_t info;
81 gnutls_certificate_credentials_t cred;
82
83 cred = (gnutls_certificate_credentials_t)
84 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
85 if (cred == NULL)
86 {
87 gnutls_assert ();
88 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
89 }
90
91 /* find the appropriate certificate */
92 if ((ret =
93 _gnutls_get_selected_cert (session, &apr_cert_list,
94 &apr_cert_list_length, &apr_pkey)) < 0)
95 {
96 gnutls_assert ();
97 return ret;
98 }
99
100 /* abort sending this message if we have a certificate
101 * of 512 bits or less.
102 */
103 if (apr_pkey && _gnutls_mpi_get_nbits (apr_pkey->params[0]) <= 512)
104 {
105 gnutls_assert ();
106 return GNUTLS_E_INT_RET_0;
107 }
108
109 rsa_params =
110 _gnutls_certificate_get_rsa_params (cred->rsa_params, cred->params_func,
111 session);
112 rsa_mpis = _gnutls_rsa_params_to_mpi (rsa_params);
113 if (rsa_mpis == NULL)
114 {
115 gnutls_assert ();
116 return GNUTLS_E_NO_TEMPORARY_RSA_PARAMS;
117 }
118
119 if ((ret = _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
120 sizeof (cert_auth_info_st), 0)) < 0)
121 {
122 gnutls_assert ();
123 return ret;
124 }
125
126 info = _gnutls_get_auth_info (session);
127 _gnutls_rsa_export_set_pubkey (session, rsa_mpis[1], rsa_mpis[0]);
128
129 _gnutls_mpi_print (NULL, &n_m, rsa_mpis[0]);
130 _gnutls_mpi_print (NULL, &n_e, rsa_mpis[1]);
131
132 (*data) = gnutls_malloc (n_e + n_m + 4);
133 if (*data == NULL)
134 {
135 return GNUTLS_E_MEMORY_ERROR;
136 }
137
138 data_m = &(*data)[0];
139 _gnutls_mpi_print (&data_m[2], &n_m, rsa_mpis[0]);
140
141 _gnutls_write_uint16 (n_m, data_m);
142
143 data_e = &data_m[2 + n_m];
144 _gnutls_mpi_print (&data_e[2], &n_e, rsa_mpis[1]);
145
146 _gnutls_write_uint16 (n_e, data_e);
147
148 data_size = n_m + n_e + 4;
149
150
151 /* Generate the signature. */
152
153 ddata.data = *data;
154 ddata.size = data_size;
155
156 if (apr_cert_list_length > 0)
157 {
158 if ((ret =
159 _gnutls_tls_sign_params (session, &apr_cert_list[0],
160 apr_pkey, &ddata, &signature)) < 0)
161 {
162 gnutls_assert ();
163 gnutls_free (*data);
164 *data = NULL;
165 return ret;
166 }
167 }
168 else
169 {
170 gnutls_assert ();
171 return data_size; /* do not put a signature - ILLEGAL! */
172 }
173
174 *data = gnutls_realloc_fast (*data, data_size + signature.size + 2);
175 if (*data == NULL)
176 {
177 _gnutls_free_datum (&signature);
178 gnutls_assert ();
179 return GNUTLS_E_MEMORY_ERROR;
180 }
181
182 _gnutls_write_datum16 (&((*data)[data_size]), signature);
183 data_size += signature.size + 2;
184
185 _gnutls_free_datum (&signature);
186
187 return data_size;
188}
189
190/* if the peer's certificate is of 512 bits or less, returns non zero.
191 */
192int
193_gnutls_peers_cert_less_512 (gnutls_session_t session)
194{
195 gnutls_cert peer_cert;
196 int ret;
197 cert_auth_info_t info = _gnutls_get_auth_info (session);
198
199 if (info == NULL || info->ncerts == 0)
200 {
201 gnutls_assert ();
202 /* we need this in order to get peer's certificate */
203 return 0;
204 }
205
206 if ((ret =
207 _gnutls_raw_cert_to_gcert (&peer_cert,
208 session->security_parameters.cert_type,
209 &info->raw_certificate_list[0],
210 CERT_NO_COPY)) < 0)
211 {
212 gnutls_assert ();
213 return 0;
214 }
215
216 if (peer_cert.subject_pk_algorithm != GNUTLS_PK_RSA)
217 {
218 gnutls_assert ();
219 _gnutls_gcert_deinit (&peer_cert);
220 return 0;
221 }
222
223 if (_gnutls_mpi_get_nbits (peer_cert.params[0]) <= 512)
224 {
225 _gnutls_gcert_deinit (&peer_cert);
226 return 1;
227 }
228
229 _gnutls_gcert_deinit (&peer_cert);
230
231 return 0;
232}
233
234static int
235proc_rsa_export_server_kx (gnutls_session_t session,
236 opaque * data, size_t _data_size)
237{
238 uint16_t n_m, n_e;
239 size_t _n_m, _n_e;
240 uint8_t *data_m;
241 uint8_t *data_e;
242 int i, sigsize;
243 gnutls_datum_t vparams, signature;
244 int ret;
245 ssize_t data_size = _data_size;
246 cert_auth_info_t info;
247 gnutls_cert peer_cert;
248
249 info = _gnutls_get_auth_info (session);
250 if (info == NULL || info->ncerts == 0)
251 {
252 gnutls_assert ();
253 /* we need this in order to get peer's certificate */
254 return GNUTLS_E_INTERNAL_ERROR;
255 }
256
257
258 i = 0;
259
260 DECR_LEN (data_size, 2);
261 n_m = _gnutls_read_uint16 (&data[i]);
262 i += 2;
263
264 DECR_LEN (data_size, n_m);
265 data_m = &data[i];
266 i += n_m;
267
268 DECR_LEN (data_size, 2);
269 n_e = _gnutls_read_uint16 (&data[i]);
270 i += 2;
271
272 DECR_LEN (data_size, n_e);
273 data_e = &data[i];
274 i += n_e;
275
276 _n_e = n_e;
277 _n_m = n_m;
278
279 if (_gnutls_mpi_scan_nz (&session->key->rsa[0], data_m, &_n_m) != 0)
280 {
281 gnutls_assert ();
282 return GNUTLS_E_MPI_SCAN_FAILED;
283 }
284
285 if (_gnutls_mpi_scan_nz (&session->key->rsa[1], data_e, &_n_e) != 0)
286 {
287 gnutls_assert ();
288 return GNUTLS_E_MPI_SCAN_FAILED;
289 }
290
291 _gnutls_rsa_export_set_pubkey (session, session->key->rsa[1],
292 session->key->rsa[0]);
293
294 /* VERIFY SIGNATURE */
295
296 vparams.size = n_m + n_e + 4;
297 vparams.data = data;
298
299 DECR_LEN (data_size, 2);
300 sigsize = _gnutls_read_uint16 (&data[vparams.size]);
301
302 DECR_LEN (data_size, sigsize);
303 signature.data = &data[vparams.size + 2];
304 signature.size = sigsize;
305
306 if ((ret =
307 _gnutls_raw_cert_to_gcert (&peer_cert,
308 session->security_parameters.cert_type,
309 &info->raw_certificate_list[0],
310 CERT_NO_COPY)) < 0)
311 {
312 gnutls_assert ();
313 return ret;
314 }
315
316 ret = _gnutls_verify_sig_params (session, &peer_cert, &vparams, &signature);
317
318 _gnutls_gcert_deinit (&peer_cert);
319 if (ret < 0)
320 {
321 gnutls_assert ();
322 }
323
324 return ret;
325}
diff --git a/src/daemon/https/tls/debug.c b/src/daemon/https/tls/debug.c
new file mode 100644
index 00000000..2ea31577
--- /dev/null
+++ b/src/daemon/https/tls/debug.c
@@ -0,0 +1,128 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include "gnutls_int.h"
26#include "gnutls_errors.h"
27#include <stdio.h>
28#include <stdlib.h>
29#include <gcrypt.h>
30
31#ifdef DEBUG
32
33
34void
35_gnutls_print_state (gnutls_session_t session)
36{
37
38 _gnutls_debug_log ("GNUTLS State:\n");
39 _gnutls_debug_log ("Connection End: %d\n",
40 session->security_parameters.entity);
41 _gnutls_debug_log ("Cipher Algorithm: %d\n",
42 session->security_parameters.read_bulk_cipher_algorithm);
43 _gnutls_debug_log ("MAC algorithm: %d\n",
44 session->security_parameters.read_mac_algorithm);
45 _gnutls_debug_log ("Compression Algorithm: %d\n",
46 session->security_parameters.read_compression_algorithm);
47 _gnutls_debug_log ("\n");
48
49}
50
51#endif
52
53const char *
54_gnutls_packet2str (content_type_t packet)
55{
56 switch (packet)
57 {
58 case GNUTLS_CHANGE_CIPHER_SPEC:
59 return "Change Cipher Spec";
60 case GNUTLS_ALERT:
61 return "Alert";
62 case GNUTLS_HANDSHAKE:
63 return "Handshake";
64 case GNUTLS_APPLICATION_DATA:
65 return "Application Data";
66 case GNUTLS_INNER_APPLICATION:
67 return "Inner Application";
68
69 default:
70 return "Unknown Packet";
71 }
72}
73
74const char *
75_gnutls_handshake2str (gnutls_handshake_description_t handshake)
76{
77
78 switch (handshake)
79 {
80 case GNUTLS_HANDSHAKE_HELLO_REQUEST:
81 return "HELLO REQUEST";
82 break;
83 case GNUTLS_HANDSHAKE_CLIENT_HELLO:
84 return "CLIENT HELLO";
85 break;
86 case GNUTLS_HANDSHAKE_SERVER_HELLO:
87 return "SERVER HELLO";
88 break;
89 case GNUTLS_HANDSHAKE_CERTIFICATE_PKT:
90 return "CERTIFICATE";
91 break;
92 case GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE:
93 return "SERVER KEY EXCHANGE";
94 break;
95 case GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST:
96 return "CERTIFICATE REQUEST";
97 break;
98 case GNUTLS_HANDSHAKE_SERVER_HELLO_DONE:
99 return "SERVER HELLO DONE";
100 break;
101 case GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY:
102 return "CERTIFICATE VERIFY";
103 break;
104 case GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE:
105 return "CLIENT KEY EXCHANGE";
106 break;
107 case GNUTLS_HANDSHAKE_FINISHED:
108 return "FINISHED";
109 break;
110 case GNUTLS_HANDSHAKE_SUPPLEMENTAL:
111 return "SUPPLEMENTAL";
112 break;
113 default:
114 return "Unknown Handshake packet";
115
116 }
117}
118
119void
120_gnutls_dump_mpi (const char *prefix, mpi_t a)
121{
122 opaque buf[1024];
123 size_t n = sizeof buf;
124
125 if (gcry_mpi_print (GCRYMPI_FMT_HEX, buf, n, &n, a))
126 strcpy (buf, "[can't print value]"); /* Flawfinder: ignore */
127 _gnutls_hard_log ("MPI: length: %d\n\t%s%s\n", (n - 1) / 2, prefix, buf);
128}
diff --git a/src/daemon/https/tls/debug.h b/src/daemon/https/tls/debug.h
new file mode 100644
index 00000000..169bc21d
--- /dev/null
+++ b/src/daemon/https/tls/debug.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright (C) 2000, 2001, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#ifdef DEBUG
26void _gnutls_print_state (gnutls_session_t session);
27#endif
28const char *_gnutls_packet2str (content_type_t packet);
29const char *_gnutls_handshake2str (gnutls_handshake_description_t handshake);
30void _gnutls_dump_mpi (const char *prefix, mpi_t a);
diff --git a/src/daemon/https/tls/defines.h b/src/daemon/https/tls/defines.h
new file mode 100644
index 00000000..a53ce2e4
--- /dev/null
+++ b/src/daemon/https/tls/defines.h
@@ -0,0 +1,64 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#ifndef DEFINES_H
26# define DEFINES_H
27
28#if HAVE_CONFIG_H
29# include <config.h>
30#endif
31
32#include <stddef.h>
33#include <string.h>
34#include <stdlib.h>
35#include <stdio.h>
36#include <ctype.h>
37#include <limits.h>
38#include <stdint.h>
39
40#ifdef NO_SSIZE_T
41# define HAVE_SSIZE_T
42typedef int ssize_t;
43#endif
44
45#include <sys/types.h>
46#include <unistd.h>
47#include <sys/stat.h>
48#include <sys/socket.h>
49#include <time.h>
50
51// TODO check if these should go into config.h
52#define SIZEOF_UNSIGNED_INT 4
53#define SIZEOF_UNSIGNED_LONG 8
54#define SIZEOF_UNSIGNED_LONG_INT SIZEOF_UNSIGNED_LONG
55
56/* some systems had problems with long long int, thus,
57 * it is not used.
58 */
59typedef struct
60{
61 unsigned char i[8];
62} uint64;
63
64#endif /* defines_h */
diff --git a/src/daemon/https/tls/ext_cert_type.c b/src/daemon/https/tls/ext_cert_type.c
new file mode 100644
index 00000000..f970e1fe
--- /dev/null
+++ b/src/daemon/https/tls/ext_cert_type.c
@@ -0,0 +1,243 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file contains the code the Certificate Type TLS extension.
26 * This extension is currently gnutls specific.
27 */
28
29#include "gnutls_int.h"
30#include "gnutls_errors.h"
31#include "gnutls_num.h"
32#include "ext_cert_type.h"
33#include <gnutls_state.h>
34#include <gnutls_num.h>
35
36inline static int _gnutls_num2cert_type (int num);
37inline static int _gnutls_cert_type2num (int record_size);
38
39/*
40 * In case of a server: if a CERT_TYPE extension type is received then it stores
41 * into the session security parameters the new value. The server may use gnutls_session_certificate_type_get(),
42 * to access it.
43 *
44 * In case of a client: If a cert_types have been specified then we send the extension.
45 *
46 */
47
48int
49_gnutls_cert_type_recv_params (gnutls_session_t session,
50 const opaque * data, size_t _data_size)
51{
52 int new_type = -1, ret, i;
53 ssize_t data_size = _data_size;
54
55 if (session->security_parameters.entity == GNUTLS_CLIENT)
56 {
57 if (data_size > 0)
58 {
59 if (data_size != 1)
60 {
61 gnutls_assert ();
62 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
63 }
64
65 new_type = _gnutls_num2cert_type (data[0]);
66
67 if (new_type < 0)
68 {
69 gnutls_assert ();
70 return new_type;
71 }
72
73 /* Check if we support this cert_type */
74 if ((ret =
75 _gnutls_session_cert_type_supported (session, new_type)) < 0)
76 {
77 gnutls_assert ();
78 return ret;
79 }
80
81 _gnutls_session_cert_type_set (session, new_type);
82 }
83 }
84 else
85 { /* SERVER SIDE - we must check if the sent cert type is the right one
86 */
87 if (data_size > 1)
88 {
89 uint8_t len;
90
91 len = data[0];
92 DECR_LEN (data_size, len);
93
94 for (i = 0; i < len; i++)
95 {
96 new_type = _gnutls_num2cert_type (data[i + 1]);
97
98 if (new_type < 0)
99 continue;
100
101 /* Check if we support this cert_type */
102 if ((ret =
103 _gnutls_session_cert_type_supported (session,
104 new_type)) < 0)
105 {
106 gnutls_assert ();
107 continue;
108 }
109 else
110 break;
111 /* new_type is ok */
112 }
113
114 if (new_type < 0)
115 {
116 gnutls_assert ();
117 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
118 }
119
120 if ((ret =
121 _gnutls_session_cert_type_supported (session, new_type)) < 0)
122 {
123 gnutls_assert ();
124 /* The peer has requested unsupported certificate
125 * types. Instead of failing, procceed normally.
126 * (the ciphersuite selection would fail, or a
127 * non certificate ciphersuite will be selected).
128 */
129 return 0;
130 }
131
132 _gnutls_session_cert_type_set (session, new_type);
133 }
134
135
136 }
137
138 return 0;
139}
140
141/* returns data_size or a negative number on failure
142 */
143int
144_gnutls_cert_type_send_params (gnutls_session_t session, opaque * data,
145 size_t data_size)
146{
147 unsigned len, i;
148
149 /* this function sends the client extension data (dnsname) */
150 if (session->security_parameters.entity == GNUTLS_CLIENT)
151 {
152
153 if (session->internals.priorities.cert_type.algorithms > 0)
154 {
155
156 len = session->internals.priorities.cert_type.algorithms;
157
158 if (len == 1 &&
159 session->internals.priorities.cert_type.priority[0] ==
160 GNUTLS_CRT_X509)
161 {
162 /* We don't use this extension if X.509 certificates
163 * are used.
164 */
165 return 0;
166 }
167
168 if (data_size < len + 1)
169 {
170 gnutls_assert ();
171 return GNUTLS_E_SHORT_MEMORY_BUFFER;
172 }
173
174 /* this is a vector!
175 */
176 data[0] = (uint8_t) len;
177
178 for (i = 0; i < len; i++)
179 {
180 data[i + 1] = _gnutls_cert_type2num (session->internals.
181 priorities.cert_type.
182 priority[i]);
183 }
184 return len + 1;
185 }
186
187 }
188 else
189 { /* server side */
190 if (session->security_parameters.cert_type != DEFAULT_CERT_TYPE)
191 {
192 len = 1;
193 if (data_size < len)
194 {
195 gnutls_assert ();
196 return GNUTLS_E_SHORT_MEMORY_BUFFER;
197 }
198
199 data[0] =
200 _gnutls_cert_type2num (session->security_parameters.cert_type);
201 return len;
202 }
203
204
205 }
206
207 return 0;
208}
209
210/* Maps numbers to record sizes according to the
211 * extensions draft.
212 */
213inline static int
214_gnutls_num2cert_type (int num)
215{
216 switch (num)
217 {
218 case 0:
219 return GNUTLS_CRT_X509;
220 case 1:
221 return GNUTLS_CRT_OPENPGP;
222 default:
223 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
224 }
225}
226
227/* Maps record size to numbers according to the
228 * extensions draft.
229 */
230inline static int
231_gnutls_cert_type2num (int cert_type)
232{
233 switch (cert_type)
234 {
235 case GNUTLS_CRT_X509:
236 return 0;
237 case GNUTLS_CRT_OPENPGP:
238 return 1;
239 default:
240 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
241 }
242
243}
diff --git a/src/daemon/https/tls/ext_cert_type.h b/src/daemon/https/tls/ext_cert_type.h
new file mode 100644
index 00000000..ea7cf219
--- /dev/null
+++ b/src/daemon/https/tls/ext_cert_type.h
@@ -0,0 +1,31 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* Maps record size to numbers according to the
26 * extensions draft.
27 */
28int _gnutls_cert_type_recv_params (gnutls_session_t session,
29 const opaque * data, size_t data_size);
30int _gnutls_cert_type_send_params (gnutls_session_t session, opaque * data,
31 size_t);
diff --git a/src/daemon/https/tls/ext_inner_application.c b/src/daemon/https/tls/ext_inner_application.c
new file mode 100644
index 00000000..b86b7151
--- /dev/null
+++ b/src/daemon/https/tls/ext_inner_application.c
@@ -0,0 +1,147 @@
1/*
2 * Copyright (C) 2005, 2006 Free Software Foundation
3 *
4 * Author: Simon Josefsson
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA
22 *
23 */
24
25#include "gnutls_int.h"
26#include "gnutls_auth_int.h"
27#include "gnutls_errors.h"
28#include "gnutls_num.h"
29#include "ext_inner_application.h"
30
31#define NO 0
32#define YES 1
33
34int
35_gnutls_inner_application_recv_params (gnutls_session_t session,
36 const opaque * data, size_t data_size)
37{
38 tls_ext_st *ext = &session->security_parameters.extensions;
39
40 if (data_size != 1)
41 {
42 gnutls_assert ();
43 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
44 }
45
46 ext->gnutls_ia_peer_enable = 1;
47 ext->gnutls_ia_peer_allowskip = 0;
48
49 switch ((unsigned char) *data)
50 {
51 case NO: /* Peer's ia_on_resume == no */
52 ext->gnutls_ia_peer_allowskip = 1;
53 break;
54
55 case YES:
56 break;
57
58 default:
59 gnutls_assert ();
60 }
61
62 return 0;
63}
64
65
66/* returns data_size or a negative number on failure
67 */
68int
69_gnutls_inner_application_send_params (gnutls_session_t session,
70 opaque * data, size_t data_size)
71{
72 tls_ext_st *ext = &session->security_parameters.extensions;
73
74 /* Set ext->gnutls_ia_enable depending on whether we have a TLS/IA
75 credential in the session. */
76
77 if (session->security_parameters.entity == GNUTLS_CLIENT)
78 {
79 gnutls_ia_client_credentials_t cred = (gnutls_ia_client_credentials_t)
80 _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL);
81
82 if (cred)
83 ext->gnutls_ia_enable = 1;
84 }
85 else
86 {
87 gnutls_ia_server_credentials_t cred = (gnutls_ia_server_credentials_t)
88 _gnutls_get_cred (session->key, GNUTLS_CRD_IA, NULL);
89
90 if (cred)
91 ext->gnutls_ia_enable = 1;
92 }
93
94 /* If we don't want gnutls_ia locally, or we are a server and the
95 * client doesn't want it, don't advertise TLS/IA support at all, as
96 * required. */
97
98 if (!ext->gnutls_ia_enable)
99 return 0;
100
101 if (session->security_parameters.entity == GNUTLS_SERVER &&
102 !ext->gnutls_ia_peer_enable)
103 return 0;
104
105 /* We'll advertise. Check if there's room in the hello buffer. */
106
107 if (data_size < 1)
108 {
109 gnutls_assert ();
110 return GNUTLS_E_SHORT_MEMORY_BUFFER;
111 }
112
113 /* default: require new application phase */
114
115 *data = YES;
116
117 if (session->security_parameters.entity == GNUTLS_CLIENT)
118 {
119
120 /* Client: value follows local setting */
121
122 if (ext->gnutls_ia_allowskip)
123 *data = NO;
124 }
125 else
126 {
127
128 /* Server: value follows local setting and client's setting, but only
129 * if we are resuming.
130 *
131 * XXX Can server test for resumption at this stage?
132 *
133 * Ai! It seems that read_client_hello only calls parse_extensions if
134 * we're NOT resuming! That would make us automatically violate the IA
135 * draft; if we're resuming, we must first learn what the client wants
136 * -- IA or no IA -- and then prepare our response. Right now we'll
137 * always skip IA on resumption, because recv_ext isn't even called
138 * to record the peer's support for IA at all. Simon? */
139
140 if (ext->gnutls_ia_allowskip &&
141 ext->gnutls_ia_peer_allowskip &&
142 session->internals.resumed == RESUME_TRUE)
143 *data = NO;
144 }
145
146 return 1;
147}
diff --git a/src/daemon/https/tls/ext_inner_application.h b/src/daemon/https/tls/ext_inner_application.h
new file mode 100644
index 00000000..e75719e3
--- /dev/null
+++ b/src/daemon/https/tls/ext_inner_application.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (C) 2005 Free Software Foundation
3 *
4 * Author: Simon Josefsson
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25int _gnutls_inner_application_recv_params (gnutls_session_t session,
26 const opaque * data,
27 size_t data_size);
28int _gnutls_inner_application_send_params (gnutls_session_t session,
29 opaque * data, size_t);
diff --git a/src/daemon/https/tls/ext_max_record.c b/src/daemon/https/tls/ext_max_record.c
new file mode 100644
index 00000000..d0787483
--- /dev/null
+++ b/src/daemon/https/tls/ext_max_record.c
@@ -0,0 +1,196 @@
1/*
2 * Copyright (C) 2001, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file contains the code for the Max Record Size TLS extension.
26 */
27
28#include "gnutls_int.h"
29#include "gnutls_errors.h"
30#include "gnutls_num.h"
31#include <ext_max_record.h>
32
33/*
34 * In case of a server: if a MAX_RECORD_SIZE extension type is received then it stores
35 * into the session the new value. The server may use gnutls_get_max_record_size(),
36 * in order to access it.
37 *
38 * In case of a client: If a different max record size (than the default) has
39 * been specified then it sends the extension.
40 *
41 */
42
43int
44_gnutls_max_record_recv_params (gnutls_session_t session,
45 const opaque * data, size_t _data_size)
46{
47 ssize_t new_size;
48 ssize_t data_size = _data_size;
49
50 if (session->security_parameters.entity == GNUTLS_SERVER)
51 {
52 if (data_size > 0)
53 {
54 DECR_LEN (data_size, 1);
55
56 new_size = _gnutls_mre_num2record (data[0]);
57
58 if (new_size < 0)
59 {
60 gnutls_assert ();
61 return new_size;
62 }
63
64 session->security_parameters.max_record_send_size = new_size;
65 session->security_parameters.max_record_recv_size = new_size;
66 }
67 }
68 else
69 { /* CLIENT SIDE - we must check if the sent record size is the right one
70 */
71 if (data_size > 0)
72 {
73
74 if (data_size != 1)
75 {
76 gnutls_assert ();
77 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
78 }
79
80 new_size = _gnutls_mre_num2record (data[0]);
81
82 if (new_size < 0
83 || new_size != session->internals.proposed_record_size)
84 {
85 gnutls_assert ();
86 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
87 }
88 else
89 {
90 session->security_parameters.max_record_recv_size =
91 session->internals.proposed_record_size;
92 }
93
94 }
95
96
97 }
98
99 return 0;
100}
101
102/* returns data_size or a negative number on failure
103 */
104int
105_gnutls_max_record_send_params (gnutls_session_t session, opaque * data,
106 size_t data_size)
107{
108 uint16_t len;
109 /* this function sends the client extension data (dnsname) */
110 if (session->security_parameters.entity == GNUTLS_CLIENT)
111 {
112
113 if (session->internals.proposed_record_size != DEFAULT_MAX_RECORD_SIZE)
114 {
115 len = 1;
116 if (data_size < len)
117 {
118 gnutls_assert ();
119 return GNUTLS_E_SHORT_MEMORY_BUFFER;
120 }
121
122 data[0] =
123 (uint8_t) _gnutls_mre_record2num (session->internals.
124 proposed_record_size);
125 return len;
126 }
127
128 }
129 else
130 { /* server side */
131
132 if (session->security_parameters.max_record_recv_size !=
133 DEFAULT_MAX_RECORD_SIZE)
134 {
135 len = 1;
136 if (data_size < len)
137 {
138 gnutls_assert ();
139 return GNUTLS_E_SHORT_MEMORY_BUFFER;
140 }
141
142 data[0] =
143 (uint8_t) _gnutls_mre_record2num (session->
144 security_parameters.
145 max_record_recv_size);
146 return len;
147 }
148
149
150 }
151
152 return 0;
153}
154
155/* Maps numbers to record sizes according to the
156 * extensions draft.
157 */
158int
159_gnutls_mre_num2record (int num)
160{
161 switch (num)
162 {
163 case 1:
164 return 512;
165 case 2:
166 return 1024;
167 case 3:
168 return 2048;
169 case 4:
170 return 4096;
171 default:
172 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
173 }
174}
175
176/* Maps record size to numbers according to the
177 * extensions draft.
178 */
179int
180_gnutls_mre_record2num (uint16_t record_size)
181{
182 switch (record_size)
183 {
184 case 512:
185 return 1;
186 case 1024:
187 return 2;
188 case 2048:
189 return 3;
190 case 4096:
191 return 4;
192 default:
193 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
194 }
195
196}
diff --git a/src/daemon/https/tls/ext_max_record.h b/src/daemon/https/tls/ext_max_record.h
new file mode 100644
index 00000000..751bedc8
--- /dev/null
+++ b/src/daemon/https/tls/ext_max_record.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* Maps record size to numbers according to the
26 * extensions draft.
27 */
28int _gnutls_mre_num2record (int num);
29int _gnutls_mre_record2num (uint16_t record_size);
30int _gnutls_max_record_recv_params (gnutls_session_t session,
31 const opaque * data, size_t data_size);
32int _gnutls_max_record_send_params (gnutls_session_t session, opaque * data,
33 size_t);
diff --git a/src/daemon/https/tls/ext_oprfi.c b/src/daemon/https/tls/ext_oprfi.c
new file mode 100644
index 00000000..c862ad1c
--- /dev/null
+++ b/src/daemon/https/tls/ext_oprfi.c
@@ -0,0 +1,253 @@
1/*
2 * Copyright (C) 2007 Free Software Foundation
3 *
4 * Author: Simon Josefsson
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* Implementation of Opaque PRF Input:
26 * http://tools.ietf.org/id/draft-rescorla-tls-opaque-prf-input-00.txt
27 *
28 */
29
30#include <ext_oprfi.h>
31
32#include <gnutls_errors.h>
33#include <gnutls_num.h>
34
35int
36oprfi_recv_server (gnutls_session_t session,
37 const opaque * data, size_t _data_size)
38{
39 ssize_t data_size = _data_size;
40 uint16_t len;
41 int ret;
42
43 if (!session->security_parameters.extensions.oprfi_cb)
44 {
45 gnutls_assert ();
46 return 0;
47 }
48
49 DECR_LEN (data_size, 2);
50 len = _gnutls_read_uint16 (data);
51 data += 2;
52
53 if (len != data_size)
54 {
55 gnutls_assert ();
56 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
57 }
58
59 /* Store incoming data. */
60 session->security_parameters.extensions.oprfi_client_len = len;
61 session->security_parameters.extensions.oprfi_client = gnutls_malloc (len);
62 if (!session->security_parameters.extensions.oprfi_client)
63 {
64 gnutls_assert ();
65 return GNUTLS_E_MEMORY_ERROR;
66 }
67 memcpy (session->security_parameters.extensions.oprfi_client, data, len);
68
69 return 0;
70}
71
72int
73oprfi_recv_client (gnutls_session_t session,
74 const opaque * data, size_t _data_size)
75{
76 ssize_t data_size = _data_size;
77 uint16_t len;
78 int ret;
79
80 if (session->security_parameters.extensions.oprfi_client == NULL)
81 {
82 gnutls_assert ();
83 return 0;
84 }
85
86 DECR_LEN (data_size, 2);
87 len = _gnutls_read_uint16 (data);
88 data += 2;
89
90 if (len != data_size)
91 {
92 gnutls_assert ();
93 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
94 }
95
96 if (len != session->security_parameters.extensions.oprfi_client_len)
97 {
98 gnutls_assert ();
99 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
100 }
101
102 /* Store incoming data. */
103 session->security_parameters.extensions.oprfi_server_len = len;
104 session->security_parameters.extensions.oprfi_server = gnutls_malloc (len);
105 if (!session->security_parameters.extensions.oprfi_server)
106 {
107 gnutls_assert ();
108 return GNUTLS_E_MEMORY_ERROR;
109 }
110 memcpy (session->security_parameters.extensions.oprfi_server, data, len);
111
112 return 0;
113}
114
115int
116_gnutls_oprfi_recv_params (gnutls_session_t session,
117 const opaque * data, size_t data_size)
118{
119 if (session->security_parameters.entity == GNUTLS_CLIENT)
120 return oprfi_recv_client (session, data, data_size);
121 else
122 return oprfi_recv_server (session, data, data_size);
123}
124
125int
126oprfi_send_client (gnutls_session_t session, opaque * data, size_t _data_size)
127{
128 opaque *p = data;
129 ssize_t data_size = _data_size;
130 int oprf_size = session->security_parameters.extensions.oprfi_client_len;
131
132 if (oprf_size == 0)
133 return 0;
134
135 DECR_LENGTH_RET (data_size, 2, GNUTLS_E_SHORT_MEMORY_BUFFER);
136 _gnutls_write_uint16 (oprf_size, p);
137 p += 2;
138
139 DECR_LENGTH_RET (data_size, oprf_size, GNUTLS_E_SHORT_MEMORY_BUFFER);
140
141 memcpy (p, session->security_parameters.extensions.oprfi_client, oprf_size);
142
143 return 2 + oprf_size;
144}
145
146int
147oprfi_send_server (gnutls_session_t session, opaque * data, size_t _data_size)
148{
149 opaque *p = data;
150 int ret;
151 ssize_t data_size = _data_size;
152 size_t len;
153
154 if (!session->security_parameters.extensions.oprfi_client ||
155 !session->security_parameters.extensions.oprfi_cb)
156 return 0;
157
158 /* Allocate buffer for outgoing data. */
159 session->security_parameters.extensions.oprfi_server_len =
160 session->security_parameters.extensions.oprfi_client_len;
161 session->security_parameters.extensions.oprfi_server =
162 gnutls_malloc (session->security_parameters.extensions.oprfi_server_len);
163 if (!session->security_parameters.extensions.oprfi_server)
164 {
165 gnutls_assert ();
166 return GNUTLS_E_MEMORY_ERROR;
167 }
168
169 /* Get outgoing data. */
170 ret = session->security_parameters.extensions.oprfi_cb
171 (session, session->security_parameters.extensions.oprfi_userdata,
172 session->security_parameters.extensions.oprfi_client_len,
173 session->security_parameters.extensions.oprfi_client,
174 session->security_parameters.extensions.oprfi_server);
175 if (ret < 0)
176 {
177 gnutls_assert ();
178 gnutls_free (session->security_parameters.extensions.oprfi_server);
179 return ret;
180 }
181
182 DECR_LENGTH_RET (data_size, 2, GNUTLS_E_SHORT_MEMORY_BUFFER);
183 _gnutls_write_uint16 (session->security_parameters.
184 extensions.oprfi_server_len, p);
185 p += 2;
186
187 DECR_LENGTH_RET (data_size, session->security_parameters.
188 extensions.oprfi_server_len, GNUTLS_E_SHORT_MEMORY_BUFFER);
189
190 memcpy (p, session->security_parameters.extensions.oprfi_server,
191 session->security_parameters.extensions.oprfi_server_len);
192
193 return 2 + session->security_parameters.extensions.oprfi_server_len;
194}
195
196int
197_gnutls_oprfi_send_params (gnutls_session_t session,
198 opaque * data, size_t data_size)
199{
200 if (session->security_parameters.entity == GNUTLS_CLIENT)
201 return oprfi_send_client (session, data, data_size);
202 else
203 return oprfi_send_server (session, data, data_size);
204}
205
206/**
207 * gnutls_oprfi_enable_client:
208 * @session: is a #gnutls_session_t structure.
209 * @len: length of Opaque PRF data to use in client.
210 * @data: Opaque PRF data to use in client.
211 *
212 * Request that the client should attempt to negotiate the Opaque PRF
213 * Input TLS extension, using the given data as the client's Opaque
214 * PRF input.
215 *
216 * The data is copied into the session context after this call, so you
217 * may de-allocate it immediately after calling this function.
218 **/
219void
220gnutls_oprfi_enable_client (gnutls_session_t session,
221 size_t len, unsigned char *data)
222{
223 session->security_parameters.extensions.oprfi_client_len = len;
224 session->security_parameters.extensions.oprfi_client = data;
225}
226
227/**
228 * gnutls_oprfi_enable_server:
229 * @session: is a #gnutls_session_t structure.
230 * @cb: function pointer to Opaque PRF extension server callback.
231 * @userdata: hook passed to callback function for passing application state.
232 *
233 * Request that the server should attempt to accept the Opaque PRF
234 * Input TLS extension. If the client requests the extension, the
235 * provided callback @cb will be invoked. The callback must have the
236 * following prototype:
237 *
238 * int callback (gnutls_session_t session, void *userdata,
239 * size_t oprfi_len, const unsigned char *in_oprfi,
240 * unsigned char *out_oprfi);
241 *
242 * The callback can inspect the client-provided data in the input
243 * parameters, and specify its own opaque prf input data in the output
244 * variable. The function must return 0 on success, otherwise the
245 * handshake will be aborted.
246 **/
247void
248gnutls_oprfi_enable_server (gnutls_session_t session,
249 gnutls_oprfi_callback_func cb, void *userdata)
250{
251 session->security_parameters.extensions.oprfi_cb = cb;
252 session->security_parameters.extensions.oprfi_userdata = userdata;
253}
diff --git a/src/daemon/https/tls/ext_oprfi.h b/src/daemon/https/tls/ext_oprfi.h
new file mode 100644
index 00000000..7f75be9c
--- /dev/null
+++ b/src/daemon/https/tls/ext_oprfi.h
@@ -0,0 +1,33 @@
1/*
2 * Copyright (C) 2007 Free Software Foundation
3 *
4 * Author: Simon Josefsson
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26
27int _gnutls_oprfi_recv_params (gnutls_session_t state,
28 const opaque * data,
29 size_t data_size);
30
31int _gnutls_oprfi_send_params (gnutls_session_t state,
32 opaque * data,
33 size_t data_size);
diff --git a/src/daemon/https/tls/ext_server_name.c b/src/daemon/https/tls/ext_server_name.c
new file mode 100644
index 00000000..bc6b4759
--- /dev/null
+++ b/src/daemon/https/tls/ext_server_name.c
@@ -0,0 +1,330 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include "gnutls_int.h"
26#include "gnutls_auth_int.h"
27#include "gnutls_errors.h"
28#include "gnutls_num.h"
29#include <ext_server_name.h>
30
31/*
32 * In case of a server: if a NAME_DNS extension type is received then it stores
33 * into the session the value of NAME_DNS. The server may use gnutls_ext_get_server_name(),
34 * in order to access it.
35 *
36 * In case of a client: If a proper NAME_DNS extension type is found in the session then
37 * it sends the extension to the peer.
38 *
39 */
40
41int
42_gnutls_server_name_recv_params (gnutls_session_t session,
43 const opaque * data, size_t _data_size)
44{
45 int i;
46 const unsigned char *p;
47 uint16_t len, type;
48 ssize_t data_size = _data_size;
49 int server_names = 0;
50
51 if (session->security_parameters.entity == GNUTLS_SERVER)
52 {
53 DECR_LENGTH_RET (data_size, 2, 0);
54 len = _gnutls_read_uint16 (data);
55
56 if (len != data_size)
57 {
58 /* This is unexpected packet length, but
59 * just ignore it, for now.
60 */
61 gnutls_assert ();
62 return 0;
63 }
64
65 p = data + 2;
66
67 /* Count all server_names in the packet. */
68 while (data_size > 0)
69 {
70 DECR_LENGTH_RET (data_size, 1, 0);
71 p++;
72
73 DECR_LEN (data_size, 2);
74 len = _gnutls_read_uint16 (p);
75 p += 2;
76
77 DECR_LENGTH_RET (data_size, len, 0);
78 server_names++;
79
80 p += len;
81 }
82
83 session->security_parameters.extensions.server_names_size =
84 server_names;
85 if (server_names == 0)
86 return 0; /* no names found */
87
88 /* we cannot accept more server names.
89 */
90 if (server_names > MAX_SERVER_NAME_EXTENSIONS)
91 server_names = MAX_SERVER_NAME_EXTENSIONS;
92
93 p = data + 2;
94 for (i = 0; i < server_names; i++)
95 {
96 type = *p;
97 p++;
98
99 len = _gnutls_read_uint16 (p);
100 p += 2;
101
102 switch (type)
103 {
104 case 0: /* NAME_DNS */
105 if (len <= MAX_SERVER_NAME_SIZE)
106 {
107 memcpy (session->security_parameters.extensions.
108 server_names[i].name, p, len);
109 session->security_parameters.extensions.
110 server_names[i].name_length = len;
111 session->security_parameters.extensions.
112 server_names[i].type = GNUTLS_NAME_DNS;
113 break;
114 }
115 }
116
117 /* move to next record */
118 p += len;
119 }
120 }
121 return 0;
122}
123
124/* returns data_size or a negative number on failure
125 */
126int
127_gnutls_server_name_send_params (gnutls_session_t session,
128 opaque * data, size_t _data_size)
129{
130 uint16_t len;
131 opaque *p;
132 unsigned i;
133 ssize_t data_size = _data_size;
134 int total_size = 0;
135
136 /* this function sends the client extension data (dnsname)
137 */
138 if (session->security_parameters.entity == GNUTLS_CLIENT)
139 {
140
141 if (session->security_parameters.extensions.server_names_size == 0)
142 return 0;
143
144 /* uint16_t
145 */
146 total_size = 2;
147 for (i = 0;
148 i < session->security_parameters.extensions.server_names_size; i++)
149 {
150 /* count the total size
151 */
152 len =
153 session->security_parameters.extensions.server_names[i].
154 name_length;
155
156 /* uint8_t + uint16_t + size
157 */
158 total_size += 1 + 2 + len;
159 }
160
161 p = data;
162
163 /* UINT16: write total size of all names
164 */
165 DECR_LENGTH_RET (data_size, 2, GNUTLS_E_SHORT_MEMORY_BUFFER);
166 _gnutls_write_uint16 (total_size - 2, p);
167 p += 2;
168
169 for (i = 0;
170 i < session->security_parameters.extensions.server_names_size; i++)
171 {
172
173 switch (session->security_parameters.extensions.
174 server_names[i].type)
175 {
176 case GNUTLS_NAME_DNS:
177
178 len =
179 session->security_parameters.extensions.
180 server_names[i].name_length;
181 if (len == 0)
182 break;
183
184 /* UINT8: type of this extension
185 * UINT16: size of the first name
186 * LEN: the actual server name.
187 */
188 DECR_LENGTH_RET (data_size, len + 3,
189 GNUTLS_E_SHORT_MEMORY_BUFFER);
190
191 *p = 0; /* NAME_DNS type */
192 p++;
193
194 _gnutls_write_uint16 (len, p);
195 p += 2;
196
197 memcpy (p,
198 session->security_parameters.extensions.
199 server_names[0].name, len);
200 p += len;
201 break;
202 default:
203 gnutls_assert ();
204 return GNUTLS_E_INTERNAL_ERROR;
205 }
206 }
207 }
208
209 return total_size;
210}
211
212/**
213 * gnutls_server_name_get - Used to get the server name indicator send by a client
214 * @session: is a #gnutls_session_t structure.
215 * @data: will hold the data
216 * @data_length: will hold the data length. Must hold the maximum size of data.
217 * @type: will hold the server name indicator type
218 * @indx: is the index of the server_name
219 *
220 * This function will allow you to get the name indication (if any),
221 * a client has sent. The name indication may be any of the enumeration
222 * gnutls_server_name_type_t.
223 *
224 * If @type is GNUTLS_NAME_DNS, then this function is to be used by servers
225 * that support virtual hosting, and the data will be a null terminated UTF-8 string.
226 *
227 * If @data has not enough size to hold the server name GNUTLS_E_SHORT_MEMORY_BUFFER
228 * is returned, and @data_length will hold the required size.
229 *
230 * @index is used to retrieve more than one server names (if sent by the client).
231 * The first server name has an index of 0, the second 1 and so on. If no name with the given
232 * index exists GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
233 *
234 **/
235int
236gnutls_server_name_get (gnutls_session_t session, void *data,
237 size_t * data_length,
238 unsigned int *type, unsigned int indx)
239{
240 char *_data = data;
241
242 if (session->security_parameters.entity == GNUTLS_CLIENT)
243 {
244 gnutls_assert ();
245 return GNUTLS_E_INVALID_REQUEST;
246 }
247
248 if (indx + 1 > session->security_parameters.extensions.server_names_size)
249 {
250 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
251 }
252
253 *type = session->security_parameters.extensions.server_names[indx].type;
254
255 if (*data_length > /* greater since we need one extra byte for the null */
256 session->security_parameters.extensions.server_names[indx].name_length)
257 {
258 *data_length =
259 session->security_parameters.extensions.server_names[indx].
260 name_length;
261 memcpy (data,
262 session->security_parameters.extensions.server_names[indx].
263 name, *data_length);
264
265 if (*type == GNUTLS_NAME_DNS) /* null terminate */
266 _data[(*data_length)] = 0;
267
268 }
269 else
270 {
271 *data_length =
272 session->security_parameters.extensions.server_names[indx].
273 name_length;
274 return GNUTLS_E_SHORT_MEMORY_BUFFER;
275 }
276
277 return 0;
278}
279
280/**
281 * gnutls_server_name_set - Used to set a name indicator to be sent as an extension
282 * @session: is a #gnutls_session_t structure.
283 * @type: specifies the indicator type
284 * @name: is a string that contains the server name.
285 * @name_length: holds the length of name
286 *
287 * This function is to be used by clients that want to inform
288 * (via a TLS extension mechanism) the server of the name they
289 * connected to. This should be used by clients that connect
290 * to servers that do virtual hosting.
291 *
292 * The value of @name depends on the @ind type. In case of GNUTLS_NAME_DNS,
293 * an ASCII or UTF-8 null terminated string, without the trailing dot, is expected.
294 * IPv4 or IPv6 addresses are not permitted.
295 *
296 **/
297int
298gnutls_server_name_set (gnutls_session_t session,
299 gnutls_server_name_type_t type,
300 const void *name, size_t name_length)
301{
302 int server_names;
303
304 if (session->security_parameters.entity == GNUTLS_SERVER)
305 {
306 gnutls_assert ();
307 return GNUTLS_E_INVALID_REQUEST;
308 }
309
310 if (name_length > MAX_SERVER_NAME_SIZE)
311 return GNUTLS_E_SHORT_MEMORY_BUFFER;
312
313 server_names =
314 session->security_parameters.extensions.server_names_size + 1;
315
316 if (server_names > MAX_SERVER_NAME_EXTENSIONS)
317 server_names = MAX_SERVER_NAME_EXTENSIONS;
318
319 session->security_parameters.extensions.server_names[server_names -
320 1].type = type;
321 memcpy (session->security_parameters.extensions.
322 server_names[server_names - 1].name, name, name_length);
323 session->security_parameters.extensions.server_names[server_names -
324 1].name_length =
325 name_length;
326
327 session->security_parameters.extensions.server_names_size++;
328
329 return 0;
330}
diff --git a/src/daemon/https/tls/ext_server_name.h b/src/daemon/https/tls/ext_server_name.h
new file mode 100644
index 00000000..91e727a1
--- /dev/null
+++ b/src/daemon/https/tls/ext_server_name.h
@@ -0,0 +1,28 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25int _gnutls_server_name_recv_params (gnutls_session_t session,
26 const opaque * data, size_t data_size);
27int _gnutls_server_name_send_params (gnutls_session_t session,
28 opaque * data, size_t);
diff --git a/src/daemon/https/tls/gnutls.asn b/src/daemon/https/tls/gnutls.asn
new file mode 100644
index 00000000..0cb98414
--- /dev/null
+++ b/src/daemon/https/tls/gnutls.asn
@@ -0,0 +1,93 @@
1GNUTLS { }
2
3DEFINITIONS EXPLICIT TAGS ::=
4
5BEGIN
6
7-- This file contains parts of PKCS-1 structures and some stuff
8-- required for DSA keys.
9
10RSAPublicKey ::= SEQUENCE {
11 modulus INTEGER, -- n
12 publicExponent INTEGER -- e
13}
14
15--
16-- Representation of RSA private key with information for the
17-- CRT algorithm.
18--
19RSAPrivateKey ::= SEQUENCE {
20 version Version,
21 modulus INTEGER, -- (Usually large) n
22 publicExponent INTEGER, -- (Usually small) e
23 privateExponent INTEGER, -- (Usually large) d
24 prime1 INTEGER, -- (Usually large) p
25 prime2 INTEGER, -- (Usually large) q
26 exponent1 INTEGER, -- (Usually large) d mod (p-1)
27 exponent2 INTEGER, -- (Usually large) d mod (q-1)
28 coefficient INTEGER, -- (Usually large) (inverse of q) mod p
29 otherPrimeInfos OtherPrimeInfos OPTIONAL
30}
31
32Version ::= INTEGER { two-prime(0), multi(1) }
33-- (CONSTRAINED BY { version must be multi if otherPrimeInfos present }) --
34
35OtherPrimeInfos ::= SEQUENCE SIZE(1..MAX) OF OtherPrimeInfo
36
37OtherPrimeInfo ::= SEQUENCE {
38 prime INTEGER, -- ri
39 exponent INTEGER, -- di
40 coefficient INTEGER -- ti
41}
42
43-- for signature calculation
44-- added by nmav
45
46AlgorithmIdentifier ::= SEQUENCE {
47 algorithm OBJECT IDENTIFIER,
48 parameters ANY DEFINED BY algorithm OPTIONAL
49}
50 -- contains a value of the type
51 -- registered for use with the
52 -- algorithm object identifier value
53
54DigestInfo ::= SEQUENCE {
55 digestAlgorithm DigestAlgorithmIdentifier,
56 digest Digest
57}
58
59DigestAlgorithmIdentifier ::= AlgorithmIdentifier
60
61Digest ::= OCTET STRING
62
63DSAPublicKey ::= INTEGER
64
65DSAParameters ::= SEQUENCE {
66 p INTEGER,
67 q INTEGER,
68 g INTEGER
69}
70
71DSASignatureValue ::= SEQUENCE {
72 r INTEGER,
73 s INTEGER
74}
75
76DSAPrivateKey ::= SEQUENCE {
77 version INTEGER, -- should be zero
78 p INTEGER,
79 q INTEGER,
80 g INTEGER,
81 Y INTEGER, -- public
82 priv INTEGER
83}
84
85-- from PKCS#3
86DHParameter ::= SEQUENCE {
87 prime INTEGER, -- p
88 base INTEGER, -- g
89 privateValueLength INTEGER OPTIONAL
90}
91
92
93END
diff --git a/src/daemon/https/tls/gnutls.pc b/src/daemon/https/tls/gnutls.pc
new file mode 100644
index 00000000..544428cb
--- /dev/null
+++ b/src/daemon/https/tls/gnutls.pc
@@ -0,0 +1,23 @@
1# Process this file with autoconf to produce a pkg-config metadata file.
2# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3# Author: Simon Josefsson
4#
5# This file is free software; as a special exception the author gives
6# unlimited permission to copy and/or distribute it, with or without
7# modifications, as long as this notice is preserved.
8#
9# This file is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
11# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13prefix=/home/lama/workbench/programming/c/gnunet/gnutls-2.2.3/build
14exec_prefix=${prefix}
15libdir=${exec_prefix}/lib
16includedir=${prefix}/include
17
18Name: GnuTLS
19Description: Transport Security Layer implementation for the GNU system
20Version: 2.2.3
21Libs: -L${libdir} -lgnutls
22Libs.private: -L${exec_prefix}/lib -lgnutls -L/usr/lib -ltasn1 -lgcrypt
23Cflags: -I${includedir}
diff --git a/src/daemon/https/tls/gnutls_alert.c b/src/daemon/https/tls/gnutls_alert.c
new file mode 100644
index 00000000..75f9dcd2
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_alert.c
@@ -0,0 +1,304 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_errors.h>
27#include <gnutls_record.h>
28#include <debug.h>
29
30typedef struct
31{
32 gnutls_alert_description_t alert;
33 const char *desc;
34} gnutls_alert_entry;
35
36static const gnutls_alert_entry sup_alerts[] = {
37 {GNUTLS_A_CLOSE_NOTIFY, "Close notify"},
38 {GNUTLS_A_UNEXPECTED_MESSAGE, "Unexpected message"},
39 {GNUTLS_A_BAD_RECORD_MAC, "Bad record MAC"},
40 {GNUTLS_A_DECRYPTION_FAILED, "Decryption failed"},
41 {GNUTLS_A_RECORD_OVERFLOW, "Record overflow"},
42 {GNUTLS_A_DECOMPRESSION_FAILURE, "Decompression failed"},
43 {GNUTLS_A_HANDSHAKE_FAILURE, "Handshake failed"},
44 {GNUTLS_A_BAD_CERTIFICATE, "Certificate is bad"},
45 {GNUTLS_A_UNSUPPORTED_CERTIFICATE, "Certificate is not supported"},
46 {GNUTLS_A_CERTIFICATE_REVOKED, "Certificate was revoked"},
47 {GNUTLS_A_CERTIFICATE_EXPIRED, "Certificate is expired"},
48 {GNUTLS_A_CERTIFICATE_UNKNOWN, "Unknown certificate"},
49 {GNUTLS_A_ILLEGAL_PARAMETER, "Illegal parameter"},
50 {GNUTLS_A_UNKNOWN_CA, "CA is unknown"},
51 {GNUTLS_A_ACCESS_DENIED, "Access was denied"},
52 {GNUTLS_A_DECODE_ERROR, "Decode error"},
53 {GNUTLS_A_DECRYPT_ERROR, "Decrypt error"},
54 {GNUTLS_A_EXPORT_RESTRICTION, "Export restriction"},
55 {GNUTLS_A_PROTOCOL_VERSION, "Error in protocol version"},
56 {GNUTLS_A_INSUFFICIENT_SECURITY, "Insufficient security"},
57 {GNUTLS_A_USER_CANCELED, "User canceled"},
58 {GNUTLS_A_INTERNAL_ERROR, "Internal error"},
59 {GNUTLS_A_NO_RENEGOTIATION, "No renegotiation is allowed"},
60 {GNUTLS_A_CERTIFICATE_UNOBTAINABLE,
61 "Could not retrieve the specified certificate"},
62 {GNUTLS_A_UNSUPPORTED_EXTENSION, "An unsupported extension was sent"},
63 {GNUTLS_A_UNRECOGNIZED_NAME,
64 "The server name sent was not recognized"},
65 {GNUTLS_A_UNKNOWN_PSK_IDENTITY,
66 "The SRP/PSK username is missing or not known"},
67 {GNUTLS_A_INNER_APPLICATION_FAILURE,
68 "Inner application negotiation failed"},
69 {GNUTLS_A_INNER_APPLICATION_VERIFICATION,
70 "Inner application verification failed"},
71 {0, NULL}
72};
73
74#define GNUTLS_ALERT_LOOP(b) \
75 const gnutls_alert_entry *p; \
76 for(p = sup_alerts; p->desc != NULL; p++) { b ; }
77
78#define GNUTLS_ALERT_ID_LOOP(a) \
79 GNUTLS_ALERT_LOOP( if(p->alert == alert) { a; break; })
80
81
82/**
83 * gnutls_alert_get_name - Returns a string describing the alert number given
84 * @alert: is an alert number #gnutls_session_t structure.
85 *
86 * This function will return a string that describes the given alert
87 * number or NULL. See gnutls_alert_get().
88 *
89 **/
90const char *
91gnutls_alert_get_name (gnutls_alert_description_t alert)
92{
93 const char *ret = NULL;
94
95 GNUTLS_ALERT_ID_LOOP (ret = p->desc);
96
97 return ret;
98}
99
100/**
101 * gnutls_alert_send - This function sends an alert message to the peer
102 * @session: is a #gnutls_session_t structure.
103 * @level: is the level of the alert
104 * @desc: is the alert description
105 *
106 * This function will send an alert to the peer in order to inform
107 * him of something important (eg. his Certificate could not be verified).
108 * If the alert level is Fatal then the peer is expected to close the
109 * connection, otherwise he may ignore the alert and continue.
110 *
111 * The error code of the underlying record send function will be returned,
112 * so you may also receive GNUTLS_E_INTERRUPTED or GNUTLS_E_AGAIN as well.
113 *
114 * Returns 0 on success.
115 *
116 **/
117int
118gnutls_alert_send (gnutls_session_t session, gnutls_alert_level_t level,
119 gnutls_alert_description_t desc)
120{
121 uint8_t data[2];
122 int ret;
123 const char *name;
124
125 data[0] = (uint8_t) level;
126 data[1] = (uint8_t) desc;
127
128 name = gnutls_alert_get_name ((int) data[1]);
129 if (name == NULL)
130 name = "(unknown)";
131 _gnutls_record_log ("REC: Sending Alert[%d|%d] - %s\n", data[0],
132 data[1], name);
133
134 if ((ret = _gnutls_send_int (session, GNUTLS_ALERT, -1, data, 2)) >= 0)
135 return 0;
136 else
137 return ret;
138}
139
140/**
141 * gnutls_error_to_alert - This function returns an alert code based on the given error code
142 * @err: is a negative integer
143 * @level: the alert level will be stored there
144 *
145 * Returns an alert depending on the error code returned by a gnutls
146 * function. All alerts sent by this function should be considered fatal.
147 * The only exception is when err == GNUTLS_E_REHANDSHAKE, where a warning
148 * alert should be sent to the peer indicating that no renegotiation will
149 * be performed.
150 *
151 * If there is no mapping to a valid alert the alert to indicate internal error
152 * is returned.
153 *
154 **/
155int
156gnutls_error_to_alert (int err, int *level)
157{
158 int ret, _level = -1;
159
160 switch (err)
161 { /* send appropriate alert */
162 case GNUTLS_E_DECRYPTION_FAILED:
163 /* GNUTLS_A_DECRYPTION_FAILED is not sent, because
164 * it is not defined in SSL3. Note that we must
165 * not distinguish Decryption failures from mac
166 * check failures, due to the possibility of some
167 * attacks.
168 */
169 ret = GNUTLS_A_BAD_RECORD_MAC;
170 _level = GNUTLS_AL_FATAL;
171 break;
172 case GNUTLS_E_DECOMPRESSION_FAILED:
173 ret = GNUTLS_A_DECOMPRESSION_FAILURE;
174 _level = GNUTLS_AL_FATAL;
175 break;
176 case GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER:
177 case GNUTLS_E_ILLEGAL_SRP_USERNAME:
178 ret = GNUTLS_A_ILLEGAL_PARAMETER;
179 _level = GNUTLS_AL_FATAL;
180 break;
181 case GNUTLS_E_ASN1_ELEMENT_NOT_FOUND:
182 case GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND:
183 case GNUTLS_E_ASN1_DER_ERROR:
184 case GNUTLS_E_ASN1_VALUE_NOT_FOUND:
185 case GNUTLS_E_ASN1_GENERIC_ERROR:
186 case GNUTLS_E_ASN1_VALUE_NOT_VALID:
187 case GNUTLS_E_ASN1_TAG_ERROR:
188 case GNUTLS_E_ASN1_TAG_IMPLICIT:
189 case GNUTLS_E_ASN1_TYPE_ANY_ERROR:
190 case GNUTLS_E_ASN1_SYNTAX_ERROR:
191 case GNUTLS_E_ASN1_DER_OVERFLOW:
192 ret = GNUTLS_A_BAD_CERTIFICATE;
193 _level = GNUTLS_AL_FATAL;
194 break;
195 case GNUTLS_E_UNKNOWN_CIPHER_SUITE:
196 case GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM:
197 case GNUTLS_E_INSUFFICIENT_CREDENTIALS:
198 case GNUTLS_E_NO_CIPHER_SUITES:
199 case GNUTLS_E_NO_COMPRESSION_ALGORITHMS:
200 ret = GNUTLS_A_HANDSHAKE_FAILURE;
201 _level = GNUTLS_AL_FATAL;
202 break;
203 case GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION:
204 ret = GNUTLS_A_UNSUPPORTED_EXTENSION;
205 _level = GNUTLS_AL_FATAL;
206 break;
207 case GNUTLS_E_UNEXPECTED_PACKET:
208 case GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET:
209 ret = GNUTLS_A_UNEXPECTED_MESSAGE;
210 _level = GNUTLS_AL_FATAL;
211 break;
212 case GNUTLS_E_REHANDSHAKE:
213 ret = GNUTLS_A_NO_RENEGOTIATION;
214 _level = GNUTLS_AL_WARNING;
215 break;
216 case GNUTLS_E_UNSUPPORTED_VERSION_PACKET:
217 ret = GNUTLS_A_PROTOCOL_VERSION;
218 _level = GNUTLS_AL_FATAL;
219 break;
220 case GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE:
221 ret = GNUTLS_A_UNSUPPORTED_CERTIFICATE;
222 _level = GNUTLS_AL_FATAL;
223 break;
224 case GNUTLS_E_UNEXPECTED_PACKET_LENGTH:
225 ret = GNUTLS_A_RECORD_OVERFLOW;
226 _level = GNUTLS_AL_FATAL;
227 break;
228 case GNUTLS_E_INTERNAL_ERROR:
229 case GNUTLS_E_NO_TEMPORARY_DH_PARAMS:
230 case GNUTLS_E_NO_TEMPORARY_RSA_PARAMS:
231 ret = GNUTLS_A_INTERNAL_ERROR;
232 _level = GNUTLS_AL_FATAL;
233 break;
234 case GNUTLS_E_OPENPGP_GETKEY_FAILED:
235 ret = GNUTLS_A_CERTIFICATE_UNOBTAINABLE;
236 _level = GNUTLS_AL_FATAL;
237 break;
238 case GNUTLS_E_DH_PRIME_UNACCEPTABLE:
239 case GNUTLS_E_NO_CERTIFICATE_FOUND:
240 ret = GNUTLS_A_INSUFFICIENT_SECURITY;
241 _level = GNUTLS_AL_FATAL;
242 break;
243 default:
244 ret = GNUTLS_A_INTERNAL_ERROR;
245 _level = GNUTLS_AL_FATAL;
246 break;
247 }
248
249 if (level != NULL)
250 *level = _level;
251
252 return ret;
253}
254
255
256/**
257 * gnutls_alert_send_appropriate - This function sends an alert to the peer depending on the error code
258 * @session: is a #gnutls_session_t structure.
259 * @err: is an integer
260 *
261 * Sends an alert to the peer depending on the error code returned by a gnutls
262 * function. This function will call gnutls_error_to_alert() to determine
263 * the appropriate alert to send.
264 *
265 * This function may also return GNUTLS_E_AGAIN, or GNUTLS_E_INTERRUPTED.
266 *
267 * If the return value is GNUTLS_E_INVALID_REQUEST, then no alert has
268 * been sent to the peer.
269 *
270 * Returns zero on success.
271 */
272int
273gnutls_alert_send_appropriate (gnutls_session_t session, int err)
274{
275 int alert;
276 int level;
277
278 alert = gnutls_error_to_alert (err, &level);
279 if (alert < 0)
280 {
281 return alert;
282 }
283
284 return gnutls_alert_send (session, level, alert);
285}
286
287/**
288 * gnutls_alert_get - Returns the last alert number received.
289 * @session: is a #gnutls_session_t structure.
290 *
291 * This function will return the last alert number received. This
292 * function should be called if GNUTLS_E_WARNING_ALERT_RECEIVED or
293 * GNUTLS_E_FATAL_ALERT_RECEIVED has been returned by a gnutls
294 * function. The peer may send alerts if he thinks some things were
295 * not right. Check gnutls.h for the available alert descriptions.
296 *
297 * If no alert has been received the returned value is undefined.
298 *
299 **/
300gnutls_alert_description_t
301gnutls_alert_get (gnutls_session_t session)
302{
303 return session->internals.last_alert;
304}
diff --git a/src/daemon/https/tls/gnutls_algorithms.c b/src/daemon/https/tls/gnutls_algorithms.c
new file mode 100644
index 00000000..82bf9bf6
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_algorithms.c
@@ -0,0 +1,2225 @@
1/*
2 * Copyright (C) 2000, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include "gnutls_int.h"
26#include "gnutls_algorithms.h"
27#include "gnutls_errors.h"
28#include "gnutls_cert.h"
29/* x509 */
30#include "common.h"
31
32/* Cred type mappings to KX algorithms
33 * FIXME: The mappings are not 1-1. Some KX such as SRP_RSA require
34 * more than one credentials type.
35 */
36typedef struct
37{
38 gnutls_kx_algorithm_t algorithm;
39 gnutls_credentials_type_t client_type;
40 gnutls_credentials_type_t server_type; /* The type of credentials a server
41 * needs to set */
42} gnutls_cred_map;
43
44static const gnutls_cred_map cred_mappings[] = {
45 {GNUTLS_KX_ANON_DH,
46 GNUTLS_CRD_ANON,
47 GNUTLS_CRD_ANON},
48 {GNUTLS_KX_RSA,
49 GNUTLS_CRD_CERTIFICATE,
50 GNUTLS_CRD_CERTIFICATE},
51 {GNUTLS_KX_RSA_EXPORT,
52 GNUTLS_CRD_CERTIFICATE,
53 GNUTLS_CRD_CERTIFICATE},
54 {GNUTLS_KX_DHE_DSS,
55 GNUTLS_CRD_CERTIFICATE,
56 GNUTLS_CRD_CERTIFICATE},
57 {GNUTLS_KX_DHE_RSA,
58 GNUTLS_CRD_CERTIFICATE,
59 GNUTLS_CRD_CERTIFICATE},
60 {GNUTLS_KX_PSK,
61 GNUTLS_CRD_PSK,
62 GNUTLS_CRD_PSK},
63 {GNUTLS_KX_DHE_PSK,
64 GNUTLS_CRD_PSK,
65 GNUTLS_CRD_PSK},
66 {GNUTLS_KX_SRP,
67 GNUTLS_CRD_SRP,
68 GNUTLS_CRD_SRP},
69 {GNUTLS_KX_SRP_RSA,
70 GNUTLS_CRD_SRP,
71 GNUTLS_CRD_CERTIFICATE},
72 {GNUTLS_KX_SRP_DSS,
73 GNUTLS_CRD_SRP,
74 GNUTLS_CRD_CERTIFICATE},
75 {0,
76 0,
77 0}
78};
79
80#define GNUTLS_KX_MAP_LOOP(b) \
81 const gnutls_cred_map *p; \
82 for(p = cred_mappings; p->algorithm != 0; p++) { b ; }
83
84#define GNUTLS_KX_MAP_ALG_LOOP_SERVER(a) \
85 GNUTLS_KX_MAP_LOOP( if(p->server_type == type) { a; break; })
86
87#define GNUTLS_KX_MAP_ALG_LOOP_CLIENT(a) \
88 GNUTLS_KX_MAP_LOOP( if(p->client_type == type) { a; break; })
89
90/* KX mappings to PK algorithms */
91typedef struct
92{
93 gnutls_kx_algorithm_t kx_algorithm;
94 gnutls_pk_algorithm_t pk_algorithm;
95 enum encipher_type encipher_type; /* CIPHER_ENCRYPT if this algorithm is to be used
96 * for encryption, CIPHER_SIGN if signature only,
97 * CIPHER_IGN if this does not apply at all.
98 *
99 * This is useful to certificate cipher suites, which check
100 * against the certificate key usage bits.
101 */
102} gnutls_pk_map;
103
104/* This table maps the Key exchange algorithms to
105 * the certificate algorithms. Eg. if we have
106 * RSA algorithm in the certificate then we can
107 * use GNUTLS_KX_RSA or GNUTLS_KX_DHE_RSA.
108 */
109static const gnutls_pk_map pk_mappings[] = {
110 {GNUTLS_KX_RSA,
111 GNUTLS_PK_RSA,
112 CIPHER_ENCRYPT},
113 {GNUTLS_KX_RSA_EXPORT,
114 GNUTLS_PK_RSA,
115 CIPHER_SIGN},
116 {GNUTLS_KX_DHE_RSA,
117 GNUTLS_PK_RSA,
118 CIPHER_SIGN},
119 {GNUTLS_KX_SRP_RSA,
120 GNUTLS_PK_RSA,
121 CIPHER_SIGN},
122 {0,
123 0,
124 0}
125};
126
127#define GNUTLS_PK_MAP_LOOP(b) \
128 const gnutls_pk_map *p; \
129 for(p = pk_mappings; p->kx_algorithm != 0; p++) { b }
130
131#define GNUTLS_PK_MAP_ALG_LOOP(a) \
132 GNUTLS_PK_MAP_LOOP( if(p->kx_algorithm == kx_algorithm) { a; break; })
133
134/* TLS Versions */
135
136typedef struct
137{
138 const char *name;
139 gnutls_protocol_t id; /* gnutls internal version number */
140 int major; /* defined by the protocol */
141 int minor; /* defined by the protocol */
142 int supported; /* 0 not supported, > 0 is supported */
143} gnutls_version_entry;
144
145static const gnutls_version_entry sup_versions[] = {
146 {"SSL3.0",
147 GNUTLS_SSL3,
148 3,
149 0,
150 1},
151 {"TLS1.0",
152 GNUTLS_TLS1,
153 3,
154 1,
155 1},
156 {"TLS1.1",
157 GNUTLS_TLS1_1,
158 3,
159 2,
160 1},
161 {"TLS1.2",
162 GNUTLS_TLS1_2,
163 3,
164 3,
165 1},
166 {0,
167 0,
168 0,
169 0,
170 0}
171};
172
173/* Keep the contents of this struct the same as the previous one. */
174static const gnutls_protocol_t supported_protocols[] = { GNUTLS_SSL3,
175 GNUTLS_TLS1,
176 GNUTLS_TLS1_1,
177 GNUTLS_TLS1_2,
178 0
179};
180
181#define GNUTLS_VERSION_LOOP(b) \
182 const gnutls_version_entry *p; \
183 for(p = sup_versions; p->name != NULL; p++) { b ; }
184
185#define GNUTLS_VERSION_ALG_LOOP(a) \
186 GNUTLS_VERSION_LOOP( if(p->id == version) { a; break; })
187
188struct gnutls_cipher_entry
189{
190 const char *name;
191 gnutls_cipher_algorithm_t id;
192 uint16_t blocksize;
193 uint16_t keysize;
194 cipher_type_t block;
195 uint16_t iv;
196 int export_flag; /* 0 non export */
197};
198typedef struct gnutls_cipher_entry gnutls_cipher_entry;
199
200/* Note that all algorithms are in CBC or STREAM modes.
201 * Do not add any algorithms in other modes (avoid modified algorithms).
202 * View first: "The order of encryption and authentication for
203 * protecting communications" by Hugo Krawczyk - CRYPTO 2001
204 */
205static const gnutls_cipher_entry algorithms[] = {
206 {"AES-256-CBC",
207 GNUTLS_CIPHER_AES_256_CBC,
208 16,
209 32,
210 CIPHER_BLOCK,
211 16,
212 0},
213 {"AES-128-CBC",
214 GNUTLS_CIPHER_AES_128_CBC,
215 16,
216 16,
217 CIPHER_BLOCK,
218 16,
219 0},
220 {"3DES-CBC",
221 GNUTLS_CIPHER_3DES_CBC,
222 8,
223 24,
224 CIPHER_BLOCK,
225 8,
226 0},
227 {"DES-CBC",
228 GNUTLS_CIPHER_DES_CBC,
229 8,
230 8,
231 CIPHER_BLOCK,
232 8,
233 0},
234 {"ARCFOUR-128",
235 GNUTLS_CIPHER_ARCFOUR_128,
236 1,
237 16,
238 CIPHER_STREAM,
239 0,
240 0},
241 {"ARCFOUR-40",
242 GNUTLS_CIPHER_ARCFOUR_40,
243 1,
244 5,
245 CIPHER_STREAM,
246 0,
247 1},
248 {"RC2-40",
249 GNUTLS_CIPHER_RC2_40_CBC,
250 8,
251 5,
252 CIPHER_BLOCK,
253 8,
254 1},
255#ifdef ENABLE_CAMELLIA
256 {"CAMELLIA-256-CBC", GNUTLS_CIPHER_CAMELLIA_256_CBC, 16, 32, CIPHER_BLOCK,
257 16, 0},
258 {"CAMELLIA-128-CBC", GNUTLS_CIPHER_CAMELLIA_128_CBC, 16, 16, CIPHER_BLOCK,
259 16, 0},
260#endif
261 {"NULL",
262 GNUTLS_CIPHER_NULL,
263 1,
264 0,
265 CIPHER_STREAM,
266 0,
267 0},
268 {0,
269 0,
270 0,
271 0,
272 0,
273 0,
274 0}
275};
276
277/* Keep the contents of this struct the same as the previous one. */
278static const gnutls_cipher_algorithm_t supported_ciphers[] =
279 { GNUTLS_CIPHER_AES_256_CBC,
280 GNUTLS_CIPHER_AES_128_CBC,
281 GNUTLS_CIPHER_3DES_CBC,
282 GNUTLS_CIPHER_DES_CBC,
283 GNUTLS_CIPHER_ARCFOUR_128,
284 GNUTLS_CIPHER_ARCFOUR_40,
285 GNUTLS_CIPHER_RC2_40_CBC,
286#ifdef ENABLE_CAMELLIA
287 GNUTLS_CIPHER_CAMELLIA_256_CBC,
288 GNUTLS_CIPHER_CAMELLIA_128_CBC,
289#endif
290 GNUTLS_CIPHER_NULL,
291 0
292};
293
294#define GNUTLS_LOOP(b) \
295 const gnutls_cipher_entry *p; \
296 for(p = algorithms; p->name != NULL; p++) { b ; }
297
298#define GNUTLS_ALG_LOOP(a) \
299 GNUTLS_LOOP( if(p->id == algorithm) { a; break; } )
300
301struct gnutls_hash_entry
302{
303 const char *name;
304 const char *oid;
305 gnutls_mac_algorithm_t id;
306 size_t key_size; /* in case of mac */
307};
308typedef struct gnutls_hash_entry gnutls_hash_entry;
309
310static const gnutls_hash_entry hash_algorithms[] = {
311 {"SHA1",
312 HASH_OID_SHA1,
313 GNUTLS_MAC_SHA1,
314 20},
315 {"MD5",
316 HASH_OID_MD5,
317 GNUTLS_MAC_MD5,
318 16},
319 {"SHA256",
320 HASH_OID_SHA256,
321 GNUTLS_MAC_SHA256,
322 32},
323 {"NULL",
324 NULL,
325 GNUTLS_MAC_NULL,
326 0},
327 {0,
328 0,
329 0,
330 0}
331};
332
333/* Keep the contents of this struct the same as the previous one. */
334static const gnutls_mac_algorithm_t supported_macs[] = { GNUTLS_MAC_SHA1,
335 GNUTLS_MAC_MD5,
336 GNUTLS_MAC_SHA256,
337 GNUTLS_MAC_NULL,
338 0
339};
340
341#define GNUTLS_HASH_LOOP(b) \
342 const gnutls_hash_entry *p; \
343 for(p = hash_algorithms; p->name != NULL; p++) { b ; }
344
345#define GNUTLS_HASH_ALG_LOOP(a) \
346 GNUTLS_HASH_LOOP( if(p->id == algorithm) { a; break; } )
347
348/* Compression Section */
349#define GNUTLS_COMPRESSION_ENTRY(name, id, wb, ml, cl) \
350 { #name, name, id, wb, ml, cl}
351
352#define MAX_COMP_METHODS 5
353const int _gnutls_comp_algorithms_size = MAX_COMP_METHODS;
354
355/* the compression entry is defined in gnutls_algorithms.h */
356
357gnutls_compression_entry _gnutls_compression_algorithms[MAX_COMP_METHODS] =
358 { GNUTLS_COMPRESSION_ENTRY (GNUTLS_COMP_NULL, 0x00, 0, 0, 0),
359#ifdef HAVE_LIBZ
360 /* draft-ietf-tls-compression-02 */
361 GNUTLS_COMPRESSION_ENTRY (GNUTLS_COMP_DEFLATE, 0x01, 15, 8, 3),
362#endif
363 {0,
364 0,
365 0,
366 0,
367 0,
368 0}
369};
370
371static const gnutls_compression_method_t supported_compressions[] = {
372#ifdef HAVE_LIBZ
373 GNUTLS_COMP_DEFLATE,
374#endif
375 GNUTLS_COMP_NULL,
376 0
377};
378
379#define GNUTLS_COMPRESSION_LOOP(b) \
380 const gnutls_compression_entry *p; \
381 for(p = _gnutls_compression_algorithms; p->name != NULL; p++) { b ; }
382#define GNUTLS_COMPRESSION_ALG_LOOP(a) \
383 GNUTLS_COMPRESSION_LOOP( if(p->id == algorithm) { a; break; } )
384#define GNUTLS_COMPRESSION_ALG_LOOP_NUM(a) \
385 GNUTLS_COMPRESSION_LOOP( if(p->num == num) { a; break; } )
386
387/* Key Exchange Section */
388extern mod_auth_st rsa_auth_struct;
389extern mod_auth_st rsa_export_auth_struct;
390extern mod_auth_st dhe_rsa_auth_struct;
391extern mod_auth_st dhe_dss_auth_struct;
392extern mod_auth_st anon_auth_struct;
393extern mod_auth_st srp_auth_struct;
394extern mod_auth_st psk_auth_struct;
395extern mod_auth_st dhe_psk_auth_struct;
396extern mod_auth_st srp_rsa_auth_struct;
397extern mod_auth_st srp_dss_auth_struct;
398
399struct gnutls_kx_algo_entry
400{
401 const char *name;
402 gnutls_kx_algorithm_t algorithm;
403 mod_auth_st *auth_struct;
404 int needs_dh_params;
405 int needs_rsa_params;
406};
407typedef struct gnutls_kx_algo_entry gnutls_kx_algo_entry;
408
409static const gnutls_kx_algo_entry _gnutls_kx_algorithms[] = {
410#ifdef ENABLE_ANON
411 {"ANON-DH", GNUTLS_KX_ANON_DH, &anon_auth_struct, 1, 0},
412#endif
413 {"RSA",
414 GNUTLS_KX_RSA,
415 &rsa_auth_struct,
416 0,
417 0},
418 {"RSA-EXPORT",
419 GNUTLS_KX_RSA_EXPORT,
420 &rsa_export_auth_struct,
421 0,
422 1 /* needs RSA params */ },
423 {"DHE-RSA",
424 GNUTLS_KX_DHE_RSA,
425 &dhe_rsa_auth_struct,
426 1,
427 0},
428 {"DHE-DSS",
429 GNUTLS_KX_DHE_DSS,
430 &dhe_dss_auth_struct,
431 1,
432 0},
433
434#ifdef ENABLE_SRP
435 {"SRP-DSS", GNUTLS_KX_SRP_DSS, &srp_dss_auth_struct, 0, 0},
436 {"SRP-RSA", GNUTLS_KX_SRP_RSA, &srp_rsa_auth_struct, 0, 0},
437 {"SRP", GNUTLS_KX_SRP, &srp_auth_struct, 0, 0},
438#endif
439#ifdef ENABLE_PSK
440 {"PSK", GNUTLS_KX_PSK, &psk_auth_struct, 0, 0},
441 {"DHE-PSK", GNUTLS_KX_DHE_PSK, &dhe_psk_auth_struct,
442 1 /* needs DHE params */ , 0},
443#endif
444 {0,
445 0,
446 0,
447 0,
448 0}
449};
450
451/* Keep the contents of this struct the same as the previous one. */
452static const gnutls_kx_algorithm_t supported_kxs[] = {
453#ifdef ENABLE_ANON
454 GNUTLS_KX_ANON_DH,
455#endif
456 GNUTLS_KX_RSA,
457 GNUTLS_KX_RSA_EXPORT,
458 GNUTLS_KX_DHE_RSA,
459 GNUTLS_KX_DHE_DSS,
460#ifdef ENABLE_SRP
461 GNUTLS_KX_SRP_DSS,
462 GNUTLS_KX_SRP_RSA,
463 GNUTLS_KX_SRP,
464#endif
465#ifdef ENABLE_PSK
466 GNUTLS_KX_PSK,
467 GNUTLS_KX_DHE_PSK,
468#endif
469 0
470};
471
472#define GNUTLS_KX_LOOP(b) \
473 const gnutls_kx_algo_entry *p; \
474 for(p = _gnutls_kx_algorithms; p->name != NULL; p++) { b ; }
475
476#define GNUTLS_KX_ALG_LOOP(a) \
477 GNUTLS_KX_LOOP( if(p->algorithm == algorithm) { a; break; } )
478
479/* Cipher SUITES */
480#define GNUTLS_CIPHER_SUITE_ENTRY( name, block_algorithm, kx_algorithm, mac_algorithm, version ) \
481 { #name, {name}, block_algorithm, kx_algorithm, mac_algorithm, version }
482
483typedef struct
484{
485 const char *name;
486 cipher_suite_st id;
487 gnutls_cipher_algorithm_t block_algorithm;
488 gnutls_kx_algorithm_t kx_algorithm;
489 gnutls_mac_algorithm_t mac_algorithm;
490 gnutls_protocol_t version; /* this cipher suite is supported
491 * from 'version' and above;
492 */
493} gnutls_cipher_suite_entry;
494
495/* RSA with NULL cipher and MD5 MAC
496 * for test purposes.
497 */
498#define GNUTLS_RSA_NULL_MD5 { 0x00, 0x01 }
499
500/* ANONymous cipher suites.
501 */
502
503#define GNUTLS_ANON_DH_3DES_EDE_CBC_SHA1 { 0x00, 0x1B }
504#define GNUTLS_ANON_DH_ARCFOUR_MD5 { 0x00, 0x18 }
505
506/* rfc3268: */
507#define GNUTLS_ANON_DH_AES_128_CBC_SHA1 { 0x00, 0x34 }
508#define GNUTLS_ANON_DH_AES_256_CBC_SHA1 { 0x00, 0x3A }
509
510/* rfc4132 */
511#define GNUTLS_ANON_DH_CAMELLIA_128_CBC_SHA1 { 0x00,0x46 }
512#define GNUTLS_ANON_DH_CAMELLIA_256_CBC_SHA1 { 0x00,0x89 }
513
514/* PSK (not in TLS 1.0)
515 * draft-ietf-tls-psk:
516 */
517#define GNUTLS_PSK_SHA_ARCFOUR_SHA1 { 0x00, 0x8A }
518#define GNUTLS_PSK_SHA_3DES_EDE_CBC_SHA1 { 0x00, 0x8B }
519#define GNUTLS_PSK_SHA_AES_128_CBC_SHA1 { 0x00, 0x8C }
520#define GNUTLS_PSK_SHA_AES_256_CBC_SHA1 { 0x00, 0x8D }
521
522#define GNUTLS_DHE_PSK_SHA_ARCFOUR_SHA1 { 0x00, 0x8E }
523#define GNUTLS_DHE_PSK_SHA_3DES_EDE_CBC_SHA1 { 0x00, 0x8F }
524#define GNUTLS_DHE_PSK_SHA_AES_128_CBC_SHA1 { 0x00, 0x90 }
525#define GNUTLS_DHE_PSK_SHA_AES_256_CBC_SHA1 { 0x00, 0x91 }
526
527/* SRP (rfc5054)
528 */
529#define GNUTLS_SRP_SHA_3DES_EDE_CBC_SHA1 { 0xC0, 0x1A }
530#define GNUTLS_SRP_SHA_RSA_3DES_EDE_CBC_SHA1 { 0xC0, 0x1B }
531#define GNUTLS_SRP_SHA_DSS_3DES_EDE_CBC_SHA1 { 0xC0, 0x1C }
532
533#define GNUTLS_SRP_SHA_AES_128_CBC_SHA1 { 0xC0, 0x1D }
534#define GNUTLS_SRP_SHA_RSA_AES_128_CBC_SHA1 { 0xC0, 0x1E }
535#define GNUTLS_SRP_SHA_DSS_AES_128_CBC_SHA1 { 0xC0, 0x1F }
536
537#define GNUTLS_SRP_SHA_AES_256_CBC_SHA1 { 0xC0, 0x20 }
538#define GNUTLS_SRP_SHA_RSA_AES_256_CBC_SHA1 { 0xC0, 0x21 }
539#define GNUTLS_SRP_SHA_DSS_AES_256_CBC_SHA1 { 0xC0, 0x22 }
540
541/* RSA
542 */
543#define GNUTLS_RSA_ARCFOUR_SHA1 { 0x00, 0x05 }
544#define GNUTLS_RSA_ARCFOUR_MD5 { 0x00, 0x04 }
545#define GNUTLS_RSA_3DES_EDE_CBC_SHA1 { 0x00, 0x0A }
546
547#define GNUTLS_RSA_EXPORT_ARCFOUR_40_MD5 { 0x00, 0x03 }
548
549/* rfc3268:
550 */
551#define GNUTLS_RSA_AES_128_CBC_SHA1 { 0x00, 0x2F }
552#define GNUTLS_RSA_AES_256_CBC_SHA1 { 0x00, 0x35 }
553
554/* rfc4132 */
555#define GNUTLS_RSA_CAMELLIA_128_CBC_SHA1 { 0x00,0x41 }
556#define GNUTLS_RSA_CAMELLIA_256_CBC_SHA1 { 0x00,0x84 }
557
558/* DHE DSS
559 */
560
561#define GNUTLS_DHE_DSS_3DES_EDE_CBC_SHA1 { 0x00, 0x13 }
562
563/* draft-ietf-tls-56-bit-ciphersuites-01:
564 */
565#define GNUTLS_DHE_DSS_ARCFOUR_SHA1 { 0x00, 0x66 }
566
567/* rfc3268:
568 */
569#define GNUTLS_DHE_DSS_AES_256_CBC_SHA1 { 0x00, 0x38 }
570#define GNUTLS_DHE_DSS_AES_128_CBC_SHA1 { 0x00, 0x32 }
571
572/* rfc4132 */
573#define GNUTLS_DHE_DSS_CAMELLIA_128_CBC_SHA1 { 0x00,0x44 }
574#define GNUTLS_DHE_DSS_CAMELLIA_256_CBC_SHA1 { 0x00,0x87 }
575
576/* DHE RSA
577 */
578#define GNUTLS_DHE_RSA_3DES_EDE_CBC_SHA1 { 0x00, 0x16 }
579
580/* rfc3268:
581 */
582#define GNUTLS_DHE_RSA_AES_128_CBC_SHA1 { 0x00, 0x33 }
583#define GNUTLS_DHE_RSA_AES_256_CBC_SHA1 { 0x00, 0x39 }
584
585/* rfc4132 */
586#define GNUTLS_DHE_RSA_CAMELLIA_128_CBC_SHA1 { 0x00,0x45 }
587#define GNUTLS_DHE_RSA_CAMELLIA_256_CBC_SHA1 { 0x00,0x88 }
588
589#define CIPHER_SUITES_COUNT sizeof(cs_algorithms)/sizeof(gnutls_cipher_suite_entry)-1
590
591static const gnutls_cipher_suite_entry cs_algorithms[] = {
592 /* ANON_DH */
593 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_ARCFOUR_MD5,
594 GNUTLS_CIPHER_ARCFOUR_128,
595 GNUTLS_KX_ANON_DH, GNUTLS_MAC_MD5,
596 GNUTLS_SSL3),
597 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_3DES_EDE_CBC_SHA1,
598 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_ANON_DH,
599 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
600 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_AES_128_CBC_SHA1,
601 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_ANON_DH,
602 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
603 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_AES_256_CBC_SHA1,
604 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_ANON_DH,
605 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
606#ifdef ENABLE_CAMELLIA
607 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_CAMELLIA_128_CBC_SHA1,
608 GNUTLS_CIPHER_CAMELLIA_128_CBC,
609 GNUTLS_KX_ANON_DH,
610 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
611 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_ANON_DH_CAMELLIA_256_CBC_SHA1,
612 GNUTLS_CIPHER_CAMELLIA_256_CBC,
613 GNUTLS_KX_ANON_DH,
614 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
615#endif
616
617 /* PSK */
618 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_ARCFOUR_SHA1,
619 GNUTLS_CIPHER_ARCFOUR, GNUTLS_KX_PSK,
620 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
621 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_3DES_EDE_CBC_SHA1,
622 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_PSK,
623 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
624 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_AES_128_CBC_SHA1,
625 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_PSK,
626 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
627 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_PSK_SHA_AES_256_CBC_SHA1,
628 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_PSK,
629 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
630
631 /* DHE-PSK */
632 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_ARCFOUR_SHA1,
633 GNUTLS_CIPHER_ARCFOUR, GNUTLS_KX_DHE_PSK,
634 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
635 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_3DES_EDE_CBC_SHA1,
636 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_DHE_PSK,
637 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
638 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_AES_128_CBC_SHA1,
639 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_PSK,
640 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
641 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_PSK_SHA_AES_256_CBC_SHA1,
642 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_PSK,
643 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
644
645 /* SRP */
646 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_3DES_EDE_CBC_SHA1,
647 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_SRP,
648 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
649 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_AES_128_CBC_SHA1,
650 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_SRP,
651 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
652 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_AES_256_CBC_SHA1,
653 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_SRP,
654 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
655
656 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_DSS_3DES_EDE_CBC_SHA1,
657 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_SRP_DSS,
658 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
659
660 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_RSA_3DES_EDE_CBC_SHA1,
661 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_SRP_RSA,
662 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
663
664 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_DSS_AES_128_CBC_SHA1,
665 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_SRP_DSS,
666 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
667
668 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_RSA_AES_128_CBC_SHA1,
669 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_SRP_RSA,
670 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
671
672 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_DSS_AES_256_CBC_SHA1,
673 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_SRP_DSS,
674 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
675
676 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_SRP_SHA_RSA_AES_256_CBC_SHA1,
677 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_SRP_RSA,
678 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
679
680 /* DHE_DSS */
681 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_ARCFOUR_SHA1,
682 GNUTLS_CIPHER_ARCFOUR_128, GNUTLS_KX_DHE_DSS,
683 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
684 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_3DES_EDE_CBC_SHA1,
685 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_DHE_DSS,
686 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
687 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_AES_128_CBC_SHA1,
688 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_DSS,
689 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
690 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_AES_256_CBC_SHA1,
691 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_DSS,
692 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
693#ifdef ENABLE_CAMELLIA
694 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_CAMELLIA_128_CBC_SHA1,
695 GNUTLS_CIPHER_CAMELLIA_128_CBC,
696 GNUTLS_KX_DHE_DSS,
697 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
698 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_DSS_CAMELLIA_256_CBC_SHA1,
699 GNUTLS_CIPHER_CAMELLIA_256_CBC,
700 GNUTLS_KX_DHE_DSS,
701 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
702#endif
703 /* DHE_RSA */
704 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_3DES_EDE_CBC_SHA1,
705 GNUTLS_CIPHER_3DES_CBC, GNUTLS_KX_DHE_RSA,
706 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
707 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_AES_128_CBC_SHA1,
708 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_DHE_RSA,
709 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
710 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_AES_256_CBC_SHA1,
711 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_DHE_RSA,
712 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
713#ifdef ENABLE_CAMELLIA
714 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_CAMELLIA_128_CBC_SHA1,
715 GNUTLS_CIPHER_CAMELLIA_128_CBC,
716 GNUTLS_KX_DHE_RSA,
717 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
718 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_DHE_RSA_CAMELLIA_256_CBC_SHA1,
719 GNUTLS_CIPHER_CAMELLIA_256_CBC,
720 GNUTLS_KX_DHE_RSA,
721 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
722#endif
723 /* RSA */
724 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_NULL_MD5,
725 GNUTLS_CIPHER_NULL,
726 GNUTLS_KX_RSA, GNUTLS_MAC_MD5, GNUTLS_SSL3),
727
728 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_EXPORT_ARCFOUR_40_MD5,
729 GNUTLS_CIPHER_ARCFOUR_40,
730 GNUTLS_KX_RSA_EXPORT, GNUTLS_MAC_MD5,
731 GNUTLS_SSL3),
732
733 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_ARCFOUR_SHA1,
734 GNUTLS_CIPHER_ARCFOUR_128,
735 GNUTLS_KX_RSA, GNUTLS_MAC_SHA1, GNUTLS_SSL3),
736 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_ARCFOUR_MD5,
737 GNUTLS_CIPHER_ARCFOUR_128,
738 GNUTLS_KX_RSA, GNUTLS_MAC_MD5, GNUTLS_SSL3),
739 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_3DES_EDE_CBC_SHA1,
740 GNUTLS_CIPHER_3DES_CBC,
741 GNUTLS_KX_RSA, GNUTLS_MAC_SHA1, GNUTLS_SSL3),
742 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_AES_128_CBC_SHA1,
743 GNUTLS_CIPHER_AES_128_CBC, GNUTLS_KX_RSA,
744 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
745 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_AES_256_CBC_SHA1,
746 GNUTLS_CIPHER_AES_256_CBC, GNUTLS_KX_RSA,
747 GNUTLS_MAC_SHA1, GNUTLS_SSL3),
748#ifdef ENABLE_CAMELLIA
749 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_CAMELLIA_128_CBC_SHA1,
750 GNUTLS_CIPHER_CAMELLIA_128_CBC, GNUTLS_KX_RSA,
751 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
752 GNUTLS_CIPHER_SUITE_ENTRY (GNUTLS_RSA_CAMELLIA_256_CBC_SHA1,
753 GNUTLS_CIPHER_CAMELLIA_256_CBC, GNUTLS_KX_RSA,
754 GNUTLS_MAC_SHA1, GNUTLS_TLS1),
755#endif
756 {0,
757 {
758 {0,
759 0}},
760 0,
761 0,
762 0,
763 0}
764};
765
766#define GNUTLS_CIPHER_SUITE_LOOP(b) \
767 const gnutls_cipher_suite_entry *p; \
768 for(p = cs_algorithms; p->name != NULL; p++) { b ; }
769
770#define GNUTLS_CIPHER_SUITE_ALG_LOOP(a) \
771 GNUTLS_CIPHER_SUITE_LOOP( if( (p->id.suite[0] == suite->suite[0]) && (p->id.suite[1] == suite->suite[1])) { a; break; } )
772
773/* Generic Functions */
774
775int
776_gnutls_mac_priority (gnutls_session_t session,
777 gnutls_mac_algorithm_t algorithm)
778{ /* actually returns the priority */
779 unsigned int i;
780 for (i = 0; i < session->internals.priorities.mac.algorithms; i++)
781 {
782 if (session->internals.priorities.mac.priority[i] == algorithm)
783 return i;
784 }
785 return -1;
786}
787
788/**
789 * gnutls_mac_get_name - Returns a string with the name of the specified mac algorithm
790 * @algorithm: is a MAC algorithm
791 *
792 * Returns: a string that contains the name of the specified MAC
793 * algorithm, or %NULL.
794 **/
795const char *
796gnutls_mac_get_name (gnutls_mac_algorithm_t algorithm)
797{
798 const char *ret = NULL;
799
800 /* avoid prefix */
801 GNUTLS_HASH_ALG_LOOP (ret = p->name);
802
803 return ret;
804}
805
806/**
807 * gnutls_mac_get_id - Returns the gnutls id of the specified in string algorithm
808 * @algorithm: is a MAC algorithm name
809 *
810 * Returns: an %gnutls_mac_algorithm_tid of the specified in a string
811 * MAC algorithm, or %GNUTLS_MAC_UNKNOWN on failures. The names are
812 * compared in a case insensitive way.
813 **/
814gnutls_mac_algorithm_t
815gnutls_mac_get_id (const char *name)
816{
817 gnutls_mac_algorithm_t ret = GNUTLS_MAC_UNKNOWN;
818
819 GNUTLS_HASH_LOOP (if (strcasecmp (p->name, name) == 0) ret = p->id)
820 ;
821
822 return ret;
823}
824
825/**
826 * gnutls_mac_get_key_size - Returns the length of the MAC's key size
827 * @algorithm: is an encryption algorithm
828 *
829 * Returns: length (in bytes) of the given MAC key size, or 0 if the
830 * given MAC algorithm is invalid.
831 *
832 **/
833size_t
834gnutls_mac_get_key_size (gnutls_mac_algorithm_t algorithm)
835{
836 size_t ret = 0;
837
838 /* avoid prefix */
839 GNUTLS_HASH_ALG_LOOP (ret = p->key_size);
840
841 return ret;
842}
843
844/**
845 * gnutls_mac_list:
846 *
847 * Get a list of hash algorithms for use as MACs. Note that not
848 * necessarily all MACs are supported in TLS cipher suites. For
849 * example, MD2 is not supported as a cipher suite, but is supported
850 * for other purposes (e.g., X.509 signature verification or similar).
851 *
852 * Returns: Return a zero-terminated list of %gnutls_mac_algorithm_t
853 * integers indicating the available MACs.
854 **/
855const gnutls_mac_algorithm_t *
856gnutls_mac_list (void)
857{
858 return supported_macs;
859}
860
861const char *
862_gnutls_x509_mac_to_oid (gnutls_mac_algorithm_t algorithm)
863{
864 const char *ret = NULL;
865
866 /* avoid prefix */
867 GNUTLS_HASH_ALG_LOOP (ret = p->oid);
868
869 return ret;
870}
871
872gnutls_mac_algorithm_t
873_gnutls_x509_oid2mac_algorithm (const char *oid)
874{
875 gnutls_mac_algorithm_t ret = 0;
876
877 GNUTLS_HASH_LOOP (if (p->oid && strcmp (oid, p->oid) == 0)
878 {
879 ret = p->id; break;}
880 )
881 ;
882
883 if (ret == 0)
884 return GNUTLS_MAC_UNKNOWN;
885 return ret;
886}
887
888int
889_gnutls_mac_is_ok (gnutls_mac_algorithm_t algorithm)
890{
891 ssize_t ret = -1;
892 GNUTLS_HASH_ALG_LOOP (ret = p->id);
893 if (ret >= 0)
894 ret = 0;
895 else
896 ret = 1;
897 return ret;
898}
899
900/* Compression Functions */
901int
902_gnutls_compression_priority (gnutls_session_t session,
903 gnutls_compression_method_t algorithm)
904{ /* actually returns the priority */
905 unsigned int i;
906 for (i = 0; i < session->internals.priorities.compression.algorithms; i++)
907 {
908 if (session->internals.priorities.compression.priority[i] == algorithm)
909 return i;
910 }
911 return -1;
912}
913
914/**
915 * gnutls_compression_get_name - Returns a string with the name of the specified compression algorithm
916 * @algorithm: is a Compression algorithm
917 *
918 * Returns: a pointer to a string that contains the name of the
919 * specified compression algorithm, or %NULL.
920 **/
921const char *
922gnutls_compression_get_name (gnutls_compression_method_t algorithm)
923{
924 const char *ret = NULL;
925
926 /* avoid prefix */
927 GNUTLS_COMPRESSION_ALG_LOOP (ret = p->name + sizeof ("GNUTLS_COMP_") - 1);
928
929 return ret;
930}
931
932/**
933 * gnutls_compression_get_id - Returns the gnutls id of the specified in string algorithm
934 * @algorithm: is a compression method name
935 *
936 * The names are compared in a case insensitive way.
937 *
938 * Returns: an id of the specified in a string compression method, or
939 * %GNUTLS_COMP_UNKNOWN on error.
940 *
941 **/
942gnutls_compression_method_t
943gnutls_compression_get_id (const char *name)
944{
945 gnutls_compression_method_t ret = GNUTLS_COMP_UNKNOWN;
946
947 GNUTLS_COMPRESSION_LOOP (if
948 (strcasecmp
949 (p->name + sizeof ("GNUTLS_COMP_") - 1,
950 name) == 0) ret = p->id)
951 ;
952
953 return ret;
954}
955
956/**
957 * gnutls_compression_list:
958 *
959 * Get a list of compression methods. Note that to be able to use LZO
960 * compression, you must link to libgnutls-extra and call
961 * gnutls_global_init_extra().
962 *
963 * Returns: a zero-terminated list of %gnutls_compression_method_t
964 * integers indicating the available compression methods.
965 **/
966const gnutls_compression_method_t *
967gnutls_compression_list (void)
968{
969 return supported_compressions;
970}
971
972/* return the tls number of the specified algorithm */
973int
974_gnutls_compression_get_num (gnutls_compression_method_t algorithm)
975{
976 int ret = -1;
977
978 /* avoid prefix */
979 GNUTLS_COMPRESSION_ALG_LOOP (ret = p->num);
980
981 return ret;
982}
983
984int
985_gnutls_compression_get_wbits (gnutls_compression_method_t algorithm)
986{
987 int ret = -1;
988 /* avoid prefix */
989 GNUTLS_COMPRESSION_ALG_LOOP (ret = p->window_bits);
990 return ret;
991}
992
993int
994_gnutls_compression_get_mem_level (gnutls_compression_method_t algorithm)
995{
996 int ret = -1;
997 /* avoid prefix */
998 GNUTLS_COMPRESSION_ALG_LOOP (ret = p->mem_level);
999 return ret;
1000}
1001
1002int
1003_gnutls_compression_get_comp_level (gnutls_compression_method_t algorithm)
1004{
1005 int ret = -1;
1006 /* avoid prefix */
1007 GNUTLS_COMPRESSION_ALG_LOOP (ret = p->comp_level);
1008 return ret;
1009}
1010
1011/* returns the gnutls internal ID of the TLS compression
1012 * method num
1013 */
1014gnutls_compression_method_t
1015_gnutls_compression_get_id (int num)
1016{
1017 gnutls_compression_method_t ret = -1;
1018
1019 /* avoid prefix */
1020 GNUTLS_COMPRESSION_ALG_LOOP_NUM (ret = p->id);
1021
1022 return ret;
1023}
1024
1025int
1026_gnutls_compression_is_ok (gnutls_compression_method_t algorithm)
1027{
1028 ssize_t ret = -1;
1029 GNUTLS_COMPRESSION_ALG_LOOP (ret = p->id);
1030 if (ret >= 0)
1031 ret = 0;
1032 else
1033 ret = 1;
1034 return ret;
1035}
1036
1037/* CIPHER functions */
1038int
1039_gnutls_cipher_get_block_size (gnutls_cipher_algorithm_t algorithm)
1040{
1041 size_t ret = 0;
1042 GNUTLS_ALG_LOOP (ret = p->blocksize);
1043 return ret;
1044
1045}
1046
1047/* returns the priority */
1048int
1049_gnutls_cipher_priority (gnutls_session_t session,
1050 gnutls_cipher_algorithm_t algorithm)
1051{
1052 unsigned int i;
1053 for (i = 0; i < session->internals.priorities.cipher.algorithms; i++)
1054 {
1055 if (session->internals.priorities.cipher.priority[i] == algorithm)
1056 return i;
1057 }
1058 return -1;
1059}
1060
1061int
1062_gnutls_cipher_is_block (gnutls_cipher_algorithm_t algorithm)
1063{
1064 size_t ret = 0;
1065
1066 GNUTLS_ALG_LOOP (ret = p->block);
1067 return ret;
1068
1069}
1070
1071/**
1072 * gnutls_cipher_get_key_size - Returns the length of the cipher's key size
1073 * @algorithm: is an encryption algorithm
1074 *
1075 * Returns: length (in bytes) of the given cipher's key size, o 0 if
1076 * the given cipher is invalid.
1077 **/
1078size_t
1079gnutls_cipher_get_key_size (gnutls_cipher_algorithm_t algorithm)
1080{ /* In bytes */
1081 size_t ret = 0;
1082 GNUTLS_ALG_LOOP (ret = p->keysize);
1083 return ret;
1084
1085}
1086
1087int
1088_gnutls_cipher_get_iv_size (gnutls_cipher_algorithm_t algorithm)
1089{ /* In bytes */
1090 size_t ret = 0;
1091 GNUTLS_ALG_LOOP (ret = p->iv);
1092 return ret;
1093
1094}
1095
1096int
1097_gnutls_cipher_get_export_flag (gnutls_cipher_algorithm_t algorithm)
1098{ /* In bytes */
1099 size_t ret = 0;
1100 GNUTLS_ALG_LOOP (ret = p->export_flag);
1101 return ret;
1102
1103}
1104
1105/**
1106 * gnutls_cipher_get_name - Returns a string with the name of the specified cipher algorithm
1107 * @algorithm: is an encryption algorithm
1108 *
1109 * Returns: a pointer to a string that contains the name of the
1110 * specified cipher, or %NULL.
1111 **/
1112const char *
1113gnutls_cipher_get_name (gnutls_cipher_algorithm_t algorithm)
1114{
1115 const char *ret = NULL;
1116
1117 /* avoid prefix */
1118 GNUTLS_ALG_LOOP (ret = p->name);
1119
1120 return ret;
1121}
1122
1123/**
1124 * gnutls_cipher_get_id - Returns the gnutls id of the specified in string algorithm
1125 * @algorithm: is a MAC algorithm name
1126 *
1127 * The names are compared in a case insensitive way.
1128 *
1129 * Returns: an id of the specified cipher, or %GNUTLS_CIPHER_UNKNOWN
1130 * on error.
1131 *
1132 **/
1133gnutls_cipher_algorithm_t
1134gnutls_cipher_get_id (const char *name)
1135{
1136 gnutls_cipher_algorithm_t ret = GNUTLS_CIPHER_UNKNOWN;
1137
1138 GNUTLS_LOOP (if (strcasecmp (p->name, name) == 0) ret = p->id)
1139 ;
1140
1141 return ret;
1142}
1143
1144/**
1145 * gnutls_cipher_list:
1146 *
1147 * Get a list of supported cipher algorithms. Note that not
1148 * necessarily all ciphers are supported as TLS cipher suites. For
1149 * example, DES is not supported as a cipher suite, but is supported
1150 * for other purposes (e.g., PKCS#8 or similar).
1151 *
1152 * Returns: a zero-terminated list of %gnutls_cipher_algorithm_t
1153 * integers indicating the available ciphers.
1154 *
1155 **/
1156const gnutls_cipher_algorithm_t *
1157gnutls_cipher_list (void)
1158{
1159 return supported_ciphers;
1160}
1161
1162int
1163_gnutls_cipher_is_ok (gnutls_cipher_algorithm_t algorithm)
1164{
1165 ssize_t ret = -1;
1166 GNUTLS_ALG_LOOP (ret = p->id);
1167 if (ret >= 0)
1168 ret = 0;
1169 else
1170 ret = 1;
1171 return ret;
1172}
1173
1174/* Key EXCHANGE functions */
1175mod_auth_st *
1176_gnutls_kx_auth_struct (gnutls_kx_algorithm_t algorithm)
1177{
1178 mod_auth_st *ret = NULL;
1179 GNUTLS_KX_ALG_LOOP (ret = p->auth_struct);
1180 return ret;
1181
1182}
1183
1184int
1185_gnutls_kx_priority (gnutls_session_t session,
1186 gnutls_kx_algorithm_t algorithm)
1187{
1188 unsigned int i;
1189 for (i = 0; i < session->internals.priorities.kx.algorithms; i++)
1190 {
1191 if (session->internals.priorities.kx.priority[i] == algorithm)
1192 return i;
1193 }
1194 return -1;
1195}
1196
1197/**
1198 * gnutls_kx_get_name - Returns a string with the name of the specified key exchange algorithm
1199 * @algorithm: is a key exchange algorithm
1200 *
1201 * Returns: a pointer to a string that contains the name of the
1202 * specified key exchange algorithm, or %NULL.
1203 **/
1204const char *
1205gnutls_kx_get_name (gnutls_kx_algorithm_t algorithm)
1206{
1207 const char *ret = NULL;
1208
1209 /* avoid prefix */
1210 GNUTLS_KX_ALG_LOOP (ret = p->name);
1211
1212 return ret;
1213}
1214
1215/**
1216 * gnutls_kx_get_id - Returns the gnutls id of the specified in string algorithm
1217 * @algorithm: is a KX name
1218 *
1219 * The names are compared in a case insensitive way.
1220 *
1221 * Returns: an id of the specified KX algorithm, or
1222 * %GNUTLS_KX_UNKNOWN on error.
1223 **/
1224gnutls_kx_algorithm_t
1225gnutls_kx_get_id (const char *name)
1226{
1227 gnutls_cipher_algorithm_t ret = GNUTLS_KX_UNKNOWN;
1228
1229 GNUTLS_KX_LOOP (if (strcasecmp (p->name, name) == 0) ret = p->algorithm)
1230 ;
1231
1232 return ret;
1233}
1234
1235/**
1236 * gnutls_kx_list:
1237 *
1238 * Get a list of supported key exchange algorithms.
1239 *
1240 * Returns: a zero-terminated list of %gnutls_kx_algorithm_t integers
1241 * indicating the available key exchange algorithms.
1242 **/
1243const gnutls_kx_algorithm_t *
1244gnutls_kx_list (void)
1245{
1246 return supported_kxs;
1247}
1248
1249int
1250_gnutls_kx_is_ok (gnutls_kx_algorithm_t algorithm)
1251{
1252 ssize_t ret = -1;
1253 GNUTLS_KX_ALG_LOOP (ret = p->algorithm);
1254 if (ret >= 0)
1255 ret = 0;
1256 else
1257 ret = 1;
1258 return ret;
1259}
1260
1261int
1262_gnutls_kx_needs_rsa_params (gnutls_kx_algorithm_t algorithm)
1263{
1264 ssize_t ret = 0;
1265 GNUTLS_KX_ALG_LOOP (ret = p->needs_rsa_params);
1266 return ret;
1267}
1268
1269int
1270_gnutls_kx_needs_dh_params (gnutls_kx_algorithm_t algorithm)
1271{
1272 ssize_t ret = 0;
1273 GNUTLS_KX_ALG_LOOP (ret = p->needs_dh_params);
1274 return ret;
1275}
1276
1277/* Version */
1278int
1279_gnutls_version_priority (gnutls_session_t session, gnutls_protocol_t version)
1280{ /* actually returns the priority */
1281 unsigned int i;
1282
1283 if (session->internals.priorities.protocol.priority == NULL)
1284 {
1285 gnutls_assert ();
1286 return -1;
1287 }
1288
1289 for (i = 0; i < session->internals.priorities.protocol.algorithms; i++)
1290 {
1291 if (session->internals.priorities.protocol.priority[i] == version)
1292 return i;
1293 }
1294 return -1;
1295}
1296
1297gnutls_protocol_t
1298_gnutls_version_lowest (gnutls_session_t session)
1299{ /* returns the lowest version supported */
1300 unsigned int i, min = 0xff;
1301
1302 if (session->internals.priorities.protocol.priority == NULL)
1303 {
1304 return GNUTLS_VERSION_UNKNOWN;
1305 }
1306 else
1307 for (i = 0; i < session->internals.priorities.protocol.algorithms; i++)
1308 {
1309 if (session->internals.priorities.protocol.priority[i] < min)
1310 min = session->internals.priorities.protocol.priority[i];
1311 }
1312
1313 if (min == 0xff)
1314 return GNUTLS_VERSION_UNKNOWN; /* unknown version */
1315
1316 return min;
1317}
1318
1319gnutls_protocol_t
1320_gnutls_version_max (gnutls_session_t session)
1321{ /* returns the maximum version supported */
1322 unsigned int i, max = 0x00;
1323
1324 if (session->internals.priorities.protocol.priority == NULL)
1325 {
1326 return GNUTLS_VERSION_UNKNOWN;
1327 }
1328 else
1329 for (i = 0; i < session->internals.priorities.protocol.algorithms; i++)
1330 {
1331 if (session->internals.priorities.protocol.priority[i] > max)
1332 max = session->internals.priorities.protocol.priority[i];
1333 }
1334
1335 if (max == 0x00)
1336 return GNUTLS_VERSION_UNKNOWN; /* unknown version */
1337
1338 return max;
1339}
1340
1341/**
1342 * gnutls_protocol_get_name - Returns a string with the name of the specified SSL/TLS version
1343 * @version: is a (gnutls) version number
1344 *
1345 * Returns: a string that contains the name of the specified TLS
1346 * version (e.g., "TLS 1.0"), or %NULL.
1347 **/
1348const char *
1349gnutls_protocol_get_name (gnutls_protocol_t version)
1350{
1351 const char *ret = NULL;
1352
1353 /* avoid prefix */
1354 GNUTLS_VERSION_ALG_LOOP (ret = p->name);
1355 return ret;
1356}
1357
1358/**
1359 * gnutls_protocol_get_id - Returns the gnutls id of the specified in string protocol
1360 * @algorithm: is a protocol name
1361 *
1362 * The names are compared in a case insensitive way.
1363 *
1364 * Returns: an id of the specified protocol, or
1365 * %GNUTLS_VERSION_UNKNOWN on error.
1366 **/
1367gnutls_protocol_t
1368gnutls_protocol_get_id (const char *name)
1369{
1370 gnutls_protocol_t ret = GNUTLS_VERSION_UNKNOWN;
1371
1372 GNUTLS_VERSION_LOOP (if (strcasecmp (p->name, name) == 0) ret = p->id)
1373 ;
1374
1375 return ret;
1376}
1377
1378/**
1379 * gnutls_protocol_list:
1380 *
1381 * Get a list of supported protocols, e.g. SSL 3.0, TLS 1.0 etc.
1382 *
1383 * Returns: a zero-terminated list of %gnutls_protocol_t integers
1384 * indicating the available protocols.
1385 *
1386 **/
1387const gnutls_protocol_t *
1388gnutls_protocol_list (void)
1389{
1390 return supported_protocols;
1391}
1392
1393int
1394_gnutls_version_get_minor (gnutls_protocol_t version)
1395{
1396 int ret = -1;
1397
1398 GNUTLS_VERSION_ALG_LOOP (ret = p->minor);
1399 return ret;
1400}
1401
1402gnutls_protocol_t
1403_gnutls_version_get (int major, int minor)
1404{
1405 int ret = -1;
1406
1407 GNUTLS_VERSION_LOOP (if ((p->major == major) && (p->minor == minor))
1408 ret = p->id)
1409 ;
1410 return ret;
1411}
1412
1413int
1414_gnutls_version_get_major (gnutls_protocol_t version)
1415{
1416 int ret = -1;
1417
1418 GNUTLS_VERSION_ALG_LOOP (ret = p->major);
1419 return ret;
1420}
1421
1422/* Version Functions */
1423
1424int
1425_gnutls_version_is_supported (gnutls_session_t session,
1426 const gnutls_protocol_t version)
1427{
1428 int ret = 0;
1429
1430 GNUTLS_VERSION_ALG_LOOP (ret = p->supported);
1431 if (ret == 0)
1432 return 0;
1433
1434 if (_gnutls_version_priority (session, version) < 0)
1435 return 0; /* disabled by the user */
1436 else
1437 return 1;
1438}
1439
1440/* Type to KX mappings */
1441gnutls_kx_algorithm_t
1442_gnutls_map_kx_get_kx (gnutls_credentials_type_t type, int server)
1443{
1444 gnutls_kx_algorithm_t ret = -1;
1445
1446 if (server)
1447 {
1448 GNUTLS_KX_MAP_ALG_LOOP_SERVER (ret = p->algorithm);
1449 }
1450 else
1451 {
1452 GNUTLS_KX_MAP_ALG_LOOP_SERVER (ret = p->algorithm);
1453 }
1454 return ret;
1455}
1456
1457gnutls_credentials_type_t
1458_gnutls_map_kx_get_cred (gnutls_kx_algorithm_t algorithm, int server)
1459{
1460 gnutls_credentials_type_t ret = -1;
1461 if (server)
1462 {
1463 GNUTLS_KX_MAP_LOOP (if (p->algorithm == algorithm) ret = p->server_type)
1464 ;
1465 }
1466 else
1467 {
1468 GNUTLS_KX_MAP_LOOP (if (p->algorithm == algorithm) ret = p->client_type)
1469 ;
1470 }
1471
1472 return ret;
1473}
1474
1475/* Cipher Suite's functions */
1476gnutls_cipher_algorithm_t
1477_gnutls_cipher_suite_get_cipher_algo (const cipher_suite_st * suite)
1478{
1479 int ret = 0;
1480 GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->block_algorithm);
1481 return ret;
1482}
1483
1484gnutls_protocol_t
1485_gnutls_cipher_suite_get_version (const cipher_suite_st * suite)
1486{
1487 int ret = 0;
1488 GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->version);
1489 return ret;
1490}
1491
1492gnutls_kx_algorithm_t
1493_gnutls_cipher_suite_get_kx_algo (const cipher_suite_st * suite)
1494{
1495 int ret = 0;
1496
1497 GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->kx_algorithm);
1498 return ret;
1499
1500}
1501
1502gnutls_mac_algorithm_t
1503_gnutls_cipher_suite_get_mac_algo (const cipher_suite_st * suite)
1504{ /* In bytes */
1505 int ret = 0;
1506 GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->mac_algorithm);
1507 return ret;
1508
1509}
1510
1511const char *
1512_gnutls_cipher_suite_get_name (cipher_suite_st * suite)
1513{
1514 const char *ret = NULL;
1515
1516 /* avoid prefix */
1517 GNUTLS_CIPHER_SUITE_ALG_LOOP (ret = p->name + sizeof ("GNUTLS_") - 1);
1518
1519 return ret;
1520}
1521
1522/**
1523 * gnutls_cipher_suite_get_name - Returns a string with the name of the specified cipher suite
1524 * @kx_algorithm: is a Key exchange algorithm
1525 * @cipher_algorithm: is a cipher algorithm
1526 * @mac_algorithm: is a MAC algorithm
1527 *
1528 * Note that the full cipher suite name must be prepended by TLS or
1529 * SSL depending of the protocol in use.
1530 *
1531 * Returns: a string that contains the name of a TLS cipher suite,
1532 * specified by the given algorithms, or %NULL.
1533 **/
1534const char *
1535gnutls_cipher_suite_get_name (gnutls_kx_algorithm_t kx_algorithm,
1536 gnutls_cipher_algorithm_t cipher_algorithm,
1537 gnutls_mac_algorithm_t mac_algorithm)
1538{
1539 const char *ret = NULL;
1540
1541 /* avoid prefix */
1542 GNUTLS_CIPHER_SUITE_LOOP (if (kx_algorithm == p->kx_algorithm &&
1543 cipher_algorithm == p->block_algorithm &&
1544 mac_algorithm == p->mac_algorithm)
1545 ret = p->name + sizeof ("GNUTLS_") - 1)
1546 ;
1547
1548 return ret;
1549}
1550
1551/**
1552 * gnutls_cipher_suite_info:
1553 * @idx: index of cipher suite to get information about, starts on 0.
1554 * @cs_id: output buffer with room for 2 bytes, indicating cipher suite value
1555 * @kx: output variable indicating key exchange algorithm, or %NULL.
1556 * @cipher: output variable indicating cipher, or %NULL.
1557 * @mac: output variable indicating MAC algorithm, or %NULL.
1558 * @version: output variable indicating TLS protocol version, or %NULL.
1559 *
1560 * Get information about supported cipher suites. Use the function
1561 * iteratively to get information about all supported cipher suites.
1562 * Call with idx=0 to get information about first cipher suite, then
1563 * idx=1 and so on until the function returns NULL.
1564 *
1565 * Returns: the name of @idx cipher suite, and set the information
1566 * about the cipher suite in the output variables. If @idx is out of
1567 * bounds, %NULL is returned.
1568 **/
1569const char *
1570gnutls_cipher_suite_info (size_t idx,
1571 char *cs_id,
1572 gnutls_kx_algorithm_t * kx,
1573 gnutls_cipher_algorithm_t * cipher,
1574 gnutls_mac_algorithm_t * mac,
1575 gnutls_protocol_t * version)
1576{
1577 if (idx >= CIPHER_SUITES_COUNT)
1578 return NULL;
1579
1580 if (cs_id)
1581 memcpy (cs_id, cs_algorithms[idx].id.suite, 2);
1582 if (kx)
1583 *kx = cs_algorithms[idx].kx_algorithm;
1584 if (cipher)
1585 *cipher = cs_algorithms[idx].block_algorithm;
1586 if (mac)
1587 *mac = cs_algorithms[idx].mac_algorithm;
1588 if (version)
1589 *version = cs_algorithms[idx].version;
1590
1591 return cs_algorithms[idx].name + sizeof ("GNU") - 1;
1592}
1593
1594static inline int
1595_gnutls_cipher_suite_is_ok (cipher_suite_st * suite)
1596{
1597 size_t ret;
1598 const char *name = NULL;
1599
1600 GNUTLS_CIPHER_SUITE_ALG_LOOP (name = p->name);
1601 if (name != NULL)
1602 ret = 0;
1603 else
1604 ret = 1;
1605 return ret;
1606
1607}
1608
1609#define SWAP(x, y) memcpy(tmp,x,size); \
1610 memcpy(x,y,size); \
1611 memcpy(y,tmp,size);
1612
1613#define MAX_ELEM_SIZE 4
1614static inline int
1615_gnutls_partition (gnutls_session_t session,
1616 void *_base,
1617 size_t nmemb,
1618 size_t size,
1619 int (*compar) (gnutls_session_t,
1620 const void *, const void *))
1621{
1622 uint8_t *base = _base;
1623 uint8_t tmp[MAX_ELEM_SIZE];
1624 uint8_t ptmp[MAX_ELEM_SIZE];
1625 unsigned int pivot;
1626 unsigned int i, j;
1627 unsigned int full;
1628
1629 i = pivot = 0;
1630 j = full = (nmemb - 1) * size;
1631
1632 memcpy (ptmp, &base[0], size); /* set pivot item */
1633
1634 while (i < j)
1635 {
1636 while ((compar (session, &base[i], ptmp) <= 0) && (i < full))
1637 {
1638 i += size;
1639 }
1640 while ((compar (session, &base[j], ptmp) >= 0) && (j > 0))
1641 j -= size;
1642
1643 if (i < j)
1644 {
1645 SWAP (&base[j], &base[i]);
1646 }
1647 }
1648
1649 if (j > pivot)
1650 {
1651 SWAP (&base[pivot], &base[j]);
1652 pivot = j;
1653 }
1654 else if (i < pivot)
1655 {
1656 SWAP (&base[pivot], &base[i]);
1657 pivot = i;
1658 }
1659 return pivot / size;
1660}
1661
1662static void
1663_gnutls_qsort (gnutls_session_t session,
1664 void *_base,
1665 size_t nmemb,
1666 size_t size,
1667 int (*compar) (gnutls_session_t, const void *, const void *))
1668{
1669 unsigned int pivot;
1670 char *base = _base;
1671 size_t snmemb = nmemb;
1672
1673#ifdef DEBUG
1674 if (size > MAX_ELEM_SIZE)
1675 {
1676 gnutls_assert ();
1677 _gnutls_debug_log ("QSORT BUG\n");
1678 exit (1);
1679 }
1680#endif
1681
1682 if (snmemb <= 1)
1683 return;
1684 pivot = _gnutls_partition (session, _base, nmemb, size, compar);
1685
1686 _gnutls_qsort (session, base, pivot < nmemb ? pivot + 1
1687 : pivot, size, compar);
1688 _gnutls_qsort (session, &base[(pivot + 1) * size], nmemb - pivot - 1, size,
1689 compar);
1690}
1691
1692/* a compare function for KX algorithms (using priorities).
1693 * For use with qsort
1694 */
1695static int
1696_gnutls_compare_algo (gnutls_session_t session,
1697 const void *i_A1, const void *i_A2)
1698{
1699 gnutls_kx_algorithm_t kA1 =
1700 _gnutls_cipher_suite_get_kx_algo ((const cipher_suite_st *) i_A1);
1701 gnutls_kx_algorithm_t kA2 =
1702 _gnutls_cipher_suite_get_kx_algo ((const cipher_suite_st *) i_A2);
1703 gnutls_cipher_algorithm_t cA1 =
1704 _gnutls_cipher_suite_get_cipher_algo ((const cipher_suite_st *) i_A1);
1705 gnutls_cipher_algorithm_t cA2 =
1706 _gnutls_cipher_suite_get_cipher_algo ((const cipher_suite_st *) i_A2);
1707 gnutls_mac_algorithm_t mA1 =
1708 _gnutls_cipher_suite_get_mac_algo ((const cipher_suite_st *) i_A1);
1709 gnutls_mac_algorithm_t mA2 =
1710 _gnutls_cipher_suite_get_mac_algo ((const cipher_suite_st *) i_A2);
1711
1712 int p1 = (_gnutls_kx_priority (session, kA1) + 1) * 64;
1713 int p2 = (_gnutls_kx_priority (session, kA2) + 1) * 64;
1714 p1 += (_gnutls_cipher_priority (session, cA1) + 1) * 8;
1715 p2 += (_gnutls_cipher_priority (session, cA2) + 1) * 8;
1716 p1 += _gnutls_mac_priority (session, mA1);
1717 p2 += _gnutls_mac_priority (session, mA2);
1718
1719 if (p1 > p2)
1720 {
1721 return 1;
1722 }
1723 else
1724 {
1725 if (p1 == p2)
1726 {
1727 return 0;
1728 }
1729 return -1;
1730 }
1731}
1732
1733#ifdef SORT_DEBUG
1734static void
1735_gnutls_bsort (gnutls_session_t session, void *_base, size_t nmemb,
1736 size_t size, int (*compar) (gnutls_session_t, const void *,
1737 const void *))
1738{
1739 unsigned int i, j;
1740 int full = nmemb * size;
1741 char *base = _base;
1742 char tmp[MAX_ELEM_SIZE];
1743
1744 for (i = 0; i < full; i += size)
1745 {
1746 for (j = 0; j < full; j += size)
1747 {
1748 if (compar (session, &base[i], &base[j]) < 0)
1749 {
1750 SWAP (&base[j], &base[i]);
1751 }
1752 }
1753 }
1754
1755}
1756#endif
1757
1758int
1759_gnutls_supported_ciphersuites_sorted (gnutls_session_t session,
1760 cipher_suite_st ** ciphers)
1761{
1762
1763#ifdef SORT_DEBUG
1764 unsigned int i;
1765#endif
1766 int count;
1767
1768 count = _gnutls_supported_ciphersuites (session, ciphers);
1769 if (count <= 0)
1770 {
1771 gnutls_assert ();
1772 return count;
1773 }
1774#ifdef SORT_DEBUG
1775 _gnutls_debug_log ("Unsorted: \n");
1776 for (i = 0; i < count; i++)
1777 _gnutls_debug_log ("\t%d: %s\n", i,
1778 _gnutls_cipher_suite_get_name ((*ciphers)[i]));
1779#endif
1780
1781 _gnutls_qsort (session, *ciphers, count, sizeof (cipher_suite_st),
1782 _gnutls_compare_algo);
1783
1784#ifdef SORT_DEBUG
1785 _gnutls_debug_log ("Sorted: \n");
1786 for (i = 0; i < count; i++)
1787 _gnutls_debug_log ("\t%d: %s\n", i,
1788 _gnutls_cipher_suite_get_name ((*ciphers)[i]));
1789#endif
1790
1791 return count;
1792}
1793
1794int
1795_gnutls_supported_ciphersuites (gnutls_session_t session,
1796 cipher_suite_st ** _ciphers)
1797{
1798
1799 unsigned int i, ret_count, j;
1800 unsigned int count = CIPHER_SUITES_COUNT;
1801 cipher_suite_st *tmp_ciphers;
1802 cipher_suite_st *ciphers;
1803 gnutls_protocol_t version;
1804
1805 if (count == 0)
1806 {
1807 return 0;
1808 }
1809
1810 tmp_ciphers = gnutls_alloca (count * sizeof (cipher_suite_st));
1811 if (tmp_ciphers == NULL)
1812 return GNUTLS_E_MEMORY_ERROR;
1813
1814 ciphers = gnutls_malloc (count * sizeof (cipher_suite_st));
1815 if (ciphers == NULL)
1816 {
1817 gnutls_afree (tmp_ciphers);
1818 return GNUTLS_E_MEMORY_ERROR;
1819 }
1820
1821 version = gnutls_protocol_get_version (session);
1822
1823 for (i = 0; i < count; i++)
1824 {
1825 memcpy (&tmp_ciphers[i], &cs_algorithms[i].id,
1826 sizeof (cipher_suite_st));
1827 }
1828
1829 for (i = j = 0; i < count; i++)
1830 {
1831 /* remove private cipher suites, if requested.
1832 */
1833 if (tmp_ciphers[i].suite[0] == 0xFF && session->internals.enable_private
1834 == 0)
1835 continue;
1836
1837 /* remove cipher suites which do not support the
1838 * protocol version used.
1839 */
1840 if (_gnutls_cipher_suite_get_version (&tmp_ciphers[i]) > version)
1841 continue;
1842
1843 if (_gnutls_kx_priority (session,
1844 _gnutls_cipher_suite_get_kx_algo (&tmp_ciphers
1845 [i])) < 0)
1846 continue;
1847 if (_gnutls_mac_priority (session,
1848 _gnutls_cipher_suite_get_mac_algo
1849 (&tmp_ciphers[i])) < 0)
1850 continue;
1851 if (_gnutls_cipher_priority (session,
1852 _gnutls_cipher_suite_get_cipher_algo
1853 (&tmp_ciphers[i])) < 0)
1854 continue;
1855
1856 memcpy (&ciphers[j], &tmp_ciphers[i], sizeof (cipher_suite_st));
1857 j++;
1858 }
1859
1860 ret_count = j;
1861
1862#if 0 /* expensive */
1863 if (ret_count > 0 && ret_count != count)
1864 {
1865 ciphers =
1866 gnutls_realloc_fast (ciphers, ret_count * sizeof (cipher_suite_st));
1867 }
1868 else
1869 {
1870 if (ret_count != count)
1871 {
1872 gnutls_free (ciphers);
1873 ciphers = NULL;
1874 }
1875 }
1876#endif
1877
1878 gnutls_afree (tmp_ciphers);
1879
1880 /* This function can no longer return 0 cipher suites.
1881 * It returns an error code instead.
1882 */
1883 if (ret_count == 0)
1884 {
1885 gnutls_assert ();
1886 gnutls_free (ciphers);
1887 return GNUTLS_E_NO_CIPHER_SUITES;
1888 }
1889 *_ciphers = ciphers;
1890 return ret_count;
1891}
1892
1893/* For compression */
1894
1895#define MIN_PRIVATE_COMP_ALGO 0xEF
1896
1897/* returns the TLS numbers of the compression methods we support
1898 */
1899#define SUPPORTED_COMPRESSION_METHODS session->internals.priorities.compression.algorithms
1900int
1901_gnutls_supported_compression_methods (gnutls_session_t session,
1902 uint8_t ** comp)
1903{
1904 unsigned int i, j;
1905
1906 *comp = gnutls_malloc (sizeof (uint8_t) * SUPPORTED_COMPRESSION_METHODS);
1907 if (*comp == NULL)
1908 return GNUTLS_E_MEMORY_ERROR;
1909
1910 for (i = j = 0; i < SUPPORTED_COMPRESSION_METHODS; i++)
1911 {
1912 int tmp = _gnutls_compression_get_num (session->internals.priorities.
1913 compression.priority[i]);
1914
1915 /* remove private compression algorithms, if requested.
1916 */
1917 if (tmp == -1 || (tmp >= MIN_PRIVATE_COMP_ALGO
1918 && session->internals.enable_private == 0))
1919 {
1920 gnutls_assert ();
1921 continue;
1922 }
1923
1924 (*comp)[j] = (uint8_t) tmp;
1925 j++;
1926 }
1927
1928 if (j == 0)
1929 {
1930 gnutls_assert ();
1931 gnutls_free (*comp);
1932 *comp = NULL;
1933 return GNUTLS_E_NO_COMPRESSION_ALGORITHMS;
1934 }
1935 return j;
1936}
1937
1938/**
1939 * gnutls_certificate_type_get_name - Returns a string with the name of the specified certificate type
1940 * @type: is a certificate type
1941 *
1942 * Returns: a string (or %NULL) that contains the name of the
1943 * specified certificate type.
1944 **/
1945const char *
1946gnutls_certificate_type_get_name (gnutls_certificate_type_t type)
1947{
1948 const char *ret = NULL;
1949
1950 if (type == GNUTLS_CRT_X509)
1951 ret = "X.509";
1952 if (type == GNUTLS_CRT_OPENPGP)
1953 ret = "OPENPGP";
1954
1955 return ret;
1956}
1957
1958/**
1959 * gnutls_certificate_type_get_id - Returns the gnutls id of the specified in string type
1960 * @name: is a certificate type name
1961 *
1962 * The names are compared in a case insensitive way.
1963 *
1964 * Returns: an id of the specified in a string certificate type, or
1965 * %GNUTLS_CRT_UNKNOWN on error.
1966 **/
1967gnutls_certificate_type_t
1968gnutls_certificate_type_get_id (const char *name)
1969{
1970 gnutls_certificate_type_t ret = GNUTLS_CRT_UNKNOWN;
1971
1972 if (strcasecmp (name, "X.509") == 0 || strcasecmp (name, "X509") == 0)
1973 return GNUTLS_CRT_X509;
1974 if (strcasecmp (name, "OPENPGP") == 0)
1975 return GNUTLS_CRT_OPENPGP;
1976
1977 return ret;
1978}
1979
1980static const gnutls_certificate_type_t supported_certificate_types[] =
1981 { GNUTLS_CRT_X509,
1982 GNUTLS_CRT_OPENPGP,
1983 0
1984};
1985
1986/**
1987 * gnutls_certificate_type_list:
1988 *
1989 * Get a list of certificate types. Note that to be able to use
1990 * OpenPGP certificates, you must link to libgnutls-extra and call
1991 * gnutls_global_init_extra().
1992 *
1993 * Returns: a zero-terminated list of %gnutls_certificate_type_t
1994 * integers indicating the available certificate types.
1995 *
1996 **/
1997const gnutls_certificate_type_t *
1998gnutls_certificate_type_list (void)
1999{
2000 return supported_certificate_types;
2001}
2002
2003/* returns the gnutls_pk_algorithm_t which is compatible with
2004 * the given gnutls_kx_algorithm_t.
2005 */
2006gnutls_pk_algorithm_t
2007_gnutls_map_pk_get_pk (gnutls_kx_algorithm_t kx_algorithm)
2008{
2009 gnutls_pk_algorithm_t ret = -1;
2010
2011 GNUTLS_PK_MAP_ALG_LOOP (ret = p->pk_algorithm) return ret;
2012}
2013
2014/* Returns the encipher type for the given key exchange algorithm.
2015 * That one of CIPHER_ENCRYPT, CIPHER_SIGN, CIPHER_IGN.
2016 *
2017 * ex. GNUTLS_KX_RSA requires a certificate able to encrypt... so returns CIPHER_ENCRYPT.
2018 */
2019enum encipher_type
2020_gnutls_kx_encipher_type (gnutls_kx_algorithm_t kx_algorithm)
2021{
2022 int ret = CIPHER_IGN;
2023 GNUTLS_PK_MAP_ALG_LOOP (ret = p->encipher_type) return ret;
2024
2025}
2026
2027/* signature algorithms;
2028 */
2029struct gnutls_sign_entry
2030{
2031 const char *name;
2032 const char *oid;
2033 gnutls_sign_algorithm_t id;
2034 gnutls_pk_algorithm_t pk;
2035 gnutls_mac_algorithm_t mac;
2036};
2037typedef struct gnutls_sign_entry gnutls_sign_entry;
2038
2039static const gnutls_sign_entry sign_algorithms[] = {
2040 {"RSA-SHA",
2041 SIG_RSA_SHA1_OID,
2042 GNUTLS_SIGN_RSA_SHA1,
2043 GNUTLS_PK_RSA,
2044 GNUTLS_MAC_SHA1},
2045 {"RSA-SHA256",
2046 SIG_RSA_SHA256_OID,
2047 GNUTLS_SIGN_RSA_SHA256,
2048 GNUTLS_PK_RSA,
2049 GNUTLS_MAC_SHA256},
2050 {"RSA-MD5",
2051 SIG_RSA_MD5_OID,
2052 GNUTLS_SIGN_RSA_MD5,
2053 GNUTLS_PK_RSA,
2054 GNUTLS_MAC_MD5},
2055 {"GOST R 34.10-2001",
2056 SIG_GOST_R3410_2001_OID,
2057 0,
2058 0,
2059 0},
2060 {"GOST R 34.10-94",
2061 SIG_GOST_R3410_94_OID,
2062 0,
2063 0,
2064 0},
2065 {0,
2066 0,
2067 0,
2068 0,
2069 0}
2070};
2071
2072#define GNUTLS_SIGN_LOOP(b) \
2073 do { \
2074 const gnutls_sign_entry *p; \
2075 for(p = sign_algorithms; p->name != NULL; p++) { b ; } \
2076 } while (0)
2077
2078#define GNUTLS_SIGN_ALG_LOOP(a) \
2079 GNUTLS_SIGN_LOOP( if(p->id && p->id == sign) { a; break; } )
2080
2081/**
2082 * gnutls_sign_algorithm_get_name - Returns a string with the name of the specified sign algorithm
2083 * @algorithm: is a sign algorithm
2084 *
2085 * Returns: a string that contains the name of the specified sign
2086 * algorithm, or %NULL.
2087 **/
2088const char *
2089gnutls_sign_algorithm_get_name (gnutls_sign_algorithm_t sign)
2090{
2091 const char *ret = NULL;
2092
2093 /* avoid prefix */
2094 GNUTLS_SIGN_ALG_LOOP (ret = p->name);
2095
2096 return ret;
2097}
2098
2099gnutls_sign_algorithm_t
2100_gnutls_x509_oid2sign_algorithm (const char *oid)
2101{
2102 gnutls_sign_algorithm_t ret = 0;
2103
2104 GNUTLS_SIGN_LOOP (if (strcmp (oid, p->oid) == 0)
2105 {
2106 ret = p->id; break;}
2107 );
2108
2109 if (ret == 0)
2110 {
2111 _gnutls_x509_log ("Unknown SIGN OID: '%s'\n", oid);
2112 return GNUTLS_SIGN_UNKNOWN;
2113 }
2114 return ret;
2115}
2116
2117gnutls_sign_algorithm_t
2118_gnutls_x509_pk_to_sign (gnutls_pk_algorithm_t pk, gnutls_mac_algorithm_t mac)
2119{
2120 gnutls_sign_algorithm_t ret = 0;
2121
2122 GNUTLS_SIGN_LOOP (if (pk == p->pk && mac == p->mac)
2123 {
2124 ret = p->id; break;}
2125 );
2126
2127 if (ret == 0)
2128 return GNUTLS_SIGN_UNKNOWN;
2129 return ret;
2130}
2131
2132const char *
2133_gnutls_x509_sign_to_oid (gnutls_pk_algorithm_t pk,
2134 gnutls_mac_algorithm_t mac)
2135{
2136 gnutls_sign_algorithm_t sign;
2137 const char *ret = NULL;
2138
2139 sign = _gnutls_x509_pk_to_sign (pk, mac);
2140 if (sign == GNUTLS_SIGN_UNKNOWN)
2141 return NULL;
2142
2143 GNUTLS_SIGN_ALG_LOOP (ret = p->oid);
2144 return ret;
2145}
2146
2147/* pk algorithms;
2148 */
2149struct gnutls_pk_entry
2150{
2151 const char *name;
2152 const char *oid;
2153 gnutls_pk_algorithm_t id;
2154};
2155typedef struct gnutls_pk_entry gnutls_pk_entry;
2156
2157static const gnutls_pk_entry pk_algorithms[] = {
2158 {"RSA",
2159 PK_PKIX1_RSA_OID,
2160 GNUTLS_PK_RSA},
2161 {"GOST R 34.10-2001",
2162 PK_GOST_R3410_2001_OID,
2163 0},
2164 {"GOST R 34.10-94",
2165 PK_GOST_R3410_94_OID,
2166 0},
2167 {0,
2168 0,
2169 0}
2170};
2171
2172/**
2173 * gnutls_pk_algorithm_get_name - Returns a string with the name of the specified public key algorithm
2174 * @algorithm: is a pk algorithm
2175 *
2176 * Returns: a string that contains the name of the specified public
2177 * key algorithm, or %NULL.
2178 **/
2179const char *
2180gnutls_pk_algorithm_get_name (gnutls_pk_algorithm_t algorithm)
2181{
2182 const char *ret = NULL;
2183 const gnutls_pk_entry *p;
2184
2185 for (p = pk_algorithms; p->name != NULL; p++)
2186 if (p->id && p->id == algorithm)
2187 {
2188 ret = p->name;
2189 break;
2190 }
2191
2192 return ret;
2193}
2194
2195gnutls_pk_algorithm_t
2196_gnutls_x509_oid2pk_algorithm (const char *oid)
2197{
2198 gnutls_pk_algorithm_t ret = GNUTLS_PK_UNKNOWN;
2199 const gnutls_pk_entry *p;
2200
2201 for (p = pk_algorithms; p->name != NULL; p++)
2202 if (strcmp (p->oid, oid) == 0)
2203 {
2204 ret = p->id;
2205 break;
2206 }
2207
2208 return ret;
2209}
2210
2211const char *
2212_gnutls_x509_pk_to_oid (gnutls_pk_algorithm_t algorithm)
2213{
2214 const char *ret = NULL;
2215 const gnutls_pk_entry *p;
2216
2217 for (p = pk_algorithms; p->name != NULL; p++)
2218 if (p->id == algorithm)
2219 {
2220 ret = p->oid;
2221 break;
2222 }
2223
2224 return ret;
2225}
diff --git a/src/daemon/https/tls/gnutls_algorithms.h b/src/daemon/https/tls/gnutls_algorithms.h
new file mode 100644
index 00000000..fd23ef0a
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_algorithms.h
@@ -0,0 +1,141 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#ifndef ALGORITHMS_H
26# define ALGORITHMS_H
27
28#include "gnutls_auth.h"
29
30/* Functions for version handling. */
31gnutls_protocol_t _gnutls_version_lowest (gnutls_session_t session);
32gnutls_protocol_t _gnutls_version_max (gnutls_session_t session);
33int _gnutls_version_priority (gnutls_session_t session,
34 gnutls_protocol_t version);
35int _gnutls_version_is_supported (gnutls_session_t session,
36 const gnutls_protocol_t version);
37int _gnutls_version_get_major (gnutls_protocol_t ver);
38int _gnutls_version_get_minor (gnutls_protocol_t ver);
39gnutls_protocol_t _gnutls_version_get (int major, int minor);
40
41/* Functions for MACs. */
42int _gnutls_mac_is_ok (gnutls_mac_algorithm_t algorithm);
43gnutls_mac_algorithm_t _gnutls_x509_oid2mac_algorithm (const char *oid);
44const char *_gnutls_x509_mac_to_oid (gnutls_mac_algorithm_t mac);
45
46/* Functions for cipher suites. */
47int _gnutls_supported_ciphersuites (gnutls_session_t session,
48 cipher_suite_st ** ciphers);
49int _gnutls_supported_ciphersuites_sorted (gnutls_session_t session,
50 cipher_suite_st ** ciphers);
51int _gnutls_supported_compression_methods (gnutls_session_t session,
52 uint8_t ** comp);
53const char *_gnutls_cipher_suite_get_name (cipher_suite_st * algorithm);
54gnutls_cipher_algorithm_t _gnutls_cipher_suite_get_cipher_algo (const
55 cipher_suite_st
56 * algorithm);
57gnutls_kx_algorithm_t _gnutls_cipher_suite_get_kx_algo (const cipher_suite_st
58 * algorithm);
59gnutls_mac_algorithm_t _gnutls_cipher_suite_get_mac_algo (const
60 cipher_suite_st *
61 algorithm);
62gnutls_protocol_t _gnutls_cipher_suite_get_version (const cipher_suite_st *
63 algorithm);
64cipher_suite_st _gnutls_cipher_suite_get_suite_name (cipher_suite_st *
65 algorithm);
66
67/* Functions for ciphers. */
68int _gnutls_cipher_get_block_size (gnutls_cipher_algorithm_t algorithm);
69int _gnutls_cipher_is_block (gnutls_cipher_algorithm_t algorithm);
70int _gnutls_cipher_is_ok (gnutls_cipher_algorithm_t algorithm);
71int _gnutls_cipher_get_iv_size (gnutls_cipher_algorithm_t algorithm);
72int _gnutls_cipher_get_export_flag (gnutls_cipher_algorithm_t algorithm);
73
74/* Functions for key exchange. */
75int _gnutls_kx_needs_dh_params (gnutls_kx_algorithm_t algorithm);
76int _gnutls_kx_needs_rsa_params (gnutls_kx_algorithm_t algorithm);
77mod_auth_st *_gnutls_kx_auth_struct (gnutls_kx_algorithm_t algorithm);
78int _gnutls_kx_is_ok (gnutls_kx_algorithm_t algorithm);
79
80/* Functions for compression. */
81int _gnutls_compression_is_ok (gnutls_compression_method_t algorithm);
82int _gnutls_compression_get_num (gnutls_compression_method_t algorithm);
83gnutls_compression_method_t _gnutls_compression_get_id (int num);
84int _gnutls_compression_get_mem_level (gnutls_compression_method_t algorithm);
85int _gnutls_compression_get_comp_level (gnutls_compression_method_t
86 algorithm);
87int _gnutls_compression_get_wbits (gnutls_compression_method_t algorithm);
88
89/* Type to KX mappings. */
90gnutls_kx_algorithm_t _gnutls_map_kx_get_kx (gnutls_credentials_type_t type,
91 int server);
92gnutls_credentials_type_t _gnutls_map_kx_get_cred (gnutls_kx_algorithm_t
93 algorithm, int server);
94
95/* KX to PK mapping. */
96gnutls_pk_algorithm_t _gnutls_map_pk_get_pk (gnutls_kx_algorithm_t
97 kx_algorithm);
98gnutls_pk_algorithm_t _gnutls_x509_oid2pk_algorithm (const char *oid);
99const char *_gnutls_x509_pk_to_oid (gnutls_pk_algorithm_t pk);
100
101enum encipher_type
102{ CIPHER_ENCRYPT = 0, CIPHER_SIGN = 1, CIPHER_IGN };
103
104enum encipher_type _gnutls_kx_encipher_type (gnutls_kx_algorithm_t algorithm);
105
106struct gnutls_compression_entry
107{
108 const char *name;
109 gnutls_compression_method_t id;
110 int num; /* the number reserved in TLS for the specific compression method */
111
112 /* used in zlib compressor */
113 int window_bits;
114 int mem_level;
115 int comp_level;
116};
117typedef struct gnutls_compression_entry gnutls_compression_entry;
118
119/* Functions for sign algorithms. */
120gnutls_sign_algorithm_t _gnutls_x509_oid2sign_algorithm (const char *oid);
121gnutls_sign_algorithm_t _gnutls_x509_pk_to_sign (gnutls_pk_algorithm_t pk,
122 gnutls_mac_algorithm_t mac);
123const char *_gnutls_x509_sign_to_oid (gnutls_pk_algorithm_t,
124 gnutls_mac_algorithm_t mac);
125
126int _gnutls_mac_priority (gnutls_session_t session,
127 gnutls_mac_algorithm_t algorithm);
128int _gnutls_cipher_priority (gnutls_session_t session,
129 gnutls_cipher_algorithm_t algorithm);
130int _gnutls_kx_priority (gnutls_session_t session,
131 gnutls_kx_algorithm_t algorithm);
132int _gnutls_compression_priority (gnutls_session_t session,
133 gnutls_compression_method_t algorithm);
134
135gnutls_mac_algorithm_t gnutls_mac_get_id (const char* name);
136gnutls_cipher_algorithm_t gnutls_cipher_get_id (const char* name);
137gnutls_kx_algorithm_t gnutls_kx_get_id (const char* name);
138gnutls_protocol_t gnutls_protocol_get_id (const char* name);
139gnutls_certificate_type_t gnutls_certificate_type_get_id (const char* name);
140
141#endif
diff --git a/src/daemon/https/tls/gnutls_anon_cred.c b/src/daemon/https/tls/gnutls_anon_cred.c
new file mode 100644
index 00000000..919315ef
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_anon_cred.c
@@ -0,0 +1,137 @@
1/*
2 * Copyright (C) 2001, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include "gnutls_int.h"
26
27#ifdef ENABLE_ANON
28
29#include "gnutls_errors.h"
30#include "auth_anon.h"
31#include "gnutls_auth_int.h"
32#include "gnutls_dh.h"
33#include "gnutls_num.h"
34#include "gnutls_mpi.h"
35
36static const int anon_dummy;
37
38/**
39 * gnutls_anon_free_server_credentials - Used to free an allocated gnutls_anon_server_credentials_t structure
40 * @sc: is an #gnutls_anon_server_credentials_t structure.
41 *
42 * This structure is complex enough to manipulate directly thus this
43 * helper function is provided in order to free (deallocate) it.
44 **/
45void
46gnutls_anon_free_server_credentials (gnutls_anon_server_credentials_t sc)
47{
48
49 gnutls_free (sc);
50}
51
52/**
53 * gnutls_anon_allocate_server_credentials - Used to allocate an gnutls_anon_server_credentials_t structure
54 * @sc: is a pointer to an #gnutls_anon_server_credentials_t structure.
55 *
56 * This structure is complex enough to manipulate directly thus this
57 * helper function is provided in order to allocate it.
58 *
59 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
60 **/
61int
62gnutls_anon_allocate_server_credentials (gnutls_anon_server_credentials_t *
63 sc)
64{
65
66 *sc = gnutls_calloc (1, sizeof (anon_server_credentials_st));
67
68 return 0;
69}
70
71
72/**
73 * gnutls_anon_free_client_credentials - Used to free an allocated gnutls_anon_client_credentials_t structure
74 * @sc: is an #gnutls_anon_client_credentials_t structure.
75 *
76 * This structure is complex enough to manipulate directly thus this
77 * helper function is provided in order to free (deallocate) it.
78 **/
79void
80gnutls_anon_free_client_credentials (gnutls_anon_client_credentials_t sc)
81{
82}
83
84/**
85 * gnutls_anon_allocate_client_credentials - Used to allocate a credentials structure
86 * @sc: is a pointer to an #gnutls_anon_client_credentials_t structure.
87 *
88 * This structure is complex enough to manipulate directly thus
89 * this helper function is provided in order to allocate it.
90 *
91 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
92 **/
93int
94gnutls_anon_allocate_client_credentials (gnutls_anon_client_credentials_t *
95 sc)
96{
97 /* anon_dummy is only there for *sc not to be null.
98 * it is not used at all;
99 */
100 *sc = (void *) &anon_dummy;
101
102 return 0;
103}
104
105/**
106 * gnutls_anon_set_server_dh_params - This function will set the DH parameters for a server to use
107 * @res: is a gnutls_anon_server_credentials_t structure
108 * @dh_params: is a structure that holds diffie hellman parameters.
109 *
110 * This function will set the diffie hellman parameters for an
111 * anonymous server to use. These parameters will be used in
112 * Anonymous Diffie Hellman cipher suites.
113 **/
114void
115gnutls_anon_set_server_dh_params (gnutls_anon_server_credentials_t res,
116 gnutls_dh_params_t dh_params)
117{
118 res->dh_params = dh_params;
119}
120
121/**
122 * gnutls_anon_set_server_params_function - This function will set the DH parameters callback
123 * @res: is a gnutls_certificate_credentials_t structure
124 * @func: is the function to be called
125 *
126 * This function will set a callback in order for the server to get
127 * the diffie hellman parameters for anonymous authentication. The
128 * callback should return zero on success.
129 **/
130void
131gnutls_anon_set_server_params_function (gnutls_anon_server_credentials_t res,
132 gnutls_params_function * func)
133{
134 res->params_func = func;
135}
136
137#endif
diff --git a/src/daemon/https/tls/gnutls_asn1_tab.c b/src/daemon/https/tls/gnutls_asn1_tab.c
new file mode 100644
index 00000000..cabea4e1
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_asn1_tab.c
@@ -0,0 +1,63 @@
1#if HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <libtasn1.h>
6
7extern const ASN1_ARRAY_TYPE gnutls_asn1_tab[] = {
8 {"GNUTLS", 536872976, 0},
9 {0, 1073741836, 0},
10 {"RSAPublicKey", 1610612741, 0},
11 {"modulus", 1073741827, 0},
12 {"publicExponent", 3, 0},
13 {"RSAPrivateKey", 1610612741, 0},
14 {"version", 1073741826, "Version"},
15 {"modulus", 1073741827, 0},
16 {"publicExponent", 1073741827, 0},
17 {"privateExponent", 1073741827, 0},
18 {"prime1", 1073741827, 0},
19 {"prime2", 1073741827, 0},
20 {"exponent1", 1073741827, 0},
21 {"exponent2", 1073741827, 0},
22 {"coefficient", 1073741827, 0},
23 {"otherPrimeInfos", 16386, "OtherPrimeInfos"},
24 {"Version", 1610874883, 0},
25 {"two-prime", 1073741825, "0"},
26 {"multi", 1, "1"},
27 {"OtherPrimeInfos", 1612709899, 0},
28 {"MAX", 1074266122, "1"},
29 {0, 2, "OtherPrimeInfo"},
30 {"OtherPrimeInfo", 1610612741, 0},
31 {"prime", 1073741827, 0},
32 {"exponent", 1073741827, 0},
33 {"coefficient", 3, 0},
34 {"AlgorithmIdentifier", 1610612741, 0},
35 {"algorithm", 1073741836, 0},
36 {"parameters", 541081613, 0},
37 {"algorithm", 1, 0},
38 {"DigestInfo", 1610612741, 0},
39 {"digestAlgorithm", 1073741826, "DigestAlgorithmIdentifier"},
40 {"digest", 2, "Digest"},
41 {"DigestAlgorithmIdentifier", 1073741826, "AlgorithmIdentifier"},
42 {"Digest", 1073741831, 0},
43 {"DSAPublicKey", 1073741827, 0},
44 {"DSAParameters", 1610612741, 0},
45 {"p", 1073741827, 0},
46 {"q", 1073741827, 0},
47 {"g", 3, 0},
48 {"DSASignatureValue", 1610612741, 0},
49 {"r", 1073741827, 0},
50 {"s", 3, 0},
51 {"DSAPrivateKey", 1610612741, 0},
52 {"version", 1073741827, 0},
53 {"p", 1073741827, 0},
54 {"q", 1073741827, 0},
55 {"g", 1073741827, 0},
56 {"Y", 1073741827, 0},
57 {"priv", 3, 0},
58 {"DHParameter", 536870917, 0},
59 {"prime", 1073741827, 0},
60 {"base", 1073741827, 0},
61 {"privateValueLength", 16387, 0},
62 {0, 0, 0}
63};
diff --git a/src/daemon/https/tls/gnutls_auth.c b/src/daemon/https/tls/gnutls_auth.c
new file mode 100644
index 00000000..89640402
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_auth.c
@@ -0,0 +1,413 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include "gnutls_int.h"
26#include "gnutls_errors.h"
27#include "gnutls_auth.h"
28#include "gnutls_auth_int.h"
29#include "gnutls_algorithms.h"
30#include "auth_cert.h"
31#include <gnutls_datum.h>
32
33#include "auth_anon.h"
34/* The functions here are used in order for authentication algorithms
35 * to be able to retrieve the needed credentials eg public and private
36 * key etc.
37 */
38
39/**
40 * gnutls_credentials_clear - Clears all the credentials previously set
41 * @session: is a #gnutls_session_t structure.
42 *
43 * Clears all the credentials previously set in this session.
44 *
45 **/
46void
47gnutls_credentials_clear (gnutls_session_t session)
48{
49 if (session->key && session->key->cred)
50 { /* beginning of the list */
51 auth_cred_st *ccred, *ncred;
52 ccred = session->key->cred;
53 while (ccred != NULL)
54 {
55 ncred = ccred->next;
56 gnutls_free (ccred);
57 ccred = ncred;
58 }
59 session->key->cred = NULL;
60 }
61}
62
63/*
64 * This creates a linked list of the form:
65 * { algorithm, credentials, pointer to next }
66 */
67/**
68 * gnutls_credentials_set - Sets the needed credentials for the specified authentication algorithm.
69 * @session: is a #gnutls_session_t structure.
70 * @type: is the type of the credentials
71 * @cred: is a pointer to a structure.
72 *
73 * Sets the needed credentials for the specified type.
74 * Eg username, password - or public and private keys etc.
75 * The (void* cred) parameter is a structure that depends on the
76 * specified type and on the current session (client or server).
77 * [ In order to minimize memory usage, and share credentials between
78 * several threads gnutls keeps a pointer to cred, and not the whole cred
79 * structure. Thus you will have to keep the structure allocated until
80 * you call gnutls_deinit(). ]
81 *
82 * For GNUTLS_CRD_ANON cred should be gnutls_anon_client_credentials_t in case of a client.
83 * In case of a server it should be gnutls_anon_server_credentials_t.
84 *
85 * For GNUTLS_CRD_SRP cred should be gnutls_srp_client_credentials_t
86 * in case of a client, and gnutls_srp_server_credentials_t, in case
87 * of a server.
88 *
89 * For GNUTLS_CRD_CERTIFICATE cred should be gnutls_certificate_credentials_t.
90 *
91 **/
92int
93gnutls_credentials_set (gnutls_session_t session,
94 gnutls_credentials_type_t type, void *cred)
95{
96 auth_cred_st *ccred = NULL, *pcred = NULL;
97 int exists = 0;
98
99 if (session->key->cred == NULL)
100 { /* beginning of the list */
101
102 session->key->cred = gnutls_malloc (sizeof (auth_cred_st));
103 if (session->key->cred == NULL)
104 return GNUTLS_E_MEMORY_ERROR;
105
106 /* copy credentials locally */
107 session->key->cred->credentials = cred;
108
109 session->key->cred->next = NULL;
110 session->key->cred->algorithm = type;
111 }
112 else
113 {
114 ccred = session->key->cred;
115 while (ccred != NULL)
116 {
117 if (ccred->algorithm == type)
118 {
119 exists = 1;
120 break;
121 }
122 pcred = ccred;
123 ccred = ccred->next;
124 }
125 /* After this, pcred is not null.
126 */
127
128 if (exists == 0)
129 { /* new entry */
130 pcred->next = gnutls_malloc (sizeof (auth_cred_st));
131 if (pcred->next == NULL)
132 return GNUTLS_E_MEMORY_ERROR;
133
134 ccred = pcred->next;
135
136 /* copy credentials locally */
137 ccred->credentials = cred;
138
139 ccred->next = NULL;
140 ccred->algorithm = type;
141 }
142 else
143 { /* modify existing entry */
144 gnutls_free (ccred->credentials);
145 ccred->credentials = cred;
146 }
147 }
148
149 return 0;
150}
151
152/**
153 * gnutls_auth_get_type - Returns the type of credentials for the current authentication schema.
154 * @session: is a #gnutls_session_t structure.
155 *
156 * Returns type of credentials for the current authentication schema.
157 * The returned information is to be used to distinguish the function used
158 * to access authentication data.
159 *
160 * Eg. for CERTIFICATE ciphersuites (key exchange algorithms: KX_RSA, KX_DHE_RSA),
161 * the same function are to be used to access the authentication data.
162 **/
163gnutls_credentials_type_t
164gnutls_auth_get_type (gnutls_session_t session)
165{
166/* This is not the credentials we must set, but the authentication data
167 * we get by the peer, so it should be reversed.
168 */
169 int server = session->security_parameters.entity == GNUTLS_SERVER ? 0 : 1;
170
171 return
172 _gnutls_map_kx_get_cred (_gnutls_cipher_suite_get_kx_algo
173 (&session->security_parameters.
174 current_cipher_suite), server);
175}
176
177/**
178 * gnutls_auth_server_get_type - Returns the type of credentials for the server authentication schema.
179 * @session: is a #gnutls_session_t structure.
180 *
181 * Returns the type of credentials that were used for server authentication.
182 * The returned information is to be used to distinguish the function used
183 * to access authentication data.
184 *
185 **/
186gnutls_credentials_type_t
187gnutls_auth_server_get_type (gnutls_session_t session)
188{
189 return
190 _gnutls_map_kx_get_cred (_gnutls_cipher_suite_get_kx_algo
191 (&session->security_parameters.
192 current_cipher_suite), 1);
193}
194
195/**
196 * gnutls_auth_client_get_type - Returns the type of credentials for the client authentication schema.
197 * @session: is a #gnutls_session_t structure.
198 *
199 * Returns the type of credentials that were used for client authentication.
200 * The returned information is to be used to distinguish the function used
201 * to access authentication data.
202 *
203 **/
204gnutls_credentials_type_t
205gnutls_auth_client_get_type (gnutls_session_t session)
206{
207 return
208 _gnutls_map_kx_get_cred (_gnutls_cipher_suite_get_kx_algo
209 (&session->security_parameters.
210 current_cipher_suite), 0);
211}
212
213
214/*
215 * This returns a pointer to the linked list. Don't
216 * free that!!!
217 */
218const void *
219_gnutls_get_kx_cred (gnutls_session_t session,
220 gnutls_kx_algorithm_t algo, int *err)
221{
222 int server = session->security_parameters.entity == GNUTLS_SERVER ? 1 : 0;
223
224 return _gnutls_get_cred (session->key,
225 _gnutls_map_kx_get_cred (algo, server), err);
226}
227
228const void *
229_gnutls_get_cred (gnutls_key_st key, gnutls_credentials_type_t type, int *err)
230{
231 const void *retval = NULL;
232 int _err = -1;
233 auth_cred_st *ccred;
234
235 if (key == NULL)
236 goto out;
237
238 ccred = key->cred;
239 while (ccred != NULL)
240 {
241 if (ccred->algorithm == type)
242 {
243 break;
244 }
245 ccred = ccred->next;
246 }
247 if (ccred == NULL)
248 goto out;
249
250 _err = 0;
251 retval = ccred->credentials;
252
253out:
254 if (err != NULL)
255 *err = _err;
256 return retval;
257}
258
259/*-
260 * _gnutls_get_auth_info - Returns a pointer to authentication information.
261 * @session: is a #gnutls_session_t structure.
262 *
263 * This function must be called after a succesful gnutls_handshake().
264 * Returns a pointer to authentication information. That information
265 * is data obtained by the handshake protocol, the key exchange algorithm,
266 * and the TLS extensions messages.
267 *
268 * In case of GNUTLS_CRD_ANON returns a type of &anon_(server/client)_auth_info_t;
269 * In case of GNUTLS_CRD_CERTIFICATE returns a type of &cert_auth_info_t;
270 * In case of GNUTLS_CRD_SRP returns a type of &srp_(server/client)_auth_info_t;
271 -*/
272void *
273_gnutls_get_auth_info (gnutls_session_t session)
274{
275 return session->key->auth_info;
276}
277
278/*-
279 * _gnutls_free_auth_info - Frees the auth info structure
280 * @session: is a #gnutls_session_t structure.
281 *
282 * This function frees the auth info structure and sets it to
283 * null. It must be called since some structures contain malloced
284 * elements.
285 -*/
286void
287_gnutls_free_auth_info (gnutls_session_t session)
288{
289 dh_info_st *dh_info;
290 rsa_info_st *rsa_info;
291
292 if (session == NULL || session->key == NULL)
293 {
294 gnutls_assert ();
295 return;
296 }
297
298 switch (session->key->auth_info_type)
299 {
300 case GNUTLS_CRD_SRP:
301 break;
302 case GNUTLS_CRD_ANON:
303 {
304 anon_auth_info_t info = _gnutls_get_auth_info (session);
305
306 if (info == NULL)
307 break;
308
309 dh_info = &info->dh;
310 _gnutls_free_dh_info (dh_info);
311 }
312 break;
313 case GNUTLS_CRD_CERTIFICATE:
314 {
315 unsigned int i;
316 cert_auth_info_t info = _gnutls_get_auth_info (session);
317
318 if (info == NULL)
319 break;
320
321 dh_info = &info->dh;
322 rsa_info = &info->rsa_export;
323 for (i = 0; i < info->ncerts; i++)
324 {
325 _gnutls_free_datum (&info->raw_certificate_list[i]);
326 }
327
328 gnutls_free (info->raw_certificate_list);
329 info->raw_certificate_list = NULL;
330 info->ncerts = 0;
331
332 _gnutls_free_dh_info (dh_info);
333 _gnutls_free_rsa_info (rsa_info);
334 }
335
336
337 break;
338 default:
339 return;
340
341 }
342
343 gnutls_free (session->key->auth_info);
344 session->key->auth_info = NULL;
345 session->key->auth_info_size = 0;
346 session->key->auth_info_type = 0;
347
348}
349
350/* This function will set the auth info structure in the key
351 * structure.
352 * If allow change is !=0 then this will allow changing the auth
353 * info structure to a different type.
354 */
355int
356_gnutls_auth_info_set (gnutls_session_t session,
357 gnutls_credentials_type_t type, int size,
358 int allow_change)
359{
360 if (session->key->auth_info == NULL)
361 {
362 session->key->auth_info = gnutls_calloc (1, size);
363 if (session->key->auth_info == NULL)
364 {
365 gnutls_assert ();
366 return GNUTLS_E_MEMORY_ERROR;
367 }
368 session->key->auth_info_type = type;
369 session->key->auth_info_size = size;
370 }
371 else
372 {
373 if (allow_change == 0)
374 {
375 /* If the credentials for the current authentication scheme,
376 * are not the one we want to set, then it's an error.
377 * This may happen if a rehandshake is performed an the
378 * ciphersuite which is negotiated has different authentication
379 * schema.
380 */
381 if (gnutls_auth_get_type (session) != session->key->auth_info_type)
382 {
383 gnutls_assert ();
384 return GNUTLS_E_INVALID_REQUEST;
385 }
386 }
387 else
388 {
389 /* The new behaviour: Here we reallocate the auth info structure
390 * in order to be able to negotiate different authentication
391 * types. Ie. perform an auth_anon and then authenticate again using a
392 * certificate (in order to prevent revealing the certificate's contents,
393 * to passive eavesdropers.
394 */
395 if (gnutls_auth_get_type (session) != session->key->auth_info_type)
396 {
397
398 _gnutls_free_auth_info (session);
399
400 session->key->auth_info = calloc (1, size);
401 if (session->key->auth_info == NULL)
402 {
403 gnutls_assert ();
404 return GNUTLS_E_MEMORY_ERROR;
405 }
406
407 session->key->auth_info_type = type;
408 session->key->auth_info_size = size;
409 }
410 }
411 }
412 return 0;
413}
diff --git a/src/daemon/https/tls/gnutls_auth.h b/src/daemon/https/tls/gnutls_auth.h
new file mode 100644
index 00000000..07d81352
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_auth.h
@@ -0,0 +1,50 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#ifndef GNUTLS_AUTH_H
26# define GNUTLS_AUTH_H
27
28typedef struct mod_auth_st_int
29{
30 const char *name; /* null terminated */
31 int (*gnutls_generate_server_certificate) (gnutls_session_t, opaque **);
32 int (*gnutls_generate_client_certificate) (gnutls_session_t, opaque **);
33 int (*gnutls_generate_server_kx) (gnutls_session_t, opaque **);
34 int (*gnutls_generate_client_kx) (gnutls_session_t, opaque **); /* used in SRP */
35 int (*gnutls_generate_client_cert_vrfy) (gnutls_session_t, opaque **);
36 int (*gnutls_generate_server_certificate_request) (gnutls_session_t,
37 opaque **);
38
39 int (*gnutls_process_server_certificate) (gnutls_session_t, opaque *,
40 size_t);
41 int (*gnutls_process_client_certificate) (gnutls_session_t, opaque *,
42 size_t);
43 int (*gnutls_process_server_kx) (gnutls_session_t, opaque *, size_t);
44 int (*gnutls_process_client_kx) (gnutls_session_t, opaque *, size_t);
45 int (*gnutls_process_client_cert_vrfy) (gnutls_session_t, opaque *, size_t);
46 int (*gnutls_process_server_certificate_request) (gnutls_session_t,
47 opaque *, size_t);
48} mod_auth_st;
49
50#endif
diff --git a/src/daemon/https/tls/gnutls_auth_int.h b/src/daemon/https/tls/gnutls_auth_int.h
new file mode 100644
index 00000000..85fe53a1
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_auth_int.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25const void *_gnutls_get_cred (gnutls_key_st key,
26 gnutls_credentials_type_t kx, int *err);
27const void *_gnutls_get_kx_cred (gnutls_session_t session,
28 gnutls_kx_algorithm_t algo, int *err);
29void *_gnutls_get_auth_info (gnutls_session_t session);
30int _gnutls_auth_info_set (gnutls_session_t session,
31 gnutls_credentials_type_t type, int size,
32 int allow_change);
diff --git a/src/daemon/https/tls/gnutls_buffer.h b/src/daemon/https/tls/gnutls_buffer.h
new file mode 100644
index 00000000..5c552a7a
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_buffer.h
@@ -0,0 +1,31 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_str.h>
26
27typedef gnutls_string gnutls_buffer;
28
29#define _gnutls_buffer_init(buf) _gnutls_string_init(buf, gnutls_malloc, gnutls_realloc, gnutls_free);
30#define _gnutls_buffer_clear _gnutls_string_clear
31#define _gnutls_buffer_append _gnutls_string_append_data
diff --git a/src/daemon/https/tls/gnutls_buffers.c b/src/daemon/https/tls/gnutls_buffers.c
new file mode 100644
index 00000000..5a272dca
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_buffers.c
@@ -0,0 +1,1241 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This is the only file that uses the berkeley sockets API.
26 *
27 * Also holds all the buffering code used in gnutls.
28 * The buffering code works as:
29 *
30 * RECORD LAYER:
31 * 1. uses a buffer to hold data (application/handshake),
32 * we got but they were not requested, yet.
33 * (see gnutls_record_buffer_put(), gnutls_record_buffer_get_size() etc.)
34 *
35 * 2. uses a buffer to hold data that were incomplete (ie the read/write
36 * was interrupted)
37 * (see _gnutls_io_read_buffered(), _gnutls_io_write_buffered() etc.)
38 *
39 * HANDSHAKE LAYER:
40 * 1. Uses a buffer to hold data that was not sent or received
41 * complete. (E.g. sent 10 bytes of a handshake packet that is 20 bytes
42 * long).
43 * (see _gnutls_handshake_send_int(), _gnutls_handshake_recv_int())
44 *
45 * 2. Uses buffer to hold the last received handshake message.
46 * (see _gnutls_handshake_buffer_put() etc.)
47 *
48 */
49
50#include <gnutls_int.h>
51#include <gnutls_errors.h>
52#include <gnutls_num.h>
53#include <gnutls_record.h>
54#include <gnutls_buffers.h>
55
56#include <errno.h>
57
58#ifdef _WIN32
59# include <winsock2.h>
60#endif
61
62#ifndef EAGAIN
63# define EAGAIN EWOULDBLOCK
64#endif
65
66#ifdef IO_DEBUG
67# include <io_debug.h>
68#endif
69
70/**
71 * gnutls_transport_set_errno:
72 * @session: is a #gnutls_session_t structure.
73 * @err: error value to store in session-specific errno variable.
74 *
75 * Store @err in the session-specific errno variable. Useful values
76 * for @err is EAGAIN and EINTR, other values are treated will be
77 * treated as real errors in the push/pull function.
78 *
79 * This function is useful in replacement push/pull functions set by
80 * gnutls_transport_set_push_function and
81 * gnutls_transport_set_pullpush_function under Windows, where the
82 * replacement push/pull may not have access to the same @errno
83 * variable that is used by GnuTLS (e.g., the application is linked to
84 * msvcr71.dll and gnutls is linked to msvcrt.dll).
85 *
86 * If you don't have the @session variable easily accessible from the
87 * push/pull function, and don't worry about thread conflicts, you can
88 * also use gnutls_transport_set_global_errno().
89 **/
90void gnutls_transport_set_errno(gnutls_session_t session,
91 int err)
92{
93 session->internals.errnum = err;
94}
95
96/**
97 * gnutls_transport_set_global_errno:
98 * @err: error value to store in global errno variable.
99 *
100 * Store @err in the global errno variable. Useful values for @err is
101 * EAGAIN and EINTR, other values are treated will be treated as real
102 * errors in the push/pull function.
103 *
104 * This function is useful in replacement push/pull functions set by
105 * gnutls_transport_set_push_function and
106 * gnutls_transport_set_pullpush_function under Windows, where the
107 * replacement push/pull may not have access to the same @errno
108 * variable that is used by GnuTLS (e.g., the application is linked to
109 * msvcr71.dll and gnutls is linked to msvcrt.dll).
110 *
111 * Whether this function is thread safe or not depends on whether the
112 * global variable errno is thread safe, some system libraries make it
113 * a thread-local variable. When feasible, using the guaranteed
114 * thread-safe gnutls_transport_set_errno() may be better.
115 **/
116void gnutls_transport_set_global_errno(int err)
117{
118 errno = err;
119}
120
121/* Buffers received packets of type APPLICATION DATA and
122 * HANDSHAKE DATA.
123 */
124int _gnutls_record_buffer_put(content_type_t type,
125 gnutls_session_t session,
126 opaque * data,
127 size_t length)
128{
129 gnutls_buffer *buf;
130
131 if (length == 0)
132 return 0;
133
134 switch (type)
135 {
136 case GNUTLS_APPLICATION_DATA:
137 buf = &session->internals.application_data_buffer;
138 _gnutls_buffers_log ("BUF[REC]: Inserted %d bytes of Data(%d)\n",
139 length, type);
140 break;
141
142 case GNUTLS_HANDSHAKE:
143 buf = &session->internals.handshake_data_buffer;
144 _gnutls_buffers_log ("BUF[HSK]: Inserted %d bytes of Data(%d)\n",
145 length, type);
146 break;
147
148 case GNUTLS_INNER_APPLICATION:
149 buf = &session->internals.ia_data_buffer;
150 _gnutls_buffers_log ("BUF[IA]: Inserted %d bytes of Data(%d)\n", length,
151 type);
152 break;
153
154 default:
155 gnutls_assert ()
156 ;
157 return GNUTLS_E_INVALID_REQUEST;
158 }
159
160 if (_gnutls_buffer_append (buf, data, length) < 0)
161 {
162 gnutls_assert ();
163 return GNUTLS_E_MEMORY_ERROR;
164 }
165
166 return 0;
167}
168
169int _gnutls_record_buffer_get_size(content_type_t type,
170 gnutls_session_t session)
171{
172 switch (type)
173 {
174 case GNUTLS_APPLICATION_DATA:
175 return session->internals.application_data_buffer.length;
176
177 case GNUTLS_HANDSHAKE:
178 return session->internals.handshake_data_buffer.length;
179
180 case GNUTLS_INNER_APPLICATION:
181 return session->internals.ia_data_buffer.length;
182
183 default:
184 return GNUTLS_E_INVALID_REQUEST;
185 }
186}
187
188/**
189 * gnutls_record_check_pending - checks if there are any data to receive in gnutls buffers.
190 * @session: is a #gnutls_session_t structure.
191 *
192 * This function checks if there are any data to receive
193 * in the gnutls buffers. Returns the size of that data or 0.
194 * Notice that you may also use select() to check for data in
195 * a TCP connection, instead of this function.
196 * (gnutls leaves some data in the tcp buffer in order for select
197 * to work).
198 **/
199size_t gnutls_record_check_pending(gnutls_session_t session)
200{
201 return _gnutls_record_buffer_get_size(GNUTLS_APPLICATION_DATA, session);
202}
203
204int _gnutls_record_buffer_get(content_type_t type,
205 gnutls_session_t session,
206 opaque * data,
207 size_t length)
208{
209 if (length == 0 || data == NULL)
210 {
211 gnutls_assert ();
212 return GNUTLS_E_INVALID_REQUEST;
213 }
214
215 switch (type)
216 {
217 case GNUTLS_APPLICATION_DATA:
218
219 if (length > session->internals.application_data_buffer.length)
220 {
221 length = session->internals.application_data_buffer.length;
222 }
223
224 _gnutls_buffers_log ("BUFFER[REC][AD]: Read %d bytes of Data(%d)\n",
225 length, type);
226
227 session->internals.application_data_buffer.length -= length;
228 memcpy(data, session->internals.application_data_buffer.data, length);
229
230 /* overwrite buffer */
231 memmove(session->internals.application_data_buffer.data,
232 &session->internals.application_data_buffer.data[length],
233 session->internals.application_data_buffer.length);
234
235 /* we do no longer realloc the application_data_buffer.data,
236 * since it serves no practical reason. It also decreases
237 * performance.
238 */
239 break;
240
241 case GNUTLS_HANDSHAKE:
242 if (length > session->internals.handshake_data_buffer.length)
243 {
244 length = session->internals.handshake_data_buffer.length;
245 }
246
247 _gnutls_buffers_log ("BUF[REC][HD]: Read %d bytes of Data(%d)\n",
248 length, type);
249
250 session->internals.handshake_data_buffer.length -= length;
251 memcpy(data, session->internals.handshake_data_buffer.data, length);
252
253 /* overwrite buffer */
254 memmove(session->internals.handshake_data_buffer.data,
255 &session->internals.handshake_data_buffer.data[length],
256 session->internals.handshake_data_buffer.length);
257
258 break;
259
260 case GNUTLS_INNER_APPLICATION:
261 if (length > session->internals.ia_data_buffer.length)
262 length = session->internals.ia_data_buffer.length;
263
264 _gnutls_buffers_log ("BUF[REC][IA]: Read %d bytes of Data(%d)\n",
265 length, type);
266
267 session->internals.ia_data_buffer.length -= length;
268 memcpy(data, session->internals.ia_data_buffer.data, length);
269
270 /* overwrite buffer */
271 memmove(session->internals.ia_data_buffer.data,
272 &session->internals.ia_data_buffer.data[length],
273 session->internals.ia_data_buffer.length);
274
275 break;
276
277 default:
278 gnutls_assert ()
279 ;
280 return GNUTLS_E_INVALID_REQUEST;
281 }
282
283 return length;
284}
285
286/* This function is like read. But it does not return -1 on error.
287 * It does return gnutls_errno instead.
288 *
289 * Flags are only used if the default recv() function is being used.
290 */
291static ssize_t _gnutls_read(gnutls_session_t session,
292 void *iptr,
293 size_t sizeOfPtr,
294 int flags)
295{
296 size_t left;
297 ssize_t i = 0;
298 char *ptr = iptr;
299 unsigned j, x, sum = 0;
300 gnutls_transport_ptr_t fd = session->internals.transport_recv_ptr;
301
302 session->internals.direction = 0;
303
304 left = sizeOfPtr;
305 while (left > 0)
306 {
307
308 session->internals.errnum = 0;
309
310 if (session->internals._gnutls_pull_func == NULL)
311 {
312 i = recv(GNUTLS_POINTER_TO_INT (fd), &ptr[sizeOfPtr - left], left,
313 flags);
314#if HAVE_WINSOCK
315 if (i < 0)
316 {
317 int tmperr = WSAGetLastError ();
318 switch (tmperr)
319 {
320 case WSAEWOULDBLOCK:
321 session->internals.errnum = EAGAIN;
322 break;
323
324 case WSAEINTR:
325 session->internals.errnum = EINTR;
326 break;
327
328 default:
329 session->internals.errnum = EIO;
330 break;
331 }
332 WSASetLastError (tmperr);
333 }
334#endif
335 }
336 else
337 i = session->internals._gnutls_pull_func(fd, &ptr[sizeOfPtr -
338 left], left);
339
340 if (i < 0)
341 {
342 int err = session->internals.errnum ? session->internals.errnum
343 : errno;
344
345 _gnutls_read_log ("READ: %d returned from %d, errno=%d gerrno=%d\n",
346 i, fd, errno, session->internals.errnum);
347
348 if (err == EAGAIN || err == EINTR)
349 {
350 if (sizeOfPtr - left > 0)
351 {
352
353 _gnutls_read_log ("READ: returning %d bytes from %d\n",
354 sizeOfPtr - left, fd);
355
356 goto finish;
357 }
358 gnutls_assert ();
359
360 if (err == EAGAIN)
361 return GNUTLS_E_AGAIN;
362 return GNUTLS_E_INTERRUPTED;
363 }
364 else
365 {
366 gnutls_assert ();
367 return GNUTLS_E_PULL_ERROR;
368 }
369 }
370 else
371 {
372
373 _gnutls_read_log ("READ: Got %d bytes from %d\n", i, fd);
374
375 if (i == 0)
376 break; /* EOF */
377 }
378
379 left -= i;
380
381 }
382
383 finish:
384
385 if (_gnutls_log_level >= 7)
386 {
387 char line[128];
388 char tmp[16];
389
390 _gnutls_read_log ("READ: read %d bytes from %d\n", (sizeOfPtr - left),
391 fd);
392
393 for (x = 0; x < ((sizeOfPtr - left) / 16) + 1; x++)
394 {
395 line[0] = 0;
396
397 sprintf(tmp, "%.4x - ", x);
398 _gnutls_str_cat(line, sizeof (line), tmp);
399
400 for (j = 0; j < 16; j++)
401 {
402 if (sum < (sizeOfPtr - left))
403 {
404 sprintf(tmp, "%.2x ", ((unsigned char *) ptr)[sum++]);
405 _gnutls_str_cat(line, sizeof (line), tmp);
406 }
407 }
408 _gnutls_read_log ("%s\n", line);
409 }
410 }
411
412 return (sizeOfPtr - left);
413}
414
415#define RCVLOWAT session->internals.lowat
416
417/* This function is only used with berkeley style sockets.
418 * Clears the peeked data (read with MSG_PEEK).
419 */
420int _gnutls_io_clear_peeked_data(gnutls_session_t session)
421{
422 char *peekdata;
423 int ret, sum;
424
425 if (session->internals.have_peeked_data == 0 || RCVLOWAT == 0)
426 return 0;
427
428 peekdata = gnutls_alloca (RCVLOWAT);
429 if (peekdata == NULL)
430 {
431 gnutls_assert ();
432 return GNUTLS_E_MEMORY_ERROR;
433 }
434
435 /* this was already read by using MSG_PEEK - so it shouldn't fail */
436 sum = 0;
437 do
438 { /* we need this to finish now */
439 ret = _gnutls_read(session, peekdata, RCVLOWAT - sum, 0);
440 if (ret > 0)
441 sum += ret;
442 } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN || sum
443 < RCVLOWAT);
444
445 gnutls_afree (peekdata);
446
447 if (ret < 0)
448 {
449 gnutls_assert ();
450 return ret;
451 }
452
453 session->internals.have_peeked_data = 0;
454
455 return 0;
456}
457
458void _gnutls_io_clear_read_buffer(gnutls_session_t session)
459{
460 session->internals.record_recv_buffer.length = 0;
461}
462
463/* This function is like recv(with MSG_PEEK). But it does not return -1 on error.
464 * It does return gnutls_errno instead.
465 * This function reads data from the socket and keeps them in a buffer, of up to
466 * MAX_RECV_SIZE.
467 *
468 * This is not a general purpose function. It returns EXACTLY the data requested,
469 * which are stored in a local (in the session) buffer. A pointer (iptr) to this buffer is returned.
470 *
471 */
472ssize_t _gnutls_io_read_buffered(gnutls_session_t session,
473 opaque ** iptr,
474 size_t sizeOfPtr,
475 content_type_t recv_type)
476{
477 ssize_t ret = 0, ret2 = 0;
478 size_t min;
479 int buf_pos;
480 opaque *buf;
481 int recvlowat;
482 int recvdata, alloc_size;
483
484 *iptr = session->internals.record_recv_buffer.data;
485
486 if (sizeOfPtr > MAX_RECV_SIZE || sizeOfPtr == 0)
487 {
488 gnutls_assert (); /* internal error */
489 return GNUTLS_E_INVALID_REQUEST;
490 }
491
492 /* If an external pull function is used, then do not leave
493 * any data into the kernel buffer.
494 */
495 if (session->internals._gnutls_pull_func != NULL)
496 {
497 recvlowat = 0;
498 }
499 else
500 {
501 /* leave peeked data to the kernel space only if application data
502 * is received and we don't have any peeked
503 * data in gnutls session.
504 */
505 if (recv_type != GNUTLS_APPLICATION_DATA
506 && session->internals.have_peeked_data == 0)
507 recvlowat = 0;
508 else
509 recvlowat = RCVLOWAT;
510 }
511
512 /* calculate the actual size, ie. get the minimum of the
513 * buffered data and the requested data.
514 */
515 min = MIN(session->internals.record_recv_buffer.length, sizeOfPtr);
516 if (min > 0)
517 {
518 /* if we have enough buffered data
519 * then just return them.
520 */
521 if (min == sizeOfPtr)
522 {
523 return min;
524 }
525 }
526
527 /* min is over zero. recvdata is the data we must
528 * receive in order to return the requested data.
529 */
530 recvdata = sizeOfPtr - min;
531
532 /* Check if the previously read data plus the new data to
533 * receive are longer than the maximum receive buffer size.
534 */
535 if ((session->internals.record_recv_buffer.length + recvdata) > MAX_RECV_SIZE)
536 {
537 gnutls_assert (); /* internal error */
538 return GNUTLS_E_INVALID_REQUEST;
539 }
540
541 /* Allocate the data required to store the new packet.
542 */
543 alloc_size = recvdata + session->internals.record_recv_buffer.length;
544 session->internals.record_recv_buffer.data
545 = gnutls_realloc_fast(session->internals.record_recv_buffer.data,
546 alloc_size);
547 if (session->internals.record_recv_buffer.data == NULL)
548 {
549 gnutls_assert ();
550 return GNUTLS_E_MEMORY_ERROR;
551 }
552
553 buf_pos = session->internals.record_recv_buffer.length;
554 buf = session->internals.record_recv_buffer.data;
555 *iptr = buf;
556
557 /* READ DATA - but leave RCVLOWAT bytes in the kernel buffer. */
558 if (recvdata - recvlowat > 0)
559 {
560 ret = _gnutls_read(session, &buf[buf_pos], recvdata - recvlowat, 0);
561
562 /* return immediately if we got an interrupt or eagain
563 * error.
564 */
565 if (ret < 0 && gnutls_error_is_fatal(ret) == 0)
566 {
567 return ret;
568 }
569 }
570
571 /* copy fresh data to our buffer.
572 */
573 if (ret > 0)
574 {
575 _gnutls_read_log ("RB: Have %d bytes into buffer. Adding %d bytes.\n",
576 session->internals.record_recv_buffer.length, ret);
577 _gnutls_read_log ("RB: Requested %d bytes\n", sizeOfPtr);
578 session->internals.record_recv_buffer.length += ret;
579 }
580
581 buf_pos = session->internals.record_recv_buffer.length;
582
583 /* This is a hack placed in order for select to work. Just leave recvlowat data,
584 * into the kernel buffer (using a read with MSG_PEEK), thus making
585 * select think, that the socket is ready for reading.
586 * MSG_PEEK is only used with berkeley style sockets.
587 */
588 if (ret == (recvdata - recvlowat) && recvlowat > 0)
589 {
590 ret2 = _gnutls_read(session, &buf[buf_pos], recvlowat, MSG_PEEK);
591
592 if (ret2 < 0 && gnutls_error_is_fatal(ret2) == 0)
593 {
594 return ret2;
595 }
596
597 if (ret2 > 0)
598 {
599 _gnutls_read_log ("RB-PEEK: Read %d bytes in PEEK MODE.\n", ret2);
600 _gnutls_read_log
601 ("RB-PEEK: Have %d bytes into buffer. Adding %d bytes.\nRB: Requested %d bytes\n",
602 session->internals.record_recv_buffer.length, ret2, sizeOfPtr);
603 session->internals.have_peeked_data = 1;
604 session->internals.record_recv_buffer.length += ret2;
605
606 }
607 }
608
609 if (ret < 0 || ret2 < 0)
610 {
611 gnutls_assert ();
612 /* that's because they are initialized to 0 */
613 return MIN(ret, ret2);
614 }
615
616 ret += ret2;
617
618 if (ret > 0 && ret < recvlowat)
619 {
620 gnutls_assert ();
621 return GNUTLS_E_AGAIN;
622 }
623
624 if (ret == 0)
625 { /* EOF */
626 gnutls_assert ();
627 return 0;
628 }
629
630 ret = session->internals.record_recv_buffer.length;
631
632 if ((ret > 0) && ((size_t) ret < sizeOfPtr))
633 {
634 /* Short Read */
635 gnutls_assert ();
636 return GNUTLS_E_AGAIN;
637 }
638 else
639 {
640 return ret;
641 }
642}
643
644/* These two functions are used to insert data to the send buffer of the handshake or
645 * record protocol. The send buffer is kept if a send is interrupted and we need to keep
646 * the data left to sent, in order to send them later.
647 */
648
649#define MEMSUB(x,y) ((ssize_t)((ptrdiff_t)x-(ptrdiff_t)y))
650
651inline static int _gnutls_buffer_insert(gnutls_buffer * buffer,
652 const opaque * _data,
653 size_t data_size)
654{
655
656 if ((MEMSUB (_data, buffer->data) >= 0) && (MEMSUB (_data, buffer->data) < (ssize_t) buffer->length))
657 {
658 /* the given _data is part of the buffer.
659 */
660 if (data_size > buffer->length)
661 {
662 gnutls_assert ();
663 /* this shouldn't have happened */
664 return GNUTLS_E_INTERNAL_ERROR;
665 }
666
667 if (_data == buffer->data)
668 { /* then don't even memmove */
669 buffer->length = data_size;
670 return 0;
671 }
672
673 memmove(buffer->data, _data, data_size);
674 buffer->length = data_size;
675
676 return 0;
677
678 }
679
680 if (_gnutls_buffer_append (buffer, _data, data_size) < 0)
681 {
682 gnutls_assert ();
683 return GNUTLS_E_MEMORY_ERROR;
684 }
685
686 return 0;
687}
688
689inline static int _gnutls_buffer_get(gnutls_buffer * buffer,
690 const opaque ** ptr,
691 size_t * ptr_size)
692{
693 *ptr_size = buffer->length;
694 *ptr = buffer->data;
695
696 return 0;
697}
698
699/* This function is like write. But it does not return -1 on error.
700 * It does return gnutls_errno instead.
701 *
702 * In case of E_AGAIN and E_INTERRUPTED errors, you must call gnutls_write_flush(),
703 * until it returns ok (0).
704 *
705 * We need to push exactly the data in n, since we cannot send less
706 * data. In TLS the peer must receive the whole packet in order
707 * to decrypt and verify the integrity.
708 *
709 */
710ssize_t _gnutls_io_write_buffered(gnutls_session_t session,
711 const void *iptr,
712 size_t n)
713{
714 size_t left;
715 unsigned j, x, sum = 0;
716 ssize_t retval, i;
717 const opaque *ptr;
718 int ret;
719 gnutls_transport_ptr_t fd = session->internals.transport_send_ptr;
720
721 /* to know where the procedure was interrupted.
722 */
723 session->internals.direction = 1;
724
725 ptr = iptr;
726
727 /* In case the previous write was interrupted, check if the
728 * iptr != NULL and we have data in the buffer.
729 * If this is true then return an error.
730 */
731 if (session->internals.record_send_buffer.length > 0 && iptr != NULL)
732 {
733 gnutls_assert ();
734 return GNUTLS_E_INVALID_REQUEST;
735 }
736
737 /* If data in the buffer exist
738 */
739 if (iptr == NULL)
740 {
741 /* checking is handled above */
742 ret
743 = _gnutls_buffer_get(&session->internals.record_send_buffer, &ptr, &n);
744 if (ret < 0)
745 {
746 gnutls_assert ();
747 return ret;
748 }
749
750 _gnutls_write_log ("WRITE: Restoring old write. (%d bytes to send)\n",
751 n);
752 }
753
754 _gnutls_write_log ("WRITE: Will write %d bytes to %d.\n", n, fd);
755
756 i = 0;
757 left = n;
758 while (left > 0)
759 {
760
761 session->internals.errnum = 0;
762
763 if (session->internals._gnutls_push_func == NULL)
764 {
765 i = send(GNUTLS_POINTER_TO_INT (fd), &ptr[n - left], left, 0);
766#if HAVE_WINSOCK
767 if (i < 0)
768 {
769 int tmperr = WSAGetLastError ();
770 switch (tmperr)
771 {
772 case WSAEWOULDBLOCK:
773 session->internals.errnum = EAGAIN;
774 break;
775
776 case WSAEINTR:
777 session->internals.errnum = EINTR;
778 break;
779
780 default:
781 session->internals.errnum = EIO;
782 break;
783 }
784 WSASetLastError (tmperr);
785 }
786#endif
787 }
788 else
789 i = session->internals._gnutls_push_func(fd, &ptr[n - left], left);
790
791 if (i == -1)
792 {
793 int err = session->internals.errnum ? session->internals.errnum
794 : errno;
795
796 if (err == EAGAIN || err == EINTR)
797 {
798 session->internals.record_send_buffer_prev_size += n - left;
799
800 retval = _gnutls_buffer_insert(&session->internals.
801 record_send_buffer, &ptr[n - left], left);
802 if (retval < 0)
803 {
804 gnutls_assert ();
805 return retval;
806 }
807
808 _gnutls_write_log
809 ("WRITE: Interrupted. Stored %d bytes to buffer. Already sent %d bytes.\n",
810 left, n - left);
811
812 if (err == EAGAIN)
813 return GNUTLS_E_AGAIN;
814 return GNUTLS_E_INTERRUPTED;
815 }
816 else
817 {
818 gnutls_assert ();
819 return GNUTLS_E_PUSH_ERROR;
820 }
821 }
822 left -= i;
823
824 if (_gnutls_log_level >= 7)
825 {
826 char line[128];
827 char tmp[16];
828
829 _gnutls_write_log
830 ("WRITE: wrote %d bytes to %d. Left %d bytes. Total %d bytes.\n",
831 i, fd, left, n);
832 for (x = 0; x < (unsigned) ((i) / 16) + 1; x++)
833 {
834 line[0] = 0;
835
836 if (sum > n - left)
837 break;
838
839 sprintf(tmp, "%.4x - ", x);
840 _gnutls_str_cat(line, sizeof (line), tmp);
841
842 for (j = 0; j < 16; j++)
843 {
844 if (sum < n - left)
845 {
846 sprintf(tmp, "%.2x ", ((unsigned char *) ptr)[sum++]);
847 _gnutls_str_cat(line, sizeof (line), tmp);
848 }
849 else
850 break;
851 }
852 _gnutls_write_log ("%s\n", line);
853 }
854 }
855 }
856
857 retval = n + session->internals.record_send_buffer_prev_size;
858
859 session->internals.record_send_buffer.length = 0;
860 session->internals.record_send_buffer_prev_size = 0;
861
862 return retval;
863
864}
865
866/* This function writes the data that are left in the
867 * TLS write buffer (ie. because the previous write was
868 * interrupted.
869 */
870ssize_t _gnutls_io_write_flush(gnutls_session_t session)
871{
872 ssize_t ret;
873
874 if (session->internals.record_send_buffer.length == 0)
875 return 0; /* done */
876
877 ret = _gnutls_io_write_buffered(session, NULL, 0);
878 _gnutls_write_log ("WRITE FLUSH: %d [buffer: %d]\n", ret,
879 session->internals.record_send_buffer.length);
880
881 return ret;
882}
883
884/* This function writes the data that are left in the
885 * Handshake write buffer (ie. because the previous write was
886 * interrupted.
887 */
888ssize_t _gnutls_handshake_io_write_flush(gnutls_session_t session)
889{
890 ssize_t ret;
891 ret = _gnutls_handshake_io_send_int(session, 0, 0, NULL, 0);
892 if (ret < 0)
893 {
894 gnutls_assert ();
895 return ret;
896 }
897
898 _gnutls_write_log ("HANDSHAKE_FLUSH: written[1] %d bytes\n", ret);
899
900 if (session->internals.handshake_send_buffer.length == 0)
901 {
902 ret = session->internals.handshake_send_buffer_prev_size; /* done */
903 session->internals.handshake_send_buffer_prev_size = 0;
904 }
905
906 return ret;
907}
908
909/* This is a send function for the gnutls handshake
910 * protocol. Just makes sure that all data have been sent.
911 */
912ssize_t _gnutls_handshake_io_send_int(gnutls_session_t session,
913 content_type_t type,
914 gnutls_handshake_description_t htype,
915 const void *iptr,
916 size_t n)
917{
918 size_t left;
919 ssize_t ret = 0;
920 const opaque *ptr;
921 ssize_t retval = 0;
922
923 ptr = iptr;
924
925 if (session->internals.handshake_send_buffer.length > 0 && ptr == NULL && n
926 == 0)
927 {
928 /* resuming previously interrupted write
929 */
930 gnutls_assert ();
931 ret = _gnutls_buffer_get(&session->internals.handshake_send_buffer, &ptr,
932 &n);
933 if (ret < 0)
934 {
935 gnutls_assert ();
936 return retval;
937 }
938
939 type = session->internals.handshake_send_buffer_type;
940 htype = session->internals.handshake_send_buffer_htype;
941
942 }
943 else if (session->internals.handshake_send_buffer.length > 0)
944 {
945 gnutls_assert ();
946 return GNUTLS_E_INTERNAL_ERROR;
947 }
948#ifdef WRITE_DEBUG
949 else
950 {
951 size_t sum = 0, x, j;
952
953 _gnutls_write_log ("HWRITE: will write %d bytes to %d.\n", n,
954 gnutls_transport_get_ptr (session));
955 for (x = 0; x < ((n) / 16) + 1; x++)
956 {
957 if (sum> n)
958 break;
959
960 _gnutls_write_log ("%.4x - ", x);
961 for (j = 0; j < 16; j++)
962 {
963 if (sum < n)
964 {
965 _gnutls_write_log ("%.2x ", ((unsigned char *) ptr)[sum++]);
966 }
967 else
968 break;
969 }
970 _gnutls_write_log ("\n");
971 }
972 _gnutls_write_log ("\n");
973 }
974#endif
975
976 if (n == 0)
977 { /* if we have no data to send */
978 gnutls_assert ();
979 return 0;
980 }
981 else if (ptr == NULL)
982 {
983 gnutls_assert ();
984 return GNUTLS_E_INTERNAL_ERROR;
985 }
986
987 left = n;
988 while (left > 0)
989 {
990 ret = _gnutls_send_int(session, type, htype, &ptr[n - left], left);
991
992 if (ret <= 0)
993 {
994 if (ret == 0)
995 {
996 gnutls_assert ();
997 ret = GNUTLS_E_INTERNAL_ERROR;
998 }
999
1000 if (left > 0
1001 && (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN))
1002 {
1003 gnutls_assert ();
1004
1005 retval = _gnutls_buffer_insert(&session->internals.
1006 handshake_send_buffer, &ptr[n - left], left);
1007 if (retval < 0)
1008 {
1009 gnutls_assert ();
1010 return retval;
1011 }
1012
1013 session->internals.handshake_send_buffer_prev_size += n - left;
1014
1015 session->internals.handshake_send_buffer_type = type;
1016 session->internals.handshake_send_buffer_htype = htype;
1017
1018 }
1019 else
1020 {
1021 session->internals.handshake_send_buffer_prev_size = 0;
1022 session->internals.handshake_send_buffer.length = 0;
1023 }
1024
1025 gnutls_assert ();
1026 return ret;
1027 }
1028 left -= ret;
1029 }
1030
1031 retval = n + session->internals.handshake_send_buffer_prev_size;
1032
1033 session->internals.handshake_send_buffer.length = 0;
1034 session->internals.handshake_send_buffer_prev_size = 0;
1035
1036 return retval;
1037
1038}
1039
1040/* This is a receive function for the gnutls handshake
1041 * protocol. Makes sure that we have received all data.
1042 */
1043ssize_t _gnutls_handshake_io_recv_int(gnutls_session_t session,
1044 content_type_t type,
1045 gnutls_handshake_description_t htype,
1046 void *iptr,
1047 size_t sizeOfPtr)
1048{
1049 size_t left;
1050 ssize_t i;
1051 opaque *ptr;
1052 size_t dsize;
1053
1054 ptr = iptr;
1055 left = sizeOfPtr;
1056
1057 if (sizeOfPtr == 0 || iptr == NULL)
1058 {
1059 gnutls_assert ();
1060 return GNUTLS_E_INVALID_REQUEST;
1061 }
1062
1063 if (session->internals.handshake_recv_buffer.length > 0)
1064 {
1065 /* if we have already received some data */
1066 if (sizeOfPtr <= session->internals.handshake_recv_buffer.length)
1067 {
1068 /* if requested less data then return it.
1069 */
1070 gnutls_assert ();
1071 memcpy(iptr, session->internals.handshake_recv_buffer.data, sizeOfPtr);
1072
1073 session->internals.handshake_recv_buffer.length -= sizeOfPtr;
1074
1075 memmove(session->internals.handshake_recv_buffer.data,
1076 &session->internals.handshake_recv_buffer.
1077 data[sizeOfPtr],
1078 session->internals.handshake_recv_buffer.length);
1079
1080 return sizeOfPtr;
1081 }
1082 gnutls_assert ();
1083 memcpy(iptr, session->internals.handshake_recv_buffer.data,
1084 session->internals.handshake_recv_buffer.length);
1085
1086 htype = session->internals.handshake_recv_buffer_htype;
1087 type = session->internals.handshake_recv_buffer_type;
1088
1089 left -= session->internals.handshake_recv_buffer.length;
1090
1091 session->internals.handshake_recv_buffer.length = 0;
1092 }
1093
1094 while (left > 0)
1095 {
1096 dsize = sizeOfPtr - left;
1097 i = _gnutls_recv_int(session, type, htype, &ptr[dsize], left);
1098 if (i < 0)
1099 {
1100
1101 if (dsize > 0 && (i == GNUTLS_E_INTERRUPTED || i == GNUTLS_E_AGAIN))
1102 {
1103 gnutls_assert ();
1104
1105 session->internals.handshake_recv_buffer.data
1106 = gnutls_realloc_fast(session->internals.
1107 handshake_recv_buffer.data, dsize);
1108 if (session->internals.handshake_recv_buffer.data == NULL)
1109 {
1110 gnutls_assert ();
1111 return GNUTLS_E_MEMORY_ERROR;
1112 }
1113
1114 memcpy(session->internals.handshake_recv_buffer.data, iptr, dsize);
1115
1116 session->internals.handshake_recv_buffer_htype = htype;
1117 session->internals.handshake_recv_buffer_type = type;
1118
1119 session->internals.handshake_recv_buffer.length = dsize;
1120 }
1121 else
1122 session->internals.handshake_recv_buffer.length = 0;
1123
1124 gnutls_assert ();
1125
1126 return i;
1127 }
1128 else
1129 {
1130 if (i == 0)
1131 break; /* EOF */
1132 }
1133
1134 left -= i;
1135
1136 }
1137
1138 session->internals.handshake_recv_buffer.length = 0;
1139
1140 return sizeOfPtr - left;
1141}
1142
1143/* Buffer for handshake packets. Keeps the packets in order
1144 * for finished messages to use them. Used in HMAC calculation
1145 * and finished messages.
1146 */
1147int _gnutls_handshake_buffer_put(gnutls_session_t session,
1148 opaque * data,
1149 size_t length)
1150{
1151
1152 if (length == 0)
1153 return 0;
1154
1155 if ((session->internals.max_handshake_data_buffer_size > 0) && ((length
1156 + session->
1157 internals.
1158 handshake_hash_buffer.
1159 length) > session->
1160 internals.
1161 max_handshake_data_buffer_size))
1162 {
1163 gnutls_assert ();
1164 return GNUTLS_E_MEMORY_ERROR;
1165 }
1166
1167 _gnutls_buffers_log ("BUF[HSK]: Inserted %d bytes of Data\n", length);
1168
1169 if (_gnutls_buffer_append (&session->internals.handshake_hash_buffer, data,
1170 length) < 0)
1171 {
1172 gnutls_assert ();
1173 return GNUTLS_E_MEMORY_ERROR;
1174 }
1175
1176 return 0;
1177}
1178
1179int _gnutls_handshake_buffer_get_size(gnutls_session_t session)
1180{
1181
1182 return session->internals.handshake_hash_buffer.length;
1183}
1184
1185/* this function does not touch the buffer
1186 * and returns data from it (peek mode!)
1187 */
1188int _gnutls_handshake_buffer_peek(gnutls_session_t session,
1189 opaque * data,
1190 size_t length)
1191{
1192 if (length > session->internals.handshake_hash_buffer.length)
1193 {
1194 length = session->internals.handshake_hash_buffer.length;
1195 }
1196
1197 _gnutls_buffers_log ("BUF[HSK]: Peeked %d bytes of Data\n", length);
1198
1199 memcpy(data, session->internals.handshake_hash_buffer.data, length);
1200 return length;
1201}
1202
1203/* this function does not touch the buffer
1204 * and returns data from it (peek mode!)
1205 */
1206int _gnutls_handshake_buffer_get_ptr(gnutls_session_t session,
1207 opaque ** data_ptr,
1208 size_t * length)
1209{
1210 if (length != NULL)
1211 *length = session->internals.handshake_hash_buffer.length;
1212
1213 _gnutls_buffers_log ("BUF[HSK]: Peeked %d bytes of Data\n", *length);
1214
1215 if (data_ptr != NULL)
1216 *data_ptr = session->internals.handshake_hash_buffer.data;
1217
1218 return 0;
1219}
1220
1221/* Does not free the buffer
1222 */
1223int _gnutls_handshake_buffer_empty(gnutls_session_t session)
1224{
1225
1226 _gnutls_buffers_log ("BUF[HSK]: Emptied buffer\n");
1227
1228 session->internals.handshake_hash_buffer.length = 0;
1229
1230 return 0;
1231}
1232
1233int _gnutls_handshake_buffer_clear(gnutls_session_t session)
1234{
1235
1236 _gnutls_buffers_log ("BUF[HSK]: Cleared Data from buffer\n");
1237
1238 _gnutls_buffer_clear (&session->internals.handshake_hash_buffer);
1239
1240 return 0;
1241}
diff --git a/src/daemon/https/tls/gnutls_buffers.h b/src/daemon/https/tls/gnutls_buffers.h
new file mode 100644
index 00000000..aaafde0d
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_buffers.h
@@ -0,0 +1,67 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25int _gnutls_record_buffer_put (content_type_t type,
26 gnutls_session_t session, opaque * data,
27 size_t length);
28int _gnutls_record_buffer_get_size (content_type_t type,
29 gnutls_session_t session);
30int _gnutls_record_buffer_get (content_type_t type,
31 gnutls_session_t session, opaque * data,
32 size_t length);
33ssize_t _gnutls_io_read_buffered (gnutls_session_t, opaque ** iptr,
34 size_t n, content_type_t);
35void _gnutls_io_clear_read_buffer (gnutls_session_t);
36int _gnutls_io_clear_peeked_data (gnutls_session_t session);
37
38ssize_t _gnutls_io_write_buffered (gnutls_session_t, const void *iptr,
39 size_t n);
40ssize_t _gnutls_io_write_buffered2 (gnutls_session_t, const void *iptr,
41 size_t n, const void *iptr2, size_t n2);
42
43int _gnutls_handshake_buffer_get_size (gnutls_session_t session);
44int _gnutls_handshake_buffer_peek (gnutls_session_t session, opaque * data,
45 size_t length);
46int _gnutls_handshake_buffer_put (gnutls_session_t session, opaque * data,
47 size_t length);
48int _gnutls_handshake_buffer_clear (gnutls_session_t session);
49int _gnutls_handshake_buffer_empty (gnutls_session_t session);
50int _gnutls_handshake_buffer_get_ptr (gnutls_session_t session,
51 opaque ** data_ptr, size_t * length);
52
53#define _gnutls_handshake_io_buffer_clear( session) \
54 _gnutls_buffer_clear( &session->internals.handshake_send_buffer); \
55 _gnutls_buffer_clear( &session->internals.handshake_recv_buffer); \
56 session->internals.handshake_send_buffer_prev_size = 0
57
58ssize_t _gnutls_handshake_io_recv_int (gnutls_session_t, content_type_t,
59 gnutls_handshake_description_t, void *,
60 size_t);
61ssize_t _gnutls_handshake_io_send_int (gnutls_session_t, content_type_t,
62 gnutls_handshake_description_t,
63 const void *, size_t);
64ssize_t _gnutls_io_write_flush (gnutls_session_t session);
65ssize_t _gnutls_handshake_io_write_flush (gnutls_session_t session);
66
67size_t gnutls_record_check_pending (gnutls_session_t session);
diff --git a/src/daemon/https/tls/gnutls_cert.c b/src/daemon/https/tls/gnutls_cert.c
new file mode 100644
index 00000000..0160d644
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_cert.c
@@ -0,0 +1,918 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* Some of the stuff needed for Certificate authentication is contained
26 * in this file.
27 */
28
29#include <gnutls_int.h>
30#include <gnutls_errors.h>
31#include <auth_cert.h>
32#include <gnutls_cert.h>
33#include <libtasn1.h>
34#include <gnutls_datum.h>
35#include <gnutls_mpi.h>
36#include <gnutls_global.h>
37#include <gnutls_algorithms.h>
38#include <gnutls_dh.h>
39#include <gnutls_str.h>
40#include <gnutls_state.h>
41#include <gnutls_auth_int.h>
42#include <gnutls_x509.h>
43#include <gnutls_extra_hooks.h>
44/* x509 */
45#include "x509.h"
46#include "mpi.h"
47
48/**
49 * gnutls_certificate_free_keys - Used to free all the keys from a gnutls_certificate_credentials_t structure
50 * @sc: is an #gnutls_certificate_credentials_t structure.
51 *
52 * This function will delete all the keys and the certificates associated
53 * with the given credentials. This function must not be called when a
54 * TLS negotiation that uses the credentials is in progress.
55 *
56 **/
57void
58gnutls_certificate_free_keys (gnutls_certificate_credentials_t sc)
59{
60 unsigned i, j;
61
62 for (i = 0; i < sc->ncerts; i++)
63 {
64 for (j = 0; j < sc->cert_list_length[i]; j++)
65 {
66 _gnutls_gcert_deinit (&sc->cert_list[i][j]);
67 }
68 gnutls_free (sc->cert_list[i]);
69 }
70
71 gnutls_free (sc->cert_list_length);
72 sc->cert_list_length = NULL;
73
74 gnutls_free (sc->cert_list);
75 sc->cert_list = NULL;
76
77 for (i = 0; i < sc->ncerts; i++)
78 {
79 _gnutls_gkey_deinit (&sc->pkey[i]);
80 }
81
82 gnutls_free (sc->pkey);
83 sc->pkey = NULL;
84
85 sc->ncerts = 0;
86
87}
88
89/**
90 * gnutls_certificate_free_cas - Used to free all the CAs from a gnutls_certificate_credentials_t structure
91 * @sc: is an #gnutls_certificate_credentials_t structure.
92 *
93 * This function will delete all the CAs associated
94 * with the given credentials. Servers that do not use
95 * gnutls_certificate_verify_peers2() may call this to
96 * save some memory.
97 *
98 **/
99void
100gnutls_certificate_free_cas (gnutls_certificate_credentials_t sc)
101{
102 unsigned j;
103
104 for (j = 0; j < sc->x509_ncas; j++)
105 {
106 gnutls_x509_crt_deinit (sc->x509_ca_list[j]);
107 }
108
109 sc->x509_ncas = 0;
110
111 gnutls_free (sc->x509_ca_list);
112 sc->x509_ca_list = NULL;
113
114}
115
116/**
117 * gnutls_certificate_free_ca_names - Used to free all the CA names from a gnutls_certificate_credentials_t structure
118 * @sc: is an #gnutls_certificate_credentials_t structure.
119 *
120 * This function will delete all the CA name in the
121 * given credentials. Clients may call this to save some memory
122 * since in client side the CA names are not used.
123 *
124 * CA names are used by servers to advertize the CAs they
125 * support to clients.
126 *
127 **/
128void
129gnutls_certificate_free_ca_names (gnutls_certificate_credentials_t sc)
130{
131 _gnutls_free_datum (&sc->x509_rdn_sequence);
132}
133
134/*-
135 * _gnutls_certificate_get_rsa_params - Returns the RSA parameters pointer
136 * @rsa_params: holds the RSA parameters or NULL.
137 * @func: function to retrieve the parameters or NULL.
138 * @session: The session.
139 *
140 * This function will return the rsa parameters pointer.
141 *
142 -*/
143gnutls_rsa_params_t
144_gnutls_certificate_get_rsa_params (gnutls_rsa_params_t rsa_params,
145 gnutls_params_function * func,
146 gnutls_session_t session)
147{
148 gnutls_params_st params;
149 int ret;
150
151 if (session->internals.params.rsa_params)
152 {
153 return session->internals.params.rsa_params;
154 }
155
156 if (rsa_params)
157 {
158 session->internals.params.rsa_params = rsa_params;
159 }
160 else if (func)
161 {
162 ret = func (session, GNUTLS_PARAMS_RSA_EXPORT, &params);
163 if (ret == 0 && params.type == GNUTLS_PARAMS_RSA_EXPORT)
164 {
165 session->internals.params.rsa_params = params.params.rsa_export;
166 session->internals.params.free_rsa_params = params.deinit;
167 }
168 }
169
170 return session->internals.params.rsa_params;
171}
172
173
174/**
175 * gnutls_certificate_free_credentials - Used to free an allocated gnutls_certificate_credentials_t structure
176 * @sc: is an #gnutls_certificate_credentials_t structure.
177 *
178 * This structure is complex enough to manipulate directly thus
179 * this helper function is provided in order to free (deallocate) it.
180 *
181 * This function does not free any temporary parameters associated
182 * with this structure (ie RSA and DH parameters are not freed by
183 * this function).
184 **/
185void
186gnutls_certificate_free_credentials (gnutls_certificate_credentials_t sc)
187{
188 gnutls_certificate_free_keys (sc);
189 gnutls_certificate_free_cas (sc);
190 gnutls_certificate_free_ca_names (sc);
191#ifdef ENABLE_PKI
192 gnutls_certificate_free_crls (sc);
193#endif
194
195#ifndef KEYRING_HACK
196 if (_E_gnutls_openpgp_keyring_deinit)
197 _E_gnutls_openpgp_keyring_deinit (sc->keyring);
198#else
199 _gnutls_free_datum (&sc->keyring);
200#endif
201
202 gnutls_free (sc);
203}
204
205
206/**
207 * gnutls_certificate_allocate_credentials - Used to allocate a gnutls_certificate_credentials_t structure
208 * @res: is a pointer to an #gnutls_certificate_credentials_t structure.
209 *
210 * This structure is complex enough to manipulate directly thus this
211 * helper function is provided in order to allocate it.
212 *
213 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
214 **/
215int
216gnutls_certificate_allocate_credentials (gnutls_certificate_credentials_t *
217 res)
218{
219 *res = gnutls_calloc (1, sizeof (certificate_credentials_st));
220
221 if (*res == NULL)
222 return GNUTLS_E_MEMORY_ERROR;
223
224 (*res)->verify_bits = DEFAULT_VERIFY_BITS;
225 (*res)->verify_depth = DEFAULT_VERIFY_DEPTH;
226
227 return 0;
228}
229
230
231/* returns the KX algorithms that are supported by a
232 * certificate. (Eg a certificate with RSA params, supports
233 * GNUTLS_KX_RSA algorithm).
234 * This function also uses the KeyUsage field of the certificate
235 * extensions in order to disable unneded algorithms.
236 */
237int
238_gnutls_selected_cert_supported_kx (gnutls_session_t session,
239 gnutls_kx_algorithm_t ** alg,
240 int *alg_size)
241{
242 gnutls_kx_algorithm_t kx;
243 gnutls_pk_algorithm_t pk;
244 gnutls_kx_algorithm_t kxlist[MAX_ALGOS];
245 gnutls_cert *cert;
246 int i;
247
248 if (session->internals.selected_cert_list_length == 0)
249 {
250 *alg_size = 0;
251 *alg = NULL;
252 return 0;
253 }
254
255 cert = &session->internals.selected_cert_list[0];
256 i = 0;
257
258 for (kx = 0; kx < MAX_ALGOS; kx++)
259 {
260 pk = _gnutls_map_pk_get_pk (kx);
261 if (pk == cert->subject_pk_algorithm)
262 {
263 /* then check key usage */
264 if (_gnutls_check_key_usage (cert, kx) == 0)
265 {
266 kxlist[i] = kx;
267 i++;
268 }
269 }
270 }
271
272 if (i == 0)
273 {
274 gnutls_assert ();
275 return GNUTLS_E_INVALID_REQUEST;
276 }
277
278 *alg = gnutls_calloc (1, sizeof (gnutls_kx_algorithm_t) * i);
279 if (*alg == NULL)
280 return GNUTLS_E_MEMORY_ERROR;
281
282 *alg_size = i;
283
284 memcpy (*alg, kxlist, i * sizeof (gnutls_kx_algorithm_t));
285
286 return 0;
287}
288
289
290/**
291 * gnutls_certificate_server_set_request - Used to set whether to request a client certificate
292 * @session: is an #gnutls_session_t structure.
293 * @req: is one of GNUTLS_CERT_REQUEST, GNUTLS_CERT_REQUIRE
294 *
295 * This function specifies if we (in case of a server) are going
296 * to send a certificate request message to the client. If @req
297 * is GNUTLS_CERT_REQUIRE then the server will return an error if
298 * the peer does not provide a certificate. If you do not
299 * call this function then the client will not be asked to
300 * send a certificate.
301 **/
302void
303gnutls_certificate_server_set_request (gnutls_session_t session,
304 gnutls_certificate_request_t req)
305{
306 session->internals.send_cert_req = req;
307}
308
309/**
310 * gnutls_certificate_client_set_retrieve_function - Used to set a callback to retrieve the certificate
311 * @cred: is a #gnutls_certificate_credentials_t structure.
312 * @func: is the callback function
313 *
314 * This function sets a callback to be called in order to retrieve the certificate
315 * to be used in the handshake.
316 * The callback's function prototype is:
317 * int (*callback)(gnutls_session_t, const gnutls_datum_t* req_ca_dn, int nreqs,
318 * const gnutls_pk_algorithm_t* pk_algos, int pk_algos_length, gnutls_retr_st* st);
319 *
320 * @req_ca_cert is only used in X.509 certificates.
321 * Contains a list with the CA names that the server considers trusted.
322 * Normally we should send a certificate that is signed
323 * by one of these CAs. These names are DER encoded. To get a more
324 * meaningful value use the function gnutls_x509_rdn_get().
325 *
326 * @pk_algos contains a list with server's acceptable signature algorithms.
327 * The certificate returned should support the server's given algorithms.
328 *
329 * @st should contain the certificates and private keys.
330 *
331 * If the callback function is provided then gnutls will call it, in the
332 * handshake, after the certificate request message has been received.
333 *
334 * The callback function should set the certificate list to be sent, and
335 * return 0 on success. If no certificate was selected then the number of certificates
336 * should be set to zero. The value (-1) indicates error and the handshake
337 * will be terminated.
338 **/
339void gnutls_certificate_client_set_retrieve_function
340 (gnutls_certificate_credentials_t cred,
341 gnutls_certificate_client_retrieve_function * func)
342{
343 cred->client_get_cert_callback = func;
344}
345
346/**
347 * gnutls_certificate_server_set_retrieve_function - Used to set a callback to retrieve the certificate
348 * @cred: is a #gnutls_certificate_credentials_t structure.
349 * @func: is the callback function
350 *
351 * This function sets a callback to be called in order to retrieve the certificate
352 * to be used in the handshake.
353 * The callback's function prototype is:
354 * int (*callback)(gnutls_session_t, gnutls_retr_st* st);
355 *
356 * @st should contain the certificates and private keys.
357 *
358 * If the callback function is provided then gnutls will call it, in the
359 * handshake, after the certificate request message has been received.
360 *
361 * The callback function should set the certificate list to be sent, and
362 * return 0 on success. The value (-1) indicates error and the handshake
363 * will be terminated.
364 **/
365void gnutls_certificate_server_set_retrieve_function
366 (gnutls_certificate_credentials_t cred,
367 gnutls_certificate_server_retrieve_function * func)
368{
369 cred->server_get_cert_callback = func;
370}
371
372/*-
373 * _gnutls_x509_extract_certificate_activation_time - This function returns the peer's certificate activation time
374 * @cert: should contain an X.509 DER encoded certificate
375 *
376 * This function will return the certificate's activation time in UNIX time
377 * (ie seconds since 00:00:00 UTC January 1, 1970).
378 *
379 * Returns a (time_t) -1 in case of an error.
380 *
381 -*/
382static time_t
383_gnutls_x509_get_raw_crt_activation_time (const gnutls_datum_t * cert)
384{
385 gnutls_x509_crt_t xcert;
386 time_t result;
387
388 result = gnutls_x509_crt_init (&xcert);
389 if (result < 0)
390 return (time_t) - 1;
391
392 result = gnutls_x509_crt_import (xcert, cert, GNUTLS_X509_FMT_DER);
393 if (result < 0)
394 {
395 gnutls_x509_crt_deinit (xcert);
396 return (time_t) - 1;
397 }
398
399 result = gnutls_x509_crt_get_activation_time (xcert);
400
401 gnutls_x509_crt_deinit (xcert);
402
403 return result;
404}
405
406/*-
407 * gnutls_x509_extract_certificate_expiration_time - This function returns the certificate's expiration time
408 * @cert: should contain an X.509 DER encoded certificate
409 *
410 * This function will return the certificate's expiration time in UNIX
411 * time (ie seconds since 00:00:00 UTC January 1, 1970). Returns a
412 *
413 * (time_t) -1 in case of an error.
414 *
415 -*/
416static time_t
417_gnutls_x509_get_raw_crt_expiration_time (const gnutls_datum_t * cert)
418{
419 gnutls_x509_crt_t xcert;
420 time_t result;
421
422 result = gnutls_x509_crt_init (&xcert);
423 if (result < 0)
424 return (time_t) - 1;
425
426 result = gnutls_x509_crt_import (xcert, cert, GNUTLS_X509_FMT_DER);
427 if (result < 0)
428 {
429 gnutls_x509_crt_deinit (xcert);
430 return (time_t) - 1;
431 }
432
433 result = gnutls_x509_crt_get_expiration_time (xcert);
434
435 gnutls_x509_crt_deinit (xcert);
436
437 return result;
438}
439
440/*-
441 * _gnutls_openpgp_crt_verify_peers - This function returns the peer's certificate status
442 * @session: is a gnutls session
443 *
444 * This function will try to verify the peer's certificate and return its status (TRUSTED, INVALID etc.).
445 * Returns a negative error code in case of an error, or GNUTLS_E_NO_CERTIFICATE_FOUND if no certificate was sent.
446 *
447 -*/
448int
449_gnutls_openpgp_crt_verify_peers (gnutls_session_t session,
450 unsigned int *status)
451{
452 cert_auth_info_t info;
453 gnutls_certificate_credentials_t cred;
454 int peer_certificate_list_size, ret;
455
456 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
457
458 info = _gnutls_get_auth_info (session);
459 if (info == NULL)
460 return GNUTLS_E_INVALID_REQUEST;
461
462 cred = (gnutls_certificate_credentials_t)
463 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
464 if (cred == NULL)
465 {
466 gnutls_assert ();
467 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
468 }
469
470 if (info->raw_certificate_list == NULL || info->ncerts == 0)
471 {
472 gnutls_assert ();
473 return GNUTLS_E_NO_CERTIFICATE_FOUND;
474 }
475
476 /* generate a list of gnutls_certs based on the auth info
477 * raw certs.
478 */
479 peer_certificate_list_size = info->ncerts;
480
481 if (peer_certificate_list_size != 1)
482 {
483 gnutls_assert ();
484 return GNUTLS_E_INTERNAL_ERROR;
485 }
486
487 /* Verify certificate
488 */
489 if (_E_gnutls_openpgp_verify_key == NULL)
490 {
491 gnutls_assert ();
492 return GNUTLS_E_INIT_LIBEXTRA;
493 }
494 ret =
495 _E_gnutls_openpgp_verify_key (cred, &info->raw_certificate_list[0],
496 peer_certificate_list_size, status);
497
498 if (ret < 0)
499 {
500 gnutls_assert ();
501 return ret;
502 }
503
504 return 0;
505}
506
507
508/**
509 * gnutls_certificate_verify_peers2 - This function returns the peer's certificate verification status
510 * @session: is a gnutls session
511 * @status: is the output of the verification
512 *
513 * This function will try to verify the peer's certificate and return
514 * its status (trusted, invalid etc.). The value of @status should
515 * be one or more of the gnutls_certificate_status_t enumerated
516 * elements bitwise or'd. To avoid denial of service attacks some
517 * default upper limits regarding the certificate key size and chain
518 * size are set. To override them use
519 * gnutls_certificate_set_verify_limits().
520 *
521 * Note that you must also check the peer's name in order to check if
522 * the verified certificate belongs to the actual peer.
523 *
524 * This is the same as gnutls_x509_crt_list_verify() and uses the
525 * loaded CAs in the credentials as trusted CAs.
526 *
527 * Note that some commonly used X.509 Certificate Authorities are
528 * still using Version 1 certificates. If you want to accept them,
529 * you need to call gnutls_certificate_set_verify_flags() with, e.g.,
530 * %GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT parameter.
531 *
532 * Returns: a negative error code on error and zero on success.
533 **/
534int
535gnutls_certificate_verify_peers2 (gnutls_session_t session,
536 unsigned int *status)
537{
538 cert_auth_info_t info;
539
540 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
541
542 info = _gnutls_get_auth_info (session);
543 if (info == NULL)
544 {
545 return GNUTLS_E_NO_CERTIFICATE_FOUND;
546 }
547
548 if (info->raw_certificate_list == NULL || info->ncerts == 0)
549 return GNUTLS_E_NO_CERTIFICATE_FOUND;
550
551 switch (gnutls_certificate_type_get (session))
552 {
553 case GNUTLS_CRT_X509:
554 return _gnutls_x509_cert_verify_peers (session, status);
555 case GNUTLS_CRT_OPENPGP:
556 return _gnutls_openpgp_crt_verify_peers (session, status);
557 default:
558 return GNUTLS_E_INVALID_REQUEST;
559 }
560}
561
562/**
563 * gnutls_certificate_verify_peers - This function returns the peer's certificate verification status
564 * @session: is a gnutls session
565 *
566 * This function will try to verify the peer's certificate and return
567 * its status (trusted, invalid etc.). However you must also check
568 * the peer's name in order to check if the verified certificate
569 * belongs to the actual peer.
570 *
571 * The return value should be one or more of the
572 * gnutls_certificate_status_t enumerated elements bitwise or'd, or a
573 * negative value on error.
574 *
575 * This is the same as gnutls_x509_crt_list_verify().
576 *
577 * Deprecated: Use gnutls_certificate_verify_peers2() instead.
578 **/
579int
580gnutls_certificate_verify_peers (gnutls_session_t session)
581{
582 unsigned int status;
583 int ret;
584
585 ret = gnutls_certificate_verify_peers2 (session, &status);
586
587 if (ret < 0)
588 {
589 gnutls_assert ();
590 return ret;
591 }
592
593 return status;
594}
595
596/**
597 * gnutls_certificate_expiration_time_peers - This function returns the peer's certificate expiration time
598 * @session: is a gnutls session
599 *
600 * This function will return the peer's certificate expiration time.
601 *
602 * Returns: (time_t)-1 on error.
603 **/
604time_t
605gnutls_certificate_expiration_time_peers (gnutls_session_t session)
606{
607 cert_auth_info_t info;
608
609 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
610
611 info = _gnutls_get_auth_info (session);
612 if (info == NULL)
613 {
614 return (time_t) - 1;
615 }
616
617 if (info->raw_certificate_list == NULL || info->ncerts == 0)
618 {
619 gnutls_assert ();
620 return (time_t) - 1;
621 }
622
623 switch (gnutls_certificate_type_get (session))
624 {
625 case GNUTLS_CRT_X509:
626 return _gnutls_x509_get_raw_crt_expiration_time (&info->
627 raw_certificate_list
628 [0]);
629 case GNUTLS_CRT_OPENPGP:
630 if (_E_gnutls_openpgp_get_raw_key_expiration_time == NULL)
631 return (time_t) - 1;
632 return _E_gnutls_openpgp_get_raw_key_expiration_time (&info->
633 raw_certificate_list
634 [0]);
635 default:
636 return (time_t) - 1;
637 }
638}
639
640/**
641 * gnutls_certificate_activation_time_peers - This function returns the peer's certificate activation time
642 * @session: is a gnutls session
643 *
644 * This function will return the peer's certificate activation time.
645 * This is the creation time for openpgp keys.
646 *
647 * Returns: (time_t)-1 on error.
648 **/
649time_t
650gnutls_certificate_activation_time_peers (gnutls_session_t session)
651{
652 cert_auth_info_t info;
653
654 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
655
656 info = _gnutls_get_auth_info (session);
657 if (info == NULL)
658 {
659 return (time_t) - 1;
660 }
661
662 if (info->raw_certificate_list == NULL || info->ncerts == 0)
663 {
664 gnutls_assert ();
665 return (time_t) - 1;
666 }
667
668 switch (gnutls_certificate_type_get (session))
669 {
670 case GNUTLS_CRT_X509:
671 return _gnutls_x509_get_raw_crt_activation_time (&info->
672 raw_certificate_list
673 [0]);
674 case GNUTLS_CRT_OPENPGP:
675 if (_E_gnutls_openpgp_get_raw_key_creation_time == NULL)
676 return (time_t) - 1;
677 return _E_gnutls_openpgp_get_raw_key_creation_time (&info->
678 raw_certificate_list
679 [0]);
680 default:
681 return (time_t) - 1;
682 }
683}
684
685int
686_gnutls_raw_cert_to_gcert (gnutls_cert * gcert,
687 gnutls_certificate_type_t type,
688 const gnutls_datum_t * raw_cert,
689 int flags /* OR of ConvFlags */ )
690{
691 switch (type)
692 {
693 case GNUTLS_CRT_X509:
694 return _gnutls_x509_raw_cert_to_gcert (gcert, raw_cert, flags);
695 case GNUTLS_CRT_OPENPGP:
696 if (_E_gnutls_openpgp_raw_key_to_gcert == NULL)
697 {
698 gnutls_assert ();
699 return GNUTLS_E_INIT_LIBEXTRA;
700 }
701 return _E_gnutls_openpgp_raw_key_to_gcert (gcert, raw_cert);
702 default:
703 gnutls_assert ();
704 return GNUTLS_E_INTERNAL_ERROR;
705 }
706}
707
708int
709_gnutls_raw_privkey_to_gkey (gnutls_privkey * key,
710 gnutls_certificate_type_t type,
711 const gnutls_datum_t * raw_key,
712 int key_enc /* DER or PEM */ )
713{
714 switch (type)
715 {
716 case GNUTLS_CRT_X509:
717 return _gnutls_x509_raw_privkey_to_gkey (key, raw_key, key_enc);
718 case GNUTLS_CRT_OPENPGP:
719 if (_E_gnutls_openpgp_raw_privkey_to_gkey == NULL)
720 {
721 gnutls_assert ();
722 return GNUTLS_E_INIT_LIBEXTRA;
723 }
724 return _E_gnutls_openpgp_raw_privkey_to_gkey (key, raw_key,
725 (gnutls_openpgp_crt_fmt_t)
726 key_enc);
727 default:
728 gnutls_assert ();
729 return GNUTLS_E_INTERNAL_ERROR;
730 }
731}
732
733
734/* This function will convert a der certificate to a format
735 * (structure) that gnutls can understand and use. Actually the
736 * important thing on this function is that it extracts the
737 * certificate's (public key) parameters.
738 *
739 * The noext flag is used to complete the handshake even if the
740 * extensions found in the certificate are unsupported and critical.
741 * The critical extensions will be catched by the verification functions.
742 */
743int
744_gnutls_x509_raw_cert_to_gcert (gnutls_cert * gcert,
745 const gnutls_datum_t * derCert,
746 int flags /* OR of ConvFlags */ )
747{
748 int ret;
749 gnutls_x509_crt_t cert;
750
751 ret = gnutls_x509_crt_init (&cert);
752 if (ret < 0)
753 {
754 gnutls_assert ();
755 return ret;
756 }
757
758 ret = gnutls_x509_crt_import (cert, derCert, GNUTLS_X509_FMT_DER);
759 if (ret < 0)
760 {
761 gnutls_assert ();
762 gnutls_x509_crt_deinit (cert);
763 return ret;
764 }
765
766 ret = _gnutls_x509_crt_to_gcert (gcert, cert, flags);
767 gnutls_x509_crt_deinit (cert);
768
769 return ret;
770}
771
772/* Like above but it accepts a parsed certificate instead.
773 */
774int
775_gnutls_x509_crt_to_gcert (gnutls_cert * gcert,
776 gnutls_x509_crt_t cert, unsigned int flags)
777{
778 int ret = 0;
779
780 memset (gcert, 0, sizeof (gnutls_cert));
781 gcert->cert_type = GNUTLS_CRT_X509;
782
783 if (!(flags & CERT_NO_COPY))
784 {
785#define SMALL_DER 512
786 opaque *der;
787 size_t der_size = SMALL_DER;
788
789 /* initially allocate a bogus size, just in case the certificate
790 * fits in it. That way we minimize the DER encodings performed.
791 */
792 der = gnutls_malloc (SMALL_DER);
793 if (der == NULL)
794 {
795 gnutls_assert ();
796 return GNUTLS_E_MEMORY_ERROR;
797 }
798
799 ret =
800 gnutls_x509_crt_export (cert, GNUTLS_X509_FMT_DER, der, &der_size);
801 if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
802 {
803 gnutls_assert ();
804 gnutls_free (der);
805 return ret;
806 }
807
808 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
809 {
810 der = gnutls_realloc (der, der_size);
811 if (der == NULL)
812 {
813 gnutls_assert ();
814 return GNUTLS_E_MEMORY_ERROR;
815 }
816
817 ret =
818 gnutls_x509_crt_export (cert, GNUTLS_X509_FMT_DER, der,
819 &der_size);
820 if (ret < 0)
821 {
822 gnutls_assert ();
823 gnutls_free (der);
824 return ret;
825 }
826 }
827
828 gcert->raw.data = der;
829 gcert->raw.size = der_size;
830 }
831 else
832 /* now we have 0 or a bitwise or of things to decode */
833 flags ^= CERT_NO_COPY;
834
835
836 if (flags & CERT_ONLY_EXTENSIONS || flags == 0)
837 {
838 gnutls_x509_crt_get_key_usage (cert, &gcert->key_usage, NULL);
839 gcert->version = gnutls_x509_crt_get_version (cert);
840 }
841 gcert->subject_pk_algorithm = gnutls_x509_crt_get_pk_algorithm (cert, NULL);
842
843 if (flags & CERT_ONLY_PUBKEY || flags == 0)
844 {
845 gcert->params_size = MAX_PUBLIC_PARAMS_SIZE;
846 ret =
847 _gnutls_x509_crt_get_mpis (cert, gcert->params, &gcert->params_size);
848 if (ret < 0)
849 {
850 gnutls_assert ();
851 return ret;
852 }
853 }
854
855 return 0;
856
857}
858
859void
860_gnutls_gcert_deinit (gnutls_cert * cert)
861{
862 int i;
863
864 if (cert == NULL)
865 return;
866
867 for (i = 0; i < cert->params_size; i++)
868 {
869 _gnutls_mpi_release (&cert->params[i]);
870 }
871
872 _gnutls_free_datum (&cert->raw);
873}
874
875/**
876 * gnutls_sign_callback_set:
877 * @session: is a gnutls session
878 * @sign_func: function pointer to application's sign callback.
879 * @userdata: void pointer that will be passed to sign callback.
880 *
881 * Set the callback function. The function must have this prototype:
882 *
883 * typedef int (*gnutls_sign_func) (gnutls_session_t session,
884 * void *userdata,
885 * gnutls_certificate_type_t cert_type,
886 * const gnutls_datum_t * cert,
887 * const gnutls_datum_t * hash,
888 * gnutls_datum_t * signature);
889 *
890 * The @userdata parameter is passed to the @sign_func verbatim, and
891 * can be used to store application-specific data needed in the
892 * callback function. See also gnutls_sign_callback_get().
893 **/
894void
895gnutls_sign_callback_set (gnutls_session_t session,
896 gnutls_sign_func sign_func, void *userdata)
897{
898 session->internals.sign_func = sign_func;
899 session->internals.sign_func_userdata = userdata;
900}
901
902/**
903 * gnutls_sign_callback_get:
904 * @session: is a gnutls session
905 * @userdata: if non-%NULL, will be set to abstract callback pointer.
906 *
907 * Retrieve the callback function, and its userdata pointer.
908 *
909 * Returns: The function pointer set by gnutls_sign_callback_set(), or
910 * if not set, %NULL.
911 **/
912gnutls_sign_func
913gnutls_sign_callback_get (gnutls_session_t session, void **userdata)
914{
915 if (userdata)
916 *userdata = session->internals.sign_func_userdata;
917 return session->internals.sign_func;
918}
diff --git a/src/daemon/https/tls/gnutls_cert.h b/src/daemon/https/tls/gnutls_cert.h
new file mode 100644
index 00000000..09df10eb
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_cert.h
@@ -0,0 +1,132 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#ifndef GNUTLS_CERT_H
26# define GNUTLS_CERT_H
27
28#include <gnutls_pk.h>
29#include <libtasn1.h>
30#include "x509.h"
31
32#define MAX_PUBLIC_PARAMS_SIZE 4 /* ok for RSA and DSA */
33
34/* parameters should not be larger than this limit */
35#define DSA_PUBLIC_PARAMS 4
36#define RSA_PUBLIC_PARAMS 2
37
38/* For key Usage, test as:
39 * if (st.key_usage & KEY_DIGITAL_SIGNATURE) ...
40 */
41#define KEY_DIGITAL_SIGNATURE 128
42#define KEY_NON_REPUDIATION 64
43#define KEY_KEY_ENCIPHERMENT 32
44#define KEY_DATA_ENCIPHERMENT 16
45#define KEY_KEY_AGREEMENT 8
46#define KEY_KEY_CERT_SIGN 4
47#define KEY_CRL_SIGN 2
48#define KEY_ENCIPHER_ONLY 1
49#define KEY_DECIPHER_ONLY 32768
50
51typedef struct gnutls_cert
52{
53 mpi_t params[MAX_PUBLIC_PARAMS_SIZE]; /* the size of params depends on the public
54 * key algorithm
55 * RSA: [0] is modulus
56 * [1] is public exponent
57 * DSA: [0] is p
58 * [1] is q
59 * [2] is g
60 * [3] is public key
61 */
62 int params_size; /* holds the size of MPI params */
63
64 gnutls_pk_algorithm_t subject_pk_algorithm;
65
66 unsigned int key_usage; /* bits from KEY_*
67 */
68
69 unsigned int version;
70 /* holds the type (PGP, X509)
71 */
72 gnutls_certificate_type_t cert_type;
73
74 gnutls_datum_t raw;
75
76} gnutls_cert;
77
78typedef struct gnutls_privkey_int
79{
80 mpi_t params[MAX_PRIV_PARAMS_SIZE]; /* the size of params depends on the public
81 * key algorithm
82 */
83 /*
84 * RSA: [0] is modulus
85 * [1] is public exponent
86 * [2] is private exponent
87 * [3] is prime1 (p)
88 * [4] is prime2 (q)
89 * [5] is coefficient (u == inverse of p mod q)
90 * DSA: [0] is p
91 * [1] is q
92 * [2] is g
93 * [3] is y (public key)
94 * [4] is x (private key)
95 */
96 int params_size; /* holds the number of params */
97
98 gnutls_pk_algorithm_t pk_algorithm;
99} gnutls_privkey;
100
101struct gnutls_session_int; /* because gnutls_session_t is not defined when this file is included */
102
103typedef enum ConvFlags
104{
105 CERT_NO_COPY = 2,
106 CERT_ONLY_PUBKEY = 4,
107 CERT_ONLY_EXTENSIONS = 16
108} ConvFlags;
109
110int _gnutls_x509_raw_cert_to_gcert (gnutls_cert * gcert,
111 const gnutls_datum_t * derCert,
112 int flags);
113int _gnutls_x509_crt_to_gcert (gnutls_cert * gcert, gnutls_x509_crt_t cert,
114 unsigned int flags);
115
116void _gnutls_gkey_deinit (gnutls_privkey * key);
117void _gnutls_gcert_deinit (gnutls_cert * cert);
118
119int _gnutls_selected_cert_supported_kx (struct gnutls_session_int *session,
120 gnutls_kx_algorithm_t ** alg,
121 int *alg_size);
122
123int _gnutls_raw_cert_to_gcert (gnutls_cert * gcert,
124 gnutls_certificate_type_t type,
125 const gnutls_datum_t * raw_cert,
126 int flags /* OR of ConvFlags */ );
127int _gnutls_raw_privkey_to_gkey (gnutls_privkey * key,
128 gnutls_certificate_type_t type,
129 const gnutls_datum_t * raw_key,
130 int key_enc /* DER or PEM */ );
131
132#endif
diff --git a/src/daemon/https/tls/gnutls_cipher.c b/src/daemon/https/tls/gnutls_cipher.c
new file mode 100644
index 00000000..8245b1c0
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_cipher.c
@@ -0,0 +1,584 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* Some high level functions to be used in the record encryption are
26 * included here.
27 */
28
29#include "gnutls_int.h"
30#include "gnutls_errors.h"
31#include "gnutls_compress.h"
32#include "gnutls_cipher.h"
33#include "gnutls_algorithms.h"
34#include "gnutls_hash_int.h"
35#include "gnutls_cipher_int.h"
36#include "debug.h"
37#include "gnutls_num.h"
38#include "gnutls_datum.h"
39#include "gnutls_kx.h"
40#include "gnutls_record.h"
41#include "gnutls_constate.h"
42#include <gc.h>
43
44inline static int
45is_write_comp_null (gnutls_session_t session)
46{
47 if (session->security_parameters.write_compression_algorithm ==
48 GNUTLS_COMP_NULL)
49 return 0;
50
51 return 1;
52}
53
54inline static int
55is_read_comp_null (gnutls_session_t session)
56{
57 if (session->security_parameters.read_compression_algorithm ==
58 GNUTLS_COMP_NULL)
59 return 0;
60
61 return 1;
62}
63
64
65/* returns ciphertext which contains the headers too. This also
66 * calculates the size in the header field.
67 *
68 * If random pad != 0 then the random pad data will be appended.
69 */
70int
71_gnutls_encrypt (gnutls_session_t session, const opaque * headers,
72 size_t headers_size, const opaque * data,
73 size_t data_size, opaque * ciphertext,
74 size_t ciphertext_size, content_type_t type, int random_pad)
75{
76 gnutls_datum_t plain;
77 gnutls_datum_t comp;
78 int ret;
79 int free_comp = 1;
80
81 plain.data = (opaque *) data;
82 plain.size = data_size;
83
84 if (plain.size == 0 || is_write_comp_null (session) == 0)
85 {
86 comp = plain;
87 free_comp = 0;
88 }
89 else
90 {
91 /* Here comp is allocated and must be
92 * freed.
93 */
94 ret = _gnutls_m_plaintext2compressed (session, &comp, &plain);
95 if (ret < 0)
96 {
97 gnutls_assert ();
98 return ret;
99 }
100 }
101
102 ret = _gnutls_compressed2ciphertext (session, &ciphertext[headers_size],
103 ciphertext_size - headers_size,
104 comp, type, random_pad);
105
106 if (free_comp)
107 _gnutls_free_datum (&comp);
108
109 if (ret < 0)
110 {
111 gnutls_assert ();
112 return ret;
113 }
114
115
116 /* copy the headers */
117 memcpy (ciphertext, headers, headers_size);
118 _gnutls_write_uint16 (ret, &ciphertext[3]);
119
120 return ret + headers_size;
121}
122
123/* Decrypts the given data.
124 * Returns the decrypted data length.
125 */
126int
127_gnutls_decrypt (gnutls_session_t session, opaque * ciphertext,
128 size_t ciphertext_size, uint8_t * data,
129 size_t max_data_size, content_type_t type)
130{
131 gnutls_datum_t gtxt;
132 gnutls_datum_t gcipher;
133 int ret;
134
135 if (ciphertext_size == 0)
136 return 0;
137
138 gcipher.size = ciphertext_size;
139 gcipher.data = ciphertext;
140
141 ret =
142 _gnutls_ciphertext2compressed (session, data, max_data_size,
143 gcipher, type);
144 if (ret < 0)
145 {
146 return ret;
147 }
148
149 if (ret == 0 || is_read_comp_null (session) == 0)
150 {
151 /* ret == ret */
152
153 }
154 else
155 {
156 gnutls_datum_t gcomp;
157
158 /* compression has this malloc overhead.
159 */
160
161 gcomp.data = data;
162 gcomp.size = ret;
163 ret = _gnutls_m_compressed2plaintext (session, &gtxt, &gcomp);
164 if (ret < 0)
165 {
166 return ret;
167 }
168
169 if (gtxt.size > MAX_RECORD_RECV_SIZE)
170 {
171 gnutls_assert ();
172 _gnutls_free_datum (&gtxt);
173 /* This shouldn't have happen and
174 * is a TLS fatal error.
175 */
176 return GNUTLS_E_DECOMPRESSION_FAILED;
177 }
178
179 /* This check is not really needed */
180 if (max_data_size < MAX_RECORD_RECV_SIZE)
181 {
182 gnutls_assert ();
183 _gnutls_free_datum (&gtxt);
184 return GNUTLS_E_INTERNAL_ERROR;
185 }
186
187 memcpy (data, gtxt.data, gtxt.size);
188 ret = gtxt.size;
189
190 _gnutls_free_datum (&gtxt);
191 }
192
193 return ret;
194}
195
196inline static mac_hd_t
197mac_init (gnutls_mac_algorithm_t mac, opaque * secret, int secret_size,
198 int ver)
199{
200 mac_hd_t td;
201
202 if (mac == GNUTLS_MAC_NULL)
203 return GNUTLS_MAC_FAILED;
204
205 if (ver == GNUTLS_SSL3)
206 { /* SSL 3.0 */
207 td = _gnutls_mac_init_ssl3 (mac, secret, secret_size);
208 }
209 else
210 { /* TLS 1.x */
211 td = _gnutls_hmac_init (mac, secret, secret_size);
212 }
213
214 return td;
215}
216
217inline static void
218mac_deinit (mac_hd_t td, opaque * res, int ver)
219{
220 if (ver == GNUTLS_SSL3)
221 { /* SSL 3.0 */
222 _gnutls_mac_deinit_ssl3 (td, res);
223 }
224 else
225 {
226 _gnutls_hmac_deinit (td, res);
227 }
228}
229
230inline static int
231calc_enc_length (gnutls_session_t session, int data_size,
232 int hash_size, uint8_t * pad, int random_pad,
233 cipher_type_t block_algo, uint16_t blocksize)
234{
235 uint8_t rnd;
236 int length;
237
238 *pad = 0;
239
240 switch (block_algo)
241 {
242 case CIPHER_STREAM:
243 length = data_size + hash_size;
244
245 break;
246 case CIPHER_BLOCK:
247 if (gc_nonce (&rnd, 1) != GC_OK)
248 {
249 gnutls_assert ();
250 return GNUTLS_E_RANDOM_FAILED;
251 }
252
253 /* make rnd a multiple of blocksize */
254 if (session->security_parameters.version == GNUTLS_SSL3 ||
255 random_pad == 0)
256 {
257 rnd = 0;
258 }
259 else
260 {
261 rnd = (rnd / blocksize) * blocksize;
262 /* added to avoid the case of pad calculated 0
263 * seen below for pad calculation.
264 */
265 if (rnd > blocksize)
266 rnd -= blocksize;
267 }
268
269 length = data_size + hash_size;
270
271 *pad = (uint8_t) (blocksize - (length % blocksize)) + rnd;
272
273 length += *pad;
274 if (session->security_parameters.version >= GNUTLS_TLS1_1)
275 length += blocksize; /* for the IV */
276
277 break;
278 default:
279 gnutls_assert ();
280 return GNUTLS_E_INTERNAL_ERROR;
281 }
282
283 return length;
284}
285
286/* This is the actual encryption
287 * Encrypts the given compressed datum, and puts the result to cipher_data,
288 * which has cipher_size size.
289 * return the actual encrypted data length.
290 */
291int
292_gnutls_compressed2ciphertext (gnutls_session_t session,
293 opaque * cipher_data, int cipher_size,
294 gnutls_datum_t compressed,
295 content_type_t _type, int random_pad)
296{
297 uint8_t MAC[MAX_HASH_SIZE];
298 uint16_t c_length;
299 uint8_t pad;
300 int length, ret;
301 mac_hd_t td;
302 uint8_t type = _type;
303 uint8_t major, minor;
304 int hash_size =
305 _gnutls_hash_get_algo_len (session->security_parameters.
306 write_mac_algorithm);
307 gnutls_protocol_t ver;
308 int blocksize =
309 _gnutls_cipher_get_block_size (session->security_parameters.
310 write_bulk_cipher_algorithm);
311 cipher_type_t block_algo =
312 _gnutls_cipher_is_block (session->security_parameters.
313 write_bulk_cipher_algorithm);
314 opaque *data_ptr;
315
316
317 ver = gnutls_protocol_get_version (session);
318 minor = _gnutls_version_get_minor (ver);
319 major = _gnutls_version_get_major (ver);
320
321
322 /* Initialize MAC */
323 td = mac_init (session->security_parameters.write_mac_algorithm,
324 session->connection_state.write_mac_secret.data,
325 session->connection_state.write_mac_secret.size, ver);
326
327 if (td == GNUTLS_MAC_FAILED
328 && session->security_parameters.write_mac_algorithm != GNUTLS_MAC_NULL)
329 {
330 gnutls_assert ();
331 return GNUTLS_E_INTERNAL_ERROR;
332 }
333
334 c_length = _gnutls_conv_uint16 (compressed.size);
335
336 if (td != GNUTLS_MAC_FAILED)
337 { /* actually when the algorithm in not the NULL one */
338 _gnutls_hmac (td,
339 UINT64DATA (session->connection_state.
340 write_sequence_number), 8);
341
342 _gnutls_hmac (td, &type, 1);
343 if (ver >= GNUTLS_TLS1)
344 { /* TLS 1.0 or higher */
345 _gnutls_hmac (td, &major, 1);
346 _gnutls_hmac (td, &minor, 1);
347 }
348 _gnutls_hmac (td, &c_length, 2);
349 _gnutls_hmac (td, compressed.data, compressed.size);
350 mac_deinit (td, MAC, ver);
351 }
352
353
354 /* Calculate the encrypted length (padding etc.)
355 */
356 length =
357 calc_enc_length (session, compressed.size, hash_size, &pad,
358 random_pad, block_algo, blocksize);
359 if (length < 0)
360 {
361 gnutls_assert ();
362 return length;
363 }
364
365 /* copy the encrypted data to cipher_data.
366 */
367 if (cipher_size < length)
368 {
369 gnutls_assert ();
370 return GNUTLS_E_MEMORY_ERROR;
371 }
372
373 data_ptr = cipher_data;
374 if (block_algo == CIPHER_BLOCK &&
375 session->security_parameters.version >= GNUTLS_TLS1_1)
376 {
377 /* copy the random IV.
378 */
379 if (gc_nonce (data_ptr, blocksize) != GC_OK)
380 {
381 gnutls_assert ();
382 return GNUTLS_E_RANDOM_FAILED;
383 }
384 data_ptr += blocksize;
385 }
386
387 memcpy (data_ptr, compressed.data, compressed.size);
388 data_ptr += compressed.size;
389
390 if (hash_size > 0)
391 {
392 memcpy (data_ptr, MAC, hash_size);
393 data_ptr += hash_size;
394 }
395 if (block_algo == CIPHER_BLOCK && pad > 0)
396 {
397 memset (data_ptr, pad - 1, pad);
398 }
399
400
401 /* Actual encryption (inplace).
402 */
403 ret = _gnutls_cipher_encrypt (session->connection_state.
404 write_cipher_state, cipher_data, length);
405 if (ret < 0)
406 {
407 gnutls_assert ();
408 return ret;
409 }
410
411 return length;
412}
413
414/* Deciphers the ciphertext packet, and puts the result to compress_data, of compress_size.
415 * Returns the actual compressed packet size.
416 */
417int
418_gnutls_ciphertext2compressed (gnutls_session_t session,
419 opaque * compress_data,
420 int compress_size,
421 gnutls_datum_t ciphertext, uint8_t type)
422{
423 uint8_t MAC[MAX_HASH_SIZE];
424 uint16_t c_length;
425 uint8_t pad;
426 int length;
427 mac_hd_t td;
428 uint16_t blocksize;
429 int ret, i, pad_failed = 0;
430 uint8_t major, minor;
431 gnutls_protocol_t ver;
432 int hash_size =
433 _gnutls_hash_get_algo_len (session->security_parameters.
434 read_mac_algorithm);
435
436 ver = gnutls_protocol_get_version (session);
437 minor = _gnutls_version_get_minor (ver);
438 major = _gnutls_version_get_major (ver);
439
440 blocksize = _gnutls_cipher_get_block_size (session->security_parameters.
441 read_bulk_cipher_algorithm);
442
443 /* initialize MAC
444 */
445 td = mac_init (session->security_parameters.read_mac_algorithm,
446 session->connection_state.read_mac_secret.data,
447 session->connection_state.read_mac_secret.size, ver);
448
449 if (td == GNUTLS_MAC_FAILED
450 && session->security_parameters.read_mac_algorithm != GNUTLS_MAC_NULL)
451 {
452 gnutls_assert ();
453 return GNUTLS_E_INTERNAL_ERROR;
454 }
455
456
457 /* actual decryption (inplace)
458 */
459 switch (_gnutls_cipher_is_block
460 (session->security_parameters.read_bulk_cipher_algorithm))
461 {
462 case CIPHER_STREAM:
463 if ((ret = _gnutls_cipher_decrypt (session->connection_state.
464 read_cipher_state,
465 ciphertext.data,
466 ciphertext.size)) < 0)
467 {
468 gnutls_assert ();
469 return ret;
470 }
471
472 length = ciphertext.size - hash_size;
473
474 break;
475 case CIPHER_BLOCK:
476 if ((ciphertext.size < blocksize) || (ciphertext.size % blocksize != 0))
477 {
478 gnutls_assert ();
479 return GNUTLS_E_DECRYPTION_FAILED;
480 }
481
482 if ((ret = _gnutls_cipher_decrypt (session->connection_state.
483 read_cipher_state,
484 ciphertext.data,
485 ciphertext.size)) < 0)
486 {
487 gnutls_assert ();
488 return ret;
489 }
490
491 /* ignore the IV in TLS 1.1.
492 */
493 if (session->security_parameters.version >= GNUTLS_TLS1_1)
494 {
495 ciphertext.size -= blocksize;
496 ciphertext.data += blocksize;
497
498 if (ciphertext.size == 0)
499 {
500 gnutls_assert ();
501 return GNUTLS_E_DECRYPTION_FAILED;
502 }
503 }
504
505 pad = ciphertext.data[ciphertext.size - 1] + 1; /* pad */
506
507 length = ciphertext.size - hash_size - pad;
508
509 if (pad > ciphertext.size - hash_size)
510 {
511 gnutls_assert ();
512 /* We do not fail here. We check below for the
513 * the pad_failed. If zero means success.
514 */
515 pad_failed = GNUTLS_E_DECRYPTION_FAILED;
516 }
517
518 /* Check the pading bytes (TLS 1.x)
519 */
520 if (ver >= GNUTLS_TLS1 && pad_failed == 0)
521 for (i = 2; i < pad; i++)
522 {
523 if (ciphertext.data[ciphertext.size - i] !=
524 ciphertext.data[ciphertext.size - 1])
525 pad_failed = GNUTLS_E_DECRYPTION_FAILED;
526 }
527 break;
528 default:
529 gnutls_assert ();
530 return GNUTLS_E_INTERNAL_ERROR;
531 }
532
533 if (length < 0)
534 length = 0;
535 c_length = _gnutls_conv_uint16 ((uint16_t) length);
536
537 /* Pass the type, version, length and compressed through
538 * MAC.
539 */
540 if (td != GNUTLS_MAC_FAILED)
541 {
542 _gnutls_hmac (td,
543 UINT64DATA (session->connection_state.
544 read_sequence_number), 8);
545
546 _gnutls_hmac (td, &type, 1);
547 if (ver >= GNUTLS_TLS1)
548 { /* TLS 1.x */
549 _gnutls_hmac (td, &major, 1);
550 _gnutls_hmac (td, &minor, 1);
551 }
552 _gnutls_hmac (td, &c_length, 2);
553
554 if (length > 0)
555 _gnutls_hmac (td, ciphertext.data, length);
556
557 mac_deinit (td, MAC, ver);
558 }
559
560 /* This one was introduced to avoid a timing attack against the TLS
561 * 1.0 protocol.
562 */
563 if (pad_failed != 0)
564 return pad_failed;
565
566 /* HMAC was not the same.
567 */
568 if (memcmp (MAC, &ciphertext.data[length], hash_size) != 0)
569 {
570 gnutls_assert ();
571 return GNUTLS_E_DECRYPTION_FAILED;
572 }
573
574 /* copy the decrypted stuff to compress_data.
575 */
576 if (compress_size < length)
577 {
578 gnutls_assert ();
579 return GNUTLS_E_DECOMPRESSION_FAILED;
580 }
581 memcpy (compress_data, ciphertext.data, length);
582
583 return length;
584}
diff --git a/src/daemon/https/tls/gnutls_cipher.h b/src/daemon/https/tls/gnutls_cipher.h
new file mode 100644
index 00000000..0279e859
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_cipher.h
@@ -0,0 +1,41 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25int _gnutls_encrypt (gnutls_session_t session, const opaque * headers,
26 size_t headers_size, const opaque * data,
27 size_t data_size, opaque * ciphertext,
28 size_t ciphertext_size, content_type_t type,
29 int random_pad);
30
31int _gnutls_decrypt (gnutls_session_t session, opaque * ciphertext,
32 size_t ciphertext_size, uint8_t * data, size_t data_size,
33 content_type_t type);
34int _gnutls_compressed2ciphertext (gnutls_session_t session,
35 opaque * cipher_data, int cipher_size,
36 gnutls_datum_t compressed,
37 content_type_t _type, int random_pad);
38int _gnutls_ciphertext2compressed (gnutls_session_t session,
39 opaque * compress_data,
40 int compress_size,
41 gnutls_datum_t ciphertext, uint8_t type);
diff --git a/src/daemon/https/tls/gnutls_cipher_int.c b/src/daemon/https/tls/gnutls_cipher_int.c
new file mode 100644
index 00000000..c9200e5b
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_cipher_int.c
@@ -0,0 +1,133 @@
1/*
2 * Copyright (C) 2000, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_errors.h>
27#include <gnutls_cipher_int.h>
28#include <gnutls_datum.h>
29
30cipher_hd_t
31_gnutls_cipher_init (gnutls_cipher_algorithm_t cipher,
32 const gnutls_datum_t * key, const gnutls_datum_t * iv)
33{
34 cipher_hd_t ret = NULL;
35 int err = GC_INVALID_CIPHER; /* doesn't matter */
36
37 switch (cipher)
38 {
39 case GNUTLS_CIPHER_AES_128_CBC:
40 err = gc_cipher_open (GC_AES128, GC_CBC, &ret);
41 break;
42
43 case GNUTLS_CIPHER_AES_256_CBC:
44 err = gc_cipher_open (GC_AES256, GC_CBC, &ret);
45 break;
46
47 case GNUTLS_CIPHER_3DES_CBC:
48 err = gc_cipher_open (GC_3DES, GC_CBC, &ret);
49 break;
50
51 case GNUTLS_CIPHER_DES_CBC:
52 err = gc_cipher_open (GC_DES, GC_CBC, &ret);
53 break;
54
55 case GNUTLS_CIPHER_ARCFOUR_128:
56 err = gc_cipher_open (GC_ARCFOUR128, GC_STREAM, &ret);
57 break;
58
59 case GNUTLS_CIPHER_ARCFOUR_40:
60 err = gc_cipher_open (GC_ARCFOUR40, GC_STREAM, &ret);
61 break;
62
63 case GNUTLS_CIPHER_RC2_40_CBC:
64 err = gc_cipher_open (GC_ARCTWO40, GC_CBC, &ret);
65 break;
66
67#ifdef ENABLE_CAMELLIA
68 case GNUTLS_CIPHER_CAMELLIA_128_CBC:
69 err = gc_cipher_open (GC_CAMELLIA128, GC_CBC, &ret);
70 break;
71
72 case GNUTLS_CIPHER_CAMELLIA_256_CBC:
73 err = gc_cipher_open (GC_CAMELLIA256, GC_CBC, &ret);
74 break;
75#endif
76
77 default:
78 return NULL;
79 }
80
81 if (err == 0)
82 {
83 gc_cipher_setkey (ret, key->size, key->data);
84 if (iv->data != NULL && iv->size > 0)
85 gc_cipher_setiv (ret, iv->size, iv->data);
86 }
87 else if (cipher != GNUTLS_CIPHER_NULL)
88 {
89 gnutls_assert ();
90 _gnutls_x509_log ("Crypto cipher[%d] error: %d\n", cipher, err);
91 /* FIXME: gc_strerror */
92 }
93
94 return ret;
95}
96
97int
98_gnutls_cipher_encrypt (cipher_hd_t handle, void *text, int textlen)
99{
100 if (handle != GNUTLS_CIPHER_FAILED)
101 {
102 if (gc_cipher_encrypt_inline (handle, textlen, text) != 0)
103 {
104 gnutls_assert ();
105 return GNUTLS_E_INTERNAL_ERROR;
106 }
107 }
108 return 0;
109}
110
111int
112_gnutls_cipher_decrypt (cipher_hd_t handle, void *ciphertext,
113 int ciphertextlen)
114{
115 if (handle != GNUTLS_CIPHER_FAILED)
116 {
117 if (gc_cipher_decrypt_inline (handle, ciphertextlen, ciphertext) != 0)
118 {
119 gnutls_assert ();
120 return GNUTLS_E_INTERNAL_ERROR;
121 }
122 }
123 return 0;
124}
125
126void
127_gnutls_cipher_deinit (cipher_hd_t handle)
128{
129 if (handle != GNUTLS_CIPHER_FAILED)
130 {
131 gc_cipher_close (handle);
132 }
133}
diff --git a/src/daemon/https/tls/gnutls_cipher_int.h b/src/daemon/https/tls/gnutls_cipher_int.h
new file mode 100644
index 00000000..78ed487f
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_cipher_int.h
@@ -0,0 +1,46 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#ifndef GNUTLS_CIPHER_INT
26# define GNUTLS_CIPHER_INT
27
28#define cipher_hd_t gc_cipher_handle
29#define GNUTLS_CIPHER_FAILED NULL
30
31// TODO gc_cipher_handle -> void * x3
32void * _gnutls_cipher_init(gnutls_cipher_algorithm_t cipher,
33 const gnutls_datum_t * key,
34 const gnutls_datum_t * iv);
35
36int _gnutls_cipher_encrypt(void * handle,
37 void *text,
38 int textlen);
39
40int _gnutls_cipher_decrypt(void * handle,
41 void *ciphertext,
42 int ciphertextlen);
43
44void _gnutls_cipher_deinit(void * handle);
45
46#endif /* GNUTLS_CIPHER_INT */
diff --git a/src/daemon/https/tls/gnutls_compress.c b/src/daemon/https/tls/gnutls_compress.c
new file mode 100644
index 00000000..e6561ad6
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_compress.c
@@ -0,0 +1,80 @@
1/*
2 * Copyright (C) 2000, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file contains the functions which convert the TLS plaintext
26 * packet to TLS compressed packet.
27 */
28
29#include "gnutls_int.h"
30#include "gnutls_compress.h"
31#include "gnutls_errors.h"
32#include "gnutls_compress_int.h"
33
34/* These functions allocate the return value internally
35 */
36int
37_gnutls_m_plaintext2compressed (gnutls_session_t session,
38 gnutls_datum_t * compressed,
39 const gnutls_datum_t * plaintext)
40{
41 int size;
42 opaque *data;
43
44 size =
45 _gnutls_compress (session->connection_state.write_compression_state,
46 plaintext->data, plaintext->size, &data,
47 MAX_RECORD_SEND_SIZE + EXTRA_COMP_SIZE);
48 if (size < 0)
49 {
50 gnutls_assert ();
51 return GNUTLS_E_COMPRESSION_FAILED;
52 }
53 compressed->data = data;
54 compressed->size = size;
55
56 return 0;
57}
58
59int
60_gnutls_m_compressed2plaintext (gnutls_session_t session,
61 gnutls_datum_t * plain,
62 const gnutls_datum_t * compressed)
63{
64 int size;
65 opaque *data;
66
67 size =
68 _gnutls_decompress (session->connection_state.
69 read_compression_state, compressed->data,
70 compressed->size, &data, MAX_RECORD_RECV_SIZE);
71 if (size < 0)
72 {
73 gnutls_assert ();
74 return GNUTLS_E_DECOMPRESSION_FAILED;
75 }
76 plain->data = data;
77 plain->size = size;
78
79 return 0;
80}
diff --git a/src/daemon/https/tls/gnutls_compress.h b/src/daemon/https/tls/gnutls_compress.h
new file mode 100644
index 00000000..44666321
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_compress.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25int _gnutls_m_plaintext2compressed (gnutls_session_t session,
26 gnutls_datum_t * compressed,
27 const gnutls_datum_t *plaintext);
28int _gnutls_m_compressed2plaintext (gnutls_session_t session,
29 gnutls_datum_t * plain,
30 const gnutls_datum_t* compressed);
diff --git a/src/daemon/https/tls/gnutls_compress_int.c b/src/daemon/https/tls/gnutls_compress_int.c
new file mode 100644
index 00000000..eedfd63d
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_compress_int.c
@@ -0,0 +1,300 @@
1/*
2 * Copyright (C) 2000, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_compress.h>
27#include <gnutls_algorithms.h>
28#include "gnutls_errors.h"
29
30/* The flag d is the direction (compress, decompress). Non zero is
31 * decompress.
32 */
33comp_hd_t
34_gnutls_comp_init (gnutls_compression_method_t method, int d)
35{
36 comp_hd_t ret;
37 int err;
38
39 ret = gnutls_malloc (sizeof (struct comp_hd_t_STRUCT));
40 if (ret == NULL)
41 {
42 gnutls_assert ();
43 return NULL;
44 }
45
46 ret->algo = method;
47 ret->handle = NULL;
48
49 switch (method)
50 {
51#ifdef HAVE_LIBZ
52 case GNUTLS_COMP_DEFLATE:
53 {
54 int window_bits, mem_level;
55 int comp_level;
56 z_stream *zhandle;
57
58 window_bits = _gnutls_compression_get_wbits (method);
59 mem_level = _gnutls_compression_get_mem_level (method);
60 comp_level = _gnutls_compression_get_comp_level (method);
61
62 ret->handle = gnutls_malloc (sizeof (z_stream));
63 if (ret->handle == NULL)
64 {
65 gnutls_assert ();
66 goto cleanup_ret;
67 }
68
69 zhandle = ret->handle;
70
71 zhandle->zalloc = (alloc_func) 0;
72 zhandle->zfree = (free_func) 0;
73 zhandle->opaque = (voidpf) 0;
74
75 if (d)
76 err = inflateInit2 (zhandle, window_bits);
77 else
78 {
79 err = deflateInit2 (zhandle,
80 comp_level, Z_DEFLATED,
81 window_bits, mem_level, Z_DEFAULT_STRATEGY);
82 }
83 if (err != Z_OK)
84 {
85 gnutls_assert ();
86 gnutls_free (ret->handle);
87 goto cleanup_ret;
88 }
89 break;
90 }
91#endif
92 case GNUTLS_COMP_NULL:
93 break;
94 }
95 return ret;
96
97cleanup_ret:
98 gnutls_free (ret);
99 return NULL;
100}
101
102/* The flag d is the direction (compress, decompress). Non zero is
103 * decompress.
104 */
105void
106_gnutls_comp_deinit (comp_hd_t handle, int d)
107{
108 int err;
109
110 if (handle != NULL)
111 {
112 switch (handle->algo)
113 {
114#ifdef HAVE_LIBZ
115 case GNUTLS_COMP_DEFLATE:
116 if (d)
117 err = inflateEnd (handle->handle);
118 else
119 err = deflateEnd (handle->handle);
120 break;
121#endif
122 default:
123 break;
124 }
125 gnutls_free (handle->handle);
126 gnutls_free (handle);
127
128 }
129}
130
131/* These functions are memory consuming
132 */
133
134int
135_gnutls_compress (comp_hd_t handle, const opaque * plain,
136 size_t plain_size, opaque ** compressed,
137 size_t max_comp_size)
138{
139 int compressed_size = GNUTLS_E_COMPRESSION_FAILED;
140 int err;
141
142 /* NULL compression is not handled here
143 */
144 if (handle == NULL)
145 {
146 gnutls_assert ();
147 return GNUTLS_E_INTERNAL_ERROR;
148 }
149
150 switch (handle->algo)
151 {
152
153#ifdef HAVE_LIBZ
154 case GNUTLS_COMP_DEFLATE:
155 {
156 uLongf size;
157 z_stream *zhandle;
158
159 size = (plain_size + plain_size) + 10;
160 *compressed = gnutls_malloc (size);
161 if (*compressed == NULL)
162 {
163 gnutls_assert ();
164 return GNUTLS_E_MEMORY_ERROR;
165 }
166
167 zhandle = handle->handle;
168
169 zhandle->next_in = (Bytef *) plain;
170 zhandle->avail_in = plain_size;
171 zhandle->next_out = (Bytef *) * compressed;
172 zhandle->avail_out = size;
173
174 err = deflate (zhandle, Z_SYNC_FLUSH);
175
176 if (err != Z_OK || zhandle->avail_in != 0)
177 {
178 gnutls_assert ();
179 gnutls_free (*compressed);
180 *compressed = NULL;
181 return GNUTLS_E_COMPRESSION_FAILED;
182 }
183
184 compressed_size = size - zhandle->avail_out;
185 break;
186 }
187#endif
188 default:
189 gnutls_assert ();
190 return GNUTLS_E_INTERNAL_ERROR;
191 } /* switch */
192
193#ifdef COMPRESSION_DEBUG
194 _gnutls_debug_log ("Compression ratio: %f\n",
195 (float) ((float) compressed_size / (float) plain_size));
196#endif
197
198 if ((size_t) compressed_size > max_comp_size)
199 {
200 gnutls_free (*compressed);
201 *compressed = NULL;
202 return GNUTLS_E_COMPRESSION_FAILED;
203 }
204
205 return compressed_size;
206}
207
208
209
210int
211_gnutls_decompress (comp_hd_t handle, opaque * compressed,
212 size_t compressed_size, opaque ** plain,
213 size_t max_record_size)
214{
215 int plain_size = GNUTLS_E_DECOMPRESSION_FAILED, err;
216 int cur_pos;
217
218 if (compressed_size > max_record_size + EXTRA_COMP_SIZE)
219 {
220 gnutls_assert ();
221 return GNUTLS_E_DECOMPRESSION_FAILED;
222 }
223
224 /* NULL compression is not handled here
225 */
226
227 if (handle == NULL)
228 {
229 gnutls_assert ();
230 return GNUTLS_E_INTERNAL_ERROR;
231 }
232
233 switch (handle->algo)
234 {
235#ifdef HAVE_LIBZ
236 case GNUTLS_COMP_DEFLATE:
237 {
238 uLongf out_size;
239 z_stream *zhandle;
240
241 *plain = NULL;
242 out_size = compressed_size + compressed_size;
243 plain_size = 0;
244
245 zhandle = handle->handle;
246
247 zhandle->next_in = (Bytef *) compressed;
248 zhandle->avail_in = compressed_size;
249
250 cur_pos = 0;
251
252 do
253 {
254 out_size += 512;
255 *plain = gnutls_realloc_fast (*plain, out_size);
256 if (*plain == NULL)
257 {
258 gnutls_assert ();
259 return GNUTLS_E_MEMORY_ERROR;
260 }
261
262 zhandle->next_out = (Bytef *) (*plain + cur_pos);
263 zhandle->avail_out = out_size - cur_pos;
264
265 err = inflate (zhandle, Z_SYNC_FLUSH);
266
267 cur_pos = out_size - zhandle->avail_out;
268
269 }
270 while ((err == Z_BUF_ERROR && zhandle->avail_out == 0
271 && out_size < max_record_size)
272 || (err == Z_OK && zhandle->avail_in != 0));
273
274 if (err != Z_OK)
275 {
276 gnutls_assert ();
277 gnutls_free (*plain);
278 *plain = NULL;
279 return GNUTLS_E_DECOMPRESSION_FAILED;
280 }
281
282 plain_size = out_size - zhandle->avail_out;
283 break;
284 }
285#endif
286 default:
287 gnutls_assert ();
288 return GNUTLS_E_INTERNAL_ERROR;
289 } /* switch */
290
291 if ((size_t) plain_size > max_record_size)
292 {
293 gnutls_assert ();
294 gnutls_free (*plain);
295 *plain = NULL;
296 return GNUTLS_E_DECOMPRESSION_FAILED;
297 }
298
299 return plain_size;
300}
diff --git a/src/daemon/https/tls/gnutls_compress_int.h b/src/daemon/https/tls/gnutls_compress_int.h
new file mode 100644
index 00000000..4479fb4d
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_compress_int.h
@@ -0,0 +1,49 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#ifndef GNUTLS_COMP_INT
26# define GNUTLS_COMP_INT
27
28#ifdef HAVE_LIBZ
29# include <zlib.h>
30#endif
31
32#define GNUTLS_COMP_FAILED NULL
33
34typedef struct comp_hd_t_STRUCT
35{
36 void *handle;
37 gnutls_compression_method_t algo;
38} *comp_hd_t;
39
40comp_hd_t _gnutls_comp_init (gnutls_compression_method_t, int d);
41void _gnutls_comp_deinit (comp_hd_t handle, int d);
42
43int _gnutls_decompress (comp_hd_t handle, opaque * compressed,
44 size_t compressed_size, opaque ** plain,
45 size_t max_record_size);
46int _gnutls_compress (comp_hd_t, const opaque * plain, size_t plain_size,
47 opaque ** compressed, size_t max_comp_size);
48
49#endif
diff --git a/src/daemon/https/tls/gnutls_constate.c b/src/daemon/https/tls/gnutls_constate.c
new file mode 100644
index 00000000..c2323c46
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_constate.c
@@ -0,0 +1,1039 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* Functions that are supposed to run after the handshake procedure is
26 * finished. These functions activate the established security parameters.
27 */
28
29#include <gnutls_int.h>
30#include <gnutls_constate.h>
31#include <gnutls_errors.h>
32#include <gnutls_kx.h>
33#include <gnutls_algorithms.h>
34#include <gnutls_num.h>
35#include <gnutls_datum.h>
36#include <gnutls_state.h>
37
38static const char keyexp[] = "key expansion";
39static const int keyexp_length = sizeof (keyexp) - 1;
40
41static const char ivblock[] = "IV block";
42static const int ivblock_length = sizeof (ivblock) - 1;
43
44static const char cliwrite[] = "client write key";
45static const int cliwrite_length = sizeof (cliwrite) - 1;
46
47static const char servwrite[] = "server write key";
48static const int servwrite_length = sizeof (servwrite) - 1;
49
50#define EXPORT_FINAL_KEY_SIZE 16
51
52/* This function is to be called after handshake, when master_secret,
53 * client_random and server_random have been initialized.
54 * This function creates the keys and stores them into pending session.
55 * (session->cipher_specs)
56 */
57int
58_gnutls_set_keys (gnutls_session_t session, int hash_size, int IV_size,
59 int key_size, int export_flag)
60{
61
62/* FIXME: This function is too long
63 */
64 opaque *key_block;
65 opaque rnd[2 * TLS_RANDOM_SIZE];
66 opaque rrnd[2 * TLS_RANDOM_SIZE];
67 int pos, ret;
68 int block_size;
69 char buf[65];
70
71 if (session->cipher_specs.generated_keys != 0)
72 {
73 /* keys have already been generated.
74 * reset generated_keys and exit normally.
75 */
76 session->cipher_specs.generated_keys = 0;
77 return 0;
78 }
79
80 block_size = 2 * hash_size + 2 * key_size;
81 if (export_flag == 0)
82 block_size += 2 * IV_size;
83
84 key_block = gnutls_secure_malloc (block_size);
85 if (key_block == NULL)
86 {
87 gnutls_assert ();
88 return GNUTLS_E_MEMORY_ERROR;
89 }
90
91 memcpy (rnd, session->security_parameters.server_random, TLS_RANDOM_SIZE);
92 memcpy (&rnd[TLS_RANDOM_SIZE],
93 session->security_parameters.client_random, TLS_RANDOM_SIZE);
94
95 memcpy (rrnd, session->security_parameters.client_random, TLS_RANDOM_SIZE);
96 memcpy (&rrnd[TLS_RANDOM_SIZE],
97 session->security_parameters.server_random, TLS_RANDOM_SIZE);
98
99 if (session->security_parameters.version == GNUTLS_SSL3)
100 { /* SSL 3 */
101 ret =
102 _gnutls_ssl3_generate_random (session->
103 security_parameters.
104 master_secret,
105 TLS_MASTER_SIZE, rnd,
106 2 * TLS_RANDOM_SIZE,
107 block_size, key_block);
108 }
109 else
110 { /* TLS 1.0 */
111 ret =
112 _gnutls_PRF (session, session->security_parameters.master_secret,
113 TLS_MASTER_SIZE, keyexp, keyexp_length,
114 rnd, 2 * TLS_RANDOM_SIZE, block_size, key_block);
115 }
116
117 if (ret < 0)
118 {
119 gnutls_assert ();
120 gnutls_free (key_block);
121 return ret;
122 }
123
124 _gnutls_hard_log ("INT: KEY BLOCK[%d]: %s\n", block_size,
125 _gnutls_bin2hex (key_block, block_size, buf,
126 sizeof (buf)));
127
128 pos = 0;
129 if (hash_size > 0)
130 {
131 if (_gnutls_sset_datum
132 (&session->cipher_specs.client_write_mac_secret,
133 &key_block[pos], hash_size) < 0)
134 {
135 gnutls_free (key_block);
136 return GNUTLS_E_MEMORY_ERROR;
137 }
138 pos += hash_size;
139
140 if (_gnutls_sset_datum
141 (&session->cipher_specs.server_write_mac_secret,
142 &key_block[pos], hash_size) < 0)
143 {
144 gnutls_free (key_block);
145 return GNUTLS_E_MEMORY_ERROR;
146 }
147 pos += hash_size;
148 }
149
150 if (key_size > 0)
151 {
152 opaque *client_write_key, *server_write_key;
153 int client_write_key_size, server_write_key_size;
154 int free_keys = 0;
155
156 if (export_flag == 0)
157 {
158 client_write_key = &key_block[pos];
159 client_write_key_size = key_size;
160
161 pos += key_size;
162
163 server_write_key = &key_block[pos];
164 server_write_key_size = key_size;
165
166 pos += key_size;
167
168 }
169 else
170 { /* export */
171 free_keys = 1;
172
173 client_write_key = gnutls_secure_malloc (EXPORT_FINAL_KEY_SIZE);
174 if (client_write_key == NULL)
175 {
176 gnutls_assert ();
177 gnutls_free (key_block);
178 return GNUTLS_E_MEMORY_ERROR;
179 }
180
181 server_write_key = gnutls_secure_malloc (EXPORT_FINAL_KEY_SIZE);
182 if (server_write_key == NULL)
183 {
184 gnutls_assert ();
185 gnutls_free (key_block);
186 gnutls_free (client_write_key);
187 return GNUTLS_E_MEMORY_ERROR;
188 }
189
190 /* generate the final keys */
191
192 if (session->security_parameters.version == GNUTLS_SSL3)
193 { /* SSL 3 */
194 ret =
195 _gnutls_ssl3_hash_md5 (&key_block[pos],
196 key_size, rrnd,
197 2 * TLS_RANDOM_SIZE,
198 EXPORT_FINAL_KEY_SIZE,
199 client_write_key);
200
201 }
202 else
203 { /* TLS 1.0 */
204 ret =
205 _gnutls_PRF (session, &key_block[pos], key_size,
206 cliwrite, cliwrite_length,
207 rrnd,
208 2 * TLS_RANDOM_SIZE,
209 EXPORT_FINAL_KEY_SIZE, client_write_key);
210 }
211
212 if (ret < 0)
213 {
214 gnutls_assert ();
215 gnutls_free (key_block);
216 gnutls_free (server_write_key);
217 gnutls_free (client_write_key);
218 return ret;
219 }
220
221 client_write_key_size = EXPORT_FINAL_KEY_SIZE;
222 pos += key_size;
223
224 if (session->security_parameters.version == GNUTLS_SSL3)
225 { /* SSL 3 */
226 ret =
227 _gnutls_ssl3_hash_md5 (&key_block[pos], key_size,
228 rnd, 2 * TLS_RANDOM_SIZE,
229 EXPORT_FINAL_KEY_SIZE,
230 server_write_key);
231 }
232 else
233 { /* TLS 1.0 */
234 ret =
235 _gnutls_PRF (session, &key_block[pos], key_size,
236 servwrite, servwrite_length,
237 rrnd, 2 * TLS_RANDOM_SIZE,
238 EXPORT_FINAL_KEY_SIZE, server_write_key);
239 }
240
241 if (ret < 0)
242 {
243 gnutls_assert ();
244 gnutls_free (key_block);
245 gnutls_free (server_write_key);
246 gnutls_free (client_write_key);
247 return ret;
248 }
249
250 server_write_key_size = EXPORT_FINAL_KEY_SIZE;
251 pos += key_size;
252 }
253
254 if (_gnutls_sset_datum
255 (&session->cipher_specs.client_write_key,
256 client_write_key, client_write_key_size) < 0)
257 {
258 gnutls_free (key_block);
259 gnutls_free (server_write_key);
260 gnutls_free (client_write_key);
261 return GNUTLS_E_MEMORY_ERROR;
262 }
263 _gnutls_hard_log ("INT: CLIENT WRITE KEY [%d]: %s\n",
264 client_write_key_size,
265 _gnutls_bin2hex (client_write_key,
266 client_write_key_size, buf,
267 sizeof (buf)));
268
269 if (_gnutls_sset_datum
270 (&session->cipher_specs.server_write_key,
271 server_write_key, server_write_key_size) < 0)
272 {
273 gnutls_free (key_block);
274 gnutls_free (server_write_key);
275 gnutls_free (client_write_key);
276 return GNUTLS_E_MEMORY_ERROR;
277 }
278
279 _gnutls_hard_log ("INT: SERVER WRITE KEY [%d]: %s\n",
280 server_write_key_size,
281 _gnutls_bin2hex (server_write_key,
282 server_write_key_size, buf,
283 sizeof (buf)));
284
285 if (free_keys != 0)
286 {
287 gnutls_free (server_write_key);
288 gnutls_free (client_write_key);
289 }
290 }
291
292
293 /* IV generation in export and non export ciphers.
294 */
295 if (IV_size > 0 && export_flag == 0)
296 {
297 if (_gnutls_sset_datum
298 (&session->cipher_specs.client_write_IV, &key_block[pos],
299 IV_size) < 0)
300 {
301 gnutls_free (key_block);
302 return GNUTLS_E_MEMORY_ERROR;
303 }
304 pos += IV_size;
305
306 if (_gnutls_sset_datum
307 (&session->cipher_specs.server_write_IV, &key_block[pos],
308 IV_size) < 0)
309 {
310 gnutls_free (key_block);
311 return GNUTLS_E_MEMORY_ERROR;
312 }
313 pos += IV_size;
314
315 }
316 else if (IV_size > 0 && export_flag != 0)
317 {
318 opaque *iv_block = gnutls_alloca (IV_size * 2);
319 if (iv_block == NULL)
320 {
321 gnutls_assert ();
322 gnutls_free (key_block);
323 return GNUTLS_E_MEMORY_ERROR;
324 }
325
326 if (session->security_parameters.version == GNUTLS_SSL3)
327 { /* SSL 3 */
328 ret = _gnutls_ssl3_hash_md5 ("", 0,
329 rrnd, TLS_RANDOM_SIZE * 2,
330 IV_size, iv_block);
331
332 if (ret < 0)
333 {
334 gnutls_assert ();
335 gnutls_free (key_block);
336 gnutls_afree (iv_block);
337 return ret;
338 }
339
340 ret = _gnutls_ssl3_hash_md5 ("", 0, rnd,
341 TLS_RANDOM_SIZE * 2,
342 IV_size, &iv_block[IV_size]);
343
344 }
345 else
346 { /* TLS 1.0 */
347 ret = _gnutls_PRF (session, "", 0,
348 ivblock, ivblock_length, rrnd,
349 2 * TLS_RANDOM_SIZE, IV_size * 2, iv_block);
350 }
351
352 if (ret < 0)
353 {
354 gnutls_assert ();
355 gnutls_afree (iv_block);
356 gnutls_free (key_block);
357 return ret;
358 }
359
360 if (_gnutls_sset_datum
361 (&session->cipher_specs.client_write_IV, iv_block, IV_size) < 0)
362 {
363 gnutls_afree (iv_block);
364 gnutls_free (key_block);
365 return GNUTLS_E_MEMORY_ERROR;
366 }
367
368 if (_gnutls_sset_datum
369 (&session->cipher_specs.server_write_IV,
370 &iv_block[IV_size], IV_size) < 0)
371 {
372 gnutls_afree (iv_block);
373 gnutls_free (key_block);
374 return GNUTLS_E_MEMORY_ERROR;
375 }
376
377 gnutls_afree (iv_block);
378 }
379
380 gnutls_free (key_block);
381
382 session->cipher_specs.generated_keys = 1;
383
384 return 0;
385}
386
387int
388_gnutls_set_read_keys (gnutls_session_t session)
389{
390 int hash_size;
391 int IV_size;
392 int key_size, export_flag;
393 gnutls_cipher_algorithm_t algo;
394 gnutls_mac_algorithm_t mac_algo;
395
396 mac_algo = session->security_parameters.read_mac_algorithm;
397 algo = session->security_parameters.read_bulk_cipher_algorithm;
398
399 hash_size = _gnutls_hash_get_algo_len (mac_algo);
400 IV_size = _gnutls_cipher_get_iv_size (algo);
401 key_size = gnutls_cipher_get_key_size (algo);
402 export_flag = _gnutls_cipher_get_export_flag (algo);
403
404 return _gnutls_set_keys (session, hash_size, IV_size, key_size,
405 export_flag);
406}
407
408int
409_gnutls_set_write_keys (gnutls_session_t session)
410{
411 int hash_size;
412 int IV_size;
413 int key_size, export_flag;
414 gnutls_cipher_algorithm_t algo;
415 gnutls_mac_algorithm_t mac_algo;
416
417 mac_algo = session->security_parameters.write_mac_algorithm;
418 algo = session->security_parameters.write_bulk_cipher_algorithm;
419
420 hash_size = _gnutls_hash_get_algo_len (mac_algo);
421 IV_size = _gnutls_cipher_get_iv_size (algo);
422 key_size = gnutls_cipher_get_key_size (algo);
423 export_flag = _gnutls_cipher_get_export_flag (algo);
424
425 return _gnutls_set_keys (session, hash_size, IV_size, key_size,
426 export_flag);
427}
428
429#define CPY_COMMON dst->entity = src->entity; \
430 dst->kx_algorithm = src->kx_algorithm; \
431 memcpy( &dst->current_cipher_suite, &src->current_cipher_suite, sizeof(cipher_suite_st)); \
432 memcpy( dst->master_secret, src->master_secret, TLS_MASTER_SIZE); \
433 memcpy( dst->client_random, src->client_random, TLS_RANDOM_SIZE); \
434 memcpy( dst->server_random, src->server_random, TLS_RANDOM_SIZE); \
435 memcpy( dst->session_id, src->session_id, TLS_MAX_SESSION_ID_SIZE); \
436 dst->session_id_size = src->session_id_size; \
437 dst->cert_type = src->cert_type; \
438 dst->timestamp = src->timestamp; \
439 dst->max_record_recv_size = src->max_record_recv_size; \
440 dst->max_record_send_size = src->max_record_send_size; \
441 dst->version = src->version; \
442 memcpy( &dst->extensions, &src->extensions, sizeof(tls_ext_st)); \
443 memcpy( &dst->inner_secret, &src->inner_secret, TLS_MASTER_SIZE);
444
445static void
446_gnutls_cpy_read_security_parameters (security_parameters_st *
447 dst, security_parameters_st * src)
448{
449 CPY_COMMON;
450
451 dst->read_bulk_cipher_algorithm = src->read_bulk_cipher_algorithm;
452 dst->read_mac_algorithm = src->read_mac_algorithm;
453 dst->read_compression_algorithm = src->read_compression_algorithm;
454}
455
456static void
457_gnutls_cpy_write_security_parameters (security_parameters_st *
458 dst, security_parameters_st * src)
459{
460 CPY_COMMON;
461
462 dst->write_bulk_cipher_algorithm = src->write_bulk_cipher_algorithm;
463 dst->write_mac_algorithm = src->write_mac_algorithm;
464 dst->write_compression_algorithm = src->write_compression_algorithm;
465}
466
467/* Sets the current connection session to conform with the
468 * Security parameters(pending session), and initializes encryption.
469 * Actually it initializes and starts encryption ( so it needs
470 * secrets and random numbers to have been negotiated)
471 * This is to be called after sending the Change Cipher Spec packet.
472 */
473int
474_gnutls_connection_state_init (gnutls_session_t session)
475{
476 int ret;
477
478/* Setup the master secret
479 */
480 if ((ret = _gnutls_generate_master (session, 0), 0) < 0)
481 {
482 gnutls_assert ();
483 return ret;
484 }
485
486
487 return 0;
488}
489
490
491/* Initializes the read connection session
492 * (read encrypted data)
493 */
494int
495_gnutls_read_connection_state_init (gnutls_session_t session)
496{
497 int mac_size;
498 int rc;
499
500 _gnutls_uint64zero (session->connection_state.read_sequence_number);
501
502/* Update internals from CipherSuite selected.
503 * If we are resuming just copy the connection session
504 */
505 if (session->internals.resumed == RESUME_FALSE)
506 {
507 rc = _gnutls_set_read_cipher (session,
508 _gnutls_cipher_suite_get_cipher_algo
509 (&session->security_parameters.
510 current_cipher_suite));
511 if (rc < 0)
512 return rc;
513 rc = _gnutls_set_read_mac (session,
514 _gnutls_cipher_suite_get_mac_algo
515 (&session->security_parameters.
516 current_cipher_suite));
517 if (rc < 0)
518 return rc;
519
520 rc = _gnutls_set_kx (session,
521 _gnutls_cipher_suite_get_kx_algo
522 (&session->security_parameters.
523 current_cipher_suite));
524 if (rc < 0)
525 return rc;
526
527 rc = _gnutls_set_read_compression (session,
528 session->internals.
529 compression_method);
530 if (rc < 0)
531 return rc;
532 }
533 else
534 { /* RESUME_TRUE */
535 _gnutls_cpy_read_security_parameters (&session->
536 security_parameters,
537 &session->
538 internals.
539 resumed_security_parameters);
540 }
541
542
543 rc = _gnutls_set_read_keys (session);
544 if (rc < 0)
545 return rc;
546
547 _gnutls_handshake_log ("HSK[%x]: Cipher Suite: %s\n",
548 session, _gnutls_cipher_suite_get_name (&session->
549 security_parameters.
550 current_cipher_suite));
551
552 if (_gnutls_compression_is_ok
553 (session->security_parameters.read_compression_algorithm) != 0)
554 {
555 gnutls_assert ();
556 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
557 }
558
559 if (_gnutls_mac_is_ok
560 (session->security_parameters.read_mac_algorithm) != 0)
561 {
562 gnutls_assert ();
563 return GNUTLS_E_INTERNAL_ERROR;
564 }
565
566 /* Free all the previous keys/ sessions etc.
567 */
568 if (session->connection_state.read_mac_secret.data != NULL)
569 _gnutls_free_datum (&session->connection_state.read_mac_secret);
570
571 if (session->connection_state.read_cipher_state != NULL)
572 _gnutls_cipher_deinit (session->connection_state.read_cipher_state);
573
574 if (session->connection_state.read_compression_state != NULL)
575 _gnutls_comp_deinit (session->connection_state.read_compression_state, 1);
576
577
578 mac_size =
579 _gnutls_hash_get_algo_len (session->security_parameters.
580 read_mac_algorithm);
581
582 _gnutls_handshake_log
583 ("HSK[%x]: Initializing internal [read] cipher sessions\n", session);
584
585 switch (session->security_parameters.entity)
586 {
587 case GNUTLS_SERVER:
588 /* initialize cipher session
589 */
590 session->connection_state.read_cipher_state =
591 _gnutls_cipher_init (session->security_parameters.
592 read_bulk_cipher_algorithm,
593 &session->cipher_specs.
594 client_write_key,
595 &session->cipher_specs.client_write_IV);
596 if (session->connection_state.read_cipher_state ==
597 GNUTLS_CIPHER_FAILED
598 && session->security_parameters.
599 read_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL)
600 {
601 gnutls_assert ();
602 return GNUTLS_E_INTERNAL_ERROR;
603 }
604
605 /* copy mac secrets from cipherspecs, to connection
606 * session.
607 */
608 if (mac_size > 0)
609 {
610 if (_gnutls_sset_datum (&session->connection_state.
611 read_mac_secret,
612 session->cipher_specs.
613 client_write_mac_secret.data,
614 session->cipher_specs.
615 client_write_mac_secret.size) < 0)
616 {
617 gnutls_assert ();
618 return GNUTLS_E_MEMORY_ERROR;
619 }
620
621 }
622
623 break;
624
625 case GNUTLS_CLIENT:
626 session->connection_state.read_cipher_state =
627 _gnutls_cipher_init (session->security_parameters.
628 read_bulk_cipher_algorithm,
629 &session->cipher_specs.
630 server_write_key,
631 &session->cipher_specs.server_write_IV);
632
633 if (session->connection_state.read_cipher_state ==
634 GNUTLS_CIPHER_FAILED
635 && session->security_parameters.
636 read_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL)
637 {
638 gnutls_assert ();
639 return GNUTLS_E_INTERNAL_ERROR;
640 }
641
642
643 /* copy mac secret to connection session
644 */
645 if (mac_size > 0)
646 {
647 if (_gnutls_sset_datum (&session->connection_state.
648 read_mac_secret,
649 session->cipher_specs.
650 server_write_mac_secret.data,
651 session->cipher_specs.
652 server_write_mac_secret.size) < 0)
653 {
654 gnutls_assert ();
655 return GNUTLS_E_MEMORY_ERROR;
656 }
657 }
658
659 break;
660
661 default: /* this check is useless */
662 gnutls_assert ();
663 return GNUTLS_E_INTERNAL_ERROR;
664 }
665
666 session->connection_state.read_compression_state =
667 _gnutls_comp_init (session->security_parameters.
668 read_compression_algorithm, 1);
669
670 if (session->connection_state.read_compression_state == GNUTLS_COMP_FAILED)
671 {
672 gnutls_assert ();
673 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
674 }
675
676 return 0;
677}
678
679
680
681/* Initializes the write connection session
682 * (write encrypted data)
683 */
684int
685_gnutls_write_connection_state_init (gnutls_session_t session)
686{
687 int mac_size;
688 int rc;
689
690 _gnutls_uint64zero (session->connection_state.write_sequence_number);
691
692/* Update internals from CipherSuite selected.
693 * If we are resuming just copy the connection session
694 */
695 if (session->internals.resumed == RESUME_FALSE)
696 {
697 rc = _gnutls_set_write_cipher (session,
698 _gnutls_cipher_suite_get_cipher_algo
699 (&session->security_parameters.
700 current_cipher_suite));
701 if (rc < 0)
702 return rc;
703 rc = _gnutls_set_write_mac (session,
704 _gnutls_cipher_suite_get_mac_algo
705 (&session->security_parameters.
706 current_cipher_suite));
707 if (rc < 0)
708 return rc;
709
710 rc = _gnutls_set_kx (session,
711 _gnutls_cipher_suite_get_kx_algo
712 (&session->security_parameters.
713 current_cipher_suite));
714 if (rc < 0)
715 return rc;
716
717 rc = _gnutls_set_write_compression (session,
718 session->internals.
719 compression_method);
720 if (rc < 0)
721 return rc;
722 }
723 else
724 { /* RESUME_TRUE */
725 _gnutls_cpy_write_security_parameters (&session->
726 security_parameters,
727 &session->
728 internals.
729 resumed_security_parameters);
730 }
731
732 rc = _gnutls_set_write_keys (session);
733 if (rc < 0)
734 return rc;
735
736 _gnutls_handshake_log ("HSK[%x]: Cipher Suite: %s\n", session,
737 _gnutls_cipher_suite_get_name (&session->
738 security_parameters.
739 current_cipher_suite));
740
741 if (_gnutls_compression_is_ok
742 (session->security_parameters.write_compression_algorithm) != 0)
743 {
744 gnutls_assert ();
745 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
746 }
747
748 if (_gnutls_mac_is_ok
749 (session->security_parameters.write_mac_algorithm) != 0)
750 {
751 gnutls_assert ();
752 return GNUTLS_E_INTERNAL_ERROR;
753 }
754
755
756
757 /* Free all the previous keys/ sessions etc.
758 */
759 if (session->connection_state.write_mac_secret.data != NULL)
760 _gnutls_free_datum (&session->connection_state.write_mac_secret);
761
762 if (session->connection_state.write_cipher_state != NULL)
763 _gnutls_cipher_deinit (session->connection_state.write_cipher_state);
764
765 if (session->connection_state.write_compression_state != NULL)
766 _gnutls_comp_deinit (session->connection_state.
767 write_compression_state, 0);
768
769 mac_size =
770 _gnutls_hash_get_algo_len (session->security_parameters.
771 write_mac_algorithm);
772
773 _gnutls_handshake_log
774 ("HSK[%x]: Initializing internal [write] cipher sessions\n", session);
775
776 switch (session->security_parameters.entity)
777 {
778 case GNUTLS_SERVER:
779 /* initialize cipher session
780 */
781 session->connection_state.write_cipher_state =
782 _gnutls_cipher_init (session->security_parameters.
783 write_bulk_cipher_algorithm,
784 &session->cipher_specs.
785 server_write_key,
786 &session->cipher_specs.server_write_IV);
787
788 if (session->connection_state.write_cipher_state ==
789 GNUTLS_CIPHER_FAILED
790 && session->security_parameters.
791 write_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL)
792 {
793 gnutls_assert ();
794 return GNUTLS_E_INTERNAL_ERROR;
795 }
796
797
798 /* copy mac secrets from cipherspecs, to connection
799 * session.
800 */
801 if (mac_size > 0)
802 {
803 if (_gnutls_sset_datum (&session->connection_state.
804 write_mac_secret,
805 session->cipher_specs.
806 server_write_mac_secret.data,
807 session->cipher_specs.
808 server_write_mac_secret.size) < 0)
809 {
810 gnutls_assert ();
811 return GNUTLS_E_MEMORY_ERROR;
812 }
813
814 }
815
816
817 break;
818
819 case GNUTLS_CLIENT:
820 session->connection_state.write_cipher_state =
821 _gnutls_cipher_init (session->security_parameters.
822 write_bulk_cipher_algorithm,
823 &session->cipher_specs.
824 client_write_key,
825 &session->cipher_specs.client_write_IV);
826
827 if (session->connection_state.write_cipher_state ==
828 GNUTLS_CIPHER_FAILED
829 && session->security_parameters.
830 write_bulk_cipher_algorithm != GNUTLS_CIPHER_NULL)
831 {
832 gnutls_assert ();
833 return GNUTLS_E_INTERNAL_ERROR;
834 }
835
836 /* copy mac secret to connection session
837 */
838 if (mac_size > 0)
839 {
840 if (_gnutls_sset_datum (&session->connection_state.
841 write_mac_secret,
842 session->cipher_specs.
843 client_write_mac_secret.data,
844 session->cipher_specs.
845 client_write_mac_secret.size) < 0)
846 {
847 gnutls_assert ();
848 return GNUTLS_E_MEMORY_ERROR;
849 }
850 }
851
852 break;
853
854 default:
855 gnutls_assert ();
856 return GNUTLS_E_INTERNAL_ERROR;
857 }
858
859
860 session->connection_state.write_compression_state =
861 _gnutls_comp_init (session->security_parameters.
862 write_compression_algorithm, 0);
863
864 if (session->connection_state.write_compression_state == GNUTLS_COMP_FAILED)
865 {
866 gnutls_assert ();
867 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
868 }
869
870 return 0;
871}
872
873/* Sets the specified cipher into the pending session
874 */
875int
876_gnutls_set_read_cipher (gnutls_session_t session,
877 gnutls_cipher_algorithm_t algo)
878{
879
880 if (_gnutls_cipher_is_ok (algo) == 0)
881 {
882 if (_gnutls_cipher_priority (session, algo) < 0)
883 {
884 gnutls_assert ();
885 return GNUTLS_E_UNWANTED_ALGORITHM;
886 }
887
888 session->security_parameters.read_bulk_cipher_algorithm = algo;
889
890 }
891 else
892 {
893 gnutls_assert ();
894 return GNUTLS_E_INTERNAL_ERROR;
895 }
896
897 return 0;
898
899}
900
901int
902_gnutls_set_write_cipher (gnutls_session_t session,
903 gnutls_cipher_algorithm_t algo)
904{
905
906 if (_gnutls_cipher_is_ok (algo) == 0)
907 {
908 if (_gnutls_cipher_priority (session, algo) < 0)
909 {
910 gnutls_assert ();
911 return GNUTLS_E_UNWANTED_ALGORITHM;
912 }
913
914 session->security_parameters.write_bulk_cipher_algorithm = algo;
915
916 }
917 else
918 {
919 gnutls_assert ();
920 return GNUTLS_E_INTERNAL_ERROR;
921 }
922
923 return 0;
924
925}
926
927
928/* Sets the specified algorithm into pending compression session
929 */
930int
931_gnutls_set_read_compression (gnutls_session_t session,
932 gnutls_compression_method_t algo)
933{
934
935 if (_gnutls_compression_is_ok (algo) == 0)
936 {
937 session->security_parameters.read_compression_algorithm = algo;
938 }
939 else
940 {
941 gnutls_assert ();
942 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
943 }
944 return 0;
945
946}
947
948int
949_gnutls_set_write_compression (gnutls_session_t session,
950 gnutls_compression_method_t algo)
951{
952
953 if (_gnutls_compression_is_ok (algo) == 0)
954 {
955 session->security_parameters.write_compression_algorithm = algo;
956 }
957 else
958 {
959 gnutls_assert ();
960 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
961 }
962 return 0;
963
964}
965
966/* Sets the specified kx algorithm into pending session
967 */
968int
969_gnutls_set_kx (gnutls_session_t session, gnutls_kx_algorithm_t algo)
970{
971
972 if (_gnutls_kx_is_ok (algo) == 0)
973 {
974 session->security_parameters.kx_algorithm = algo;
975 }
976 else
977 {
978 gnutls_assert ();
979 return GNUTLS_E_INTERNAL_ERROR;
980 }
981 if (_gnutls_kx_priority (session, algo) < 0)
982 {
983 gnutls_assert ();
984 /* we shouldn't get here */
985 return GNUTLS_E_UNWANTED_ALGORITHM;
986 }
987
988 return 0;
989
990}
991
992/* Sets the specified mac algorithm into pending session */
993int
994_gnutls_set_read_mac (gnutls_session_t session, gnutls_mac_algorithm_t algo)
995{
996
997 if (_gnutls_mac_is_ok (algo) == 0)
998 {
999 session->security_parameters.read_mac_algorithm = algo;
1000 }
1001 else
1002 {
1003 gnutls_assert ();
1004 return GNUTLS_E_INTERNAL_ERROR;
1005 }
1006 if (_gnutls_mac_priority (session, algo) < 0)
1007 {
1008 gnutls_assert ();
1009 return GNUTLS_E_UNWANTED_ALGORITHM;
1010 }
1011
1012
1013 return 0;
1014
1015}
1016
1017int
1018_gnutls_set_write_mac (gnutls_session_t session, gnutls_mac_algorithm_t algo)
1019{
1020
1021 if (_gnutls_mac_is_ok (algo) == 0)
1022 {
1023 session->security_parameters.write_mac_algorithm = algo;
1024 }
1025 else
1026 {
1027 gnutls_assert ();
1028 return GNUTLS_E_INTERNAL_ERROR;
1029 }
1030 if (_gnutls_mac_priority (session, algo) < 0)
1031 {
1032 gnutls_assert ();
1033 return GNUTLS_E_UNWANTED_ALGORITHM;
1034 }
1035
1036
1037 return 0;
1038
1039}
diff --git a/src/daemon/https/tls/gnutls_constate.h b/src/daemon/https/tls/gnutls_constate.h
new file mode 100644
index 00000000..f58c8b14
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_constate.h
@@ -0,0 +1,40 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25int _gnutls_connection_state_init (gnutls_session_t session);
26int _gnutls_read_connection_state_init (gnutls_session_t session);
27int _gnutls_write_connection_state_init (gnutls_session_t session);
28int _gnutls_set_write_cipher (gnutls_session_t session,
29 gnutls_cipher_algorithm_t algo);
30int _gnutls_set_write_mac (gnutls_session_t session,
31 gnutls_mac_algorithm_t algo);
32int _gnutls_set_read_cipher (gnutls_session_t session,
33 gnutls_cipher_algorithm_t algo);
34int _gnutls_set_read_mac (gnutls_session_t session,
35 gnutls_mac_algorithm_t algo);
36int _gnutls_set_read_compression (gnutls_session_t session,
37 gnutls_compression_method_t algo);
38int _gnutls_set_write_compression (gnutls_session_t session,
39 gnutls_compression_method_t algo);
40int _gnutls_set_kx (gnutls_session_t session, gnutls_kx_algorithm_t algo);
diff --git a/src/daemon/https/tls/gnutls_datum.c b/src/daemon/https/tls/gnutls_datum.c
new file mode 100644
index 00000000..4b2eb1f4
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_datum.c
@@ -0,0 +1,114 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* contains functions that make it easier to
26 * write vectors of <size|data>. The destination size
27 * should be preallocated (datum.size+(bits/8))
28 */
29
30#include <gnutls_int.h>
31#include <gnutls_num.h>
32#include <gnutls_datum.h>
33#include <gnutls_errors.h>
34
35
36void
37_gnutls_write_datum16 (opaque * dest, gnutls_datum_t dat)
38{
39 _gnutls_write_uint16 (dat.size, dest);
40 if (dat.data != NULL)
41 memcpy (&dest[2], dat.data, dat.size);
42}
43
44void
45_gnutls_write_datum24 (opaque * dest, gnutls_datum_t dat)
46{
47 _gnutls_write_uint24 (dat.size, dest);
48 if (dat.data != NULL)
49 memcpy (&dest[3], dat.data, dat.size);
50}
51
52void
53_gnutls_write_datum32 (opaque * dest, gnutls_datum_t dat)
54{
55 _gnutls_write_uint32 (dat.size, dest);
56 if (dat.data != NULL)
57 memcpy (&dest[4], dat.data, dat.size);
58}
59
60void
61_gnutls_write_datum8 (opaque * dest, gnutls_datum_t dat)
62{
63 dest[0] = (uint8_t) dat.size;
64 if (dat.data != NULL)
65 memcpy (&dest[1], dat.data, dat.size);
66}
67
68
69int
70_gnutls_set_datum_m (gnutls_datum_t * dat, const void *data,
71 size_t data_size, gnutls_alloc_function galloc_func)
72{
73 if (data_size == 0 || data == NULL)
74 {
75 dat->data = NULL;
76 dat->size = 0;
77 return 0;
78 }
79
80 dat->data = galloc_func (data_size);
81 if (dat->data == NULL)
82 return GNUTLS_E_MEMORY_ERROR;
83
84 dat->size = data_size;
85 memcpy (dat->data, data, data_size);
86
87 return 0;
88}
89
90int
91_gnutls_datum_append_m (gnutls_datum_t * dst, const void *data,
92 size_t data_size,
93 gnutls_realloc_function grealloc_func)
94{
95
96 dst->data = grealloc_func (dst->data, data_size + dst->size);
97 if (dst->data == NULL)
98 return GNUTLS_E_MEMORY_ERROR;
99
100 memcpy (&dst->data[dst->size], data, data_size);
101 dst->size += data_size;
102
103 return 0;
104}
105
106void
107_gnutls_free_datum_m (gnutls_datum_t * dat, gnutls_free_function gfree_func)
108{
109 if (dat->data != NULL)
110 gfree_func (dat->data);
111
112 dat->data = NULL;
113 dat->size = 0;
114}
diff --git a/src/daemon/https/tls/gnutls_datum.h b/src/daemon/https/tls/gnutls_datum.h
new file mode 100644
index 00000000..0f609531
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_datum.h
@@ -0,0 +1,40 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25void _gnutls_write_datum16 (opaque * dest, gnutls_datum_t dat);
26void _gnutls_write_datum24 (opaque * dest, gnutls_datum_t dat);
27void _gnutls_write_datum32 (opaque * dest, gnutls_datum_t dat);
28void _gnutls_write_datum8 (opaque * dest, gnutls_datum_t dat);
29
30int _gnutls_set_datum_m (gnutls_datum_t * dat, const void *data,
31 size_t data_size, gnutls_alloc_function);
32#define _gnutls_set_datum( x, y, z) _gnutls_set_datum_m(x,y,z, gnutls_malloc)
33#define _gnutls_sset_datum( x, y, z) _gnutls_set_datum_m(x,y,z, gnutls_secure_malloc)
34
35int _gnutls_datum_append_m (gnutls_datum_t * dat, const void *data,
36 size_t data_size, gnutls_realloc_function);
37#define _gnutls_datum_append(x,y,z) _gnutls_datum_append_m(x,y,z, gnutls_realloc)
38
39void _gnutls_free_datum_m (gnutls_datum_t * dat, gnutls_free_function);
40#define _gnutls_free_datum(x) _gnutls_free_datum_m(x, gnutls_free)
diff --git a/src/daemon/https/tls/gnutls_db.c b/src/daemon/https/tls/gnutls_db.c
new file mode 100644
index 00000000..701be2f0
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_db.c
@@ -0,0 +1,386 @@
1/*
2 * Copyright (C) 2000, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file contains functions that manipulate a database backend
26 * for resumed sessions.
27 */
28
29#include "gnutls_int.h"
30#include "gnutls_errors.h"
31#include "gnutls_session.h"
32#include <gnutls_db.h>
33#include "debug.h"
34#include <gnutls_session_pack.h>
35#include <gnutls_datum.h>
36
37/**
38 * gnutls_db_set_retrieve_function - Sets the function that will be used to get data
39 * @session: is a #gnutls_session_t structure.
40 * @retr_func: is the function.
41 *
42 * Sets the function that will be used to retrieve data from the resumed
43 * sessions database. This function must return a gnutls_datum_t containing the
44 * data on success, or a gnutls_datum_t containing null and 0 on failure.
45 *
46 * The datum's data must be allocated using the function
47 * gnutls_malloc().
48 *
49 * The first argument to retr_func() will be null unless gnutls_db_set_ptr()
50 * has been called.
51 *
52 **/
53void
54gnutls_db_set_retrieve_function (gnutls_session_t session,
55 gnutls_db_retr_func retr_func)
56{
57 session->internals.db_retrieve_func = retr_func;
58}
59
60/**
61 * gnutls_db_set_remove_function - Sets the function that will be used to remove data
62 * @session: is a #gnutls_session_t structure.
63 * @rem_func: is the function.
64 *
65 * Sets the function that will be used to remove data from the resumed
66 * sessions database. This function must return 0 on success.
67 *
68 * The first argument to rem_func() will be null unless gnutls_db_set_ptr()
69 * has been called.
70 *
71 **/
72void
73gnutls_db_set_remove_function (gnutls_session_t session,
74 gnutls_db_remove_func rem_func)
75{
76 session->internals.db_remove_func = rem_func;
77}
78
79/**
80 * gnutls_db_set_store_function - Sets the function that will be used to put data
81 * @session: is a #gnutls_session_t structure.
82 * @store_func: is the function
83 *
84 * Sets the function that will be used to store data from the resumed
85 * sessions database. This function must remove 0 on success.
86 *
87 * The first argument to store_func() will be null unless gnutls_db_set_ptr()
88 * has been called.
89 *
90 **/
91void
92gnutls_db_set_store_function (gnutls_session_t session,
93 gnutls_db_store_func store_func)
94{
95 session->internals.db_store_func = store_func;
96}
97
98/**
99 * gnutls_db_set_ptr - Sets a pointer to be sent to db functions
100 * @session: is a #gnutls_session_t structure.
101 * @ptr: is the pointer
102 *
103 * Sets the pointer that will be provided to db store, retrieve and delete functions, as
104 * the first argument.
105 *
106 **/
107void
108gnutls_db_set_ptr (gnutls_session_t session, void *ptr)
109{
110 session->internals.db_ptr = ptr;
111}
112
113/**
114 * gnutls_db_get_ptr - Returns the pointer which is sent to db functions
115 * @session: is a #gnutls_session_t structure.
116 *
117 * Returns the pointer that will be sent to db store, retrieve and delete functions, as
118 * the first argument.
119 *
120 **/
121void *
122gnutls_db_get_ptr (gnutls_session_t session)
123{
124 return session->internals.db_ptr;
125}
126
127/**
128 * gnutls_db_set_cache_expiration - Sets the expiration time for resumed sessions.
129 * @session: is a #gnutls_session_t structure.
130 * @seconds: is the number of seconds.
131 *
132 * Sets the expiration time for resumed sessions. The default is 3600 (one hour)
133 * at the time writing this.
134 **/
135void
136gnutls_db_set_cache_expiration (gnutls_session_t session, int seconds)
137{
138 session->internals.expire_time = seconds;
139}
140
141/**
142 * gnutls_db_check_entry - checks if the given db entry has expired
143 * @session: is a #gnutls_session_t structure.
144 * @session_entry: is the session data (not key)
145 *
146 * This function returns GNUTLS_E_EXPIRED, if the database entry
147 * has expired or 0 otherwise. This function is to be used when
148 * you want to clear unnesessary session which occupy space in your
149 * backend.
150 *
151 **/
152int
153gnutls_db_check_entry (gnutls_session_t session, gnutls_datum_t session_entry)
154{
155 time_t timestamp;
156
157 timestamp = time (0);
158
159 if (session_entry.data != NULL)
160 if (timestamp -
161 ((security_parameters_st *) (session_entry.data))->timestamp <=
162 session->internals.expire_time
163 || ((security_parameters_st *) (session_entry.data))->
164 timestamp > timestamp
165 || ((security_parameters_st *) (session_entry.data))->timestamp == 0)
166 return GNUTLS_E_EXPIRED;
167
168 return 0;
169}
170
171/* The format of storing data is:
172 * (forget it). Check gnutls_session_pack.c
173 */
174int
175_gnutls_server_register_current_session (gnutls_session_t session)
176{
177 gnutls_datum_t key;
178 gnutls_datum_t content;
179 int ret = 0;
180
181 key.data = session->security_parameters.session_id;
182 key.size = session->security_parameters.session_id_size;
183
184 if (session->internals.resumable == RESUME_FALSE)
185 {
186 gnutls_assert ();
187 return GNUTLS_E_INVALID_SESSION;
188 }
189
190 if (session->security_parameters.session_id == NULL
191 || session->security_parameters.session_id_size == 0)
192 {
193 gnutls_assert ();
194 return GNUTLS_E_INVALID_SESSION;
195 }
196
197/* copy data */
198 ret = _gnutls_session_pack (session, &content);
199 if (ret < 0)
200 {
201 gnutls_assert ();
202 return ret;
203 }
204
205 ret = _gnutls_store_session (session, key, content);
206 _gnutls_free_datum (&content);
207
208 return ret;
209}
210
211/* Checks if both db_store and db_retrieve functions have
212 * been set up.
213 */
214static int
215_gnutls_db_func_is_ok (gnutls_session_t session)
216{
217 if (session->internals.db_store_func != NULL &&
218 session->internals.db_retrieve_func != NULL &&
219 session->internals.db_remove_func != NULL)
220 return 0;
221 else
222 return GNUTLS_E_DB_ERROR;
223}
224
225
226int
227_gnutls_server_restore_session (gnutls_session_t session,
228 uint8_t * session_id, int session_id_size)
229{
230 gnutls_datum_t data;
231 gnutls_datum_t key;
232 int ret;
233
234 key.data = session_id;
235 key.size = session_id_size;
236
237 if (_gnutls_db_func_is_ok (session) != 0)
238 {
239 gnutls_assert ();
240 return GNUTLS_E_INVALID_SESSION;
241 }
242
243 data = _gnutls_retrieve_session (session, key);
244
245 if (data.data == NULL)
246 {
247 gnutls_assert ();
248 return GNUTLS_E_INVALID_SESSION;
249 }
250
251 /* expiration check is performed inside */
252 ret = gnutls_session_set_data (session, data.data, data.size);
253 if (ret < 0)
254 {
255 gnutls_assert ();
256 return ret;
257 }
258
259 gnutls_free (data.data);
260
261 return 0;
262}
263
264int
265_gnutls_db_remove_session (gnutls_session_t session, uint8_t * session_id,
266 int session_id_size)
267{
268 gnutls_datum_t key;
269
270 key.data = session_id;
271 key.size = session_id_size;
272
273 return _gnutls_remove_session (session, key);
274}
275
276
277/* Stores session data to the db backend.
278 */
279int
280_gnutls_store_session (gnutls_session_t session,
281 gnutls_datum_t session_id, gnutls_datum_t session_data)
282{
283 int ret = 0;
284
285 if (session->internals.resumable == RESUME_FALSE)
286 {
287 gnutls_assert ();
288 return GNUTLS_E_INVALID_SESSION;
289 }
290
291 if (_gnutls_db_func_is_ok (session) != 0)
292 {
293 return GNUTLS_E_DB_ERROR;
294 }
295
296 if (session_id.data == NULL || session_id.size == 0)
297 {
298 gnutls_assert ();
299 return GNUTLS_E_INVALID_SESSION;
300 }
301
302 if (session_data.data == NULL || session_data.size == 0)
303 {
304 gnutls_assert ();
305 return GNUTLS_E_INVALID_SESSION;
306 }
307 /* if we can't read why bother writing? */
308
309 if (session->internals.db_store_func != NULL)
310 ret =
311 session->internals.db_store_func (session->internals.db_ptr,
312 session_id, session_data);
313
314 return (ret == 0 ? ret : GNUTLS_E_DB_ERROR);
315
316}
317
318/* Retrieves session data from the db backend.
319 */
320gnutls_datum_t
321_gnutls_retrieve_session (gnutls_session_t session, gnutls_datum_t session_id)
322{
323 gnutls_datum_t ret = { NULL, 0 };
324
325 if (session_id.data == NULL || session_id.size == 0)
326 {
327 gnutls_assert ();
328 return ret;
329 }
330
331 if (session->internals.db_retrieve_func != NULL)
332 ret =
333 session->internals.db_retrieve_func (session->internals.db_ptr,
334 session_id);
335
336 return ret;
337
338}
339
340/* Removes session data from the db backend.
341 */
342int
343_gnutls_remove_session (gnutls_session_t session, gnutls_datum_t session_id)
344{
345 int ret = 0;
346
347 if (_gnutls_db_func_is_ok (session) != 0)
348 {
349 return GNUTLS_E_DB_ERROR;
350 }
351
352 if (session_id.data == NULL || session_id.size == 0)
353 return GNUTLS_E_INVALID_SESSION;
354
355 /* if we can't read why bother writing? */
356 if (session->internals.db_remove_func != NULL)
357 ret =
358 session->internals.db_remove_func (session->internals.db_ptr,
359 session_id);
360
361 return (ret == 0 ? ret : GNUTLS_E_DB_ERROR);
362
363}
364
365/**
366 * gnutls_db_remove_session - This function will remove the current session data from the database
367 * @session: is a #gnutls_session_t structure.
368 *
369 * This function will remove the current session data from the session
370 * database. This will prevent future handshakes reusing these session
371 * data. This function should be called if a session was terminated
372 * abnormally, and before gnutls_deinit() is called.
373 *
374 * Normally gnutls_deinit() will remove abnormally terminated sessions.
375 *
376 **/
377void
378gnutls_db_remove_session (gnutls_session_t session)
379{
380 /* if the session has failed abnormally it has
381 * to be removed from the db
382 */
383 _gnutls_db_remove_session (session,
384 session->security_parameters.session_id,
385 session->security_parameters.session_id_size);
386}
diff --git a/src/daemon/https/tls/gnutls_db.h b/src/daemon/https/tls/gnutls_db.h
new file mode 100644
index 00000000..9adece4e
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_db.h
@@ -0,0 +1,37 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25int _gnutls_server_register_current_session (gnutls_session_t session);
26int _gnutls_server_restore_session (gnutls_session_t session,
27 uint8_t * session_id,
28 int session_id_size);
29int _gnutls_db_remove_session (gnutls_session_t session, uint8_t * session_id,
30 int session_id_size);
31int _gnutls_store_session (gnutls_session_t session,
32 gnutls_datum_t session_id,
33 gnutls_datum_t session_data);
34gnutls_datum_t _gnutls_retrieve_session (gnutls_session_t session,
35 gnutls_datum_t session_id);
36int _gnutls_remove_session (gnutls_session_t session,
37 gnutls_datum_t session_id);
diff --git a/src/daemon/https/tls/gnutls_dh.c b/src/daemon/https/tls/gnutls_dh.c
new file mode 100644
index 00000000..19322c73
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_dh.c
@@ -0,0 +1,162 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_errors.h>
27
28
29/*
30 --Example--
31 you: X = g ^ x mod p;
32 peer:Y = g ^ y mod p;
33
34 your_key = Y ^ x mod p;
35 his_key = X ^ y mod p;
36
37// generate our secret and the public value (X) for it
38 X = gnutls_calc_dh_secret(&x, g, p);
39// now we can calculate the shared secret
40 key = gnutls_calc_dh_key(Y, x, g, p);
41 _gnutls_mpi_release(x);
42 _gnutls_mpi_release(g);
43*/
44
45#define MAX_BITS 18000
46
47/* returns the public value (X), and the secret (ret_x).
48 */
49mpi_t
50gnutls_calc_dh_secret (mpi_t * ret_x, mpi_t g, mpi_t prime)
51{
52 mpi_t e, x;
53 int x_size = _gnutls_mpi_get_nbits (prime) - 1;
54 /* The size of the secret key is less than
55 * prime/2
56 */
57
58 if (x_size > MAX_BITS || x_size <= 0)
59 {
60 gnutls_assert ();
61 return NULL;
62 }
63
64 x = _gnutls_mpi_new (x_size);
65 if (x == NULL)
66 {
67 gnutls_assert ();
68 if (ret_x)
69 *ret_x = NULL;
70
71 return NULL;
72 }
73
74 /* FIXME: (x_size/8)*8 is there to overcome a bug in libgcrypt
75 * which does not really check the bits given but the bytes.
76 */
77 do
78 {
79 _gnutls_mpi_randomize (x, (x_size / 8) * 8, GCRY_STRONG_RANDOM);
80 /* Check whether x is zero.
81 */
82 }
83 while (_gnutls_mpi_cmp_ui (x, 0) == 0);
84
85 e = _gnutls_mpi_alloc_like (prime);
86 if (e == NULL)
87 {
88 gnutls_assert ();
89 if (ret_x)
90 *ret_x = NULL;
91
92 _gnutls_mpi_release (&x);
93 return NULL;
94 }
95
96 _gnutls_mpi_powm (e, g, x, prime);
97
98 if (ret_x)
99 *ret_x = x;
100 else
101 _gnutls_mpi_release (&x);
102 return e;
103}
104
105
106mpi_t
107gnutls_calc_dh_key (mpi_t f, mpi_t x, mpi_t prime)
108{
109 mpi_t k;
110 int bits;
111
112 bits = _gnutls_mpi_get_nbits (prime);
113 if (bits <= 0 || bits > MAX_BITS)
114 {
115 gnutls_assert ();
116 return NULL;
117 }
118
119 k = _gnutls_mpi_alloc_like (prime);
120 if (k == NULL)
121 return NULL;
122 _gnutls_mpi_powm (k, f, x, prime);
123 return k;
124}
125
126/*-
127 * _gnutls_get_dh_params - Returns the DH parameters pointer
128 * @dh_params: is an DH parameters structure, or NULL.
129 * @func: is a callback function to receive the parameters or NULL.
130 * @session: a gnutls session.
131 *
132 * This function will return the dh parameters pointer.
133 *
134 -*/
135gnutls_dh_params_t
136_gnutls_get_dh_params (gnutls_dh_params_t dh_params,
137 gnutls_params_function * func,
138 gnutls_session_t session)
139{
140 gnutls_params_st params;
141 int ret;
142
143 /* if cached return the cached */
144 if (session->internals.params.dh_params)
145 return session->internals.params.dh_params;
146
147 if (dh_params)
148 {
149 session->internals.params.dh_params = dh_params;
150 }
151 else if (func)
152 {
153 ret = func (session, GNUTLS_PARAMS_DH, &params);
154 if (ret == 0 && params.type == GNUTLS_PARAMS_DH)
155 {
156 session->internals.params.dh_params = params.params.dh;
157 session->internals.params.free_dh_params = params.deinit;
158 }
159 }
160
161 return session->internals.params.dh_params;
162}
diff --git a/src/daemon/https/tls/gnutls_dh.h b/src/daemon/https/tls/gnutls_dh.h
new file mode 100644
index 00000000..dc8a129d
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_dh.h
@@ -0,0 +1,38 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#ifndef GNUTLS_DH_H
26# define GNUTLS_DH_H
27
28const mpi_t *_gnutls_dh_params_to_mpi (gnutls_dh_params_t);
29mpi_t gnutls_calc_dh_secret (mpi_t * ret_x, mpi_t g, mpi_t prime);
30mpi_t gnutls_calc_dh_key (mpi_t f, mpi_t x, mpi_t prime);
31int _gnutls_dh_generate_prime (mpi_t * ret_g, mpi_t * ret_n, unsigned bits);
32
33gnutls_dh_params_t
34_gnutls_get_dh_params (gnutls_dh_params_t dh_params,
35 gnutls_params_function * func,
36 gnutls_session_t session);
37
38#endif
diff --git a/src/daemon/https/tls/gnutls_dh_primes.c b/src/daemon/https/tls/gnutls_dh_primes.c
new file mode 100644
index 00000000..0aea5b5f
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_dh_primes.c
@@ -0,0 +1,626 @@
1/*
2 * Copyright (C) 2000, 2001, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_errors.h>
27#include <gnutls_datum.h>
28#include <x509_b64.h> /* for PKCS3 PEM decoding */
29#include <gnutls_global.h>
30#include <gnutls_dh.h>
31#include "debug.h"
32/* x509 */
33#include "mpi.h"
34
35
36/* returns the prime and the generator of DH params.
37 */
38const mpi_t *
39_gnutls_dh_params_to_mpi (gnutls_dh_params_t dh_primes)
40{
41 if (dh_primes == NULL || dh_primes->params[1] == NULL
42 || dh_primes->params[0] == NULL)
43 {
44 return NULL;
45 }
46
47 return dh_primes->params;
48}
49
50int
51_gnutls_dh_generate_prime (mpi_t * ret_g, mpi_t * ret_n, unsigned int bits)
52{
53 mpi_t g = NULL, prime = NULL;
54 gcry_error_t err;
55 int result, times = 0, qbits;
56 mpi_t *factors = NULL;
57
58 /* Calculate the size of a prime factor of (prime-1)/2.
59 * This is an emulation of the values in "Selecting Cryptographic Key Sizes" paper.
60 */
61 if (bits < 256)
62 qbits = bits / 2;
63 else
64 {
65 qbits = (bits / 40) + 105;
66 }
67
68 if (qbits & 1) /* better have an even number */
69 qbits++;
70
71 /* find a prime number of size bits.
72 */
73 do
74 {
75
76 if (times)
77 {
78 _gnutls_mpi_release (&prime);
79 gcry_prime_release_factors (factors);
80 }
81
82 err = gcry_prime_generate (&prime, bits, qbits, &factors, NULL, NULL,
83 GCRY_STRONG_RANDOM,
84 GCRY_PRIME_FLAG_SPECIAL_FACTOR);
85
86 if (err != 0)
87 {
88 gnutls_assert ();
89 result = GNUTLS_E_INTERNAL_ERROR;
90 goto cleanup;
91 }
92
93 err = gcry_prime_check (prime, 0);
94
95 times++;
96 }
97 while (err != 0 && times < 10);
98
99 if (err != 0)
100 {
101 gnutls_assert ();
102 result = GNUTLS_E_INTERNAL_ERROR;
103 goto cleanup;
104 }
105
106 /* generate the group generator.
107 */
108 err = gcry_prime_group_generator (&g, prime, factors, NULL);
109 if (err != 0)
110 {
111 gnutls_assert ();
112 result = GNUTLS_E_INTERNAL_ERROR;
113 goto cleanup;
114 }
115
116 gcry_prime_release_factors (factors);
117 factors = NULL;
118
119 if (ret_g)
120 *ret_g = g;
121 else
122 _gnutls_mpi_release (&g);
123 if (ret_n)
124 *ret_n = prime;
125 else
126 _gnutls_mpi_release (&prime);
127
128 return 0;
129
130cleanup:gcry_prime_release_factors (factors);
131 _gnutls_mpi_release (&g);
132 _gnutls_mpi_release (&prime);
133
134 return result;
135
136}
137
138/* Replaces the prime in the static DH parameters, with a randomly
139 * generated one.
140 */
141/**
142 * gnutls_dh_params_import_raw - This function will import DH parameters
143 * @dh_params: Is a structure that will hold the prime numbers
144 * @prime: holds the new prime
145 * @generator: holds the new generator
146 *
147 * This function will replace the pair of prime and generator for use in
148 * the Diffie-Hellman key exchange. The new parameters should be stored in the
149 * appropriate gnutls_datum.
150 *
151 **/
152int
153gnutls_dh_params_import_raw (gnutls_dh_params_t dh_params,
154 const gnutls_datum_t * prime,
155 const gnutls_datum_t * generator)
156{
157 mpi_t tmp_prime, tmp_g;
158 size_t siz;
159
160 siz = prime->size;
161 if (_gnutls_mpi_scan_nz (&tmp_prime, prime->data, &siz))
162 {
163 gnutls_assert ();
164 return GNUTLS_E_MPI_SCAN_FAILED;
165 }
166
167 siz = generator->size;
168 if (_gnutls_mpi_scan_nz (&tmp_g, generator->data, &siz))
169 {
170 _gnutls_mpi_release (&tmp_prime);
171 gnutls_assert ();
172 return GNUTLS_E_MPI_SCAN_FAILED;
173 }
174
175 /* store the generated values
176 */
177 dh_params->params[0] = tmp_prime;
178 dh_params->params[1] = tmp_g;
179
180 return 0;
181
182}
183
184/**
185 * gnutls_dh_params_init - This function will initialize the DH parameters
186 * @dh_params: Is a structure that will hold the prime numbers
187 *
188 * This function will initialize the DH parameters structure.
189 *
190 **/
191int
192gnutls_dh_params_init (gnutls_dh_params_t * dh_params)
193{
194
195 (*dh_params) = gnutls_calloc (1, sizeof (dh_params_st));
196 if (*dh_params == NULL)
197 {
198 gnutls_assert ();
199 return GNUTLS_E_MEMORY_ERROR;
200 }
201
202 return 0;
203
204}
205
206/**
207 * gnutls_dh_params_deinit - This function will deinitialize the DH parameters
208 * @dh_params: Is a structure that holds the prime numbers
209 *
210 * This function will deinitialize the DH parameters structure.
211 *
212 **/
213void
214gnutls_dh_params_deinit (gnutls_dh_params_t dh_params)
215{
216 if (dh_params == NULL)
217 return;
218
219 _gnutls_mpi_release (&dh_params->params[0]);
220 _gnutls_mpi_release (&dh_params->params[1]);
221
222 gnutls_free (dh_params);
223
224}
225
226/**
227 * gnutls_dh_params_cpy - This function will copy a DH parameters structure
228 * @dst: Is the destination structure, which should be initialized.
229 * @src: Is the source structure
230 *
231 * This function will copy the DH parameters structure from source
232 * to destination.
233 *
234 **/
235int
236gnutls_dh_params_cpy (gnutls_dh_params_t dst, gnutls_dh_params_t src)
237{
238 if (src == NULL)
239 return GNUTLS_E_INVALID_REQUEST;
240
241 dst->params[0] = _gnutls_mpi_copy (src->params[0]);
242 dst->params[1] = _gnutls_mpi_copy (src->params[1]);
243
244 if (dst->params[0] == NULL || dst->params[1] == NULL)
245 return GNUTLS_E_MEMORY_ERROR;
246
247 return 0;
248}
249
250/**
251 * gnutls_dh_params_generate2 - This function will generate new DH parameters
252 * @params: Is the structure that the DH parameters will be stored
253 * @bits: is the prime's number of bits
254 *
255 * This function will generate a new pair of prime and generator for use in
256 * the Diffie-Hellman key exchange. The new parameters will be allocated using
257 * gnutls_malloc() and will be stored in the appropriate datum.
258 * This function is normally slow.
259 *
260 * Note that the bits value should be one of 768, 1024, 2048, 3072 or 4096.
261 * Also note that the DH parameters are only useful to servers.
262 * Since clients use the parameters sent by the server, it's of
263 * no use to call this in client side.
264 *
265 **/
266int
267gnutls_dh_params_generate2 (gnutls_dh_params_t params, unsigned int bits)
268{
269 int ret;
270
271 ret =
272 _gnutls_dh_generate_prime (&params->params[1], &params->params[0], bits);
273 if (ret < 0)
274 {
275 gnutls_assert ();
276 return ret;
277 }
278
279 return 0;
280}
281
282/**
283 * gnutls_dh_params_import_pkcs3 - This function will import DH params from a pkcs3 structure
284 * @params: A structure where the parameters will be copied to
285 * @pkcs3_params: should contain a PKCS3 DHParams structure PEM or DER encoded
286 * @format: the format of params. PEM or DER.
287 *
288 * This function will extract the DHParams found in a PKCS3 formatted
289 * structure. This is the format generated by "openssl dhparam" tool.
290 *
291 * If the structure is PEM encoded, it should have a header
292 * of "BEGIN DH PARAMETERS".
293 *
294 * In case of failure a negative value will be returned, and
295 * 0 on success.
296 *
297 **/
298int
299gnutls_dh_params_import_pkcs3 (gnutls_dh_params_t params,
300 const gnutls_datum_t * pkcs3_params,
301 gnutls_x509_crt_fmt_t format)
302{
303 ASN1_TYPE c2;
304 int result, need_free = 0;
305 gnutls_datum_t _params;
306
307 if (format == GNUTLS_X509_FMT_PEM)
308 {
309 opaque *out;
310
311 result = _gnutls_fbase64_decode ("DH PARAMETERS", pkcs3_params->data,
312 pkcs3_params->size, &out);
313
314 if (result <= 0)
315 {
316 if (result == 0)
317 result = GNUTLS_E_INTERNAL_ERROR;
318 gnutls_assert ();
319 return result;
320 }
321
322 _params.data = out;
323 _params.size = result;
324
325 need_free = 1;
326
327 }
328 else
329 {
330 _params.data = pkcs3_params->data;
331 _params.size = pkcs3_params->size;
332 }
333
334 if ((result =
335 asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DHParameter",
336 &c2)) != ASN1_SUCCESS)
337 {
338 gnutls_assert ();
339 if (need_free != 0)
340 {
341 gnutls_free (_params.data);
342 _params.data = NULL;
343 }
344 return _gnutls_asn2err (result);
345 }
346
347 result = asn1_der_decoding (&c2, _params.data, _params.size, NULL);
348
349 if (need_free != 0)
350 {
351 gnutls_free (_params.data);
352 _params.data = NULL;
353 }
354
355 if (result != ASN1_SUCCESS)
356 {
357 /* couldn't decode DER */
358
359 _gnutls_x509_log ("DHParams: Decoding error %d\n", result);
360 gnutls_assert ();
361 asn1_delete_structure (&c2);
362 return _gnutls_asn2err (result);
363 }
364
365 /* Read PRIME
366 */
367 result = _gnutls_x509_read_int (c2, "prime", &params->params[0]);
368 if (result < 0)
369 {
370 asn1_delete_structure (&c2);
371 gnutls_assert ();
372 return result;
373 }
374
375 /* read the generator
376 */
377 result = _gnutls_x509_read_int (c2, "base", &params->params[1]);
378 if (result < 0)
379 {
380 asn1_delete_structure (&c2);
381 _gnutls_mpi_release (&params->params[0]);
382 gnutls_assert ();
383 return result;
384 }
385
386 asn1_delete_structure (&c2);
387
388 return 0;
389}
390
391/**
392 * gnutls_dh_params_export_pkcs3 - This function will export DH params to a pkcs3 structure
393 * @params: Holds the DH parameters
394 * @format: the format of output params. One of PEM or DER.
395 * @params_data: will contain a PKCS3 DHParams structure PEM or DER encoded
396 * @params_data_size: holds the size of params_data (and will be replaced by the actual size of parameters)
397 *
398 * This function will export the given dh parameters to a PKCS3
399 * DHParams structure. This is the format generated by "openssl dhparam" tool.
400 * If the buffer provided is not long enough to hold the output, then
401 * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
402 *
403 * If the structure is PEM encoded, it will have a header
404 * of "BEGIN DH PARAMETERS".
405 *
406 * In case of failure a negative value will be returned, and
407 * 0 on success.
408 *
409 **/
410int
411gnutls_dh_params_export_pkcs3 (gnutls_dh_params_t params,
412 gnutls_x509_crt_fmt_t format,
413 unsigned char *params_data,
414 size_t * params_data_size)
415{
416 ASN1_TYPE c2;
417 int result, _params_data_size;
418 size_t g_size, p_size;
419 opaque *p_data, *g_data;
420 opaque *all_data;
421
422 _gnutls_mpi_print_lz (NULL, &g_size, params->params[1]);
423 _gnutls_mpi_print_lz (NULL, &p_size, params->params[0]);
424
425 all_data = gnutls_malloc (g_size + p_size);
426 if (all_data == NULL)
427 {
428 gnutls_assert ();
429 return GNUTLS_E_MEMORY_ERROR;
430 }
431
432 p_data = &all_data[0];
433 g_data = &all_data[p_size];
434
435 _gnutls_mpi_print_lz (p_data, &p_size, params->params[0]);
436 _gnutls_mpi_print_lz (g_data, &g_size, params->params[1]);
437
438 /* Ok. Now we have the data. Create the asn1 structures
439 */
440
441 if ((result =
442 asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DHParameter",
443 &c2)) != ASN1_SUCCESS)
444 {
445 gnutls_assert ();
446 gnutls_free (all_data);
447 return _gnutls_asn2err (result);
448 }
449
450 /* Write PRIME
451 */
452 if ((result =
453 asn1_write_value (c2, "prime", p_data, p_size)) != ASN1_SUCCESS)
454 {
455 gnutls_assert ();
456 gnutls_free (all_data);
457 asn1_delete_structure (&c2);
458 return _gnutls_asn2err (result);
459 }
460
461 /* Write the GENERATOR
462 */
463 if ((result =
464 asn1_write_value (c2, "base", g_data, g_size)) != ASN1_SUCCESS)
465 {
466 gnutls_assert ();
467 gnutls_free (all_data);
468 asn1_delete_structure (&c2);
469 return _gnutls_asn2err (result);
470 }
471
472 gnutls_free (all_data);
473
474 if ((result = asn1_write_value (c2, "privateValueLength",
475 NULL, 0)) != ASN1_SUCCESS)
476 {
477 gnutls_assert ();
478 asn1_delete_structure (&c2);
479 return _gnutls_asn2err (result);
480 }
481
482 if (format == GNUTLS_X509_FMT_DER)
483 {
484 if (params_data == NULL)
485 *params_data_size = 0;
486
487 _params_data_size = *params_data_size;
488 result =
489 asn1_der_coding (c2, "", params_data, &_params_data_size, NULL);
490 *params_data_size = _params_data_size;
491 asn1_delete_structure (&c2);
492
493 if (result != ASN1_SUCCESS)
494 {
495 gnutls_assert ();
496 if (result == ASN1_MEM_ERROR)
497 return GNUTLS_E_SHORT_MEMORY_BUFFER;
498
499 return _gnutls_asn2err (result);
500 }
501
502 }
503 else
504 { /* PEM */
505 opaque *tmp;
506 opaque *out;
507 int len;
508
509 len = 0;
510 asn1_der_coding (c2, "", NULL, &len, NULL);
511
512 tmp = gnutls_malloc (len);
513 if (tmp == NULL)
514 {
515 gnutls_assert ();
516 asn1_delete_structure (&c2);
517 return GNUTLS_E_MEMORY_ERROR;
518 }
519
520 if ((result =
521 asn1_der_coding (c2, "", tmp, &len, NULL)) != ASN1_SUCCESS)
522 {
523 gnutls_assert ();
524 gnutls_free (tmp);
525 asn1_delete_structure (&c2);
526 return _gnutls_asn2err (result);
527 }
528
529 asn1_delete_structure (&c2);
530
531 result = _gnutls_fbase64_encode ("DH PARAMETERS", tmp, len, &out);
532
533 gnutls_free (tmp);
534
535 if (result < 0)
536 {
537 gnutls_assert ();
538 return result;
539 }
540
541 if (result == 0)
542 { /* oooops */
543 gnutls_assert ();
544 gnutls_free (out);
545 return GNUTLS_E_INTERNAL_ERROR;
546 }
547
548 if ((unsigned) result + 1 > *params_data_size)
549 {
550 gnutls_assert ();
551 gnutls_free (out);
552 *params_data_size = result + 1;
553 return GNUTLS_E_SHORT_MEMORY_BUFFER;
554 }
555
556 *params_data_size = result;
557
558 if (params_data)
559 {
560 memcpy (params_data, out, result);
561 params_data[result] = 0;
562 }
563 gnutls_free (out);
564
565 }
566
567 return 0;
568}
569
570/**
571 * gnutls_dh_params_export_raw - This function will export the raw DH parameters
572 * @params: Holds the DH parameters
573 * @prime: will hold the new prime
574 * @generator: will hold the new generator
575 * @bits: if non null will hold is the prime's number of bits
576 *
577 * This function will export the pair of prime and generator for use in
578 * the Diffie-Hellman key exchange. The new parameters will be allocated using
579 * gnutls_malloc() and will be stored in the appropriate datum.
580 *
581 **/
582int
583gnutls_dh_params_export_raw (gnutls_dh_params_t params,
584 gnutls_datum_t * prime,
585 gnutls_datum_t * generator, unsigned int *bits)
586{
587
588 size_t size;
589
590 if (params->params[1] == NULL || params->params[0] == NULL)
591 {
592 gnutls_assert ();
593 return GNUTLS_E_INVALID_REQUEST;
594 }
595
596 size = 0;
597 _gnutls_mpi_print (NULL, &size, params->params[1]);
598
599 generator->data = gnutls_malloc (size);
600 if (generator->data == NULL)
601 {
602 return GNUTLS_E_MEMORY_ERROR;
603 }
604
605 generator->size = size;
606 _gnutls_mpi_print (generator->data, &size, params->params[1]);
607
608 size = 0;
609 _gnutls_mpi_print (NULL, &size, params->params[0]);
610
611 prime->data = gnutls_malloc (size);
612 if (prime->data == NULL)
613 {
614 gnutls_free (generator->data);
615 generator->data = NULL;
616 return GNUTLS_E_MEMORY_ERROR;
617 }
618 prime->size = size;
619 _gnutls_mpi_print (prime->data, &size, params->params[0]);
620
621 if (bits)
622 *bits = _gnutls_mpi_get_nbits (params->params[0]);
623
624 return 0;
625
626}
diff --git a/src/daemon/https/tls/gnutls_errors.c b/src/daemon/https/tls/gnutls_errors.c
new file mode 100644
index 00000000..9916dc96
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_errors.c
@@ -0,0 +1,422 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26#include "gnutls_errors.h"
27#include <libtasn1.h>
28#ifdef STDC_HEADERS
29# include <stdarg.h>
30#endif
31
32/* I18n of error codes. */
33#include "gettext.h"
34#define _(String) dgettext (PACKAGE, String)
35#define N_(String) gettext_noop (String)
36
37extern LOG_FUNC _gnutls_log_func;
38
39#define ERROR_ENTRY(desc, name, fatal) \
40 { desc, #name, name, fatal}
41
42struct gnutls_error_entry
43{
44 const char *desc;
45 const char *_name;
46 int number;
47 int fatal;
48};
49typedef struct gnutls_error_entry gnutls_error_entry;
50
51static const gnutls_error_entry error_algorithms[] = {
52 /* "Short Description", Error code define, critical (0,1) -- 1 in most cases */
53 ERROR_ENTRY (N_("Success."), GNUTLS_E_SUCCESS, 0),
54 ERROR_ENTRY (N_("Could not negotiate a supported cipher suite."),
55 GNUTLS_E_UNKNOWN_CIPHER_SUITE, 1),
56 ERROR_ENTRY (N_("The cipher type is unsupported."),
57 GNUTLS_E_UNKNOWN_CIPHER_TYPE, 1),
58 ERROR_ENTRY (N_("The certificate and the given key do not match."),
59 GNUTLS_E_CERTIFICATE_KEY_MISMATCH, 1),
60 ERROR_ENTRY (N_("Could not negotiate a supported compression method."),
61 GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM, 1),
62 ERROR_ENTRY (N_("An unknown public key algorithm was encountered."),
63 GNUTLS_E_UNKNOWN_PK_ALGORITHM, 1),
64
65 ERROR_ENTRY (N_("An algorithm that is not enabled was negotiated."),
66 GNUTLS_E_UNWANTED_ALGORITHM, 1),
67 ERROR_ENTRY (N_("A large TLS record packet was received."),
68 GNUTLS_E_LARGE_PACKET, 1),
69 ERROR_ENTRY (N_("A record packet with illegal version was received."),
70 GNUTLS_E_UNSUPPORTED_VERSION_PACKET, 1),
71 ERROR_ENTRY (N_
72 ("The Diffie Hellman prime sent by the server is not acceptable (not long enough)."),
73 GNUTLS_E_DH_PRIME_UNACCEPTABLE, 1),
74 ERROR_ENTRY (N_("A TLS packet with unexpected length was received."),
75 GNUTLS_E_UNEXPECTED_PACKET_LENGTH, 1),
76 ERROR_ENTRY (N_
77 ("The specified session has been invalidated for some reason."),
78 GNUTLS_E_INVALID_SESSION, 1),
79
80 ERROR_ENTRY (N_("GnuTLS internal error."), GNUTLS_E_INTERNAL_ERROR, 1),
81 ERROR_ENTRY (N_("An illegal TLS extension was received."),
82 GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION, 1),
83 ERROR_ENTRY (N_("A TLS fatal alert has been received."),
84 GNUTLS_E_FATAL_ALERT_RECEIVED, 1),
85 ERROR_ENTRY (N_("An unexpected TLS packet was received."),
86 GNUTLS_E_UNEXPECTED_PACKET, 1),
87 ERROR_ENTRY (N_("A TLS warning alert has been received."),
88 GNUTLS_E_WARNING_ALERT_RECEIVED, 0),
89 ERROR_ENTRY (N_
90 ("An error was encountered at the TLS Finished packet calculation."),
91 GNUTLS_E_ERROR_IN_FINISHED_PACKET, 1),
92 ERROR_ENTRY (N_("The peer did not send any certificate."),
93 GNUTLS_E_NO_CERTIFICATE_FOUND, 1),
94
95 ERROR_ENTRY (N_("No temporary RSA parameters were found."),
96 GNUTLS_E_NO_TEMPORARY_RSA_PARAMS, 1),
97 ERROR_ENTRY (N_("No temporary DH parameters were found."),
98 GNUTLS_E_NO_TEMPORARY_DH_PARAMS, 1),
99 ERROR_ENTRY (N_("An unexpected TLS handshake packet was received."),
100 GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET, 1),
101 ERROR_ENTRY (N_("The scanning of a large integer has failed."),
102 GNUTLS_E_MPI_SCAN_FAILED, 1),
103 ERROR_ENTRY (N_("Could not export a large integer."),
104 GNUTLS_E_MPI_PRINT_FAILED, 1),
105 ERROR_ENTRY (N_("Decryption has failed."), GNUTLS_E_DECRYPTION_FAILED, 1),
106 ERROR_ENTRY (N_("Encryption has failed."), GNUTLS_E_ENCRYPTION_FAILED, 1),
107 ERROR_ENTRY (N_("Public key decryption has failed."),
108 GNUTLS_E_PK_DECRYPTION_FAILED, 1),
109 ERROR_ENTRY (N_("Public key encryption has failed."),
110 GNUTLS_E_PK_ENCRYPTION_FAILED, 1),
111 ERROR_ENTRY (N_("Public key signing has failed."), GNUTLS_E_PK_SIGN_FAILED,
112 1),
113 ERROR_ENTRY (N_("Public key signature verification has failed."),
114 GNUTLS_E_PK_SIG_VERIFY_FAILED, 1),
115 ERROR_ENTRY (N_("Decompression of the TLS record packet has failed."),
116 GNUTLS_E_DECOMPRESSION_FAILED, 1),
117 ERROR_ENTRY (N_("Compression of the TLS record packet has failed."),
118 GNUTLS_E_COMPRESSION_FAILED, 1),
119
120 ERROR_ENTRY (N_("Internal error in memory allocation."),
121 GNUTLS_E_MEMORY_ERROR, 1),
122 ERROR_ENTRY (N_("An unimplemented or disabled feature has been requested."),
123 GNUTLS_E_UNIMPLEMENTED_FEATURE, 1),
124 ERROR_ENTRY (N_("Insufficient credentials for that request."),
125 GNUTLS_E_INSUFFICIENT_CREDENTIALS, 1),
126 ERROR_ENTRY (N_("Error in password file."), GNUTLS_E_SRP_PWD_ERROR, 1),
127 ERROR_ENTRY (N_("Wrong padding in PKCS1 packet."), GNUTLS_E_PKCS1_WRONG_PAD,
128 1),
129 ERROR_ENTRY (N_("The requested session has expired."), GNUTLS_E_EXPIRED, 1),
130 ERROR_ENTRY (N_("Hashing has failed."), GNUTLS_E_HASH_FAILED, 1),
131 ERROR_ENTRY (N_("Base64 decoding error."), GNUTLS_E_BASE64_DECODING_ERROR,
132 1),
133 ERROR_ENTRY (N_("Base64 unexpected header error."),
134 GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR,
135 1),
136 ERROR_ENTRY (N_("Base64 encoding error."), GNUTLS_E_BASE64_ENCODING_ERROR,
137 1),
138 ERROR_ENTRY (N_("Parsing error in password file."),
139 GNUTLS_E_SRP_PWD_PARSING_ERROR, 1),
140 ERROR_ENTRY (N_("The requested data were not available."),
141 GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE, 0),
142 ERROR_ENTRY (N_("Error in the pull function."), GNUTLS_E_PULL_ERROR, 1),
143 ERROR_ENTRY (N_("Error in the push function."), GNUTLS_E_PUSH_ERROR, 1),
144 ERROR_ENTRY (N_
145 ("The upper limit of record packet sequence numbers has been reached. Wow!"),
146 GNUTLS_E_RECORD_LIMIT_REACHED, 1),
147 ERROR_ENTRY (N_("Error in the certificate."), GNUTLS_E_CERTIFICATE_ERROR,
148 1),
149 ERROR_ENTRY (N_("Unknown Subject Alternative name in X.509 certificate."),
150 GNUTLS_E_X509_UNKNOWN_SAN, 1),
151
152 ERROR_ENTRY (N_("Unsupported critical extension in X.509 certificate."),
153 GNUTLS_E_X509_UNSUPPORTED_CRITICAL_EXTENSION, 1),
154 ERROR_ENTRY (N_("Key usage violation in certificate has been detected."),
155 GNUTLS_E_KEY_USAGE_VIOLATION, 1),
156 ERROR_ENTRY (N_("Function was interrupted."), GNUTLS_E_AGAIN, 0),
157 ERROR_ENTRY (N_("Function was interrupted."), GNUTLS_E_INTERRUPTED, 0),
158 ERROR_ENTRY (N_("Rehandshake was requested by the peer."),
159 GNUTLS_E_REHANDSHAKE, 0),
160 ERROR_ENTRY (N_
161 ("TLS Application data were received, while expecting handshake data."),
162 GNUTLS_E_GOT_APPLICATION_DATA, 1),
163 ERROR_ENTRY (N_("Error in Database backend."), GNUTLS_E_DB_ERROR, 1),
164 ERROR_ENTRY (N_("The certificate type is not supported."),
165 GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE, 1),
166 ERROR_ENTRY (N_("The given memory buffer is too short to hold parameters."),
167 GNUTLS_E_SHORT_MEMORY_BUFFER, 1),
168 ERROR_ENTRY (N_("The request is invalid."), GNUTLS_E_INVALID_REQUEST, 1),
169 ERROR_ENTRY (N_("An illegal parameter has been received."),
170 GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER, 1),
171 ERROR_ENTRY (N_("Error while reading file."), GNUTLS_E_FILE_ERROR, 1),
172
173 ERROR_ENTRY (N_("ASN1 parser: Element was not found."),
174 GNUTLS_E_ASN1_ELEMENT_NOT_FOUND, 1),
175 ERROR_ENTRY (N_("ASN1 parser: Identifier was not found"),
176 GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND, 1),
177 ERROR_ENTRY (N_("ASN1 parser: Error in DER parsing."),
178 GNUTLS_E_ASN1_DER_ERROR, 1),
179 ERROR_ENTRY (N_("ASN1 parser: Value was not found."),
180 GNUTLS_E_ASN1_VALUE_NOT_FOUND, 1),
181 ERROR_ENTRY (N_("ASN1 parser: Generic parsing error."),
182 GNUTLS_E_ASN1_GENERIC_ERROR, 1),
183 ERROR_ENTRY (N_("ASN1 parser: Value is not valid."),
184 GNUTLS_E_ASN1_VALUE_NOT_VALID, 1),
185 ERROR_ENTRY (N_("ASN1 parser: Error in TAG."), GNUTLS_E_ASN1_TAG_ERROR, 1),
186 ERROR_ENTRY (N_("ASN1 parser: error in implicit tag"),
187 GNUTLS_E_ASN1_TAG_IMPLICIT, 1),
188 ERROR_ENTRY (N_("ASN1 parser: Error in type 'ANY'."),
189 GNUTLS_E_ASN1_TYPE_ANY_ERROR, 1),
190 ERROR_ENTRY (N_("ASN1 parser: Syntax error."), GNUTLS_E_ASN1_SYNTAX_ERROR,
191 1),
192 ERROR_ENTRY (N_("ASN1 parser: Overflow in DER parsing."),
193 GNUTLS_E_ASN1_DER_OVERFLOW, 1),
194
195 ERROR_ENTRY (N_("Too many empty record packets have been received."),
196 GNUTLS_E_TOO_MANY_EMPTY_PACKETS, 1),
197 ERROR_ENTRY (N_("The initialization of GnuTLS-extra has failed."),
198 GNUTLS_E_INIT_LIBEXTRA, 1),
199 ERROR_ENTRY (N_
200 ("The GnuTLS library version does not match the GnuTLS-extra library version."),
201 GNUTLS_E_LIBRARY_VERSION_MISMATCH, 1),
202 ERROR_ENTRY (N_("The gcrypt library version is too old."),
203 GNUTLS_E_INCOMPATIBLE_GCRYPT_LIBRARY, 1),
204
205 ERROR_ENTRY (N_("The tasn1 library version is too old."),
206 GNUTLS_E_INCOMPATIBLE_LIBTASN1_LIBRARY, 1),
207
208 ERROR_ENTRY (N_("Error loading the keyring."),
209 GNUTLS_E_OPENPGP_KEYRING_ERROR, 1),
210 ERROR_ENTRY (N_("The initialization of LZO has failed."),
211 GNUTLS_E_LZO_INIT_FAILED, 1),
212 ERROR_ENTRY (N_("No supported compression algorithms have been found."),
213 GNUTLS_E_NO_COMPRESSION_ALGORITHMS, 1),
214 ERROR_ENTRY (N_("No supported cipher suites have been found."),
215 GNUTLS_E_NO_CIPHER_SUITES, 1),
216 ERROR_ENTRY (N_("Could not get OpenPGP key."),
217 GNUTLS_E_OPENPGP_GETKEY_FAILED, 1),
218
219 ERROR_ENTRY (N_("The SRP username supplied is illegal."),
220 GNUTLS_E_ILLEGAL_SRP_USERNAME, 1),
221
222 ERROR_ENTRY (N_("The OpenPGP fingerprint is not supported."),
223 GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED, 1),
224 ERROR_ENTRY (N_("The certificate has unsupported attributes."),
225 GNUTLS_E_X509_UNSUPPORTED_ATTRIBUTE, 1),
226 ERROR_ENTRY (N_("The OID is not supported."), GNUTLS_E_X509_UNSUPPORTED_OID,
227 1),
228 ERROR_ENTRY (N_("The hash algorithm is unknown."),
229 GNUTLS_E_UNKNOWN_HASH_ALGORITHM, 1),
230 ERROR_ENTRY (N_("The PKCS structure's content type is unknown."),
231 GNUTLS_E_UNKNOWN_PKCS_CONTENT_TYPE, 1),
232 ERROR_ENTRY (N_("The PKCS structure's bag type is unknown."),
233 GNUTLS_E_UNKNOWN_PKCS_BAG_TYPE, 1),
234 ERROR_ENTRY (N_("The given password contains invalid characters."),
235 GNUTLS_E_INVALID_PASSWORD, 1),
236 ERROR_ENTRY (N_("The Message Authentication Code verification failed."),
237 GNUTLS_E_MAC_VERIFY_FAILED, 1),
238 ERROR_ENTRY (N_("Some constraint limits were reached."),
239 GNUTLS_E_CONSTRAINT_ERROR, 1),
240 ERROR_ENTRY (N_("Failed to acquire random data."), GNUTLS_E_RANDOM_FAILED,
241 1),
242
243 ERROR_ENTRY (N_("Received a TLS/IA Intermediate Phase Finished message"),
244 GNUTLS_E_WARNING_IA_IPHF_RECEIVED, 0),
245 ERROR_ENTRY (N_("Received a TLS/IA Final Phase Finished message"),
246 GNUTLS_E_WARNING_IA_FPHF_RECEIVED, 0),
247 ERROR_ENTRY (N_("Verifying TLS/IA phase checksum failed"),
248 GNUTLS_E_IA_VERIFY_FAILED, 1),
249
250 ERROR_ENTRY (N_("The specified algorithm or protocol is unknown."),
251 GNUTLS_E_UNKNOWN_ALGORITHM, 1),
252
253 {NULL, NULL, 0, 0}
254};
255
256#define GNUTLS_ERROR_LOOP(b) \
257 const gnutls_error_entry *p; \
258 for(p = error_algorithms; p->desc != NULL; p++) { b ; }
259
260#define GNUTLS_ERROR_ALG_LOOP(a) \
261 GNUTLS_ERROR_LOOP( if(p->number == error) { a; break; } )
262
263
264
265/**
266 * gnutls_error_is_fatal - Returns non-zero in case of a fatal error
267 * @error: is an error returned by a gnutls function. Error should be a negative value.
268 *
269 * If a function returns a negative value you may feed that value
270 * to this function to see if it is fatal. Returns 1 for a fatal
271 * error 0 otherwise. However you may want to check the
272 * error code manually, since some non-fatal errors to the protocol
273 * may be fatal for you (your program).
274 *
275 * This is only useful if you are dealing with errors from the
276 * record layer or the handshake layer.
277 *
278 * For positive @error values, 0 is returned.
279 *
280 **/
281int
282gnutls_error_is_fatal (int error)
283{
284 int ret = 1;
285
286 /* Input sanitzation. Positive values are not errors at all, and
287 definitely not fatal. */
288 if (error > 0)
289 return 0;
290
291 GNUTLS_ERROR_ALG_LOOP (ret = p->fatal);
292
293 return ret;
294}
295
296/**
297 * gnutls_perror - prints a string to stderr with a description of an error
298 * @error: is an error returned by a gnutls function. Error is always a negative value.
299 *
300 * This function is like perror(). The only difference is that it accepts an
301 * error number returned by a gnutls function.
302 **/
303void
304gnutls_perror (int error)
305{
306 const char *ret = NULL;
307
308 /* avoid prefix */
309 GNUTLS_ERROR_ALG_LOOP (ret = p->desc);
310 if (ret == NULL)
311 ret = "(unknown)";
312 fprintf (stderr, "GNUTLS ERROR: %s\n", _(ret));
313}
314
315
316/**
317 * gnutls_strerror - Returns a string with a description of an error
318 * @error: is an error returned by a gnutls function. Error is always a negative value.
319 *
320 * This function is similar to strerror(). Differences: it accepts an error
321 * number returned by a gnutls function; In case of an unknown error
322 * a descriptive string is sent instead of NULL.
323 **/
324const char *
325gnutls_strerror (int error)
326{
327 const char *ret = NULL;
328
329 /* avoid prefix */
330 GNUTLS_ERROR_ALG_LOOP (ret = p->desc);
331 if (ret == NULL)
332 return "(unknown error code)";
333 return _(ret);
334}
335
336/* This will print the actual define of the
337 * given error code.
338 */
339const char *
340_gnutls_strerror (int error)
341{
342 const char *ret = NULL;
343
344 /* avoid prefix */
345 GNUTLS_ERROR_ALG_LOOP (ret = p->_name);
346
347 return _(ret);
348}
349
350int
351_gnutls_asn2err (int asn_err)
352{
353 switch (asn_err)
354 {
355 case ASN1_FILE_NOT_FOUND:
356 return GNUTLS_E_FILE_ERROR;
357 case ASN1_ELEMENT_NOT_FOUND:
358 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
359 case ASN1_IDENTIFIER_NOT_FOUND:
360 return GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND;
361 case ASN1_DER_ERROR:
362 return GNUTLS_E_ASN1_DER_ERROR;
363 case ASN1_VALUE_NOT_FOUND:
364 return GNUTLS_E_ASN1_VALUE_NOT_FOUND;
365 case ASN1_GENERIC_ERROR:
366 return GNUTLS_E_ASN1_GENERIC_ERROR;
367 case ASN1_VALUE_NOT_VALID:
368 return GNUTLS_E_ASN1_VALUE_NOT_VALID;
369 case ASN1_TAG_ERROR:
370 return GNUTLS_E_ASN1_TAG_ERROR;
371 case ASN1_TAG_IMPLICIT:
372 return GNUTLS_E_ASN1_TAG_IMPLICIT;
373 case ASN1_ERROR_TYPE_ANY:
374 return GNUTLS_E_ASN1_TYPE_ANY_ERROR;
375 case ASN1_SYNTAX_ERROR:
376 return GNUTLS_E_ASN1_SYNTAX_ERROR;
377 case ASN1_MEM_ERROR:
378 return GNUTLS_E_SHORT_MEMORY_BUFFER;
379 case ASN1_MEM_ALLOC_ERROR:
380 return GNUTLS_E_MEMORY_ERROR;
381 case ASN1_DER_OVERFLOW:
382 return GNUTLS_E_ASN1_DER_OVERFLOW;
383 default:
384 return GNUTLS_E_ASN1_GENERIC_ERROR;
385 }
386}
387
388
389/* this function will output a message using the
390 * caller provided function
391 */
392void
393_gnutls_log (int level, const char *fmt, ...)
394{
395 va_list args;
396 char str[MAX_LOG_SIZE];
397 void (*log_func) (int, const char *) = _gnutls_log_func;
398
399 if (_gnutls_log_func == NULL)
400 return;
401
402 va_start (args, fmt);
403 vsnprintf (str, MAX_LOG_SIZE - 1, fmt, args); /* Flawfinder: ignore */
404 va_end (args);
405
406 log_func (level, str);
407}
408
409#ifndef DEBUG
410# ifndef C99_MACROS
411
412/* Without C99 macros these functions have to
413 * be called. This may affect performance.
414 */
415void
416_gnutls_null_log (void *x, ...)
417{
418 return;
419}
420
421# endif /* C99_MACROS */
422#endif /* DEBUG */
diff --git a/src/daemon/https/tls/gnutls_errors.h b/src/daemon/https/tls/gnutls_errors.h
new file mode 100644
index 00000000..667bd62b
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_errors.h
@@ -0,0 +1,73 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <defines.h>
26
27#define GNUTLS_E_INT_RET_0 -1251
28
29#ifdef __FILE__
30# ifdef __LINE__
31# define gnutls_assert() _gnutls_debug_log( "ASSERT: %s:%d\n", __FILE__,__LINE__);
32# else
33# define gnutls_assert()
34# endif
35#else /* __FILE__ not defined */
36# define gnutls_assert()
37#endif
38
39int _gnutls_asn2err (int asn_err);
40void _gnutls_log (int, const char *fmt, ...);
41
42extern int _gnutls_log_level;
43
44#ifdef C99_MACROS
45#define LEVEL(l, ...) if (_gnutls_log_level >= l || _gnutls_log_level > 9) \
46 _gnutls_log( l, __VA_ARGS__)
47
48#define LEVEL_EQ(l, ...) if (_gnutls_log_level == l || _gnutls_log_level > 9) \
49 _gnutls_log( l, __VA_ARGS__)
50
51# define _gnutls_debug_log(...) LEVEL(2, __VA_ARGS__)
52# define _gnutls_handshake_log(...) LEVEL(3, __VA_ARGS__)
53# define _gnutls_io_log(...) LEVEL_EQ(5, __VA_ARGS__)
54# define _gnutls_buffers_log(...) LEVEL_EQ(6, __VA_ARGS__)
55# define _gnutls_hard_log(...) LEVEL(9, __VA_ARGS__)
56# define _gnutls_record_log(...) LEVEL(4, __VA_ARGS__)
57# define _gnutls_read_log(...) LEVEL_EQ(7, __VA_ARGS__)
58# define _gnutls_write_log(...) LEVEL_EQ(7, __VA_ARGS__)
59# define _gnutls_x509_log(...) LEVEL(1, __VA_ARGS__)
60#else
61# define _gnutls_debug_log _gnutls_null_log
62# define _gnutls_handshake_log _gnutls_null_log
63# define _gnutls_io_log _gnutls_null_log
64# define _gnutls_buffers_log _gnutls_null_log
65# define _gnutls_hard_log _gnutls_null_log
66# define _gnutls_record_log _gnutls_null_log
67# define _gnutls_read_log _gnutls_null_log
68# define _gnutls_write_log _gnutls_null_log
69# define _gnutls_x509_log _gnutls_null_log
70
71void _gnutls_null_log (void *, ...);
72
73#endif /* C99_MACROS */
diff --git a/src/daemon/https/tls/gnutls_extensions.c b/src/daemon/https/tls/gnutls_extensions.c
new file mode 100644
index 00000000..603446d7
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_extensions.c
@@ -0,0 +1,318 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* Functions that relate to the TLS hello extension parsing.
26 * Hello extensions are packets appended in the TLS hello packet, and
27 * allow for extra functionality.
28 */
29
30#include "gnutls_int.h"
31#include "gnutls_extensions.h"
32#include "gnutls_errors.h"
33#include "ext_max_record.h"
34#include <ext_cert_type.h>
35#include <ext_server_name.h>
36#include <ext_oprfi.h>
37#include <ext_inner_application.h>
38#include <gnutls_num.h>
39
40/* Key Exchange Section */
41#define GNUTLS_EXTENSION_ENTRY(type, parse_type, ext_func_recv, ext_func_send) \
42 { #type, type, parse_type, ext_func_recv, ext_func_send }
43
44
45#define MAX_EXT_SIZE 10
46const int _gnutls_extensions_size = MAX_EXT_SIZE;
47
48gnutls_extension_entry _gnutls_extensions[MAX_EXT_SIZE] = {
49 GNUTLS_EXTENSION_ENTRY (GNUTLS_EXTENSION_MAX_RECORD_SIZE,
50 EXTENSION_TLS,
51 _gnutls_max_record_recv_params,
52 _gnutls_max_record_send_params),
53 GNUTLS_EXTENSION_ENTRY (GNUTLS_EXTENSION_CERT_TYPE,
54 EXTENSION_TLS,
55 _gnutls_cert_type_recv_params,
56 _gnutls_cert_type_send_params),
57 GNUTLS_EXTENSION_ENTRY (GNUTLS_EXTENSION_SERVER_NAME,
58 EXTENSION_APPLICATION,
59 _gnutls_server_name_recv_params,
60 _gnutls_server_name_send_params),
61#ifdef ENABLE_OPRFI
62 GNUTLS_EXTENSION_ENTRY (GNUTLS_EXTENSION_OPAQUE_PRF_INPUT,
63 EXTENSION_TLS,
64 _gnutls_oprfi_recv_params,
65 _gnutls_oprfi_send_params),
66#endif
67#ifdef ENABLE_SRP
68 GNUTLS_EXTENSION_ENTRY (GNUTLS_EXTENSION_SRP,
69 EXTENSION_TLS,
70 _gnutls_srp_recv_params,
71 _gnutls_srp_send_params),
72#endif
73 GNUTLS_EXTENSION_ENTRY (GNUTLS_EXTENSION_INNER_APPLICATION,
74 EXTENSION_TLS,
75 _gnutls_inner_application_recv_params,
76 _gnutls_inner_application_send_params),
77 {0, 0, 0, 0}
78};
79
80#define GNUTLS_EXTENSION_LOOP2(b) \
81 gnutls_extension_entry *p; \
82 for(p = _gnutls_extensions; p->name != NULL; p++) { b ; }
83
84#define GNUTLS_EXTENSION_LOOP(a) \
85 GNUTLS_EXTENSION_LOOP2( if(p->type == type) { a; break; } )
86
87
88/* EXTENSION functions */
89
90ext_recv_func
91_gnutls_ext_func_recv (uint16_t type, tls_ext_parse_type_t parse_type)
92{
93 ext_recv_func ret = NULL;
94 GNUTLS_EXTENSION_LOOP (if
95 (parse_type == EXTENSION_ANY
96 || p->parse_type == parse_type) ret =
97 p->gnutls_ext_func_recv);
98 return ret;
99
100}
101
102ext_send_func
103_gnutls_ext_func_send (uint16_t type)
104{
105 ext_send_func ret = NULL;
106 GNUTLS_EXTENSION_LOOP (ret = p->gnutls_ext_func_send);
107 return ret;
108
109}
110
111const char *
112_gnutls_extension_get_name (uint16_t type)
113{
114 const char *ret = NULL;
115
116 /* avoid prefix */
117 GNUTLS_EXTENSION_LOOP (ret = p->name + sizeof ("GNUTLS_EXTENSION_") - 1);
118
119 return ret;
120}
121
122/* Checks if the extension we just received is one of the
123 * requested ones. Otherwise it's a fatal error.
124 */
125static int
126_gnutls_extension_list_check (gnutls_session_t session, uint16_t type)
127{
128 if (session->security_parameters.entity == GNUTLS_CLIENT)
129 {
130 int i;
131 for (i = 0; i < session->internals.extensions_sent_size; i++)
132 {
133 if (type == session->internals.extensions_sent[i])
134 return 0; /* ok found */
135 }
136 return GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION;
137 }
138
139 return 0;
140}
141
142int
143_gnutls_parse_extensions (gnutls_session_t session,
144 tls_ext_parse_type_t parse_type,
145 const opaque * data, int data_size)
146{
147 int next, ret;
148 int pos = 0;
149 uint16_t type;
150 const opaque *sdata;
151 ext_recv_func ext_recv;
152 uint16_t size;
153
154#ifdef DEBUG
155 int i;
156
157 if (session->security_parameters.entity == GNUTLS_CLIENT)
158 for (i = 0; i < session->internals.extensions_sent_size; i++)
159 {
160 _gnutls_debug_log ("EXT[%d]: expecting extension '%s'\n",
161 session,
162 _gnutls_extension_get_name (session->
163 internals.
164 extensions_sent[i]));
165 }
166#endif
167
168 DECR_LENGTH_RET (data_size, 2, 0);
169 next = _gnutls_read_uint16 (data);
170 pos += 2;
171
172 DECR_LENGTH_RET (data_size, next, 0);
173
174 do
175 {
176 DECR_LENGTH_RET (next, 2, 0);
177 type = _gnutls_read_uint16 (&data[pos]);
178 pos += 2;
179
180 _gnutls_debug_log ("EXT[%x]: Received extension '%s/%d'\n", session,
181 _gnutls_extension_get_name (type), type);
182
183 if ((ret = _gnutls_extension_list_check (session, type)) < 0)
184 {
185 gnutls_assert ();
186 return ret;
187 }
188
189 DECR_LENGTH_RET (next, 2, 0);
190 size = _gnutls_read_uint16 (&data[pos]);
191 pos += 2;
192
193 DECR_LENGTH_RET (next, size, 0);
194 sdata = &data[pos];
195 pos += size;
196
197 ext_recv = _gnutls_ext_func_recv (type, parse_type);
198 if (ext_recv == NULL)
199 continue;
200 if ((ret = ext_recv (session, sdata, size)) < 0)
201 {
202 gnutls_assert ();
203 return ret;
204 }
205
206 }
207 while (next > 2);
208
209 return 0;
210
211}
212
213/* Adds the extension we want to send in the extensions list.
214 * This list is used to check whether the (later) received
215 * extensions are the ones we requested.
216 */
217static void
218_gnutls_extension_list_add (gnutls_session_t session, uint16_t type)
219{
220
221 if (session->security_parameters.entity == GNUTLS_CLIENT)
222 {
223 if (session->internals.extensions_sent_size < MAX_EXT_TYPES)
224 {
225 session->internals.extensions_sent[session->internals.
226 extensions_sent_size] = type;
227 session->internals.extensions_sent_size++;
228 }
229 else
230 {
231 _gnutls_debug_log ("extensions: Increase MAX_EXT_TYPES\n");
232 }
233 }
234}
235
236int
237_gnutls_gen_extensions (gnutls_session_t session, opaque * data,
238 size_t data_size)
239{
240 int size;
241 uint16_t pos = 0;
242 opaque *sdata;
243 int sdata_size;
244 ext_send_func ext_send;
245 gnutls_extension_entry *p;
246
247 if (data_size < 2)
248 {
249 gnutls_assert ();
250 return GNUTLS_E_INTERNAL_ERROR;
251 }
252
253 /* allocate enough data for each extension.
254 */
255 sdata_size = data_size;
256 sdata = gnutls_malloc (sdata_size);
257 if (sdata == NULL)
258 {
259 gnutls_assert ();
260 return GNUTLS_E_MEMORY_ERROR;
261 }
262
263 pos += 2;
264 for (p = _gnutls_extensions; p->name != NULL; p++)
265 {
266 ext_send = _gnutls_ext_func_send (p->type);
267 if (ext_send == NULL)
268 continue;
269 size = ext_send (session, sdata, sdata_size);
270 if (size > 0)
271 {
272 if (data_size < pos + (size_t) size + 4)
273 {
274 gnutls_assert ();
275 gnutls_free (sdata);
276 return GNUTLS_E_INTERNAL_ERROR;
277 }
278
279 /* write extension type */
280 _gnutls_write_uint16 (p->type, &data[pos]);
281 pos += 2;
282
283 /* write size */
284 _gnutls_write_uint16 (size, &data[pos]);
285 pos += 2;
286
287 memcpy (&data[pos], sdata, size);
288 pos += size;
289
290 /* add this extension to the extension list
291 */
292 _gnutls_extension_list_add (session, p->type);
293
294 _gnutls_debug_log ("EXT[%x]: Sending extension %s\n", session,
295 _gnutls_extension_get_name (p->type));
296 }
297 else if (size < 0)
298 {
299 gnutls_assert ();
300 gnutls_free (sdata);
301 return size;
302 }
303 }
304
305 size = pos;
306 pos -= 2; /* remove the size of the size header! */
307
308 _gnutls_write_uint16 (pos, data);
309
310 if (size == 2)
311 { /* empty */
312 size = 0;
313 }
314
315 gnutls_free (sdata);
316 return size;
317
318}
diff --git a/src/daemon/https/tls/gnutls_extensions.h b/src/daemon/https/tls/gnutls_extensions.h
new file mode 100644
index 00000000..c305846c
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_extensions.h
@@ -0,0 +1,45 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26
27const char *_gnutls_extension_get_name (uint16_t type);
28int _gnutls_parse_extensions (gnutls_session_t, tls_ext_parse_type_t, const opaque *, int);
29int _gnutls_gen_extensions (gnutls_session_t session, opaque * data,
30 size_t data_size);
31
32typedef int (*ext_recv_func) (gnutls_session_t, const opaque *, size_t); /* recv data */
33typedef int (*ext_send_func) (gnutls_session_t, opaque *, size_t); /* send data */
34
35ext_send_func _gnutls_ext_func_send (uint16_t type);
36ext_recv_func _gnutls_ext_func_recv (uint16_t type, tls_ext_parse_type_t);
37
38typedef struct
39{
40 const char *name;
41 uint16_t type;
42 tls_ext_parse_type_t parse_type;
43 ext_recv_func gnutls_ext_func_recv;
44 ext_send_func gnutls_ext_func_send;
45} gnutls_extension_entry;
diff --git a/src/daemon/https/tls/gnutls_extra_hooks.c b/src/daemon/https/tls/gnutls_extra_hooks.c
new file mode 100644
index 00000000..f7852f64
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_extra_hooks.c
@@ -0,0 +1,78 @@
1/*
2 * Copyright (C) 2007 Free Software Foundation
3 *
4 * Author: Simon Josefsson
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_extra_hooks.h>
27
28/* Variables used by libgnutls, set by
29 _gnutls_add_openpgp_functions(), typically invoked by
30 libgnutls_extra. */
31_gnutls_openpgp_verify_key_func _E_gnutls_openpgp_verify_key = NULL;
32_gnutls_openpgp_crt_creation_time_func
33 _E_gnutls_openpgp_get_raw_key_creation_time = NULL;
34_gnutls_openpgp_crt_expiration_time_func
35 _E_gnutls_openpgp_get_raw_key_expiration_time = NULL;
36_gnutls_openpgp_fingerprint_func _E_gnutls_openpgp_fingerprint = NULL;
37_gnutls_openpgp_crt_request_func _E_gnutls_openpgp_request_key = NULL;
38_gnutls_openpgp_raw_key_to_gcert_func _E_gnutls_openpgp_raw_key_to_gcert =
39 NULL;
40_gnutls_openpgp_raw_privkey_to_gkey_func _E_gnutls_openpgp_raw_privkey_to_gkey
41 = NULL;
42_gnutls_openpgp_crt_to_gcert_func _E_gnutls_openpgp_crt_to_gcert = NULL;
43_gnutls_openpgp_privkey_to_gkey_func _E_gnutls_openpgp_privkey_to_gkey = NULL;
44_gnutls_openpgp_crt_deinit_func _E_gnutls_openpgp_crt_deinit = NULL;
45_gnutls_openpgp_keyring_deinit_func _E_gnutls_openpgp_keyring_deinit = NULL;
46_gnutls_openpgp_privkey_deinit_func _E_gnutls_openpgp_privkey_deinit = NULL;
47
48/* Called by libgnutls_extra to set the OpenPGP functions that are
49 needed by GnuTLS. */
50extern void
51 _gnutls_add_openpgp_functions
52 (_gnutls_openpgp_verify_key_func verify_key,
53 _gnutls_openpgp_crt_creation_time_func key_creation_time,
54 _gnutls_openpgp_crt_expiration_time_func key_expiration_time,
55 _gnutls_openpgp_fingerprint_func fingerprint,
56 _gnutls_openpgp_crt_request_func request_key,
57 _gnutls_openpgp_raw_key_to_gcert_func raw_key_to_gcert,
58 _gnutls_openpgp_raw_privkey_to_gkey_func raw_privkey_to_gkey,
59 _gnutls_openpgp_crt_to_gcert_func key_to_gcert,
60 _gnutls_openpgp_privkey_to_gkey_func privkey_to_gkey,
61 _gnutls_openpgp_crt_deinit_func key_deinit,
62 _gnutls_openpgp_keyring_deinit_func keyring_deinit,
63 _gnutls_openpgp_privkey_deinit_func privkey_deinit)
64{
65 _E_gnutls_openpgp_verify_key = verify_key;
66 _E_gnutls_openpgp_get_raw_key_creation_time = key_creation_time;
67 _E_gnutls_openpgp_get_raw_key_expiration_time = key_expiration_time;
68 _E_gnutls_openpgp_fingerprint = fingerprint;
69 _E_gnutls_openpgp_request_key = request_key;
70 _E_gnutls_openpgp_raw_key_to_gcert = raw_key_to_gcert;
71 _E_gnutls_openpgp_raw_privkey_to_gkey = raw_privkey_to_gkey;
72 _E_gnutls_openpgp_crt_to_gcert = key_to_gcert;
73 _E_gnutls_openpgp_privkey_to_gkey = privkey_to_gkey;
74 _E_gnutls_openpgp_crt_deinit = key_deinit;
75 _E_gnutls_openpgp_keyring_deinit = keyring_deinit;
76 _E_gnutls_openpgp_privkey_deinit = privkey_deinit;
77
78}
diff --git a/src/daemon/https/tls/gnutls_extra_hooks.h b/src/daemon/https/tls/gnutls_extra_hooks.h
new file mode 100644
index 00000000..ac55d06a
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_extra_hooks.h
@@ -0,0 +1,106 @@
1/*
2 * Copyright (C) 2007 Free Software Foundation
3 *
4 * Author: Simon Josefsson
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file is included by libgnutls-extra, and it will call the
26 _gnutls_add_openpgp_functions() function to register its OpenPGP
27 functions. */
28
29#include <auth_cert.h>
30
31typedef int (*_gnutls_openpgp_verify_key_func)
32(const gnutls_certificate_credentials_t,
33 const gnutls_datum_t *, int,
34 unsigned int *);
35
36typedef time_t (*_gnutls_openpgp_crt_creation_time_func)
37(const gnutls_datum_t *);
38
39typedef time_t (*_gnutls_openpgp_crt_expiration_time_func)
40(const gnutls_datum_t *);
41
42typedef int (*_gnutls_openpgp_crt_request_func)
43(gnutls_session_t, gnutls_datum_t *,
44 const gnutls_certificate_credentials_t,
45 opaque *, int);
46
47typedef int (*_gnutls_openpgp_fingerprint_func)
48(const gnutls_datum_t *,
49 unsigned char *, size_t *);
50
51typedef int (*_gnutls_openpgp_raw_key_to_gcert_func)
52(gnutls_cert *,
53 const gnutls_datum_t *);
54typedef int (*_gnutls_openpgp_raw_privkey_to_gkey_func)
55(gnutls_privkey *,
56 const gnutls_datum_t *,
57 gnutls_openpgp_crt_fmt_t);
58
59typedef int (*_gnutls_openpgp_crt_to_gcert_func)
60(gnutls_cert *, gnutls_openpgp_crt_t);
61
62typedef int (*_gnutls_openpgp_privkey_to_gkey_func)
63(gnutls_privkey *,
64 gnutls_openpgp_privkey_t);
65
66typedef void (*_gnutls_openpgp_crt_deinit_func)
67(gnutls_openpgp_crt_t);
68
69typedef void (*_gnutls_openpgp_keyring_deinit_func)
70(gnutls_openpgp_keyring_t);
71
72typedef void (*_gnutls_openpgp_privkey_deinit_func)
73(gnutls_openpgp_privkey_t);
74
75/* These are defined in libgnutls, but not exported from libgnutls,
76 and not intended to be used by libgnutls-extra or elsewhere. They
77 are declared here, because this file is included by auth_cert.c and
78 gnutls_cert.c too. */
79extern _gnutls_openpgp_verify_key_func _E_gnutls_openpgp_verify_key;
80extern _gnutls_openpgp_crt_creation_time_func
81_E_gnutls_openpgp_get_raw_key_creation_time;
82extern _gnutls_openpgp_crt_expiration_time_func
83_E_gnutls_openpgp_get_raw_key_expiration_time;
84extern _gnutls_openpgp_fingerprint_func _E_gnutls_openpgp_fingerprint;
85extern _gnutls_openpgp_crt_request_func _E_gnutls_openpgp_request_key;
86extern _gnutls_openpgp_raw_key_to_gcert_func _E_gnutls_openpgp_raw_key_to_gcert;
87extern _gnutls_openpgp_raw_privkey_to_gkey_func _E_gnutls_openpgp_raw_privkey_to_gkey;
88extern _gnutls_openpgp_crt_to_gcert_func _E_gnutls_openpgp_crt_to_gcert;
89extern _gnutls_openpgp_privkey_to_gkey_func _E_gnutls_openpgp_privkey_to_gkey;
90extern _gnutls_openpgp_crt_deinit_func _E_gnutls_openpgp_crt_deinit;
91extern _gnutls_openpgp_keyring_deinit_func _E_gnutls_openpgp_keyring_deinit;
92extern _gnutls_openpgp_privkey_deinit_func _E_gnutls_openpgp_privkey_deinit;
93
94extern void _gnutls_add_openpgp_functions
95(_gnutls_openpgp_verify_key_func verify_key,
96 _gnutls_openpgp_crt_creation_time_func key_creation_time,
97 _gnutls_openpgp_crt_expiration_time_func key_expiration_time,
98 _gnutls_openpgp_fingerprint_func fingerprint,
99 _gnutls_openpgp_crt_request_func request_key,
100 _gnutls_openpgp_raw_key_to_gcert_func raw_key_to_gcert,
101 _gnutls_openpgp_raw_privkey_to_gkey_func raw_privkey_to_gkey,
102 _gnutls_openpgp_crt_to_gcert_func key_to_gcert,
103 _gnutls_openpgp_privkey_to_gkey_func privkey_to_gkey,
104 _gnutls_openpgp_crt_deinit_func key_deinit,
105 _gnutls_openpgp_keyring_deinit_func keyring_deinit,
106 _gnutls_openpgp_privkey_deinit_func privkey_deinit);
diff --git a/src/daemon/https/tls/gnutls_global.c b/src/daemon/https/tls/gnutls_global.c
new file mode 100644
index 00000000..d019dcda
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_global.c
@@ -0,0 +1,375 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_errors.h>
27#include <libtasn1.h>
28#include <gnutls_dh.h>
29
30#ifdef HAVE_WINSOCK
31# include <winsock2.h>
32#endif
33
34#include "gettext.h"
35
36#define gnutls_log_func LOG_FUNC
37
38/* created by asn1c */
39extern const ASN1_ARRAY_TYPE gnutls_asn1_tab[];
40extern const ASN1_ARRAY_TYPE pkix_asn1_tab[];
41
42LOG_FUNC _gnutls_log_func;
43int _gnutls_log_level = 0; /* default log level */
44
45ASN1_TYPE _gnutls_pkix1_asn;
46ASN1_TYPE _gnutls_gnutls_asn;
47
48/**
49 * gnutls_global_set_log_function - This function sets the logging function
50 * @log_func: it's a log function
51 *
52 * This is the function where you set the logging function gnutls
53 * is going to use. This function only accepts a character array.
54 * Normally you may not use this function since it is only used
55 * for debugging purposes.
56 *
57 * gnutls_log_func is of the form,
58 * void (*gnutls_log_func)( int level, const char*);
59 **/
60void gnutls_global_set_log_function(gnutls_log_func log_func)
61{
62 _gnutls_log_func = log_func;
63}
64
65/**
66 * gnutls_global_set_log_level - This function sets the logging level
67 * @level: it's an integer from 0 to 9.
68 *
69 * This is the function that allows you to set the log level.
70 * The level is an integer between 0 and 9. Higher values mean
71 * more verbosity. The default value is 0. Larger values should
72 * only be used with care, since they may reveal sensitive information.
73 *
74 * Use a log level over 10 to enable all debugging options.
75 *
76 **/
77void gnutls_global_set_log_level(int level)
78{
79 _gnutls_log_level = level;
80}
81
82#ifdef DEBUG
83/* default logging function */
84static void
85dlog (int level, const char *str)
86 {
87 fputs (str, stderr);
88 }
89#endif
90
91extern gnutls_alloc_function gnutls_secure_malloc;
92extern gnutls_alloc_function gnutls_malloc;
93extern gnutls_free_function gnutls_free;
94extern int (*_gnutls_is_secure_memory)(const void *);
95extern gnutls_realloc_function gnutls_realloc;
96extern char *(*gnutls_strdup)(const char *);
97extern void *(*gnutls_calloc)(size_t,
98 size_t);
99
100int _gnutls_is_secure_mem_null(const void *);
101
102/**
103 * gnutls_global_set_mem_functions - This function sets the memory allocation functions
104 * @alloc_func: it's the default memory allocation function. Like malloc().
105 * @secure_alloc_func: This is the memory allocation function that will be used for sensitive data.
106 * @is_secure_func: a function that returns 0 if the memory given is not secure. May be NULL.
107 * @realloc_func: A realloc function
108 * @free_func: The function that frees allocated data. Must accept a NULL pointer.
109 *
110 * This is the function were you set the memory allocation functions gnutls
111 * is going to use. By default the libc's allocation functions (malloc(), free()),
112 * are used by gnutls, to allocate both sensitive and not sensitive data.
113 * This function is provided to set the memory allocation functions to
114 * something other than the defaults (ie the gcrypt allocation functions).
115 *
116 * This function must be called before gnutls_global_init() is called.
117 *
118 **/
119void gnutls_global_set_mem_functions(gnutls_alloc_function alloc_func,
120 gnutls_alloc_function
121 secure_alloc_func,
122 gnutls_is_secure_function
123 is_secure_func,
124 gnutls_realloc_function realloc_func,
125 gnutls_free_function free_func)
126{
127 gnutls_secure_malloc = secure_alloc_func;
128 gnutls_malloc = alloc_func;
129 gnutls_realloc = realloc_func;
130 gnutls_free = free_func;
131
132 if (is_secure_func != NULL)
133 _gnutls_is_secure_memory = is_secure_func;
134 else
135 _gnutls_is_secure_memory = _gnutls_is_secure_mem_null;
136
137 /* if using the libc's default malloc
138 * use libc's calloc as well.
139 */
140 if (gnutls_malloc == malloc)
141 {
142 gnutls_calloc = calloc;
143 }
144 else
145 { /* use the included ones */
146 gnutls_calloc = _gnutls_calloc;
147 }
148 gnutls_strdup = _gnutls_strdup;
149
150}
151
152#ifdef DEBUG
153static void
154_gnutls_gcry_log_handler (void *dummy, int level,
155 const char *fmt, va_list list)
156 {
157 _gnutls_log (fmt, list);
158 }
159#endif
160
161static int _gnutls_init = 0;
162
163/**
164 * gnutls_global_init - This function initializes the global data to defaults.
165 *
166 * This function initializes the global data to defaults.
167 * Every gnutls application has a global data which holds common parameters
168 * shared by gnutls session structures.
169 * You must call gnutls_global_deinit() when gnutls usage is no longer needed
170 * Returns zero on success.
171 *
172 * Note that this function will also initialize libgcrypt, if it has not
173 * been initialized before. Thus if you want to manually initialize libgcrypt
174 * you must do it before calling this function. This is useful in cases you
175 * want to disable libgcrypt's internal lockings etc.
176 *
177 * This function increment a global counter, so that
178 * gnutls_global_deinit() only releases resources when it has been
179 * called as many times as gnutls_global_init(). This is useful when
180 * GnuTLS is used by more than one library in an application. This
181 * function can be called many times, but will only do something the
182 * first time.
183 *
184 * Note! This function is not thread safe. If two threads call this
185 * function simultaneously, they can cause a race between checking
186 * the global counter and incrementing it, causing both threads to
187 * execute the library initialization code. That would lead to a
188 * memory leak. To handle this, your application could invoke this
189 * function after aquiring a thread mutex. To ignore the potential
190 * memory leak is also an option.
191 *
192 **/
193int gnutls_global_init(void)
194{
195 int result = 0;
196 int res;
197 char c;
198
199 if (_gnutls_init++)
200 return;
201
202#if HAVE_WINSOCK
203 {
204 WORD requested;
205 WSADATA data;
206 int err;
207
208 requested = MAKEWORD (1, 1);
209 err = WSAStartup (requested, &data);
210 if (err != 0)
211 {
212 _gnutls_debug_log ("WSAStartup failed: %d.\n", err);
213 return GNUTLS_E_LIBRARY_VERSION_MISMATCH;
214 }
215
216 if (data.wVersion < requested)
217 {
218 _gnutls_debug_log ("WSAStartup version check failed (%d < %d).\n",
219 data.wVersion, requested);
220 WSACleanup ();
221 return GNUTLS_E_LIBRARY_VERSION_MISMATCH;
222 }
223 }
224#endif
225
226 // TODO rm ? bindtextdomain(PACKAGE, LOCALEDIR);
227
228 if (gcry_control(GCRYCTL_ANY_INITIALIZATION_P) == 0)
229 {
230 /* for gcrypt in order to be able to allocate memory */
231 gcry_set_allocation_handler(gnutls_malloc, gnutls_secure_malloc,
232 _gnutls_is_secure_memory, gnutls_realloc,
233 gnutls_free);
234
235 /* gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING, NULL, 0); */
236
237 gcry_control(GCRYCTL_INITIALIZATION_FINISHED, NULL, 0);
238
239#ifdef DEBUG
240 /* applications may want to override that, so we only use
241 * it in debugging mode.
242 */
243 gcry_set_log_handler (_gnutls_gcry_log_handler, NULL);
244#endif
245 }
246
247 if (gc_init() != GC_OK)
248 {
249 gnutls_assert ();
250 _gnutls_debug_log ("Initializing crypto backend failed\n");
251 return GNUTLS_E_INCOMPATIBLE_CRYPTO_LIBRARY;
252 }
253
254#ifdef DEBUG
255 gnutls_global_set_log_function (dlog);
256#endif
257
258 /* initialize parser
259 * This should not deal with files in the final
260 * version.
261 */
262
263 res = asn1_array2tree(pkix_asn1_tab, &_gnutls_pkix1_asn, NULL);
264 if (res != ASN1_SUCCESS)
265 {
266 result = _gnutls_asn2err(res);
267 return result;
268 }
269
270 res = asn1_array2tree(gnutls_asn1_tab, &_gnutls_gnutls_asn, NULL);
271 if (res != ASN1_SUCCESS)
272 {
273 asn1_delete_structure(&_gnutls_pkix1_asn);
274 result = _gnutls_asn2err(res);
275 return result;
276 }
277
278 /* Initialize the gcrypt (if used random generator) */
279 gc_pseudo_random(&c, 1);
280
281 return result;
282}
283
284/**
285 * gnutls_global_deinit - This function deinitializes the global data
286 *
287 * This function deinitializes the global data, that were initialized
288 * using gnutls_global_init().
289 *
290 * Note! This function is not thread safe. See the discussion for
291 * gnutls_global_init() for more information.
292 *
293 **/
294void gnutls_global_deinit(void)
295{
296 if (_gnutls_init == 1)
297 {
298#if HAVE_WINSOCK
299 WSACleanup ();
300#endif
301 asn1_delete_structure(&_gnutls_gnutls_asn);
302 asn1_delete_structure(&_gnutls_pkix1_asn);
303 gc_done();
304 }
305 _gnutls_init--;
306}
307
308/* These functions should be elsewere. Kept here for
309 * historical reasons.
310 */
311
312/**
313 * gnutls_transport_set_pull_function - This function sets a read like function
314 * @pull_func: a callback function similar to read()
315 * @session: gnutls session
316 *
317 * This is the function where you set a function for gnutls
318 * to receive data. Normally, if you use berkeley style sockets,
319 * do not need to use this function since the default (recv(2)) will
320 * probably be ok.
321 *
322 * PULL_FUNC is of the form,
323 * ssize_t (*gnutls_pull_func)(gnutls_transport_ptr_t, void*, size_t);
324 **/
325void gnutls_transport_set_pull_function(gnutls_session_t session,
326 gnutls_pull_func pull_func)
327{
328 session->internals._gnutls_pull_func = pull_func;
329}
330
331/**
332 * gnutls_transport_set_push_function - This function sets the function to send data
333 * @push_func: a callback function similar to write()
334 * @session: gnutls session
335 *
336 * This is the function where you set a push function for gnutls
337 * to use in order to send data. If you are going to use berkeley style
338 * sockets, you do not need to use this function since
339 * the default (send(2)) will probably be ok. Otherwise you should
340 * specify this function for gnutls to be able to send data.
341 *
342 * PUSH_FUNC is of the form,
343 * ssize_t (*gnutls_push_func)(gnutls_transport_ptr_t, const void*, size_t);
344 **/
345void gnutls_transport_set_push_function(gnutls_session_t session,
346 gnutls_push_func push_func)
347{
348 session->internals._gnutls_push_func = push_func;
349}
350
351#include <strverscmp.h>
352
353/**
354 * gnutls_check_version - This function checks the library's version
355 * @req_version: the version to check
356 *
357 * Check that the version of the library is at minimum the requested one
358 * and return the version string; return NULL if the condition is not
359 * satisfied. If a NULL is passed to this function, no check is done,
360 * but the version string is simply returned.
361 *
362 * See %LIBGNUTLS_VERSION for a suitable @req_version string.
363 *
364 * Return value: Version string of run-time library, or NULL if the
365 * run-time library does not meet the required version number. If
366 * %NULL is passed to this function no check is done and only the
367 * version string is returned.
368 **/
369const char * gnutls_check_version(const char *req_version)
370{
371 if (!req_version || strverscmp(req_version, VERSION) <= 0)
372 return VERSION;
373
374 return NULL;
375}
diff --git a/src/daemon/https/tls/gnutls_global.h b/src/daemon/https/tls/gnutls_global.h
new file mode 100644
index 00000000..3305ebad
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_global.h
@@ -0,0 +1,42 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#ifndef GNUTLS_GLOBAL_H
26# define GNUTLS_GLOBAL_H
27
28#include <libtasn1.h>
29
30int gnutls_is_secure_memory (const void *mem);
31
32extern ASN1_TYPE _gnutls_pkix1_asn;
33extern ASN1_TYPE _gnutls_gnutls_asn;
34
35/* removed const from node_asn* to
36 * prevent warnings, since libtasn1 doesn't
37 * use the const keywork in its functions.
38 */
39#define _gnutls_get_gnutls_asn() ((node_asn*) _gnutls_gnutls_asn)
40#define _gnutls_get_pkix() ((node_asn*) _gnutls_pkix1_asn)
41
42#endif
diff --git a/src/daemon/https/tls/gnutls_handshake.c b/src/daemon/https/tls/gnutls_handshake.c
new file mode 100644
index 00000000..1af07a91
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_handshake.c
@@ -0,0 +1,3029 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* Functions that relate to the TLS handshake procedure.
26 */
27
28#include "gnutls_int.h"
29#include "gnutls_errors.h"
30#include "gnutls_dh.h"
31#include "debug.h"
32#include "gnutls_algorithms.h"
33#include "gnutls_compress.h"
34#include "gnutls_cipher.h"
35#include "gnutls_buffers.h"
36#include "gnutls_kx.h"
37#include "gnutls_handshake.h"
38#include "gnutls_num.h"
39#include "gnutls_hash_int.h"
40#include "gnutls_db.h"
41#include "gnutls_extensions.h"
42#include "gnutls_supplemental.h"
43#include "gnutls_auth_int.h"
44#include "gnutls_v2_compat.h"
45#include "auth_cert.h"
46#include "gnutls_cert.h"
47#include "gnutls_constate.h"
48#include <gnutls_record.h>
49#include <gnutls_state.h>
50#include <gnutls_rsa_export.h> /* for gnutls_get_rsa_params() */
51#include <auth_anon.h> /* for gnutls_anon_server_credentials_t */
52#include <gc.h>
53
54#ifdef HANDSHAKE_DEBUG
55#define ERR(x, y) _gnutls_handshake_log( "HSK[%x]: %s (%d)\n", session, x,y)
56#else
57#define ERR(x, y)
58#endif
59
60#define TRUE 1
61#define FALSE 0
62
63int _gnutls_server_select_comp_method (gnutls_session_t session,
64 opaque * data, int datalen);
65
66
67/* Clears the handshake hash buffers and handles.
68 */
69inline static void
70_gnutls_handshake_hash_buffers_clear (gnutls_session_t session)
71{
72 _gnutls_hash_deinit (session->internals.handshake_mac_handle_md5, NULL);
73 _gnutls_hash_deinit (session->internals.handshake_mac_handle_sha, NULL);
74 session->internals.handshake_mac_handle_md5 = NULL;
75 session->internals.handshake_mac_handle_sha = NULL;
76 _gnutls_handshake_buffer_clear (session);
77}
78
79/* this will copy the required values for resuming to
80 * internals, and to security_parameters.
81 * this will keep as less data to security_parameters.
82 */
83static void
84resume_copy_required_values (gnutls_session_t session)
85{
86 /* get the new random values */
87 memcpy (session->internals.resumed_security_parameters.
88 server_random,
89 session->security_parameters.server_random, TLS_RANDOM_SIZE);
90 memcpy (session->internals.resumed_security_parameters.
91 client_random,
92 session->security_parameters.client_random, TLS_RANDOM_SIZE);
93
94 /* keep the ciphersuite and compression
95 * That is because the client must see these in our
96 * hello message.
97 */
98 memcpy (session->security_parameters.current_cipher_suite.
99 suite,
100 session->internals.resumed_security_parameters.
101 current_cipher_suite.suite, 2);
102
103 session->internals.compression_method =
104 session->internals.resumed_security_parameters.read_compression_algorithm;
105 /* or write_compression_algorithm
106 * they are the same
107 */
108
109 session->security_parameters.entity =
110 session->internals.resumed_security_parameters.entity;
111
112 _gnutls_set_current_version (session,
113 session->internals.
114 resumed_security_parameters.version);
115
116 session->security_parameters.cert_type =
117 session->internals.resumed_security_parameters.cert_type;
118
119 memcpy (session->security_parameters.session_id,
120 session->internals.resumed_security_parameters.
121 session_id, sizeof (session->security_parameters.session_id));
122 session->security_parameters.session_id_size =
123 session->internals.resumed_security_parameters.session_id_size;
124}
125
126void
127_gnutls_set_server_random (gnutls_session_t session, uint8_t * rnd)
128{
129 memcpy (session->security_parameters.server_random, rnd, TLS_RANDOM_SIZE);
130}
131
132void
133_gnutls_set_client_random (gnutls_session_t session, uint8_t * rnd)
134{
135 memcpy (session->security_parameters.client_random, rnd, TLS_RANDOM_SIZE);
136}
137
138/* Calculate The SSL3 Finished message
139 */
140#define SSL3_CLIENT_MSG "CLNT"
141#define SSL3_SERVER_MSG "SRVR"
142#define SSL_MSG_LEN 4
143static int
144_gnutls_ssl3_finished (gnutls_session_t session, int type, opaque * ret)
145{
146 const int siz = SSL_MSG_LEN;
147 mac_hd_t td_md5;
148 mac_hd_t td_sha;
149 const char *mesg;
150
151 td_md5 = _gnutls_hash_copy (session->internals.handshake_mac_handle_md5);
152 if (td_md5 == NULL)
153 {
154 gnutls_assert ();
155 return GNUTLS_E_HASH_FAILED;
156 }
157
158 td_sha = _gnutls_hash_copy (session->internals.handshake_mac_handle_sha);
159 if (td_sha == NULL)
160 {
161 gnutls_assert ();
162 _gnutls_hash_deinit (td_md5, NULL);
163 return GNUTLS_E_HASH_FAILED;
164 }
165
166 if (type == GNUTLS_SERVER)
167 {
168 mesg = SSL3_SERVER_MSG;
169 }
170 else
171 {
172 mesg = SSL3_CLIENT_MSG;
173 }
174
175 _gnutls_hash (td_md5, mesg, siz);
176 _gnutls_hash (td_sha, mesg, siz);
177
178 _gnutls_mac_deinit_ssl3_handshake (td_md5, ret,
179 session->security_parameters.
180 master_secret, TLS_MASTER_SIZE);
181 _gnutls_mac_deinit_ssl3_handshake (td_sha, &ret[16],
182 session->security_parameters.
183 master_secret, TLS_MASTER_SIZE);
184
185 return 0;
186}
187
188/* Hash the handshake messages as required by TLS 1.0
189 */
190#define SERVER_MSG "server finished"
191#define CLIENT_MSG "client finished"
192#define TLS_MSG_LEN 15
193int
194_gnutls_finished (gnutls_session_t session, int type, void *ret)
195{
196 const int siz = TLS_MSG_LEN;
197 opaque concat[36];
198 size_t len;
199 const char *mesg;
200 mac_hd_t td_md5 = NULL;
201 mac_hd_t td_sha;
202 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
203
204 if (ver < GNUTLS_TLS1_2)
205 {
206 td_md5 =
207 _gnutls_hash_copy (session->internals.handshake_mac_handle_md5);
208 if (td_md5 == NULL)
209 {
210 gnutls_assert ();
211 return GNUTLS_E_HASH_FAILED;
212 }
213 }
214
215 td_sha = _gnutls_hash_copy (session->internals.handshake_mac_handle_sha);
216 if (td_sha == NULL)
217 {
218 gnutls_assert ();
219 _gnutls_hash_deinit (td_md5, NULL);
220 return GNUTLS_E_HASH_FAILED;
221 }
222
223 if (ver < GNUTLS_TLS1_2)
224 {
225 _gnutls_hash_deinit (td_md5, concat);
226 _gnutls_hash_deinit (td_sha, &concat[16]);
227 len = 20 + 16;
228 }
229 else
230 {
231 _gnutls_hash_deinit (td_sha, concat);
232 len = 20;
233 }
234
235 if (type == GNUTLS_SERVER)
236 {
237 mesg = SERVER_MSG;
238 }
239 else
240 {
241 mesg = CLIENT_MSG;
242 }
243
244 return _gnutls_PRF (session, session->security_parameters.master_secret,
245 TLS_MASTER_SIZE, mesg, siz, concat, len, 12, ret);
246}
247
248/* this function will produce TLS_RANDOM_SIZE==32 bytes of random data
249 * and put it to dst.
250 */
251int
252_gnutls_tls_create_random (opaque * dst)
253{
254 uint32_t tim;
255
256 /* Use weak random numbers for the most of the
257 * buffer except for the first 4 that are the
258 * system's time.
259 */
260
261 tim = time (NULL);
262 /* generate server random value */
263 _gnutls_write_uint32 (tim, dst);
264
265 if (gc_nonce (&dst[4], TLS_RANDOM_SIZE - 4) != GC_OK)
266 {
267 gnutls_assert ();
268 return GNUTLS_E_RANDOM_FAILED;
269 }
270
271 return 0;
272}
273
274/* returns the 0 on success or a negative value.
275 */
276int
277_gnutls_negotiate_version (gnutls_session_t session,
278 gnutls_protocol_t adv_version)
279{
280 int ret;
281
282 /* if we do not support that version */
283 if (_gnutls_version_is_supported (session, adv_version) == 0)
284 {
285 /* If he requested something we do not support
286 * then we send him the highest we support.
287 */
288 ret = _gnutls_version_max (session);
289 if (ret == GNUTLS_VERSION_UNKNOWN)
290 {
291 /* this check is not really needed.
292 */
293 gnutls_assert ();
294 return GNUTLS_E_UNKNOWN_CIPHER_SUITE;
295 }
296 }
297 else
298 {
299 ret = adv_version;
300 }
301
302 _gnutls_set_current_version (session, ret);
303
304 return ret;
305}
306
307int
308_gnutls_user_hello_func (gnutls_session session,
309 gnutls_protocol_t adv_version)
310{
311 int ret;
312
313 if (session->internals.user_hello_func != NULL)
314 {
315 ret = session->internals.user_hello_func (session);
316 if (ret < 0)
317 {
318 gnutls_assert ();
319 return ret;
320 }
321 /* Here we need to renegotiate the version since the callee might
322 * have disabled some TLS versions.
323 */
324 ret = _gnutls_negotiate_version (session, adv_version);
325 if (ret < 0)
326 {
327 gnutls_assert ();
328 return ret;
329 }
330 }
331 return 0;
332}
333
334/* Read a client hello packet.
335 * A client hello must be a known version client hello
336 * or version 2.0 client hello (only for compatibility
337 * since SSL version 2.0 is not supported).
338 */
339int
340_gnutls_read_client_hello (gnutls_session_t session, opaque * data,
341 int datalen)
342{
343 uint8_t session_id_len;
344 int pos = 0, ret;
345 uint16_t suite_size, comp_size;
346 gnutls_protocol_t adv_version;
347 int neg_version;
348 int len = datalen;
349 opaque rnd[TLS_RANDOM_SIZE], *suite_ptr, *comp_ptr;
350
351 if (session->internals.v2_hello != 0)
352 { /* version 2.0 */
353 return _gnutls_read_client_hello_v2 (session, data, datalen);
354 }
355 DECR_LEN (len, 2);
356
357 _gnutls_handshake_log ("HSK[%x]: Client's version: %d.%d\n", session,
358 data[pos], data[pos + 1]);
359
360 adv_version = _gnutls_version_get (data[pos], data[pos + 1]);
361 set_adv_version (session, data[pos], data[pos + 1]);
362 pos += 2;
363
364 neg_version = _gnutls_negotiate_version (session, adv_version);
365 if (neg_version < 0)
366 {
367 gnutls_assert ();
368 return ret;
369 }
370
371 /* Read client random value.
372 */
373 DECR_LEN (len, TLS_RANDOM_SIZE);
374 _gnutls_set_client_random (session, &data[pos]);
375 pos += TLS_RANDOM_SIZE;
376
377 _gnutls_tls_create_random (rnd);
378 _gnutls_set_server_random (session, rnd);
379
380 session->security_parameters.timestamp = time (NULL);
381
382 DECR_LEN (len, 1);
383 session_id_len = data[pos++];
384
385 /* RESUME SESSION
386 */
387 if (session_id_len > TLS_MAX_SESSION_ID_SIZE)
388 {
389 gnutls_assert ();
390 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
391 }
392 DECR_LEN (len, session_id_len);
393
394 ret = _gnutls_server_restore_session (session, &data[pos], session_id_len);
395 pos += session_id_len;
396
397 if (ret == 0)
398 { /* resumed! */
399 resume_copy_required_values (session);
400 session->internals.resumed = RESUME_TRUE;
401 return _gnutls_user_hello_func (session, adv_version);
402 }
403 else
404 {
405 _gnutls_generate_session_id (session->security_parameters.
406 session_id,
407 &session->security_parameters.
408 session_id_size);
409
410 session->internals.resumed = RESUME_FALSE;
411 }
412
413 /* Remember ciphersuites for later
414 */
415 DECR_LEN (len, 2);
416 suite_size = _gnutls_read_uint16 (&data[pos]);
417 pos += 2;
418
419 DECR_LEN (len, suite_size);
420 suite_ptr = &data[pos];
421 pos += suite_size;
422
423 /* Point to the compression methods
424 */
425 DECR_LEN (len, 1);
426 comp_size = data[pos++]; /* z is the number of compression methods */
427
428 DECR_LEN (len, comp_size);
429 comp_ptr = &data[pos];
430 pos += comp_size;
431
432 /* Parse the extensions (if any)
433 */
434 if (neg_version >= GNUTLS_TLS1)
435 {
436 ret = _gnutls_parse_extensions (session, EXTENSION_APPLICATION, &data[pos], len); /* len is the rest of the parsed length */
437 if (ret < 0)
438 {
439 gnutls_assert ();
440 return ret;
441 }
442 }
443
444 ret = _gnutls_user_hello_func (session, adv_version);
445 if (ret < 0)
446 {
447 gnutls_assert ();
448 return ret;
449 }
450
451 if (neg_version >= GNUTLS_TLS1)
452 {
453 ret = _gnutls_parse_extensions (session, EXTENSION_TLS, &data[pos], len); /* len is the rest of the parsed length */
454 if (ret < 0)
455 {
456 gnutls_assert ();
457 return ret;
458 }
459 }
460
461 /* select an appropriate cipher suite
462 */
463 ret = _gnutls_server_select_suite (session, suite_ptr, suite_size);
464 if (ret < 0)
465 {
466 gnutls_assert ();
467 return ret;
468 }
469
470 /* select appropriate compression method */
471 ret = _gnutls_server_select_comp_method (session, comp_ptr, comp_size);
472 if (ret < 0)
473 {
474 gnutls_assert ();
475 return ret;
476 }
477
478 return 0;
479}
480
481/* here we hash all pending data.
482 */
483inline static int
484_gnutls_handshake_hash_pending (gnutls_session_t session)
485{
486 size_t siz;
487 int ret;
488 opaque *data;
489
490 if (session->internals.handshake_mac_handle_sha == NULL ||
491 session->internals.handshake_mac_handle_md5 == NULL)
492 {
493 gnutls_assert ();
494 return GNUTLS_E_INTERNAL_ERROR;
495 }
496
497 /* We check if there are pending data to hash.
498 */
499 if ((ret = _gnutls_handshake_buffer_get_ptr (session, &data, &siz)) < 0)
500 {
501 gnutls_assert ();
502 return ret;
503 }
504
505 if (siz > 0)
506 {
507 _gnutls_hash (session->internals.handshake_mac_handle_sha, data, siz);
508 _gnutls_hash (session->internals.handshake_mac_handle_md5, data, siz);
509 }
510
511 _gnutls_handshake_buffer_empty (session);
512
513 return 0;
514}
515
516
517/* This is to be called after sending CHANGE CIPHER SPEC packet
518 * and initializing encryption. This is the first encrypted message
519 * we send.
520 */
521int
522_gnutls_send_finished (gnutls_session_t session, int again)
523{
524 uint8_t data[36];
525 int ret;
526 int data_size = 0;
527
528
529 if (again == 0)
530 {
531
532 /* This is needed in order to hash all the required
533 * messages.
534 */
535 if ((ret = _gnutls_handshake_hash_pending (session)) < 0)
536 {
537 gnutls_assert ();
538 return ret;
539 }
540
541 if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
542 {
543 ret =
544 _gnutls_ssl3_finished (session,
545 session->security_parameters.entity, data);
546 data_size = 36;
547 }
548 else
549 { /* TLS 1.0 */
550 ret =
551 _gnutls_finished (session,
552 session->security_parameters.entity, data);
553 data_size = 12;
554 }
555
556 if (ret < 0)
557 {
558 gnutls_assert ();
559 return ret;
560 }
561
562 }
563
564 ret =
565 _gnutls_send_handshake (session, data, data_size,
566 GNUTLS_HANDSHAKE_FINISHED);
567
568 return ret;
569}
570
571/* This is to be called after sending our finished message. If everything
572 * went fine we have negotiated a secure connection
573 */
574int
575_gnutls_recv_finished (gnutls_session_t session)
576{
577 uint8_t data[36], *vrfy;
578 int data_size;
579 int ret;
580 int vrfysize;
581
582 ret =
583 _gnutls_recv_handshake (session, &vrfy, &vrfysize,
584 GNUTLS_HANDSHAKE_FINISHED, MANDATORY_PACKET);
585 if (ret < 0)
586 {
587 ERR ("recv finished int", ret);
588 gnutls_assert ();
589 return ret;
590 }
591
592
593 if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
594 {
595 data_size = 36;
596 }
597 else
598 {
599 data_size = 12;
600 }
601
602 if (vrfysize != data_size)
603 {
604 gnutls_assert ();
605 gnutls_free (vrfy);
606 return GNUTLS_E_ERROR_IN_FINISHED_PACKET;
607 }
608
609 if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
610 {
611 ret =
612 _gnutls_ssl3_finished (session,
613 (session->security_parameters.
614 entity + 1) % 2, data);
615 }
616 else
617 { /* TLS 1.0 */
618 ret =
619 _gnutls_finished (session,
620 (session->security_parameters.entity +
621 1) % 2, data);
622 }
623
624 if (ret < 0)
625 {
626 gnutls_assert ();
627 gnutls_free (vrfy);
628 return ret;
629 }
630
631 if (memcmp (vrfy, data, data_size) != 0)
632 {
633 gnutls_assert ();
634 ret = GNUTLS_E_ERROR_IN_FINISHED_PACKET;
635 }
636 gnutls_free (vrfy);
637
638 return ret;
639}
640
641/* returns PK_RSA if the given cipher suite list only supports,
642 * RSA algorithms, PK_DSA if DSS, and PK_ANY for both or PK_NONE for none.
643 */
644static int
645_gnutls_server_find_pk_algos_in_ciphersuites (const opaque *
646 data, int datalen)
647{
648 int j;
649 gnutls_pk_algorithm_t algo = GNUTLS_PK_NONE, prev_algo = 0;
650 gnutls_kx_algorithm_t kx;
651 cipher_suite_st cs;
652
653 if (datalen % 2 != 0)
654 {
655 gnutls_assert ();
656 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
657 }
658
659 for (j = 0; j < datalen; j += 2)
660 {
661 memcpy (&cs.suite, &data[j], 2);
662 kx = _gnutls_cipher_suite_get_kx_algo (&cs);
663
664 if (_gnutls_map_kx_get_cred (kx, 1) == GNUTLS_CRD_CERTIFICATE)
665 {
666 algo = _gnutls_map_pk_get_pk (kx);
667
668 if (algo != prev_algo && prev_algo != 0)
669 return GNUTLS_PK_ANY;
670 prev_algo = algo;
671 }
672 }
673
674 return algo;
675}
676
677
678/* This selects the best supported ciphersuite from the given ones. Then
679 * it adds the suite to the session and performs some checks.
680 */
681int
682_gnutls_server_select_suite (gnutls_session_t session, opaque * data,
683 int datalen)
684{
685 int x, i, j;
686 cipher_suite_st *ciphers, cs;
687 int retval, err;
688 gnutls_pk_algorithm_t pk_algo; /* will hold the pk algorithms
689 * supported by the peer.
690 */
691
692 pk_algo = _gnutls_server_find_pk_algos_in_ciphersuites (data, datalen);
693
694 x = _gnutls_supported_ciphersuites (session, &ciphers);
695 if (x < 0)
696 { /* the case x==0 is handled within the function. */
697 gnutls_assert ();
698 return x;
699 }
700
701 /* Here we remove any ciphersuite that does not conform
702 * the certificate requested, or to the
703 * authentication requested (e.g. SRP).
704 */
705 x = _gnutls_remove_unwanted_ciphersuites (session, &ciphers, x, pk_algo);
706 if (x <= 0)
707 {
708 gnutls_assert ();
709 gnutls_free (ciphers);
710 if (x < 0)
711 return x;
712 else
713 return GNUTLS_E_UNKNOWN_CIPHER_SUITE;
714 }
715
716 /* Data length should be zero mod 2 since
717 * every ciphersuite is 2 bytes. (this check is needed
718 * see below).
719 */
720 if (datalen % 2 != 0)
721 {
722 gnutls_assert ();
723 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
724 }
725#ifdef HANDSHAKE_DEBUG
726
727 _gnutls_handshake_log ("HSK[%x]: Requested cipher suites: \n", session);
728 for (j = 0; j < datalen; j += 2)
729 {
730 memcpy (&cs.suite, &data[j], 2);
731 _gnutls_handshake_log ("\t%s\n", _gnutls_cipher_suite_get_name (&cs));
732 }
733 _gnutls_handshake_log ("HSK[%x]: Supported cipher suites: \n", session);
734 for (j = 0; j < x; j++)
735 _gnutls_handshake_log ("\t%s\n",
736 _gnutls_cipher_suite_get_name (&ciphers[j]));
737#endif
738 memset (session->security_parameters.current_cipher_suite.suite, '\0', 2);
739
740 retval = GNUTLS_E_UNKNOWN_CIPHER_SUITE;
741
742 for (j = 0; j < datalen; j += 2)
743 {
744 for (i = 0; i < x; i++)
745 {
746 if (memcmp (ciphers[i].suite, &data[j], 2) == 0)
747 {
748 memcpy (&cs.suite, &data[j], 2);
749
750 _gnutls_handshake_log
751 ("HSK[%x]: Selected cipher suite: %s\n", session,
752 _gnutls_cipher_suite_get_name (&cs));
753 memcpy (session->security_parameters.current_cipher_suite.
754 suite, ciphers[i].suite, 2);
755 retval = 0;
756 goto finish;
757 }
758 }
759 }
760
761finish:
762 gnutls_free (ciphers);
763
764 if (retval != 0)
765 {
766 gnutls_assert ();
767 return retval;
768 }
769
770 /* check if the credentials (username, public key etc.) are ok
771 */
772 if (_gnutls_get_kx_cred
773 (session,
774 _gnutls_cipher_suite_get_kx_algo (&session->security_parameters.
775 current_cipher_suite),
776 &err) == NULL && err != 0)
777 {
778 gnutls_assert ();
779 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
780 }
781
782
783 /* set the mod_auth_st to the appropriate struct
784 * according to the KX algorithm. This is needed since all the
785 * handshake functions are read from there;
786 */
787 session->internals.auth_struct =
788 _gnutls_kx_auth_struct (_gnutls_cipher_suite_get_kx_algo
789 (&session->security_parameters.
790 current_cipher_suite));
791 if (session->internals.auth_struct == NULL)
792 {
793
794 _gnutls_handshake_log
795 ("HSK[%x]: Cannot find the appropriate handler for the KX algorithm\n",
796 session);
797 gnutls_assert ();
798 return GNUTLS_E_INTERNAL_ERROR;
799 }
800
801 return 0;
802
803}
804
805
806/* This selects the best supported compression method from the ones provided
807 */
808int
809_gnutls_server_select_comp_method (gnutls_session_t session,
810 opaque * data, int datalen)
811{
812 int x, i, j;
813 uint8_t *comps;
814
815 x = _gnutls_supported_compression_methods (session, &comps);
816 if (x < 0)
817 {
818 gnutls_assert ();
819 return x;
820 }
821
822 memset (&session->internals.compression_method, 0,
823 sizeof (gnutls_compression_method_t));
824
825 for (j = 0; j < datalen; j++)
826 {
827 for (i = 0; i < x; i++)
828 {
829 if (comps[i] == data[j])
830 {
831 gnutls_compression_method_t method =
832 _gnutls_compression_get_id (comps[i]);
833
834 session->internals.compression_method = method;
835 gnutls_free (comps);
836
837 _gnutls_handshake_log
838 ("HSK[%x]: Selected Compression Method: %s\n", session,
839 gnutls_compression_get_name (session->internals.
840 compression_method));
841
842
843 return 0;
844 }
845 }
846 }
847
848 /* we were not able to find a compatible compression
849 * algorithm
850 */
851 gnutls_free (comps);
852 gnutls_assert ();
853 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
854
855}
856
857/* This function sends an empty handshake packet. (like hello request).
858 * If the previous _gnutls_send_empty_handshake() returned
859 * GNUTLS_E_AGAIN or GNUTLS_E_INTERRUPTED, then it must be called again
860 * (until it returns ok), with NULL parameters.
861 */
862int
863_gnutls_send_empty_handshake (gnutls_session_t session,
864 gnutls_handshake_description_t type, int again)
865{
866 opaque data = 0;
867 opaque *ptr;
868
869 if (again == 0)
870 ptr = &data;
871 else
872 ptr = NULL;
873
874 return _gnutls_send_handshake (session, ptr, 0, type);
875}
876
877
878/* This function will hash the handshake message we sent.
879 */
880static int
881_gnutls_handshake_hash_add_sent (gnutls_session_t session,
882 gnutls_handshake_description_t type,
883 opaque * dataptr, uint32_t datalen)
884{
885 int ret;
886
887 if ((ret = _gnutls_handshake_hash_pending (session)) < 0)
888 {
889 gnutls_assert ();
890 return ret;
891 }
892
893 if (type != GNUTLS_HANDSHAKE_HELLO_REQUEST)
894 {
895 _gnutls_hash (session->internals.handshake_mac_handle_sha, dataptr,
896 datalen);
897 _gnutls_hash (session->internals.handshake_mac_handle_md5, dataptr,
898 datalen);
899 }
900
901 return 0;
902}
903
904
905/* This function sends a handshake message of type 'type' containing the
906 * data specified here. If the previous _gnutls_send_handshake() returned
907 * GNUTLS_E_AGAIN or GNUTLS_E_INTERRUPTED, then it must be called again
908 * (until it returns ok), with NULL parameters.
909 */
910int
911_gnutls_send_handshake (gnutls_session_t session, void *i_data,
912 uint32_t i_datasize,
913 gnutls_handshake_description_t type)
914{
915 int ret;
916 uint8_t *data;
917 uint32_t datasize;
918 int pos = 0;
919
920 if (i_data == NULL && i_datasize == 0)
921 {
922 /* we are resuming a previously interrupted
923 * send.
924 */
925 ret = _gnutls_handshake_io_write_flush (session);
926 return ret;
927
928 }
929
930 if (i_data == NULL && i_datasize > 0)
931 {
932 gnutls_assert ();
933 return GNUTLS_E_INVALID_REQUEST;
934 }
935
936 /* first run */
937 datasize = i_datasize + HANDSHAKE_HEADER_SIZE;
938 data = gnutls_alloca (datasize);
939 if (data == NULL)
940 {
941 gnutls_assert ();
942 return GNUTLS_E_MEMORY_ERROR;
943 }
944
945 data[pos++] = (uint8_t) type;
946 _gnutls_write_uint24 (i_datasize, &data[pos]);
947 pos += 3;
948
949 if (i_datasize > 0)
950 memcpy (&data[pos], i_data, i_datasize);
951
952 _gnutls_handshake_log ("HSK[%x]: %s was send [%ld bytes]\n",
953 session, _gnutls_handshake2str (type), datasize);
954
955
956 /* Here we keep the handshake messages in order to hash them...
957 */
958 if (type != GNUTLS_HANDSHAKE_HELLO_REQUEST)
959 if ((ret =
960 _gnutls_handshake_hash_add_sent (session, type, data, datasize)) < 0)
961 {
962 gnutls_assert ();
963 gnutls_afree (data);
964 return ret;
965 }
966
967 session->internals.last_handshake_out = type;
968
969 ret =
970 _gnutls_handshake_io_send_int (session, GNUTLS_HANDSHAKE, type,
971 data, datasize);
972
973 gnutls_afree (data);
974
975 return ret;
976}
977
978/* This function will read the handshake header and return it to the caller. If the
979 * received handshake packet is not the one expected then it buffers the header, and
980 * returns UNEXPECTED_HANDSHAKE_PACKET.
981 *
982 * FIXME: This function is complex.
983 */
984#define SSL2_HEADERS 1
985static int
986_gnutls_recv_handshake_header (gnutls_session_t session,
987 gnutls_handshake_description_t type,
988 gnutls_handshake_description_t * recv_type)
989{
990 int ret;
991 uint32_t length32 = 0;
992 uint8_t *dataptr = NULL; /* for realloc */
993 size_t handshake_header_size = HANDSHAKE_HEADER_SIZE;
994
995 /* if we have data into the buffer then return them, do not read the next packet.
996 * In order to return we need a full TLS handshake header, or in case of a version 2
997 * packet, then we return the first byte.
998 */
999 if (session->internals.handshake_header_buffer.header_size ==
1000 handshake_header_size || (session->internals.v2_hello != 0
1001 && type == GNUTLS_HANDSHAKE_CLIENT_HELLO
1002 && session->internals.
1003 handshake_header_buffer.packet_length > 0))
1004 {
1005
1006 *recv_type = session->internals.handshake_header_buffer.recv_type;
1007
1008 return session->internals.handshake_header_buffer.packet_length;
1009 }
1010
1011 /* Note: SSL2_HEADERS == 1 */
1012
1013 dataptr = session->internals.handshake_header_buffer.header;
1014
1015 /* If we haven't already read the handshake headers.
1016 */
1017 if (session->internals.handshake_header_buffer.header_size < SSL2_HEADERS)
1018 {
1019 ret =
1020 _gnutls_handshake_io_recv_int (session, GNUTLS_HANDSHAKE,
1021 type, dataptr, SSL2_HEADERS);
1022
1023 if (ret < 0)
1024 {
1025 gnutls_assert ();
1026 return ret;
1027 }
1028
1029 /* The case ret==0 is caught here.
1030 */
1031 if (ret != SSL2_HEADERS)
1032 {
1033 gnutls_assert ();
1034 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1035 }
1036 session->internals.handshake_header_buffer.header_size = SSL2_HEADERS;
1037 }
1038
1039 if (session->internals.v2_hello == 0
1040 || type != GNUTLS_HANDSHAKE_CLIENT_HELLO)
1041 {
1042 ret =
1043 _gnutls_handshake_io_recv_int (session, GNUTLS_HANDSHAKE,
1044 type,
1045 &dataptr[session->
1046 internals.
1047 handshake_header_buffer.
1048 header_size],
1049 HANDSHAKE_HEADER_SIZE -
1050 session->internals.
1051 handshake_header_buffer.header_size);
1052 if (ret <= 0)
1053 {
1054 gnutls_assert ();
1055 return (ret < 0) ? ret : GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1056 }
1057 if ((size_t) ret !=
1058 HANDSHAKE_HEADER_SIZE -
1059 session->internals.handshake_header_buffer.header_size)
1060 {
1061 gnutls_assert ();
1062 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1063 }
1064 *recv_type = dataptr[0];
1065
1066 /* we do not use DECR_LEN because we know
1067 * that the packet has enough data.
1068 */
1069 length32 = _gnutls_read_uint24 (&dataptr[1]);
1070 handshake_header_size = HANDSHAKE_HEADER_SIZE;
1071
1072 _gnutls_handshake_log ("HSK[%x]: %s was received [%ld bytes]\n",
1073 session, _gnutls_handshake2str (dataptr[0]),
1074 length32 + HANDSHAKE_HEADER_SIZE);
1075
1076 }
1077 else
1078 { /* v2 hello */
1079 length32 = session->internals.v2_hello - SSL2_HEADERS; /* we've read the first byte */
1080
1081 handshake_header_size = SSL2_HEADERS; /* we've already read one byte */
1082
1083 *recv_type = dataptr[0];
1084
1085 _gnutls_handshake_log ("HSK[%x]: %s(v2) was received [%ld bytes]\n",
1086 session, _gnutls_handshake2str (*recv_type),
1087 length32 + handshake_header_size);
1088
1089 if (*recv_type != GNUTLS_HANDSHAKE_CLIENT_HELLO)
1090 { /* it should be one or nothing */
1091 gnutls_assert ();
1092 return GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
1093 }
1094 }
1095
1096 /* put the packet into the buffer */
1097 session->internals.handshake_header_buffer.header_size =
1098 handshake_header_size;
1099 session->internals.handshake_header_buffer.packet_length = length32;
1100 session->internals.handshake_header_buffer.recv_type = *recv_type;
1101
1102 if (*recv_type != type)
1103 {
1104 gnutls_assert ();
1105 return GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
1106 }
1107
1108 return length32;
1109}
1110
1111#define _gnutls_handshake_header_buffer_clear( session) session->internals.handshake_header_buffer.header_size = 0
1112
1113
1114
1115/* This function will hash the handshake headers and the
1116 * handshake data.
1117 */
1118static int
1119_gnutls_handshake_hash_add_recvd (gnutls_session_t session,
1120 gnutls_handshake_description_t recv_type,
1121 opaque * header, uint16_t header_size,
1122 opaque * dataptr, uint32_t datalen)
1123{
1124 int ret;
1125
1126 /* The idea here is to hash the previous message we received,
1127 * and add the one we just received into the handshake_hash_buffer.
1128 */
1129
1130 if ((ret = _gnutls_handshake_hash_pending (session)) < 0)
1131 {
1132 gnutls_assert ();
1133 return ret;
1134 }
1135
1136 /* here we buffer the handshake messages - needed at Finished message */
1137 if (recv_type != GNUTLS_HANDSHAKE_HELLO_REQUEST)
1138 {
1139
1140 if ((ret =
1141 _gnutls_handshake_buffer_put (session, header, header_size)) < 0)
1142 {
1143 gnutls_assert ();
1144 return ret;
1145 }
1146
1147 if (datalen > 0)
1148 {
1149 if ((ret =
1150 _gnutls_handshake_buffer_put (session, dataptr, datalen)) < 0)
1151 {
1152 gnutls_assert ();
1153 return ret;
1154 }
1155 }
1156 }
1157
1158 return 0;
1159}
1160
1161
1162/* This function will receive handshake messages of the given types,
1163 * and will pass the message to the right place in order to be processed.
1164 * E.g. for the SERVER_HELLO message (if it is expected), it will be
1165 * passed to _gnutls_recv_hello().
1166 */
1167int
1168_gnutls_recv_handshake (gnutls_session_t session, uint8_t ** data,
1169 int *datalen, gnutls_handshake_description_t type,
1170 Optional optional)
1171{
1172 int ret;
1173 uint32_t length32 = 0;
1174 opaque *dataptr = NULL;
1175 gnutls_handshake_description_t recv_type;
1176
1177 ret = _gnutls_recv_handshake_header (session, type, &recv_type);
1178 if (ret < 0)
1179 {
1180
1181 if (ret == GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET
1182 && optional == OPTIONAL_PACKET)
1183 {
1184 if (datalen != NULL)
1185 *datalen = 0;
1186 if (data != NULL)
1187 *data = NULL;
1188 return 0; /* ok just ignore the packet */
1189 }
1190
1191 return ret;
1192 }
1193
1194 session->internals.last_handshake_in = recv_type;
1195
1196 length32 = ret;
1197
1198 if (length32 > 0)
1199 dataptr = gnutls_malloc (length32);
1200 else if (recv_type != GNUTLS_HANDSHAKE_SERVER_HELLO_DONE)
1201 {
1202 gnutls_assert ();
1203 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1204 }
1205
1206 if (dataptr == NULL && length32 > 0)
1207 {
1208 gnutls_assert ();
1209 return GNUTLS_E_MEMORY_ERROR;
1210 }
1211
1212 if (datalen != NULL)
1213 *datalen = length32;
1214
1215 if (length32 > 0)
1216 {
1217 ret =
1218 _gnutls_handshake_io_recv_int (session, GNUTLS_HANDSHAKE,
1219 type, dataptr, length32);
1220 if (ret <= 0)
1221 {
1222 gnutls_assert ();
1223 gnutls_free (dataptr);
1224 return (ret == 0) ? GNUTLS_E_UNEXPECTED_PACKET_LENGTH : ret;
1225 }
1226 }
1227
1228 if (data != NULL && length32 > 0)
1229 *data = dataptr;
1230
1231
1232 ret = _gnutls_handshake_hash_add_recvd (session, recv_type,
1233 session->internals.
1234 handshake_header_buffer.header,
1235 session->internals.
1236 handshake_header_buffer.
1237 header_size, dataptr, length32);
1238 if (ret < 0)
1239 {
1240 gnutls_assert ();
1241 _gnutls_handshake_header_buffer_clear (session);
1242 return ret;
1243 }
1244
1245 /* If we fail before this then we will reuse the handshake header
1246 * have have received above. if we get here the we clear the handshake
1247 * header we received.
1248 */
1249 _gnutls_handshake_header_buffer_clear (session);
1250
1251 switch (recv_type)
1252 {
1253 case GNUTLS_HANDSHAKE_CLIENT_HELLO:
1254 case GNUTLS_HANDSHAKE_SERVER_HELLO:
1255 ret = _gnutls_recv_hello (session, dataptr, length32);
1256 /* dataptr is freed because the caller does not
1257 * need it */
1258 gnutls_free (dataptr);
1259 if (data != NULL)
1260 *data = NULL;
1261 break;
1262 case GNUTLS_HANDSHAKE_SERVER_HELLO_DONE:
1263 if (length32 == 0)
1264 ret = 0;
1265 else
1266 ret = GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1267 break;
1268 case GNUTLS_HANDSHAKE_CERTIFICATE_PKT:
1269 case GNUTLS_HANDSHAKE_FINISHED:
1270 case GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE:
1271 case GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE:
1272 case GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST:
1273 case GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY:
1274 case GNUTLS_HANDSHAKE_SUPPLEMENTAL:
1275 ret = length32;
1276 break;
1277 default:
1278 gnutls_assert ();
1279 gnutls_free (dataptr);
1280 if (data != NULL)
1281 *data = NULL;
1282 ret = GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET;
1283 }
1284
1285 return ret;
1286}
1287
1288/* This function checks if the given cipher suite is supported, and sets it
1289 * to the session;
1290 */
1291static int
1292_gnutls_client_set_ciphersuite (gnutls_session_t session, opaque suite[2])
1293{
1294 uint8_t z;
1295 cipher_suite_st *cipher_suites;
1296 int cipher_suite_num;
1297 int i, err;
1298
1299 z = 1;
1300 cipher_suite_num = _gnutls_supported_ciphersuites (session, &cipher_suites);
1301 if (cipher_suite_num < 0)
1302 {
1303 gnutls_assert ();
1304 return cipher_suite_num;
1305 }
1306
1307 for (i = 0; i < cipher_suite_num; i++)
1308 {
1309 if (memcmp (&cipher_suites[i], suite, 2) == 0)
1310 {
1311 z = 0;
1312 break;
1313 }
1314 }
1315
1316 gnutls_free (cipher_suites);
1317
1318 if (z != 0)
1319 {
1320 gnutls_assert ();
1321 return GNUTLS_E_UNKNOWN_CIPHER_SUITE;
1322 }
1323
1324 memcpy (session->security_parameters.current_cipher_suite.suite, suite, 2);
1325
1326 _gnutls_handshake_log ("HSK[%x]: Selected cipher suite: %s\n", session,
1327 _gnutls_cipher_suite_get_name (&session->
1328 security_parameters.
1329 current_cipher_suite));
1330
1331
1332 /* check if the credentials (username, public key etc.) are ok.
1333 * Actually checks if they exist.
1334 */
1335 if (_gnutls_get_kx_cred
1336 (session, _gnutls_cipher_suite_get_kx_algo (&session->
1337 security_parameters.
1338 current_cipher_suite),
1339 &err) == NULL && err != 0)
1340 {
1341 gnutls_assert ();
1342 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1343 }
1344
1345
1346 /* set the mod_auth_st to the appropriate struct
1347 * according to the KX algorithm. This is needed since all the
1348 * handshake functions are read from there;
1349 */
1350 session->internals.auth_struct =
1351 _gnutls_kx_auth_struct (_gnutls_cipher_suite_get_kx_algo
1352 (&session->security_parameters.
1353 current_cipher_suite));
1354
1355 if (session->internals.auth_struct == NULL)
1356 {
1357
1358 _gnutls_handshake_log
1359 ("HSK[%x]: Cannot find the appropriate handler for the KX algorithm\n",
1360 session);
1361 gnutls_assert ();
1362 return GNUTLS_E_INTERNAL_ERROR;
1363 }
1364
1365
1366 return 0;
1367}
1368
1369/* This function sets the given comp method to the session.
1370 */
1371static int
1372_gnutls_client_set_comp_method (gnutls_session_t session, opaque comp_method)
1373{
1374 int comp_methods_num;
1375 uint8_t *compression_methods;
1376 int i;
1377
1378 comp_methods_num = _gnutls_supported_compression_methods (session,
1379 &compression_methods);
1380 if (comp_methods_num < 0)
1381 {
1382 gnutls_assert ();
1383 return comp_methods_num;
1384 }
1385
1386 for (i = 0; i < comp_methods_num; i++)
1387 {
1388 if (compression_methods[i] == comp_method)
1389 {
1390 comp_methods_num = 0;
1391 break;
1392 }
1393 }
1394
1395 gnutls_free (compression_methods);
1396
1397 if (comp_methods_num != 0)
1398 {
1399 gnutls_assert ();
1400 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
1401 }
1402
1403 session->internals.compression_method =
1404 _gnutls_compression_get_id (comp_method);
1405
1406
1407 return 0;
1408}
1409
1410/* This function returns 0 if we are resuming a session or -1 otherwise.
1411 * This also sets the variables in the session. Used only while reading a server
1412 * hello.
1413 */
1414static int
1415_gnutls_client_check_if_resuming (gnutls_session_t session,
1416 opaque * session_id, int session_id_len)
1417{
1418 opaque buf[2 * TLS_MAX_SESSION_ID_SIZE + 1];
1419
1420 _gnutls_handshake_log ("HSK[%x]: SessionID length: %d\n", session,
1421 session_id_len);
1422 _gnutls_handshake_log ("HSK[%x]: SessionID: %s\n", session,
1423 _gnutls_bin2hex (session_id, session_id_len, buf,
1424 sizeof (buf)));
1425
1426 if (session_id_len > 0 &&
1427 session->internals.resumed_security_parameters.session_id_size ==
1428 session_id_len
1429 && memcmp (session_id,
1430 session->internals.resumed_security_parameters.
1431 session_id, session_id_len) == 0)
1432 {
1433 /* resume session */
1434 memcpy (session->internals.
1435 resumed_security_parameters.server_random,
1436 session->security_parameters.server_random, TLS_RANDOM_SIZE);
1437 memcpy (session->internals.
1438 resumed_security_parameters.client_random,
1439 session->security_parameters.client_random, TLS_RANDOM_SIZE);
1440 session->internals.resumed = RESUME_TRUE; /* we are resuming */
1441
1442 return 0;
1443 }
1444 else
1445 {
1446 /* keep the new session id */
1447 session->internals.resumed = RESUME_FALSE; /* we are not resuming */
1448 session->security_parameters.session_id_size = session_id_len;
1449 memcpy (session->security_parameters.session_id,
1450 session_id, session_id_len);
1451
1452 return -1;
1453 }
1454}
1455
1456
1457/* This function reads and parses the server hello handshake message.
1458 * This function also restores resumed parameters if we are resuming a
1459 * session.
1460 */
1461static int
1462_gnutls_read_server_hello (gnutls_session_t session,
1463 opaque * data, int datalen)
1464{
1465 uint8_t session_id_len = 0;
1466 int pos = 0;
1467 int ret = 0;
1468 gnutls_protocol_t version;
1469 int len = datalen;
1470
1471 if (datalen < 38)
1472 {
1473 gnutls_assert ();
1474 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
1475 }
1476
1477 _gnutls_handshake_log ("HSK[%x]: Server's version: %d.%d\n",
1478 session, data[pos], data[pos + 1]);
1479
1480 DECR_LEN (len, 2);
1481 version = _gnutls_version_get (data[pos], data[pos + 1]);
1482 if (_gnutls_version_is_supported (session, version) == 0)
1483 {
1484 gnutls_assert ();
1485 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
1486 }
1487 else
1488 {
1489 _gnutls_set_current_version (session, version);
1490 }
1491
1492 pos += 2;
1493
1494 DECR_LEN (len, TLS_RANDOM_SIZE);
1495 _gnutls_set_server_random (session, &data[pos]);
1496 pos += TLS_RANDOM_SIZE;
1497
1498
1499 /* Read session ID
1500 */
1501 DECR_LEN (len, 1);
1502 session_id_len = data[pos++];
1503
1504 if (len < session_id_len)
1505 {
1506 gnutls_assert ();
1507 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
1508 }
1509 DECR_LEN (len, session_id_len);
1510
1511
1512 /* check if we are resuming and set the appropriate
1513 * values;
1514 */
1515 if (_gnutls_client_check_if_resuming
1516 (session, &data[pos], session_id_len) == 0)
1517 return 0;
1518 pos += session_id_len;
1519
1520
1521 /* Check if the given cipher suite is supported and copy
1522 * it to the session.
1523 */
1524
1525 DECR_LEN (len, 2);
1526 ret = _gnutls_client_set_ciphersuite (session, &data[pos]);
1527 if (ret < 0)
1528 {
1529 gnutls_assert ();
1530 return ret;
1531 }
1532 pos += 2;
1533
1534
1535
1536 /* move to compression
1537 */
1538 DECR_LEN (len, 1);
1539
1540 ret = _gnutls_client_set_comp_method (session, data[pos++]);
1541 if (ret < 0)
1542 {
1543 gnutls_assert ();
1544 return GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM;
1545 }
1546
1547 /* Parse extensions.
1548 */
1549 if (version >= GNUTLS_TLS1)
1550 {
1551 ret = _gnutls_parse_extensions (session, EXTENSION_ANY, &data[pos], len); /* len is the rest of the parsed length */
1552 if (ret < 0)
1553 {
1554 gnutls_assert ();
1555 return ret;
1556 }
1557 }
1558 return ret;
1559}
1560
1561
1562/* This function copies the appropriate ciphersuites to a locally allocated buffer
1563 * Needed in client hello messages. Returns the new data length.
1564 */
1565static int
1566_gnutls_copy_ciphersuites (gnutls_session_t session,
1567 opaque * ret_data, size_t ret_data_size)
1568{
1569 int ret, i;
1570 cipher_suite_st *cipher_suites;
1571 uint16_t cipher_num;
1572 int datalen, pos;
1573
1574 ret = _gnutls_supported_ciphersuites_sorted (session, &cipher_suites);
1575 if (ret < 0)
1576 {
1577 gnutls_assert ();
1578 return ret;
1579 }
1580
1581 /* Here we remove any ciphersuite that does not conform
1582 * the certificate requested, or to the
1583 * authentication requested (eg SRP).
1584 */
1585 ret =
1586 _gnutls_remove_unwanted_ciphersuites (session, &cipher_suites, ret, -1);
1587 if (ret < 0)
1588 {
1589 gnutls_assert ();
1590 gnutls_free (cipher_suites);
1591 return ret;
1592 }
1593
1594 /* If no cipher suites were enabled.
1595 */
1596 if (ret == 0)
1597 {
1598 gnutls_assert ();
1599 gnutls_free (cipher_suites);
1600 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
1601 }
1602
1603 cipher_num = ret;
1604
1605 cipher_num *= sizeof (uint16_t); /* in order to get bytes */
1606
1607 datalen = pos = 0;
1608
1609 datalen += sizeof (uint16_t) + cipher_num;
1610
1611 if ((size_t) datalen > ret_data_size)
1612 {
1613 gnutls_assert ();
1614 return GNUTLS_E_INTERNAL_ERROR;
1615 }
1616
1617 _gnutls_write_uint16 (cipher_num, ret_data);
1618 pos += 2;
1619
1620 for (i = 0; i < (cipher_num / 2); i++)
1621 {
1622 memcpy (&ret_data[pos], cipher_suites[i].suite, 2);
1623 pos += 2;
1624 }
1625 gnutls_free (cipher_suites);
1626
1627 return datalen;
1628}
1629
1630
1631/* This function copies the appropriate compression methods, to a locally allocated buffer
1632 * Needed in hello messages. Returns the new data length.
1633 */
1634static int
1635_gnutls_copy_comp_methods (gnutls_session_t session,
1636 opaque * ret_data, size_t ret_data_size)
1637{
1638 int ret, i;
1639 uint8_t *compression_methods, comp_num;
1640 int datalen, pos;
1641
1642 ret = _gnutls_supported_compression_methods (session, &compression_methods);
1643 if (ret < 0)
1644 {
1645 gnutls_assert ();
1646 return ret;
1647 }
1648
1649 comp_num = ret;
1650
1651 datalen = pos = 0;
1652 datalen += comp_num + 1;
1653
1654 if ((size_t) datalen > ret_data_size)
1655 {
1656 gnutls_assert ();
1657 return GNUTLS_E_INTERNAL_ERROR;
1658 }
1659
1660 ret_data[pos++] = comp_num; /* put the number of compression methods */
1661
1662 for (i = 0; i < comp_num; i++)
1663 {
1664 ret_data[pos++] = compression_methods[i];
1665 }
1666
1667 gnutls_free (compression_methods);
1668
1669 return datalen;
1670}
1671
1672/* This should be sufficient by now. It should hold all the extensions
1673 * plus the headers in a hello message.
1674 */
1675#define MAX_EXT_DATA_LENGTH 1024
1676
1677/* This function sends the client hello handshake message.
1678 */
1679static int
1680_gnutls_send_client_hello (gnutls_session_t session, int again)
1681{
1682 opaque *data = NULL;
1683 int extdatalen;
1684 int pos = 0;
1685 int datalen = 0, ret = 0;
1686 opaque rnd[TLS_RANDOM_SIZE];
1687 gnutls_protocol_t hver;
1688 opaque extdata[MAX_EXT_DATA_LENGTH];
1689
1690 opaque *SessionID =
1691 session->internals.resumed_security_parameters.session_id;
1692 uint8_t session_id_len =
1693 session->internals.resumed_security_parameters.session_id_size;
1694
1695 if (SessionID == NULL)
1696 session_id_len = 0;
1697 else if (session_id_len == 0)
1698 SessionID = NULL;
1699
1700 if (again == 0)
1701 {
1702
1703 datalen = 2 + (session_id_len + 1) + TLS_RANDOM_SIZE;
1704 /* 2 for version, (4 for unix time + 28 for random bytes==TLS_RANDOM_SIZE)
1705 */
1706
1707 data = gnutls_malloc (datalen);
1708 if (data == NULL)
1709 {
1710 gnutls_assert ();
1711 return GNUTLS_E_MEMORY_ERROR;
1712 }
1713
1714 /* if we are resuming a session then we set the
1715 * version number to the previously established.
1716 */
1717 if (SessionID == NULL)
1718 hver = _gnutls_version_max (session);
1719 else
1720 { /* we are resuming a session */
1721 hver = session->internals.resumed_security_parameters.version;
1722 }
1723
1724 if (hver == GNUTLS_VERSION_UNKNOWN || hver == 0)
1725 {
1726 gnutls_assert ();
1727 gnutls_free (data);
1728 return GNUTLS_E_INTERNAL_ERROR;
1729 }
1730
1731 data[pos++] = _gnutls_version_get_major (hver);
1732 data[pos++] = _gnutls_version_get_minor (hver);
1733
1734 /* Set the version we advertized as maximum
1735 * (RSA uses it).
1736 */
1737 _gnutls_set_adv_version (session, hver);
1738
1739 /* Some old implementations do not interoperate if we send a
1740 * different version in the record layer.
1741 * It seems they prefer to read the record's version
1742 * as the one we actually requested.
1743 * The proper behaviour is to use the one in the client hello
1744 * handshake packet and ignore the one in the packet's record
1745 * header.
1746 */
1747 _gnutls_set_current_version (session, hver);
1748
1749 /* In order to know when this session was initiated.
1750 */
1751 session->security_parameters.timestamp = time (NULL);
1752
1753 /* Generate random data
1754 */
1755 _gnutls_tls_create_random (rnd);
1756 _gnutls_set_client_random (session, rnd);
1757
1758 memcpy (&data[pos], rnd, TLS_RANDOM_SIZE);
1759 pos += TLS_RANDOM_SIZE;
1760
1761 /* Copy the Session ID
1762 */
1763 data[pos++] = session_id_len;
1764
1765 if (session_id_len > 0)
1766 {
1767 memcpy (&data[pos], SessionID, session_id_len);
1768 pos += session_id_len;
1769 }
1770
1771
1772 /* Copy the ciphersuites.
1773 */
1774 extdatalen =
1775 _gnutls_copy_ciphersuites (session, extdata, sizeof (extdata));
1776 if (extdatalen > 0)
1777 {
1778 datalen += extdatalen;
1779 data = gnutls_realloc_fast (data, datalen);
1780 if (data == NULL)
1781 {
1782 gnutls_assert ();
1783 return GNUTLS_E_MEMORY_ERROR;
1784 }
1785
1786 memcpy (&data[pos], extdata, extdatalen);
1787 pos += extdatalen;
1788
1789 }
1790 else
1791 {
1792 if (extdatalen == 0)
1793 extdatalen = GNUTLS_E_INTERNAL_ERROR;
1794 gnutls_free (data);
1795 gnutls_assert ();
1796 return extdatalen;
1797 }
1798
1799
1800 /* Copy the compression methods.
1801 */
1802 extdatalen =
1803 _gnutls_copy_comp_methods (session, extdata, sizeof (extdata));
1804 if (extdatalen > 0)
1805 {
1806 datalen += extdatalen;
1807 data = gnutls_realloc_fast (data, datalen);
1808 if (data == NULL)
1809 {
1810 gnutls_assert ();
1811 return GNUTLS_E_MEMORY_ERROR;
1812 }
1813
1814 memcpy (&data[pos], extdata, extdatalen);
1815 pos += extdatalen;
1816
1817 }
1818 else
1819 {
1820 if (extdatalen == 0)
1821 extdatalen = GNUTLS_E_INTERNAL_ERROR;
1822 gnutls_free (data);
1823 gnutls_assert ();
1824 return extdatalen;
1825 }
1826
1827 /* Generate and copy TLS extensions.
1828 */
1829 if (hver >= GNUTLS_TLS1)
1830 {
1831 extdatalen =
1832 _gnutls_gen_extensions (session, extdata, sizeof (extdata));
1833
1834 if (extdatalen > 0)
1835 {
1836 datalen += extdatalen;
1837 data = gnutls_realloc_fast (data, datalen);
1838 if (data == NULL)
1839 {
1840 gnutls_assert ();
1841 return GNUTLS_E_MEMORY_ERROR;
1842 }
1843
1844 memcpy (&data[pos], extdata, extdatalen);
1845 }
1846 else if (extdatalen < 0)
1847 {
1848 gnutls_assert ();
1849 gnutls_free (data);
1850 return extdatalen;
1851 }
1852 }
1853 }
1854
1855 ret =
1856 _gnutls_send_handshake (session, data, datalen,
1857 GNUTLS_HANDSHAKE_CLIENT_HELLO);
1858 gnutls_free (data);
1859
1860 return ret;
1861}
1862
1863static int
1864_gnutls_send_server_hello (gnutls_session_t session, int again)
1865{
1866 opaque *data = NULL;
1867 opaque extdata[MAX_EXT_DATA_LENGTH];
1868 int extdatalen;
1869 int pos = 0;
1870 int datalen, ret = 0;
1871 uint8_t comp;
1872 opaque *SessionID = session->security_parameters.session_id;
1873 uint8_t session_id_len = session->security_parameters.session_id_size;
1874 opaque buf[2 * TLS_MAX_SESSION_ID_SIZE + 1];
1875
1876 if (SessionID == NULL)
1877 session_id_len = 0;
1878
1879 datalen = 0;
1880
1881#ifdef ENABLE_SRP
1882 if (IS_SRP_KX
1883 (_gnutls_cipher_suite_get_kx_algo
1884 (&session->security_parameters.current_cipher_suite)))
1885 {
1886 /* While resuming we cannot check the username extension since it is
1887 * not available at this point. It will be copied on connection
1888 * state activation.
1889 */
1890 if (session->internals.resumed == RESUME_FALSE &&
1891 session->security_parameters.extensions.srp_username[0] == 0)
1892 {
1893 /* The peer didn't send a valid SRP extension with the
1894 * SRP username. The draft requires that we send a fatal
1895 * alert and abort.
1896 */
1897 gnutls_assert ();
1898 ret = gnutls_alert_send (session, GNUTLS_AL_FATAL,
1899 GNUTLS_A_UNKNOWN_PSK_IDENTITY);
1900 if (ret < 0)
1901 {
1902 gnutls_assert ();
1903 return ret;
1904 }
1905
1906 return GNUTLS_E_ILLEGAL_SRP_USERNAME;
1907 }
1908 }
1909#endif
1910
1911 if (again == 0)
1912 {
1913 datalen = 2 + session_id_len + 1 + TLS_RANDOM_SIZE + 3;
1914 extdatalen =
1915 _gnutls_gen_extensions (session, extdata, sizeof (extdata));
1916
1917 if (extdatalen < 0)
1918 {
1919 gnutls_assert ();
1920 return extdatalen;
1921 }
1922
1923 data = gnutls_alloca (datalen + extdatalen);
1924 if (data == NULL)
1925 {
1926 gnutls_assert ();
1927 return GNUTLS_E_MEMORY_ERROR;
1928 }
1929
1930 data[pos++] =
1931 _gnutls_version_get_major (session->security_parameters.version);
1932 data[pos++] =
1933 _gnutls_version_get_minor (session->security_parameters.version);
1934
1935 memcpy (&data[pos],
1936 session->security_parameters.server_random, TLS_RANDOM_SIZE);
1937 pos += TLS_RANDOM_SIZE;
1938
1939 data[pos++] = session_id_len;
1940 if (session_id_len > 0)
1941 {
1942 memcpy (&data[pos], SessionID, session_id_len);
1943 }
1944 pos += session_id_len;
1945
1946 _gnutls_handshake_log ("HSK[%x]: SessionID: %s\n", session,
1947 _gnutls_bin2hex (SessionID, session_id_len,
1948 buf, sizeof (buf)));
1949
1950 memcpy (&data[pos],
1951 session->security_parameters.current_cipher_suite.suite, 2);
1952 pos += 2;
1953
1954 comp =
1955 (uint8_t) _gnutls_compression_get_num (session->
1956 internals.compression_method);
1957 data[pos++] = comp;
1958
1959
1960 if (extdatalen > 0)
1961 {
1962 datalen += extdatalen;
1963
1964 memcpy (&data[pos], extdata, extdatalen);
1965 }
1966 }
1967
1968 ret =
1969 _gnutls_send_handshake (session, data, datalen,
1970 GNUTLS_HANDSHAKE_SERVER_HELLO);
1971 gnutls_afree (data);
1972
1973 return ret;
1974}
1975
1976int
1977_gnutls_send_hello (gnutls_session_t session, int again)
1978{
1979 int ret;
1980
1981 if (session->security_parameters.entity == GNUTLS_CLIENT)
1982 {
1983 ret = _gnutls_send_client_hello (session, again);
1984
1985 }
1986 else
1987 { /* SERVER */
1988 ret = _gnutls_send_server_hello (session, again);
1989 }
1990
1991 return ret;
1992}
1993
1994/* RECEIVE A HELLO MESSAGE. This should be called from gnutls_recv_handshake_int only if a
1995 * hello message is expected. It uses the security_parameters.current_cipher_suite
1996 * and internals.compression_method.
1997 */
1998int
1999_gnutls_recv_hello (gnutls_session_t session, opaque * data, int datalen)
2000{
2001 int ret;
2002
2003 if (session->security_parameters.entity == GNUTLS_CLIENT)
2004 {
2005 ret = _gnutls_read_server_hello (session, data, datalen);
2006 if (ret < 0)
2007 {
2008 gnutls_assert ();
2009 return ret;
2010 }
2011 }
2012 else
2013 { /* Server side reading a client hello */
2014
2015 ret = _gnutls_read_client_hello (session, data, datalen);
2016 if (ret < 0)
2017 {
2018 gnutls_assert ();
2019 return ret;
2020 }
2021 }
2022
2023 return ret;
2024}
2025
2026/* The packets in gnutls_handshake (it's more broad than original TLS handshake)
2027 *
2028 * Client Server
2029 *
2030 * ClientHello -------->
2031 * <-------- ServerHello
2032 *
2033 * Certificate*
2034 * ServerKeyExchange*
2035 * <-------- CertificateRequest*
2036 *
2037 * <-------- ServerHelloDone
2038 * Certificate*
2039 * ClientKeyExchange
2040 * CertificateVerify*
2041 * [ChangeCipherSpec]
2042 * Finished -------->
2043 * [ChangeCipherSpec]
2044 * <-------- Finished
2045 *
2046 * (*): means optional packet.
2047 */
2048
2049/**
2050 * gnutls_rehandshake - This function will renegotiate security parameters
2051 * @session: is a #gnutls_session_t structure.
2052 *
2053 * This function will renegotiate security parameters with the
2054 * client. This should only be called in case of a server.
2055 *
2056 * This message informs the peer that we want to renegotiate
2057 * parameters (perform a handshake).
2058 *
2059 * If this function succeeds (returns 0), you must call the
2060 * gnutls_handshake() function in order to negotiate the new
2061 * parameters.
2062 *
2063 * If the client does not wish to renegotiate parameters he will
2064 * should with an alert message, thus the return code will be
2065 * %GNUTLS_E_WARNING_ALERT_RECEIVED and the alert will be
2066 * %GNUTLS_A_NO_RENEGOTIATION. A client may also choose to ignore
2067 * this message.
2068 *
2069 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
2070 *
2071 **/
2072int
2073gnutls_rehandshake (gnutls_session_t session)
2074{
2075 int ret;
2076
2077 /* only server sends that handshake packet */
2078 if (session->security_parameters.entity == GNUTLS_CLIENT)
2079 return GNUTLS_E_INVALID_REQUEST;
2080
2081 ret =
2082 _gnutls_send_empty_handshake (session, GNUTLS_HANDSHAKE_HELLO_REQUEST,
2083 AGAIN (STATE50));
2084 STATE = STATE50;
2085
2086 if (ret < 0)
2087 {
2088 gnutls_assert ();
2089 return ret;
2090 }
2091 STATE = STATE0;
2092
2093 return 0;
2094}
2095
2096inline static int
2097_gnutls_abort_handshake (gnutls_session_t session, int ret)
2098{
2099 if (((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) &&
2100 (gnutls_alert_get (session) == GNUTLS_A_NO_RENEGOTIATION))
2101 || ret == GNUTLS_E_GOT_APPLICATION_DATA)
2102 return 0;
2103
2104 /* this doesn't matter */
2105 return GNUTLS_E_INTERNAL_ERROR;
2106}
2107
2108
2109/* This function initialized the handshake hash session.
2110 * required for finished messages.
2111 */
2112inline static int
2113_gnutls_handshake_hash_init (gnutls_session_t session)
2114{
2115
2116 if (session->internals.handshake_mac_handle_md5 == NULL)
2117 {
2118 session->internals.handshake_mac_handle_md5 =
2119 _gnutls_hash_init (GNUTLS_MAC_MD5);
2120
2121 if (session->internals.handshake_mac_handle_md5 == GNUTLS_HASH_FAILED)
2122 {
2123 gnutls_assert ();
2124 return GNUTLS_E_MEMORY_ERROR;
2125 }
2126 }
2127
2128 if (session->internals.handshake_mac_handle_sha == NULL)
2129 {
2130 session->internals.handshake_mac_handle_sha =
2131 _gnutls_hash_init (GNUTLS_MAC_SHA1);
2132 if (session->internals.handshake_mac_handle_sha == GNUTLS_HASH_FAILED)
2133 {
2134 gnutls_assert ();
2135 return GNUTLS_E_MEMORY_ERROR;
2136 }
2137 }
2138
2139 return 0;
2140}
2141
2142int
2143_gnutls_send_supplemental (gnutls_session_t session, int again)
2144{
2145 int ret = 0;
2146
2147 _gnutls_debug_log ("EXT[%x]: Sending supplemental data\n", session);
2148
2149 if (again)
2150 ret = _gnutls_send_handshake (session, NULL, 0,
2151 GNUTLS_HANDSHAKE_SUPPLEMENTAL);
2152 else
2153 {
2154 gnutls_buffer buf;
2155 _gnutls_buffer_init (&buf);
2156
2157 ret = _gnutls_gen_supplemental (session, &buf);
2158 if (ret < 0)
2159 {
2160 gnutls_assert ();
2161 return ret;
2162 }
2163
2164 ret = _gnutls_send_handshake (session, buf.data, buf.length,
2165 GNUTLS_HANDSHAKE_SUPPLEMENTAL);
2166 _gnutls_buffer_clear (&buf);
2167 }
2168
2169 return ret;
2170}
2171
2172int
2173_gnutls_recv_supplemental (gnutls_session_t session)
2174{
2175 uint8_t *data = NULL;
2176 int datalen = 0;
2177 int ret;
2178
2179 _gnutls_debug_log ("EXT[%x]: Expecting supplemental data\n", session);
2180
2181 ret = _gnutls_recv_handshake (session, &data, &datalen,
2182 GNUTLS_HANDSHAKE_SUPPLEMENTAL,
2183 OPTIONAL_PACKET);
2184 if (ret < 0)
2185 {
2186 gnutls_assert ();
2187 return ret;
2188 }
2189
2190 ret = _gnutls_parse_supplemental (session, data, datalen);
2191 if (ret < 0)
2192 {
2193 gnutls_assert ();
2194 return ret;
2195 }
2196
2197 gnutls_free (data);
2198
2199 return ret;
2200}
2201
2202/**
2203 * gnutls_handshake - This is the main function in the handshake protocol.
2204 * @session: is a #gnutls_session_t structure.
2205 *
2206 * This function does the handshake of the TLS/SSL protocol, and
2207 * initializes the TLS connection.
2208 *
2209 * This function will fail if any problem is encountered, and will
2210 * return a negative error code. In case of a client, if the client
2211 * has asked to resume a session, but the server couldn't, then a
2212 * full handshake will be performed.
2213 *
2214 * The non-fatal errors such as %GNUTLS_E_AGAIN and
2215 * %GNUTLS_E_INTERRUPTED interrupt the handshake procedure, which
2216 * should be later be resumed. Call this function again, until it
2217 * returns 0; cf. gnutls_record_get_direction() and
2218 * gnutls_error_is_fatal().
2219 *
2220 * If this function is called by a server after a rehandshake request
2221 * then %GNUTLS_E_GOT_APPLICATION_DATA or
2222 * %GNUTLS_E_WARNING_ALERT_RECEIVED may be returned. Note that these
2223 * are non fatal errors, only in the specific case of a rehandshake.
2224 * Their meaning is that the client rejected the rehandshake request.
2225 *
2226 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
2227 *
2228 **/
2229int
2230gnutls_handshake (gnutls_session_t session)
2231{
2232 int ret;
2233
2234 if ((ret = _gnutls_handshake_hash_init (session)) < 0)
2235 {
2236 gnutls_assert ();
2237 return ret;
2238 }
2239
2240 if (session->security_parameters.entity == GNUTLS_CLIENT)
2241 {
2242 ret = _gnutls_handshake_client (session);
2243 }
2244 else
2245 {
2246 ret = _gnutls_handshake_server (session);
2247 }
2248 if (ret < 0)
2249 {
2250 /* In the case of a rehandshake abort
2251 * we should reset the handshake's internal state.
2252 */
2253 if (_gnutls_abort_handshake (session, ret) == 0)
2254 STATE = STATE0;
2255
2256 return ret;
2257 }
2258
2259 ret = _gnutls_handshake_common (session);
2260
2261 if (ret < 0)
2262 {
2263 if (_gnutls_abort_handshake (session, ret) == 0)
2264 STATE = STATE0;
2265
2266 return ret;
2267 }
2268
2269 STATE = STATE0;
2270
2271 _gnutls_handshake_io_buffer_clear (session);
2272 _gnutls_handshake_internal_state_clear (session);
2273
2274 return 0;
2275}
2276
2277#define IMED_RET( str, ret) do { \
2278 if (ret < 0) { \
2279 if (gnutls_error_is_fatal(ret)==0) return ret; \
2280 gnutls_assert(); \
2281 ERR( str, ret); \
2282 _gnutls_handshake_hash_buffers_clear(session); \
2283 return ret; \
2284 } } while (0)
2285
2286
2287
2288/*
2289 * _gnutls_handshake_client
2290 * This function performs the client side of the handshake of the TLS/SSL protocol.
2291 */
2292int
2293_gnutls_handshake_client (gnutls_session_t session)
2294{
2295 int ret = 0;
2296
2297#ifdef HANDSHAKE_DEBUG
2298 char buf[64];
2299
2300 if (session->internals.resumed_security_parameters.session_id_size > 0)
2301 _gnutls_handshake_log ("HSK[%x]: Ask to resume: %s\n", session,
2302 _gnutls_bin2hex (session->internals.
2303 resumed_security_parameters.
2304 session_id,
2305 session->internals.
2306 resumed_security_parameters.
2307 session_id_size, buf,
2308 sizeof (buf)));
2309#endif
2310
2311 switch (STATE)
2312 {
2313 case STATE0:
2314 case STATE1:
2315 ret = _gnutls_send_hello (session, AGAIN (STATE1));
2316 STATE = STATE1;
2317 IMED_RET ("send hello", ret);
2318
2319 case STATE2:
2320 /* receive the server hello */
2321 ret =
2322 _gnutls_recv_handshake (session, NULL, NULL,
2323 GNUTLS_HANDSHAKE_SERVER_HELLO,
2324 MANDATORY_PACKET);
2325 STATE = STATE2;
2326 IMED_RET ("recv hello", ret);
2327
2328 case STATE70:
2329 if (session->security_parameters.extensions.do_recv_supplemental)
2330 {
2331 ret = _gnutls_recv_supplemental (session);
2332 STATE = STATE70;
2333 IMED_RET ("recv supplemental", ret);
2334 }
2335
2336 case STATE3:
2337 /* RECV CERTIFICATE */
2338 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2339 ret = _gnutls_recv_server_certificate (session);
2340 STATE = STATE3;
2341 IMED_RET ("recv server certificate", ret);
2342
2343 case STATE4:
2344 /* receive the server key exchange */
2345 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2346 ret = _gnutls_recv_server_kx_message (session);
2347 STATE = STATE4;
2348 IMED_RET ("recv server kx message", ret);
2349
2350 case STATE5:
2351 /* receive the server certificate request - if any
2352 */
2353
2354 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2355 ret = _gnutls_recv_server_certificate_request (session);
2356 STATE = STATE5;
2357 IMED_RET ("recv server certificate request message", ret);
2358
2359 case STATE6:
2360 /* receive the server hello done */
2361 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2362 ret =
2363 _gnutls_recv_handshake (session, NULL, NULL,
2364 GNUTLS_HANDSHAKE_SERVER_HELLO_DONE,
2365 MANDATORY_PACKET);
2366 STATE = STATE6;
2367 IMED_RET ("recv server hello done", ret);
2368
2369 case STATE71:
2370 if (session->security_parameters.extensions.do_send_supplemental)
2371 {
2372 ret = _gnutls_send_supplemental (session, AGAIN (STATE71));
2373 STATE = STATE71;
2374 IMED_RET ("send supplemental", ret);
2375 }
2376
2377 case STATE7:
2378 /* send our certificate - if any and if requested
2379 */
2380 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2381 ret = _gnutls_send_client_certificate (session, AGAIN (STATE7));
2382 STATE = STATE7;
2383 IMED_RET ("send client certificate", ret);
2384
2385 case STATE8:
2386 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2387 ret = _gnutls_send_client_kx_message (session, AGAIN (STATE8));
2388 STATE = STATE8;
2389 IMED_RET ("send client kx", ret);
2390
2391 case STATE9:
2392 /* send client certificate verify */
2393 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2394 ret =
2395 _gnutls_send_client_certificate_verify (session, AGAIN (STATE9));
2396 STATE = STATE9;
2397 IMED_RET ("send client certificate verify", ret);
2398
2399 STATE = STATE0;
2400 default:
2401 break;
2402 }
2403
2404
2405 return 0;
2406}
2407
2408/* This function sends the final handshake packets and initializes connection
2409 */
2410static int
2411_gnutls_send_handshake_final (gnutls_session_t session, int init)
2412{
2413 int ret = 0;
2414
2415 /* Send the CHANGE CIPHER SPEC PACKET */
2416
2417 switch (STATE)
2418 {
2419 case STATE0:
2420 case STATE20:
2421 ret = _gnutls_send_change_cipher_spec (session, AGAIN (STATE20));
2422 STATE = STATE20;
2423 if (ret < 0)
2424 {
2425 ERR ("send ChangeCipherSpec", ret);
2426 gnutls_assert ();
2427 return ret;
2428 }
2429
2430 /* Initialize the connection session (start encryption) - in case of client
2431 */
2432 if (init == TRUE)
2433 {
2434 ret = _gnutls_connection_state_init (session);
2435 if (ret < 0)
2436 {
2437 gnutls_assert ();
2438 return ret;
2439 }
2440 }
2441
2442 ret = _gnutls_write_connection_state_init (session);
2443 if (ret < 0)
2444 {
2445 gnutls_assert ();
2446 return ret;
2447 }
2448
2449 case STATE21:
2450 /* send the finished message */
2451 ret = _gnutls_send_finished (session, AGAIN (STATE21));
2452 STATE = STATE21;
2453 if (ret < 0)
2454 {
2455 ERR ("send Finished", ret);
2456 gnutls_assert ();
2457 return ret;
2458 }
2459
2460 STATE = STATE0;
2461 default:
2462 break;
2463 }
2464
2465 return 0;
2466}
2467
2468/* This function receives the final handshake packets
2469 * And executes the appropriate function to initialize the
2470 * read session.
2471 */
2472static int
2473_gnutls_recv_handshake_final (gnutls_session_t session, int init)
2474{
2475 int ret = 0;
2476 uint8_t ch;
2477
2478 switch (STATE)
2479 {
2480 case STATE0:
2481 case STATE30:
2482 ret = _gnutls_recv_int (session, GNUTLS_CHANGE_CIPHER_SPEC, -1, &ch, 1);
2483 STATE = STATE30;
2484 if (ret <= 0)
2485 {
2486 ERR ("recv ChangeCipherSpec", ret);
2487 gnutls_assert ();
2488 return (ret < 0) ? ret : GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
2489 }
2490
2491 /* Initialize the connection session (start encryption) - in case of server */
2492 if (init == TRUE)
2493 {
2494 ret = _gnutls_connection_state_init (session);
2495 if (ret < 0)
2496 {
2497 gnutls_assert ();
2498 return ret;
2499 }
2500 }
2501
2502 ret = _gnutls_read_connection_state_init (session);
2503 if (ret < 0)
2504 {
2505 gnutls_assert ();
2506 return ret;
2507 }
2508
2509 case STATE31:
2510 ret = _gnutls_recv_finished (session);
2511 STATE = STATE31;
2512 if (ret < 0)
2513 {
2514 ERR ("recv finished", ret);
2515 gnutls_assert ();
2516 return ret;
2517 }
2518 STATE = STATE0;
2519 default:
2520 break;
2521 }
2522
2523
2524 return 0;
2525}
2526
2527 /*
2528 * _gnutls_handshake_server
2529 * This function does the server stuff of the handshake protocol.
2530 */
2531
2532int
2533_gnutls_handshake_server (gnutls_session_t session)
2534{
2535 int ret = 0;
2536
2537 switch (STATE)
2538 {
2539 case STATE0:
2540 case STATE1:
2541 ret =
2542 _gnutls_recv_handshake (session, NULL, NULL,
2543 GNUTLS_HANDSHAKE_CLIENT_HELLO,
2544 MANDATORY_PACKET);
2545 STATE = STATE1;
2546 IMED_RET ("recv hello", ret);
2547
2548 case STATE2:
2549 ret = _gnutls_send_hello (session, AGAIN (STATE2));
2550 STATE = STATE2;
2551 IMED_RET ("send hello", ret);
2552
2553 case STATE70:
2554 if (session->security_parameters.extensions.do_send_supplemental)
2555 {
2556 ret = _gnutls_send_supplemental (session, AGAIN (STATE70));
2557 STATE = STATE70;
2558 IMED_RET ("send supplemental data", ret);
2559 }
2560
2561 /* SEND CERTIFICATE + KEYEXCHANGE + CERTIFICATE_REQUEST */
2562 case STATE3:
2563 /* NOTE: these should not be send if we are resuming */
2564
2565 if (session->internals.resumed == RESUME_FALSE)
2566 ret = _gnutls_send_server_certificate (session, AGAIN (STATE3));
2567 STATE = STATE3;
2568 IMED_RET ("send server certificate", ret);
2569
2570 case STATE4:
2571 /* send server key exchange (A) */
2572 if (session->internals.resumed == RESUME_FALSE)
2573 ret = _gnutls_send_server_kx_message (session, AGAIN (STATE4));
2574 STATE = STATE4;
2575 IMED_RET ("send server kx", ret);
2576
2577 case STATE5:
2578 /* Send certificate request - if requested to */
2579 if (session->internals.resumed == RESUME_FALSE)
2580 ret =
2581 _gnutls_send_server_certificate_request (session, AGAIN (STATE5));
2582 STATE = STATE5;
2583 IMED_RET ("send server cert request", ret);
2584
2585 case STATE6:
2586 /* send the server hello done */
2587 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2588 ret =
2589 _gnutls_send_empty_handshake (session,
2590 GNUTLS_HANDSHAKE_SERVER_HELLO_DONE,
2591 AGAIN (STATE6));
2592 STATE = STATE6;
2593 IMED_RET ("send server hello done", ret);
2594
2595 case STATE71:
2596 if (session->security_parameters.extensions.do_recv_supplemental)
2597 {
2598 ret = _gnutls_recv_supplemental (session);
2599 STATE = STATE71;
2600 IMED_RET ("recv client supplemental", ret);
2601 }
2602
2603 /* RECV CERTIFICATE + KEYEXCHANGE + CERTIFICATE_VERIFY */
2604 case STATE7:
2605 /* receive the client certificate message */
2606 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2607 ret = _gnutls_recv_client_certificate (session);
2608 STATE = STATE7;
2609 IMED_RET ("recv client certificate", ret);
2610
2611 case STATE8:
2612 /* receive the client key exchange message */
2613 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2614 ret = _gnutls_recv_client_kx_message (session);
2615 STATE = STATE8;
2616 IMED_RET ("recv client kx", ret);
2617
2618 case STATE9:
2619 /* receive the client certificate verify message */
2620 if (session->internals.resumed == RESUME_FALSE) /* if we are not resuming */
2621 ret = _gnutls_recv_client_certificate_verify_message (session);
2622 STATE = STATE9;
2623 IMED_RET ("recv client certificate verify", ret);
2624
2625 STATE = STATE0; /* finished thus clear session */
2626 default:
2627 break;
2628 }
2629
2630 return 0;
2631}
2632
2633int
2634_gnutls_handshake_common (gnutls_session_t session)
2635{
2636 int ret = 0;
2637
2638 /* send and recv the change cipher spec and finished messages */
2639 if ((session->internals.resumed == RESUME_TRUE
2640 && session->security_parameters.entity == GNUTLS_CLIENT)
2641 || (session->internals.resumed == RESUME_FALSE
2642 && session->security_parameters.entity == GNUTLS_SERVER))
2643 {
2644 /* if we are a client resuming - or we are a server not resuming */
2645
2646 ret = _gnutls_recv_handshake_final (session, TRUE);
2647 IMED_RET ("recv handshake final", ret);
2648
2649 ret = _gnutls_send_handshake_final (session, FALSE);
2650 IMED_RET ("send handshake final", ret);
2651 }
2652 else
2653 { /* if we are a client not resuming - or we are a server resuming */
2654
2655 ret = _gnutls_send_handshake_final (session, TRUE);
2656 IMED_RET ("send handshake final 2", ret);
2657
2658 ret = _gnutls_recv_handshake_final (session, FALSE);
2659 IMED_RET ("recv handshake final 2", ret);
2660 }
2661
2662 if (session->security_parameters.entity == GNUTLS_SERVER)
2663 {
2664 /* in order to support session resuming */
2665 _gnutls_server_register_current_session (session);
2666 }
2667
2668 /* clear handshake buffer */
2669 _gnutls_handshake_hash_buffers_clear (session);
2670 return ret;
2671
2672}
2673
2674int
2675_gnutls_generate_session_id (opaque * session_id, uint8_t * len)
2676{
2677 *len = TLS_MAX_SESSION_ID_SIZE;
2678
2679 if (gc_nonce (session_id, *len) != GC_OK)
2680 {
2681 gnutls_assert ();
2682 return GNUTLS_E_RANDOM_FAILED;
2683 }
2684
2685 return 0;
2686}
2687
2688int
2689_gnutls_recv_hello_request (gnutls_session_t session, void *data,
2690 uint32_t data_size)
2691{
2692 uint8_t type;
2693
2694 if (session->security_parameters.entity == GNUTLS_SERVER)
2695 {
2696 gnutls_assert ();
2697 return GNUTLS_E_UNEXPECTED_PACKET;
2698 }
2699 if (data_size < 1)
2700 {
2701 gnutls_assert ();
2702 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
2703 }
2704 type = ((uint8_t *) data)[0];
2705 if (type == GNUTLS_HANDSHAKE_HELLO_REQUEST)
2706 return GNUTLS_E_REHANDSHAKE;
2707 else
2708 {
2709 gnutls_assert ();
2710 return GNUTLS_E_UNEXPECTED_PACKET;
2711 }
2712}
2713
2714/* Returns 1 if the given KX has not the corresponding parameters
2715 * (DH or RSA) set up. Otherwise returns 0.
2716 */
2717inline static int
2718check_server_params (gnutls_session_t session,
2719 gnutls_kx_algorithm_t kx,
2720 gnutls_kx_algorithm_t * alg, int alg_size)
2721{
2722 int cred_type;
2723 gnutls_dh_params_t dh_params = NULL;
2724 gnutls_rsa_params_t rsa_params = NULL;
2725 int j;
2726
2727 cred_type = _gnutls_map_kx_get_cred (kx, 1);
2728
2729 /* Read the Diffie Hellman parameters, if any.
2730 */
2731 if (cred_type == GNUTLS_CRD_CERTIFICATE)
2732 {
2733 int delete;
2734 gnutls_certificate_credentials_t x509_cred =
2735 (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key,
2736 cred_type, NULL);
2737
2738 if (x509_cred != NULL)
2739 {
2740 dh_params =
2741 _gnutls_get_dh_params (x509_cred->dh_params,
2742 x509_cred->params_func, session);
2743 rsa_params =
2744 _gnutls_certificate_get_rsa_params (x509_cred->rsa_params,
2745 x509_cred->params_func,
2746 session);
2747 }
2748
2749 /* Check also if the certificate supports the
2750 * KX method.
2751 */
2752 delete = 1;
2753 for (j = 0; j < alg_size; j++)
2754 {
2755 if (alg[j] == kx)
2756 {
2757 delete = 0;
2758 break;
2759 }
2760 }
2761
2762 if (delete == 1)
2763 return 1;
2764
2765#ifdef ENABLE_ANON
2766 }
2767 else if (cred_type == GNUTLS_CRD_ANON)
2768 {
2769 gnutls_anon_server_credentials_t anon_cred =
2770 (gnutls_anon_server_credentials_t) _gnutls_get_cred (session->key,
2771 cred_type, NULL);
2772
2773 if (anon_cred != NULL)
2774 {
2775 dh_params =
2776 _gnutls_get_dh_params (anon_cred->dh_params,
2777 anon_cred->params_func, session);
2778 }
2779#endif
2780#ifdef ENABLE_PSK
2781 }
2782 else if (cred_type == GNUTLS_CRD_PSK)
2783 {
2784 gnutls_psk_server_credentials_t psk_cred =
2785 (gnutls_psk_server_credentials_t) _gnutls_get_cred (session->key,
2786 cred_type, NULL);
2787
2788 if (psk_cred != NULL)
2789 {
2790 dh_params =
2791 _gnutls_get_dh_params (psk_cred->dh_params, psk_cred->params_func,
2792 session);
2793 }
2794#endif
2795 }
2796 else
2797 return 0; /* no need for params */
2798
2799
2800 /* If the key exchange method needs RSA or DH params,
2801 * but they are not set then remove it.
2802 */
2803 if (_gnutls_kx_needs_rsa_params (kx) != 0)
2804 {
2805 /* needs rsa params. */
2806 if (_gnutls_rsa_params_to_mpi (rsa_params) == NULL)
2807 {
2808 gnutls_assert ();
2809 return 1;
2810 }
2811 }
2812
2813 if (_gnutls_kx_needs_dh_params (kx) != 0)
2814 {
2815 /* needs DH params. */
2816 if (_gnutls_dh_params_to_mpi (dh_params) == NULL)
2817 {
2818 gnutls_assert ();
2819 return 1;
2820 }
2821 }
2822
2823 return 0;
2824}
2825
2826/* This function will remove algorithms that are not supported by
2827 * the requested authentication method. We remove an algorithm if
2828 * we have a certificate with keyUsage bits set.
2829 *
2830 * This does a more high level check than gnutls_supported_ciphersuites(),
2831 * by checking certificates etc.
2832 */
2833int
2834_gnutls_remove_unwanted_ciphersuites (gnutls_session_t session,
2835 cipher_suite_st ** cipherSuites,
2836 int numCipherSuites,
2837 gnutls_pk_algorithm_t requested_pk_algo)
2838{
2839
2840 int ret = 0;
2841 cipher_suite_st *newSuite, cs;
2842 int newSuiteSize = 0, i;
2843 gnutls_certificate_credentials_t cert_cred;
2844 gnutls_kx_algorithm_t kx;
2845 int server = session->security_parameters.entity == GNUTLS_SERVER ? 1 : 0;
2846 gnutls_kx_algorithm_t *alg = NULL;
2847 int alg_size = 0;
2848
2849 /* if we should use a specific certificate,
2850 * we should remove all algorithms that are not supported
2851 * by that certificate and are on the same authentication
2852 * method (CERTIFICATE).
2853 */
2854
2855 cert_cred =
2856 (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key,
2857 GNUTLS_CRD_CERTIFICATE,
2858 NULL);
2859
2860 /* If there are certificate credentials, find an appropriate certificate
2861 * or disable them;
2862 */
2863 if (session->security_parameters.entity == GNUTLS_SERVER
2864 && cert_cred != NULL)
2865 {
2866 ret = _gnutls_server_select_cert (session, requested_pk_algo);
2867 if (ret < 0)
2868 {
2869 gnutls_assert ();
2870 _gnutls_x509_log ("Could not find an appropriate certificate: %s\n",
2871 gnutls_strerror (ret));
2872 cert_cred = NULL;
2873 }
2874 }
2875
2876 /* get all the key exchange algorithms that are
2877 * supported by the X509 certificate parameters.
2878 */
2879 if ((ret =
2880 _gnutls_selected_cert_supported_kx (session, &alg, &alg_size)) < 0)
2881 {
2882 gnutls_assert ();
2883 return ret;
2884 }
2885
2886 newSuite = gnutls_malloc (numCipherSuites * sizeof (cipher_suite_st));
2887 if (newSuite == NULL)
2888 {
2889 gnutls_assert ();
2890 gnutls_free (alg);
2891 return GNUTLS_E_MEMORY_ERROR;
2892 }
2893
2894 /* now removes ciphersuites based on the KX algorithm
2895 */
2896 for (i = 0; i < numCipherSuites; i++)
2897 {
2898 int delete = 0;
2899
2900 /* finds the key exchange algorithm in
2901 * the ciphersuite
2902 */
2903 kx = _gnutls_cipher_suite_get_kx_algo (&(*cipherSuites)[i]);
2904
2905 /* if it is defined but had no credentials
2906 */
2907 if (_gnutls_get_kx_cred (session, kx, NULL) == NULL)
2908 {
2909 delete = 1;
2910 }
2911 else
2912 {
2913 delete = 0;
2914
2915 if (server)
2916 delete = check_server_params (session, kx, alg, alg_size);
2917 }
2918
2919 /* These two SRP kx's are marked to require a CRD_CERTIFICATE,
2920 (see cred_mappings in gnutls_algorithms.c), but it also
2921 requires a SRP credential. Don't use SRP kx unless we have a
2922 SRP credential too. */
2923 if (kx == GNUTLS_KX_SRP_RSA || kx == GNUTLS_KX_SRP_DSS)
2924 {
2925 if (!_gnutls_get_cred (session->key, GNUTLS_CRD_SRP, NULL))
2926 delete = 1;
2927 }
2928
2929 memcpy (&cs.suite, &(*cipherSuites)[i].suite, 2);
2930
2931 if (delete == 0)
2932 {
2933
2934 _gnutls_handshake_log ("HSK[%x]: Keeping ciphersuite: %s\n",
2935 session,
2936 _gnutls_cipher_suite_get_name (&cs));
2937
2938 memcpy (newSuite[newSuiteSize].suite, (*cipherSuites)[i].suite, 2);
2939 newSuiteSize++;
2940 }
2941 else
2942 {
2943 _gnutls_handshake_log ("HSK[%x]: Removing ciphersuite: %s\n",
2944 session,
2945 _gnutls_cipher_suite_get_name (&cs));
2946
2947 }
2948 }
2949
2950 gnutls_free (alg);
2951 gnutls_free (*cipherSuites);
2952 *cipherSuites = newSuite;
2953
2954 ret = newSuiteSize;
2955
2956 return ret;
2957
2958}
2959
2960/**
2961 * gnutls_handshake_set_max_packet_length - This function will set the maximum length of a handshake message
2962 * @session: is a #gnutls_session_t structure.
2963 * @max: is the maximum number.
2964 *
2965 * This function will set the maximum size of a handshake message.
2966 * Handshake messages over this size are rejected. The default value
2967 * is 16kb which is large enough. Set this to 0 if you do not want to
2968 * set an upper limit.
2969 *
2970 **/
2971void
2972gnutls_handshake_set_max_packet_length (gnutls_session_t session, size_t max)
2973{
2974 session->internals.max_handshake_data_buffer_size = max;
2975}
2976
2977void
2978_gnutls_set_adv_version (gnutls_session_t session, gnutls_protocol_t ver)
2979{
2980 set_adv_version (session, _gnutls_version_get_major (ver),
2981 _gnutls_version_get_minor (ver));
2982}
2983
2984gnutls_protocol_t
2985_gnutls_get_adv_version (gnutls_session_t session)
2986{
2987 return _gnutls_version_get (_gnutls_get_adv_version_major (session),
2988 _gnutls_get_adv_version_minor (session));
2989}
2990
2991/**
2992 * gnutls_handshake_get_last_in - Returns the last handshake message received.
2993 * @session: is a #gnutls_session_t structure.
2994 *
2995 * This function is only useful to check where the last performed
2996 * handshake failed. If the previous handshake succeed or was not
2997 * performed at all then no meaningful value will be returned.
2998 *
2999 * Check %gnutls_handshake_description_t in gnutls.h for the
3000 * available handshake descriptions.
3001 *
3002 * Returns: the last handshake message type received, a
3003 * %gnutls_handshake_description_t.
3004 **/
3005gnutls_handshake_description_t
3006gnutls_handshake_get_last_in (gnutls_session_t session)
3007{
3008 return session->internals.last_handshake_in;
3009}
3010
3011/**
3012 * gnutls_handshake_get_last_out - Returns the last handshake message sent.
3013 * @session: is a #gnutls_session_t structure.
3014 *
3015 * This function is only useful to check where the last performed
3016 * handshake failed. If the previous handshake succeed or was not
3017 * performed at all then no meaningful value will be returned.
3018 *
3019 * Check %gnutls_handshake_description_t in gnutls.h for the
3020 * available handshake descriptions.
3021 *
3022 * Returns: the last handshake message type sent, a
3023 * %gnutls_handshake_description_t.
3024 **/
3025gnutls_handshake_description_t
3026gnutls_handshake_get_last_out (gnutls_session_t session)
3027{
3028 return session->internals.last_handshake_out;
3029}
diff --git a/src/daemon/https/tls/gnutls_handshake.h b/src/daemon/https/tls/gnutls_handshake.h
new file mode 100644
index 00000000..5cff279a
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_handshake.h
@@ -0,0 +1,60 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25typedef enum Optional
26{ OPTIONAL_PACKET, MANDATORY_PACKET } Optional;
27
28int _gnutls_send_handshake (gnutls_session_t session, void *i_data,
29 uint32_t i_datasize,
30 gnutls_handshake_description_t type);
31int _gnutls_recv_hello_request (gnutls_session_t session, void *data,
32 uint32_t data_size);
33int _gnutls_send_hello (gnutls_session_t session, int again);
34int _gnutls_recv_hello (gnutls_session_t session, opaque * data, int datalen);
35int _gnutls_recv_handshake (gnutls_session_t session, uint8_t **, int *,
36 gnutls_handshake_description_t,
37 Optional optional);
38int _gnutls_generate_session_id (opaque * session_id, uint8_t * len);
39int _gnutls_handshake_common (gnutls_session_t session);
40int _gnutls_handshake_client (gnutls_session_t session);
41int _gnutls_handshake_server (gnutls_session_t session);
42void _gnutls_set_server_random (gnutls_session_t session, uint8_t * rnd);
43void _gnutls_set_client_random (gnutls_session_t session, uint8_t * rnd);
44int _gnutls_tls_create_random (opaque * dst);
45int _gnutls_remove_unwanted_ciphersuites (gnutls_session_t session,
46 cipher_suite_st ** cipherSuites,
47 int numCipherSuites,
48 gnutls_pk_algorithm_t);
49int _gnutls_find_pk_algos_in_ciphersuites (opaque * data, int datalen);
50int _gnutls_server_select_suite (gnutls_session_t session, opaque * data,
51 int datalen);
52
53int _gnutls_negotiate_version( gnutls_session_t session, gnutls_protocol_t adv_version);
54int _gnutls_user_hello_func( gnutls_session, gnutls_protocol_t adv_version);
55
56#define STATE session->internals.handshake_state
57/* This returns true if we have got there
58 * before (and not finished due to an interrupt).
59 */
60#define AGAIN(target) STATE==target?1:0
diff --git a/src/daemon/https/tls/gnutls_hash_int.c b/src/daemon/https/tls/gnutls_hash_int.c
new file mode 100644
index 00000000..2574f213
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_hash_int.c
@@ -0,0 +1,446 @@
1/*
2 * Copyright (C) 2000, 2001, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file handles all the internal functions that cope with hashes
26 * and HMACs.
27 */
28
29#include <gnutls_int.h>
30#include <gnutls_hash_int.h>
31#include <gnutls_errors.h>
32
33static inline Gc_hash
34_gnutls_mac2gc (gnutls_mac_algorithm_t mac)
35{
36 switch (mac)
37 {
38 case GNUTLS_MAC_NULL:
39 return -1;
40 break;
41 case GNUTLS_MAC_SHA1:
42 return GC_SHA1;
43 break;
44 case GNUTLS_MAC_SHA256:
45 return GC_SHA256;
46 break;
47 case GNUTLS_MAC_MD5:
48 return GC_MD5;
49 break;
50 default:
51 gnutls_assert ();
52 return -1;
53 }
54 return -1;
55}
56
57GNUTLS_HASH_HANDLE
58_gnutls_hash_init (gnutls_mac_algorithm_t algorithm)
59{
60 mac_hd_t ret;
61 int result;
62
63 ret = gnutls_malloc (sizeof (mac_hd_st));
64 if (ret == NULL)
65 {
66 gnutls_assert ();
67 return GNUTLS_HASH_FAILED;
68 }
69
70 ret->algorithm = algorithm;
71
72 result = gc_hash_open (_gnutls_mac2gc (algorithm), 0, &ret->handle);
73 if (result)
74 {
75 gnutls_assert ();
76 gnutls_free (ret);
77 ret = GNUTLS_HASH_FAILED;
78 }
79
80 return ret;
81}
82
83int
84_gnutls_hash_get_algo_len (gnutls_mac_algorithm_t algorithm)
85{
86 int ret;
87
88 ret = gc_hash_digest_length (_gnutls_mac2gc (algorithm));
89
90 return ret;
91
92}
93
94int
95_gnutls_hash (GNUTLS_HASH_HANDLE handle, const void *text, size_t textlen)
96{
97 if (textlen > 0)
98 gc_hash_write (handle->handle, textlen, text);
99 return 0;
100}
101
102GNUTLS_HASH_HANDLE
103_gnutls_hash_copy (GNUTLS_HASH_HANDLE handle)
104{
105 GNUTLS_HASH_HANDLE ret;
106 int result;
107
108 ret = gnutls_malloc (sizeof (mac_hd_st));
109
110 if (ret == NULL)
111 return GNUTLS_HASH_FAILED;
112
113 ret->algorithm = handle->algorithm;
114 ret->key = NULL; /* it's a hash anyway */
115 ret->keysize = 0;
116
117 result = gc_hash_clone (handle->handle, &ret->handle);
118
119 if (result)
120 {
121 gnutls_free (ret);
122 return GNUTLS_HASH_FAILED;
123 }
124
125 return ret;
126}
127
128void
129_gnutls_hash_deinit (GNUTLS_HASH_HANDLE handle, void *digest)
130{
131 const opaque *mac;
132 int maclen;
133
134 maclen = _gnutls_hash_get_algo_len (handle->algorithm);
135
136 mac = gc_hash_read (handle->handle);
137 if (digest != NULL)
138 memcpy (digest, mac, maclen);
139
140 gc_hash_close (handle->handle);
141
142 gnutls_free (handle);
143}
144
145
146mac_hd_t
147_gnutls_hmac_init (gnutls_mac_algorithm_t algorithm,
148 const void *key, int keylen)
149{
150 mac_hd_t ret;
151 int result;
152
153 ret = gnutls_malloc (sizeof (mac_hd_st));
154 if (ret == NULL)
155 return GNUTLS_MAC_FAILED;
156
157 result = gc_hash_open (_gnutls_mac2gc (algorithm), GC_HMAC, &ret->handle);
158 if (result)
159 {
160 gnutls_free (ret);
161 return GNUTLS_MAC_FAILED;
162 }
163
164 gc_hash_hmac_setkey (ret->handle, keylen, key);
165
166 ret->algorithm = algorithm;
167 ret->key = key;
168 ret->keysize = keylen;
169
170 return ret;
171}
172
173void
174_gnutls_hmac_deinit (mac_hd_t handle, void *digest)
175{
176 const opaque *mac;
177 int maclen;
178
179 maclen = _gnutls_hash_get_algo_len (handle->algorithm);
180
181 mac = gc_hash_read (handle->handle);
182
183 if (digest != NULL)
184 memcpy (digest, mac, maclen);
185
186 gc_hash_close (handle->handle);
187
188 gnutls_free (handle);
189}
190
191inline static int
192get_padsize (gnutls_mac_algorithm_t algorithm)
193{
194 switch (algorithm)
195 {
196 case GNUTLS_MAC_MD5:
197 return 48;
198 case GNUTLS_MAC_SHA1:
199 return 40;
200 default:
201 return 0;
202 }
203}
204
205mac_hd_t
206_gnutls_mac_init_ssl3 (gnutls_mac_algorithm_t algorithm, void *key,
207 int keylen)
208{
209 mac_hd_t ret;
210 opaque ipad[48];
211 int padsize;
212
213 padsize = get_padsize (algorithm);
214 if (padsize == 0)
215 {
216 gnutls_assert ();
217 return GNUTLS_MAC_FAILED;
218 }
219
220 memset (ipad, 0x36, padsize);
221
222 ret = _gnutls_hash_init (algorithm);
223 if (ret != GNUTLS_HASH_FAILED)
224 {
225 ret->key = key;
226 ret->keysize = keylen;
227
228 if (keylen > 0)
229 _gnutls_hash (ret, key, keylen);
230 _gnutls_hash (ret, ipad, padsize);
231 }
232
233 return ret;
234}
235
236void
237_gnutls_mac_deinit_ssl3 (mac_hd_t handle, void *digest)
238{
239 opaque ret[MAX_HASH_SIZE];
240 mac_hd_t td;
241 opaque opad[48];
242 int padsize;
243 int block;
244
245 padsize = get_padsize (handle->algorithm);
246 if (padsize == 0)
247 {
248 gnutls_assert ();
249 return;
250 }
251
252 memset (opad, 0x5C, padsize);
253
254 td = _gnutls_hash_init (handle->algorithm);
255 if (td != GNUTLS_MAC_FAILED)
256 {
257 if (handle->keysize > 0)
258 _gnutls_hash (td, handle->key, handle->keysize);
259
260 _gnutls_hash (td, opad, padsize);
261 block = _gnutls_hmac_get_algo_len (handle->algorithm);
262 _gnutls_hash_deinit (handle, ret); /* get the previous hash */
263 _gnutls_hash (td, ret, block);
264
265 _gnutls_hash_deinit (td, digest);
266 }
267}
268
269void
270_gnutls_mac_deinit_ssl3_handshake (mac_hd_t handle,
271 void *digest, opaque * key,
272 uint32_t key_size)
273{
274 opaque ret[MAX_HASH_SIZE];
275 mac_hd_t td;
276 opaque opad[48];
277 opaque ipad[48];
278 int padsize;
279 int block;
280
281 padsize = get_padsize (handle->algorithm);
282 if (padsize == 0)
283 {
284 gnutls_assert ();
285 return;
286 }
287
288 memset (opad, 0x5C, padsize);
289 memset (ipad, 0x36, padsize);
290
291 td = _gnutls_hash_init (handle->algorithm);
292 if (td != GNUTLS_HASH_FAILED)
293 {
294 if (key_size > 0)
295 _gnutls_hash (td, key, key_size);
296
297 _gnutls_hash (td, opad, padsize);
298 block = _gnutls_hmac_get_algo_len (handle->algorithm);
299
300 if (key_size > 0)
301 _gnutls_hash (handle, key, key_size);
302 _gnutls_hash (handle, ipad, padsize);
303 _gnutls_hash_deinit (handle, ret); /* get the previous hash */
304
305 _gnutls_hash (td, ret, block);
306
307 _gnutls_hash_deinit (td, digest);
308 }
309}
310
311static int
312ssl3_sha (int i, opaque * secret, int secret_len,
313 opaque * rnd, int rnd_len, void *digest)
314{
315 int j;
316 opaque text1[26];
317
318 GNUTLS_HASH_HANDLE td;
319
320 for (j = 0; j < i + 1; j++)
321 {
322 text1[j] = 65 + i; /* A==65 */
323 }
324
325 td = _gnutls_hash_init (GNUTLS_MAC_SHA1);
326 if (td == NULL)
327 {
328 gnutls_assert ();
329 return GNUTLS_E_HASH_FAILED;
330 }
331
332 _gnutls_hash (td, text1, i + 1);
333 _gnutls_hash (td, secret, secret_len);
334 _gnutls_hash (td, rnd, rnd_len);
335
336 _gnutls_hash_deinit (td, digest);
337 return 0;
338}
339
340static int
341ssl3_md5 (int i, opaque * secret, int secret_len,
342 opaque * rnd, int rnd_len, void *digest)
343{
344 opaque tmp[MAX_HASH_SIZE];
345 mac_hd_t td;
346 int ret;
347
348 td = _gnutls_hash_init (GNUTLS_MAC_MD5);
349 if (td == NULL)
350 {
351 gnutls_assert ();
352 return GNUTLS_E_HASH_FAILED;
353 }
354
355 _gnutls_hash (td, secret, secret_len);
356
357 ret = ssl3_sha (i, secret, secret_len, rnd, rnd_len, tmp);
358 if (ret < 0)
359 {
360 gnutls_assert ();
361 _gnutls_hash_deinit (td, digest);
362 return ret;
363 }
364
365 _gnutls_hash (td, tmp, _gnutls_hash_get_algo_len (GNUTLS_MAC_SHA1));
366
367 _gnutls_hash_deinit (td, digest);
368 return 0;
369}
370
371int
372_gnutls_ssl3_hash_md5 (void *first, int first_len,
373 void *second, int second_len, int ret_len,
374 opaque * ret)
375{
376 opaque digest[MAX_HASH_SIZE];
377 mac_hd_t td;
378 int block = _gnutls_hash_get_algo_len (GNUTLS_MAC_MD5);
379
380 td = _gnutls_hash_init (GNUTLS_MAC_MD5);
381 if (td == NULL)
382 {
383 gnutls_assert ();
384 return GNUTLS_E_HASH_FAILED;
385 }
386
387 _gnutls_hash (td, first, first_len);
388 _gnutls_hash (td, second, second_len);
389
390 _gnutls_hash_deinit (td, digest);
391
392 if (ret_len > block)
393 {
394 gnutls_assert ();
395 return GNUTLS_E_INTERNAL_ERROR;
396 }
397
398 memcpy (ret, digest, ret_len);
399
400 return 0;
401
402}
403
404int
405_gnutls_ssl3_generate_random (void *secret, int secret_len,
406 void *rnd, int rnd_len,
407 int ret_bytes, opaque * ret)
408{
409 int i = 0, copy, output_bytes;
410 opaque digest[MAX_HASH_SIZE];
411 int block = _gnutls_hash_get_algo_len (GNUTLS_MAC_MD5);
412 int result, times;
413
414 output_bytes = 0;
415 do
416 {
417 output_bytes += block;
418 }
419 while (output_bytes < ret_bytes);
420
421 times = output_bytes / block;
422
423 for (i = 0; i < times; i++)
424 {
425
426 result = ssl3_md5 (i, secret, secret_len, rnd, rnd_len, digest);
427 if (result < 0)
428 {
429 gnutls_assert ();
430 return result;
431 }
432
433 if ((1 + i) * block < ret_bytes)
434 {
435 copy = block;
436 }
437 else
438 {
439 copy = ret_bytes - (i) * block;
440 }
441
442 memcpy (&ret[i * block], digest, copy);
443 }
444
445 return 0;
446}
diff --git a/src/daemon/https/tls/gnutls_hash_int.h b/src/daemon/https/tls/gnutls_hash_int.h
new file mode 100644
index 00000000..3e1b75e6
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_hash_int.h
@@ -0,0 +1,72 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#ifndef GNUTLS_HASH_INT_H
26# define GNUTLS_HASH_INT_H
27
28#include <gnutls_int.h>
29
30/* for message digests */
31
32typedef struct
33{
34 gc_hash_handle handle;
35 gnutls_mac_algorithm_t algorithm;
36 const void *key;
37 int keysize;
38} mac_hd_st;
39typedef mac_hd_st *mac_hd_t;
40typedef mac_hd_t GNUTLS_HASH_HANDLE;
41
42#define GNUTLS_HASH_FAILED NULL
43#define GNUTLS_MAC_FAILED NULL
44
45mac_hd_t _gnutls_hmac_init (gnutls_mac_algorithm_t algorithm,
46 const void *key, int keylen);
47#define _gnutls_hmac_get_algo_len _gnutls_hash_get_algo_len
48#define _gnutls_hmac _gnutls_hash
49void _gnutls_hmac_deinit (mac_hd_t handle, void *digest);
50
51mac_hd_t _gnutls_mac_init_ssl3 (gnutls_mac_algorithm_t algorithm, void *key,
52 int keylen);
53void _gnutls_mac_deinit_ssl3 (mac_hd_t handle, void *digest);
54
55GNUTLS_HASH_HANDLE _gnutls_hash_init (gnutls_mac_algorithm_t algorithm);
56int _gnutls_hash_get_algo_len (gnutls_mac_algorithm_t algorithm);
57int _gnutls_hash (GNUTLS_HASH_HANDLE handle, const void *text,
58 size_t textlen);
59void _gnutls_hash_deinit (GNUTLS_HASH_HANDLE handle, void *digest);
60
61int _gnutls_ssl3_generate_random (void *secret, int secret_len,
62 void *rnd, int random_len, int bytes,
63 opaque * ret);
64int _gnutls_ssl3_hash_md5 (void *first, int first_len, void *second,
65 int second_len, int ret_len, opaque * ret);
66
67void _gnutls_mac_deinit_ssl3_handshake (mac_hd_t handle, void *digest,
68 opaque * key, uint32_t key_size);
69
70GNUTLS_HASH_HANDLE _gnutls_hash_copy (GNUTLS_HASH_HANDLE handle);
71
72#endif /* GNUTLS_HASH_INT_H */
diff --git a/src/daemon/https/tls/gnutls_int.h b/src/daemon/https/tls/gnutls_int.h
new file mode 100644
index 00000000..9c54262e
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_int.h
@@ -0,0 +1,679 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#ifndef GNUTLS_INT_H
26
27#define GNUTLS_INT_H
28
29#include <defines.h>
30
31#include <gnutls.h>
32#include <extra.h>
33#include <gnutls_mem.h>
34
35/* FIXME: delete this once opencdk has reentrant keyring functions
36 */
37#define KEYRING_HACK
38
39#define MAX32 4294967295
40#define MAX24 16777215
41#define MAX16 65535
42
43/* The size of a handshake message should not
44 * be larger than this value.
45 */
46#define MAX_HANDSHAKE_PACKET_SIZE 48*1024
47
48#define TLS_RANDOM_SIZE 32
49#define TLS_MAX_SESSION_ID_SIZE 32
50#define TLS_MASTER_SIZE 48
51
52/* The maximum digest size of hash algorithms.
53 */
54#define MAX_HASH_SIZE 64
55
56#define MAX_LOG_SIZE 1024 /* maximum size of log message */
57#define MAX_SRP_USERNAME 128
58#define MAX_SERVER_NAME_SIZE 128
59
60/* we can receive up to MAX_EXT_TYPES extensions.
61 */
62#define MAX_EXT_TYPES 64
63
64/* The initial size of the receive
65 * buffer size. This will grow if larger
66 * packets are received.
67 */
68#define INITIAL_RECV_BUFFER_SIZE 256
69
70/* the default for TCP */
71#define DEFAULT_LOWAT 1
72
73/* expire time for resuming sessions */
74#define DEFAULT_EXPIRE_TIME 3600
75
76/* the maximum size of encrypted packets */
77#define DEFAULT_MAX_RECORD_SIZE 16384
78#define RECORD_HEADER_SIZE 5
79#define MAX_RECORD_SEND_SIZE (size_t)session->security_parameters.max_record_send_size
80#define MAX_RECORD_RECV_SIZE (size_t)session->security_parameters.max_record_recv_size
81#define MAX_PAD_SIZE 255
82#define EXTRA_COMP_SIZE 2048
83#define MAX_RECORD_OVERHEAD MAX_PAD_SIZE+EXTRA_COMP_SIZE
84#define MAX_RECV_SIZE MAX_RECORD_OVERHEAD+MAX_RECORD_RECV_SIZE+RECORD_HEADER_SIZE
85
86#define HANDSHAKE_HEADER_SIZE 4
87
88/* defaults for verification functions
89 */
90#define DEFAULT_VERIFY_DEPTH 32
91#define DEFAULT_VERIFY_BITS 16*1024
92
93#define DECR_LEN(len, x) do { len-=x; if (len<0) {gnutls_assert(); return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;} } while (0)
94#define DECR_LENGTH_RET(len, x, RET) do { len-=x; if (len<0) {gnutls_assert(); return RET;} } while (0)
95#define DECR_LENGTH_COM(len, x, COM) do { len-=x; if (len<0) {gnutls_assert(); COM;} } while (0)
96
97#define HASH2MAC(x) ((gnutls_mac_algorithm_t)x)
98
99// TODO rm
100/* Additional cast to bring void* to a type castable to int. */
101#define GNUTLS_POINTER_TO_INT_CAST (long)
102
103#define GNUTLS_POINTER_TO_INT(_) ((int) GNUTLS_POINTER_TO_INT_CAST (_))
104#define GNUTLS_INT_TO_POINTER(_) ((void*) GNUTLS_POINTER_TO_INT_CAST (_))
105
106typedef unsigned char opaque;
107typedef struct
108 {
109 opaque pint[3];
110 } uint24;
111
112#include <gnutls_mpi.h>
113
114typedef enum change_cipher_spec_t
115 {
116 GNUTLS_TYPE_CHANGE_CIPHER_SPEC = 1
117 } change_cipher_spec_t;
118
119typedef enum handshake_state_t
120 {
121 STATE0 = 0, STATE1, STATE2,
122 STATE3, STATE4, STATE5,
123 STATE6, STATE7, STATE8, STATE9, STATE20 = 20, STATE21,
124 STATE30 = 30, STATE31, STATE50 = 50, STATE60 = 60, STATE61, STATE62,
125 STATE70, STATE71
126 } handshake_state_t;
127
128#include <gnutls_buffer.h>
129
130/* This is the maximum number of algorithms (ciphers or macs etc).
131 * keep it synced with GNUTLS_MAX_ALGORITHM_NUM in gnutls.h
132 */
133#define MAX_ALGOS 16
134
135#define MAX_CIPHERSUITES 256
136
137typedef enum extensions_t
138 { GNUTLS_EXTENSION_SERVER_NAME = 0,
139 GNUTLS_EXTENSION_MAX_RECORD_SIZE = 1,
140 GNUTLS_EXTENSION_CERT_TYPE = 9,
141#ifdef ENABLE_OPRFI
142 GNUTLS_EXTENSION_OPAQUE_PRF_INPUT = ENABLE_OPRFI,
143#endif
144 GNUTLS_EXTENSION_SRP = 12,
145 GNUTLS_EXTENSION_INNER_APPLICATION = 37703
146 } extensions_t;
147
148typedef enum
149 { CIPHER_STREAM, CIPHER_BLOCK} cipher_type_t;
150
151typedef enum valid_session_t
152 { VALID_TRUE, VALID_FALSE} valid_session_t;
153typedef enum resumable_session_t
154 { RESUME_TRUE,
155 RESUME_FALSE
156 } resumable_session_t;
157
158/* Record Protocol */
159typedef enum content_type_t
160 {
161 GNUTLS_CHANGE_CIPHER_SPEC = 20, GNUTLS_ALERT,
162 GNUTLS_HANDSHAKE, GNUTLS_APPLICATION_DATA,
163 GNUTLS_INNER_APPLICATION = 24
164 } content_type_t;
165
166#define GNUTLS_PK_ANY (gnutls_pk_algorithm_t)-1
167#define GNUTLS_PK_NONE (gnutls_pk_algorithm_t)-2
168
169/* STATE (stop) */
170
171typedef void (*LOG_FUNC)(int,
172 const char *);
173
174/* Store & Retrieve functions defines: */
175typedef struct auth_cred_st
176 {
177 gnutls_credentials_type_t algorithm;
178
179 /* the type of credentials depends on algorithm
180 */
181 void *credentials;
182 struct auth_cred_st *next;
183 } auth_cred_st;
184
185struct gnutls_key_st
186 {
187 /* For DH KX */
188 gnutls_datum_t key;
189 mpi_t KEY;
190 mpi_t client_Y;
191 mpi_t client_g;
192 mpi_t client_p;
193 mpi_t dh_secret;
194 /* for SRP */
195 mpi_t A;
196 mpi_t B;
197 mpi_t u;
198 mpi_t b;
199 mpi_t a;
200 mpi_t x;
201 /* RSA: e, m
202 */
203 mpi_t rsa[2];
204
205 /* this is used to hold the peers authentication data
206 */
207 /* auth_info_t structures SHOULD NOT contain malloced
208 * elements. Check gnutls_session_pack.c, and gnutls_auth.c.
209 * Rememember that this should be calloced!
210 */
211 void *auth_info;
212 gnutls_credentials_type_t auth_info_type;
213 int auth_info_size; /* needed in order to store to db for restoring
214 */
215 uint8_t crypt_algo;
216
217 auth_cred_st *cred; /* used to specify keys/certificates etc */
218
219 int certificate_requested;
220 /* some ciphersuites use this
221 * to provide client authentication.
222 * 1 if client auth was requested
223 * by the peer, 0 otherwise
224 *** In case of a server this
225 * holds 1 if we should wait
226 * for a client certificate verify
227 */
228 };
229typedef struct gnutls_key_st *gnutls_key_st;
230
231/* STATE (cont) */
232#include <gnutls_hash_int.h>
233#include <gnutls_cipher_int.h>
234#include <gnutls_compress_int.h>
235#include <gnutls_cert.h>
236
237typedef struct
238 {
239 uint8_t suite[2];
240 } cipher_suite_st;
241
242/* This structure holds parameters got from TLS extension
243 * mechanism. (some extensions may hold parameters in auth_info_t
244 * structures also - see SRP).
245 */
246typedef struct
247 {
248 opaque name[MAX_SERVER_NAME_SIZE];
249 unsigned name_length;
250 gnutls_server_name_type_t type;
251 } server_name_st;
252
253#define MAX_SERVER_NAME_EXTENSIONS 3
254typedef struct
255 {
256 server_name_st server_names[MAX_SERVER_NAME_EXTENSIONS];
257 /* limit server_name extensions */
258 unsigned server_names_size;
259
260 opaque srp_username[MAX_SRP_USERNAME + 1];
261
262 /* TLS/IA data. */
263 int gnutls_ia_enable, gnutls_ia_peer_enable;
264 int gnutls_ia_allowskip, gnutls_ia_peer_allowskip;
265
266 /* Used by extensions that enable supplemental data. */
267 int do_recv_supplemental, do_send_supplemental;
268
269 /* Opaque PRF input. */
270 gnutls_oprfi_callback_func oprfi_cb;
271 void *oprfi_userdata;
272 opaque *oprfi_client;
273 uint16_t oprfi_client_len;
274 opaque *oprfi_server;
275 uint16_t oprfi_server_len;
276 } tls_ext_st;
277
278/* This flag indicates for an extension whether
279 * it is useful to application level or TLS level only.
280 * This is used to parse the application level extensions
281 * before the user_hello callback is called.
282 */
283typedef enum tls_ext_parse_type_t
284 {
285 EXTENSION_ANY,
286 EXTENSION_APPLICATION,
287 EXTENSION_TLS
288 } tls_ext_parse_type_t;
289
290/* auth_info_t structures now MAY contain malloced
291 * elements.
292 */
293
294/* This structure and auth_info_t, are stored in the resume database,
295 * and are restored, in case of resume.
296 * Holds all the required parameters to resume the current
297 * session.
298 */
299
300/* if you add anything in Security_Parameters struct, then
301 * also modify CPY_COMMON in gnutls_constate.c
302 */
303
304/* Note that the security parameters structure is set up after the
305 * handshake has finished. The only value you may depend on while
306 * the handshake is in progress is the cipher suite value.
307 */
308typedef struct
309 {
310 gnutls_connection_end_t entity;
311 gnutls_kx_algorithm_t kx_algorithm;
312 /* we've got separate write/read bulk/macs because
313 * there is a time in handshake where the peer has
314 * null cipher and we don't
315 */
316 gnutls_cipher_algorithm_t read_bulk_cipher_algorithm;
317 gnutls_mac_algorithm_t read_mac_algorithm;
318 gnutls_compression_method_t read_compression_algorithm;
319
320 gnutls_cipher_algorithm_t write_bulk_cipher_algorithm;
321 gnutls_mac_algorithm_t write_mac_algorithm;
322 gnutls_compression_method_t write_compression_algorithm;
323
324 /* this is the ciphersuite we are going to use
325 * moved here from internals in order to be restored
326 * on resume;
327 */
328 cipher_suite_st current_cipher_suite;
329 opaque master_secret[TLS_MASTER_SIZE];
330 opaque client_random[TLS_RANDOM_SIZE];
331 opaque server_random[TLS_RANDOM_SIZE];
332 opaque session_id[TLS_MAX_SESSION_ID_SIZE];
333 uint8_t session_id_size;
334 time_t timestamp;
335 tls_ext_st extensions;
336
337 /* The send size is the one requested by the programmer.
338 * The recv size is the one negotiated with the peer.
339 */
340 uint16_t max_record_send_size;
341 uint16_t max_record_recv_size;
342 /* holds the negotiated certificate type */
343 gnutls_certificate_type_t cert_type;
344 gnutls_protocol_t version; /* moved here */
345 /* For TLS/IA. XXX: Move to IA credential? */
346 opaque inner_secret[TLS_MASTER_SIZE];
347 } security_parameters_st;
348
349/* This structure holds the generated keys
350 */
351typedef struct
352 {
353 gnutls_datum_t server_write_mac_secret;
354 gnutls_datum_t client_write_mac_secret;
355 gnutls_datum_t server_write_IV;
356 gnutls_datum_t client_write_IV;
357 gnutls_datum_t server_write_key;
358 gnutls_datum_t client_write_key;
359 int generated_keys; /* zero if keys have not
360 * been generated. Non zero
361 * otherwise.
362 */
363 } cipher_specs_st;
364
365typedef struct
366 {
367 cipher_hd_t write_cipher_state;
368 cipher_hd_t read_cipher_state;
369 comp_hd_t read_compression_state;
370 comp_hd_t write_compression_state;
371 gnutls_datum_t read_mac_secret;
372 gnutls_datum_t write_mac_secret;
373 uint64 read_sequence_number;
374 uint64 write_sequence_number;
375 } conn_stat_st;
376
377typedef struct
378 {
379 unsigned int priority[MAX_ALGOS];
380 unsigned int algorithms;
381 } priority_st;
382
383/* For the external api */
384struct gnutls_priority_st
385 {
386 priority_st cipher;
387 priority_st mac;
388 priority_st kx;
389 priority_st compression;
390 priority_st protocol;
391 priority_st cert_type;
392
393 /* to disable record padding */
394 int no_padding;
395 };
396
397/* DH and RSA parameters types.
398 */
399typedef struct gnutls_dh_params_int
400 {
401 /* [0] is the prime, [1] is the generator.
402 */
403 mpi_t params[2];
404 } dh_params_st;
405
406typedef struct
407 {
408 gnutls_dh_params_t dh_params;
409 int free_dh_params;
410 gnutls_rsa_params_t rsa_params;
411 int free_rsa_params;
412 } internal_params_st;
413
414typedef struct
415 {
416 opaque header[HANDSHAKE_HEADER_SIZE];
417 /* this holds the number of bytes in the handshake_header[] */
418 size_t header_size;
419 /* this holds the length of the handshake packet */
420 size_t packet_length;
421 gnutls_handshake_description_t recv_type;
422 } handshake_header_buffer_st;
423
424typedef struct
425 {
426 gnutls_buffer application_data_buffer; /* holds data to be delivered to application layer */
427 gnutls_buffer handshake_hash_buffer; /* used to keep the last received handshake
428 * message */
429 mac_hd_t handshake_mac_handle_sha; /* hash of the handshake messages */
430 mac_hd_t handshake_mac_handle_md5; /* hash of the handshake messages */
431
432 gnutls_buffer handshake_data_buffer; /* this is a buffer that holds the current handshake message */
433 gnutls_buffer ia_data_buffer; /* holds inner application data (TLS/IA) */
434 resumable_session_t resumable; /* TRUE or FALSE - if we can resume that session */
435 handshake_state_t handshake_state; /* holds
436 * a number which indicates where
437 * the handshake procedure has been
438 * interrupted. If it is 0 then
439 * no interruption has happened.
440 */
441
442 valid_session_t valid_connection; /* true or FALSE - if this session is valid */
443
444 int may_not_read; /* if it's 0 then we can read/write, otherwise it's forbiden to read/write
445 */
446 int may_not_write;
447 int read_eof; /* non-zero if we have received a closure alert. */
448
449 int last_alert; /* last alert received */
450
451 /* The last handshake messages sent or received.
452 */
453 int last_handshake_in;
454 int last_handshake_out;
455
456 /* this is the compression method we are going to use */
457 gnutls_compression_method_t compression_method;
458
459 /* priorities */
460 struct gnutls_priority_st priorities;
461
462 /* resumed session */
463 resumable_session_t resumed; /* RESUME_TRUE or FALSE - if we are resuming a session */
464 security_parameters_st resumed_security_parameters;
465
466 /* sockets internals */
467 int lowat;
468
469 /* These buffers are used in the handshake
470 * protocol only. freed using _gnutls_handshake_io_buffer_clear();
471 */
472 gnutls_buffer handshake_send_buffer;
473 size_t handshake_send_buffer_prev_size;
474 content_type_t handshake_send_buffer_type;
475 gnutls_handshake_description_t handshake_send_buffer_htype;
476 content_type_t handshake_recv_buffer_type;
477 gnutls_handshake_description_t handshake_recv_buffer_htype;
478 gnutls_buffer handshake_recv_buffer;
479
480 /* this buffer holds a record packet -mostly used for
481 * non blocking IO.
482 */
483 gnutls_buffer record_recv_buffer;
484 gnutls_buffer record_send_buffer; /* holds cached data
485 * for the gnutls_io_write_buffered()
486 * function.
487 */
488 size_t record_send_buffer_prev_size; /* holds the
489 * data written in the previous runs.
490 */
491 size_t record_send_buffer_user_size; /* holds the
492 * size of the user specified data to
493 * send.
494 */
495
496 /* 0 if no peeked data was kept, 1 otherwise.
497 */
498 int have_peeked_data;
499
500 int expire_time; /* after expire_time seconds this session will expire */
501 struct mod_auth_st_int *auth_struct; /* used in handshake packets and KX algorithms */
502 int v2_hello; /* 0 if the client hello is v3+.
503 * non-zero if we got a v2 hello.
504 */
505 /* keeps the headers of the handshake packet
506 */
507 handshake_header_buffer_st handshake_header_buffer;
508
509 /* this is the highest version available
510 * to the peer. (advertized version).
511 * This is obtained by the Handshake Client Hello
512 * message. (some implementations read the Record version)
513 */
514 uint8_t adv_version_major;
515 uint8_t adv_version_minor;
516
517 /* if this is non zero a certificate request message
518 * will be sent to the client. - only if the ciphersuite
519 * supports it.
520 */
521 int send_cert_req;
522
523 /* bits to use for DHE and DHA
524 * use _gnutls_dh_get_prime_bits() and gnutls_dh_set_prime_bits()
525 * to access it.
526 */
527 uint16_t dh_prime_bits;
528
529 size_t max_handshake_data_buffer_size;
530
531 /* PUSH & PULL functions.
532 */
533 gnutls_pull_func _gnutls_pull_func;
534 gnutls_push_func _gnutls_push_func;
535 /* Holds the first argument of PUSH and PULL
536 * functions;
537 */
538 gnutls_transport_ptr_t transport_recv_ptr;
539 gnutls_transport_ptr_t transport_send_ptr;
540
541 /* STORE & RETRIEVE functions. Only used if other
542 * backend than gdbm is used.
543 */
544 gnutls_db_store_func db_store_func;
545 gnutls_db_retr_func db_retrieve_func;
546 gnutls_db_remove_func db_remove_func;
547 void *db_ptr;
548
549 /* post client hello callback (server side only)
550 */
551 gnutls_handshake_post_client_hello_func user_hello_func;
552
553 /* Holds the record size requested by the
554 * user.
555 */
556 uint16_t proposed_record_size;
557
558 /* holds the selected certificate and key.
559 * use _gnutls_selected_certs_deinit() and _gnutls_selected_certs_set()
560 * to change them.
561 */
562 gnutls_cert *selected_cert_list;
563 int selected_cert_list_length;
564 gnutls_privkey *selected_key;
565 int selected_need_free;
566
567 /* holds the extensions we sent to the peer
568 * (in case of a client)
569 */
570 uint16_t extensions_sent[MAX_EXT_TYPES];
571 uint16_t extensions_sent_size;
572
573 /* is 0 if we are to send the whole PGP key, or non zero
574 * if the fingerprint is to be sent.
575 */
576 int pgp_fingerprint;
577
578 /* This holds the default version that our first
579 * record packet will have. */
580 opaque default_record_version[2];
581
582 int cbc_protection_hack;
583
584 void *user_ptr;
585
586 int enable_private; /* non zero to
587 * enable cipher suites
588 * which have 0xFF status.
589 */
590
591 /* Holds 0 if the last called function was interrupted while
592 * receiving, and non zero otherwise.
593 */
594 int direction;
595
596 /* This callback will be used (if set) to receive an
597 * openpgp key. (if the peer sends a fingerprint)
598 */
599 gnutls_openpgp_recv_key_func openpgp_recv_key_func;
600
601 /* If non zero the server will not advertize the CA's he
602 * trusts (do not send an RDN sequence).
603 */
604 int ignore_rdn_sequence;
605
606 /* This is used to set an arbitary version in the RSA
607 * PMS secret. Can be used by clients to test whether the
608 * server checks that version. (** only used in gnutls-cli-debug)
609 */
610 opaque rsa_pms_version[2];
611
612 char *srp_username;
613 char *srp_password;
614
615 /* Here we cache the DH or RSA parameters got from the
616 * credentials structure, or from a callback. That is to
617 * minimize external calls.
618 */
619 internal_params_st params;
620
621 /* This buffer is used by the record recv functions,
622 * as a temporary store buffer.
623 */
624 gnutls_datum_t recv_buffer;
625
626 /* To avoid using global variables, and especially on Windows where
627 * the application may use a different errno variable than GnuTLS,
628 * it is possible to use gnutls_transport_set_errno to set a
629 * session-specific errno variable in the user-replaceable push/pull
630 * functions. This value is used by the send/recv functions. (The
631 * strange name of this variable is because 'errno' is typically
632 * #define'd.)
633 */
634 int errnum;
635
636 /* Function used to perform public-key signing operation during
637 handshake. Used by gnutls_sig.c:_gnutls_tls_sign(), see also
638 gnutls_sign_callback_set(). */
639 gnutls_sign_func sign_func;
640 void *sign_func_userdata;
641
642 /* If you add anything here, check _gnutls_handshake_internal_state_clear().
643 */
644 } internals_st;
645
646struct gnutls_session_int
647 {
648 security_parameters_st security_parameters;
649 cipher_specs_st cipher_specs;
650 conn_stat_st connection_state;
651 internals_st internals;
652 gnutls_key_st key;
653 };
654
655/* functions
656 */
657void _gnutls_set_current_version(gnutls_session_t session,
658 gnutls_protocol_t version);
659
660void _gnutls_free_auth_info(gnutls_session_t session);
661
662/* These two macros return the advertized TLS version of
663 * the peer.
664 */
665#define _gnutls_get_adv_version_major( session) \
666 session->internals.adv_version_major
667
668#define _gnutls_get_adv_version_minor( session) \
669 session->internals.adv_version_minor
670
671#define set_adv_version( session, major, minor) \
672 session->internals.adv_version_major = major; \
673 session->internals.adv_version_minor = minor
674
675void _gnutls_set_adv_version(gnutls_session_t,
676 gnutls_protocol_t);
677gnutls_protocol_t _gnutls_get_adv_version(gnutls_session_t);
678
679#endif /* GNUTLS_INT_H */
diff --git a/src/daemon/https/tls/gnutls_kx.c b/src/daemon/https/tls/gnutls_kx.c
new file mode 100644
index 00000000..5e7f0d4d
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_kx.c
@@ -0,0 +1,773 @@
1/*
2 * Copyright (C) 2000, 2001, 2004, 2005, 2006 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file contains functions which are wrappers for the key exchange
26 * part of TLS. They are called by the handshake functions (gnutls_handshake)
27 */
28
29#include "gnutls_int.h"
30#include "gnutls_handshake.h"
31#include "gnutls_kx.h"
32#include "gnutls_dh.h"
33#include "gnutls_errors.h"
34#include "gnutls_algorithms.h"
35#include "debug.h"
36#include "gnutls_mpi.h"
37#include <gnutls_state.h>
38#include <gnutls_datum.h>
39#include <gnutls_rsa_export.h>
40
41/* This file contains important thing for the TLS handshake procedure.
42 */
43
44#define MASTER_SECRET "master secret"
45static int generate_normal_master (gnutls_session_t session, int);
46
47int
48_gnutls_generate_master (gnutls_session_t session, int keep_premaster)
49{
50 if (session->internals.resumed == RESUME_FALSE)
51 return generate_normal_master (session, keep_premaster);
52 return 0;
53}
54
55/* here we generate the TLS Master secret.
56 */
57#define PREMASTER session->key->key
58static int
59generate_normal_master (gnutls_session_t session, int keep_premaster)
60{
61 int ret = 0;
62 char buf[512];
63
64 _gnutls_hard_log ("INT: PREMASTER SECRET[%d]: %s\n", PREMASTER.size,
65 _gnutls_bin2hex (PREMASTER.data, PREMASTER.size, buf,
66 sizeof (buf)));
67 _gnutls_hard_log ("INT: CLIENT RANDOM[%d]: %s\n", 32,
68 _gnutls_bin2hex (session->security_parameters.
69 client_random, 32, buf, sizeof (buf)));
70 _gnutls_hard_log ("INT: SERVER RANDOM[%d]: %s\n", 32,
71 _gnutls_bin2hex (session->security_parameters.
72 server_random, 32, buf, sizeof (buf)));
73
74 if (gnutls_protocol_get_version (session) == GNUTLS_SSL3)
75 {
76 opaque rnd[2 * TLS_RANDOM_SIZE + 1];
77
78 memcpy (rnd, session->security_parameters.client_random,
79 TLS_RANDOM_SIZE);
80 memcpy (&rnd[TLS_RANDOM_SIZE],
81 session->security_parameters.server_random, TLS_RANDOM_SIZE);
82
83 ret =
84 _gnutls_ssl3_generate_random (PREMASTER.data, PREMASTER.size,
85 rnd, 2 * TLS_RANDOM_SIZE,
86 TLS_MASTER_SIZE,
87 session->security_parameters.
88 master_secret);
89
90 }
91 else if (session->security_parameters.extensions.oprfi_client_len > 0 &&
92 session->security_parameters.extensions.oprfi_server_len > 0)
93 {
94 opaque *rnd;
95 size_t rndlen = 2 * TLS_RANDOM_SIZE;
96
97 rndlen += session->security_parameters.extensions.oprfi_client_len;
98 rndlen += session->security_parameters.extensions.oprfi_server_len;
99
100 rnd = gnutls_malloc (rndlen + 1);
101 if (!rnd)
102 {
103 gnutls_assert ();
104 return GNUTLS_E_MEMORY_ERROR;
105 }
106
107 _gnutls_hard_log ("INT: CLIENT OPRFI[%d]: %s\n",
108 session->security_parameters.
109 extensions.oprfi_server_len,
110 _gnutls_bin2hex (session->security_parameters.
111 extensions.oprfi_client,
112 session->security_parameters.
113 extensions.oprfi_client_len,
114 buf, sizeof (buf)));
115 _gnutls_hard_log ("INT: SERVER OPRFI[%d]: %s\n",
116 session->security_parameters.
117 extensions.oprfi_server_len,
118 _gnutls_bin2hex (session->security_parameters.
119 extensions.oprfi_server,
120 session->security_parameters.
121 extensions.oprfi_server_len,
122 buf, sizeof (buf)));
123
124 memcpy (rnd, session->security_parameters.client_random,
125 TLS_RANDOM_SIZE);
126 memcpy (rnd + TLS_RANDOM_SIZE,
127 session->security_parameters.extensions.oprfi_client,
128 session->security_parameters.extensions.oprfi_client_len);
129 memcpy (rnd + TLS_RANDOM_SIZE +
130 session->security_parameters.extensions.oprfi_client_len,
131 session->security_parameters.server_random, TLS_RANDOM_SIZE);
132 memcpy (rnd + TLS_RANDOM_SIZE +
133 session->security_parameters.extensions.oprfi_client_len +
134 TLS_RANDOM_SIZE,
135 session->security_parameters.extensions.oprfi_server,
136 session->security_parameters.extensions.oprfi_server_len);
137
138 ret = _gnutls_PRF (session, PREMASTER.data, PREMASTER.size,
139 MASTER_SECRET, strlen (MASTER_SECRET),
140 rnd, rndlen, TLS_MASTER_SIZE,
141 session->security_parameters.master_secret);
142
143 gnutls_free (rnd);
144 }
145 else
146 {
147 opaque rnd[2 * TLS_RANDOM_SIZE + 1];
148
149 memcpy (rnd, session->security_parameters.client_random,
150 TLS_RANDOM_SIZE);
151 memcpy (&rnd[TLS_RANDOM_SIZE],
152 session->security_parameters.server_random, TLS_RANDOM_SIZE);
153
154 ret =
155 _gnutls_PRF (session, PREMASTER.data, PREMASTER.size,
156 MASTER_SECRET, strlen (MASTER_SECRET),
157 rnd, 2 * TLS_RANDOM_SIZE, TLS_MASTER_SIZE,
158 session->security_parameters.master_secret);
159 }
160
161 /* TLS/IA inner secret is derived from the master secret. */
162 memcpy (session->security_parameters.inner_secret,
163 session->security_parameters.master_secret, TLS_MASTER_SIZE);
164
165 if (!keep_premaster)
166 _gnutls_free_datum (&PREMASTER);
167
168 if (ret < 0)
169 return ret;
170
171 _gnutls_hard_log ("INT: MASTER SECRET: %s\n",
172 _gnutls_bin2hex (session->security_parameters.
173 master_secret, TLS_MASTER_SIZE, buf,
174 sizeof (buf)));
175
176 return ret;
177}
178
179
180/* This is called when we want to receive the key exchange message of the
181 * server. It does nothing if this type of message is not required
182 * by the selected ciphersuite.
183 */
184int
185_gnutls_send_server_kx_message (gnutls_session_t session, int again)
186{
187 uint8_t *data = NULL;
188 int data_size = 0;
189 int ret = 0;
190
191 if (session->internals.auth_struct->gnutls_generate_server_kx == NULL)
192 return 0;
193
194 data = NULL;
195 data_size = 0;
196
197 if (again == 0)
198 {
199 data_size =
200 session->internals.auth_struct->
201 gnutls_generate_server_kx (session, &data);
202
203 if (data_size == GNUTLS_E_INT_RET_0)
204 {
205 gnutls_assert ();
206 return 0;
207 }
208
209 if (data_size < 0)
210 {
211 gnutls_assert ();
212 return data_size;
213 }
214 }
215
216 ret =
217 _gnutls_send_handshake (session, data, data_size,
218 GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE);
219 gnutls_free (data);
220
221 if (ret < 0)
222 {
223 gnutls_assert ();
224 return ret;
225 }
226 return data_size;
227}
228
229/* This function sends a certificate request message to the
230 * client.
231 */
232int
233_gnutls_send_server_certificate_request (gnutls_session_t session, int again)
234{
235 uint8_t *data = NULL;
236 int data_size = 0;
237 int ret = 0;
238
239 if (session->internals.auth_struct->
240 gnutls_generate_server_certificate_request == NULL)
241 return 0;
242
243 if (session->internals.send_cert_req <= 0)
244 return 0;
245
246 data = NULL;
247 data_size = 0;
248
249 if (again == 0)
250 {
251 data_size =
252 session->internals.auth_struct->
253 gnutls_generate_server_certificate_request (session, &data);
254
255 if (data_size < 0)
256 {
257 gnutls_assert ();
258 return data_size;
259 }
260 }
261 ret =
262 _gnutls_send_handshake (session, data, data_size,
263 GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST);
264 gnutls_free (data);
265
266 if (ret < 0)
267 {
268 gnutls_assert ();
269 return ret;
270 }
271 return data_size;
272}
273
274
275/* This is the function for the client to send the key
276 * exchange message
277 */
278int
279_gnutls_send_client_kx_message (gnutls_session_t session, int again)
280{
281 uint8_t *data;
282 int data_size;
283 int ret = 0;
284
285 if (session->internals.auth_struct->gnutls_generate_client_kx == NULL)
286 return 0;
287
288
289 data = NULL;
290 data_size = 0;
291
292 if (again == 0)
293 {
294 data_size =
295 session->internals.auth_struct->
296 gnutls_generate_client_kx (session, &data);
297 if (data_size < 0)
298 {
299 gnutls_assert ();
300 return data_size;
301 }
302 }
303 ret =
304 _gnutls_send_handshake (session, data, data_size,
305 GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE);
306 gnutls_free (data);
307
308 if (ret < 0)
309 {
310 gnutls_assert ();
311 return ret;
312 }
313
314 return ret;
315}
316
317
318/* This is the function for the client to send the certificate
319 * verify message
320 */
321int
322_gnutls_send_client_certificate_verify (gnutls_session_t session, int again)
323{
324 uint8_t *data;
325 int ret = 0;
326 int data_size;
327
328 /* This is a packet that is only sent by the client
329 */
330 if (session->security_parameters.entity == GNUTLS_SERVER)
331 return 0;
332
333 /* if certificate verify is not needed just exit
334 */
335 if (session->key->certificate_requested == 0)
336 return 0;
337
338 if (session->internals.auth_struct->gnutls_generate_client_cert_vrfy ==
339 NULL)
340 {
341 gnutls_assert ();
342 return 0; /* this algorithm does not support cli_cert_vrfy
343 */
344 }
345
346 data = NULL;
347 data_size = 0;
348
349 if (again == 0)
350 {
351 data_size =
352 session->internals.auth_struct->
353 gnutls_generate_client_cert_vrfy (session, &data);
354 if (data_size < 0)
355 {
356 gnutls_assert ();
357 return data_size;
358 }
359 if (data_size == 0)
360 return 0;
361
362 }
363 ret =
364 _gnutls_send_handshake (session, data,
365 data_size, GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY);
366 gnutls_free (data);
367
368 return ret;
369}
370
371
372int
373_gnutls_recv_server_kx_message (gnutls_session_t session)
374{
375 uint8_t *data = NULL;
376 int datasize;
377 int ret = 0;
378
379 if (session->internals.auth_struct->gnutls_process_server_kx != NULL)
380 {
381
382 /* EXCEPTION FOR RSA_EXPORT cipher suite
383 */
384 if (_gnutls_session_is_export (session) != 0 &&
385 _gnutls_peers_cert_less_512 (session) != 0)
386 {
387 gnutls_assert ();
388 return 0;
389 }
390
391 ret =
392 _gnutls_recv_handshake (session, &data,
393 &datasize,
394 GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE,
395 MANDATORY_PACKET);
396 if (ret < 0)
397 {
398 gnutls_assert ();
399 return ret;
400 }
401
402 ret =
403 session->internals.auth_struct->
404 gnutls_process_server_kx (session, data, datasize);
405 gnutls_free (data);
406
407 if (ret < 0)
408 {
409 gnutls_assert ();
410 return ret;
411 }
412
413 }
414 return ret;
415}
416
417int
418_gnutls_recv_server_certificate_request (gnutls_session_t session)
419{
420 uint8_t *data;
421 int datasize;
422 int ret = 0;
423
424 if (session->internals.auth_struct->
425 gnutls_process_server_certificate_request != NULL)
426 {
427
428 ret =
429 _gnutls_recv_handshake (session, &data,
430 &datasize,
431 GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST,
432 OPTIONAL_PACKET);
433 if (ret < 0)
434 return ret;
435
436 if (ret == 0 && datasize == 0)
437 return 0; /* ignored */
438
439 ret =
440 session->internals.auth_struct->
441 gnutls_process_server_certificate_request (session, data, datasize);
442 gnutls_free (data);
443 if (ret < 0)
444 return ret;
445
446 }
447 return ret;
448}
449
450int
451_gnutls_recv_client_kx_message (gnutls_session_t session)
452{
453 uint8_t *data;
454 int datasize;
455 int ret = 0;
456
457
458 /* Do key exchange only if the algorithm permits it */
459 if (session->internals.auth_struct->gnutls_process_client_kx != NULL)
460 {
461
462 ret =
463 _gnutls_recv_handshake (session, &data,
464 &datasize,
465 GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE,
466 MANDATORY_PACKET);
467 if (ret < 0)
468 return ret;
469
470 ret =
471 session->internals.auth_struct->
472 gnutls_process_client_kx (session, data, datasize);
473 gnutls_free (data);
474 if (ret < 0)
475 return ret;
476
477 }
478
479 return ret;
480}
481
482
483/* This is called when we want send our certificate
484 */
485int
486_gnutls_send_client_certificate (gnutls_session_t session, int again)
487{
488 uint8_t *data = NULL;
489 int data_size = 0;
490 int ret = 0;
491
492
493 if (session->key->certificate_requested == 0)
494 return 0;
495
496 if (session->internals.auth_struct->
497 gnutls_generate_client_certificate == NULL)
498 return 0;
499
500 data = NULL;
501 data_size = 0;
502
503 if (again == 0)
504 {
505 if (gnutls_protocol_get_version (session) != GNUTLS_SSL3 ||
506 session->internals.selected_cert_list_length > 0)
507 {
508 /* TLS 1.0 or SSL 3.0 with a valid certificate
509 */
510 data_size =
511 session->internals.auth_struct->
512 gnutls_generate_client_certificate (session, &data);
513
514 if (data_size < 0)
515 {
516 gnutls_assert ();
517 return data_size;
518 }
519 }
520 }
521
522 /* In the SSL 3.0 protocol we need to send a
523 * no certificate alert instead of an
524 * empty certificate.
525 */
526 if (gnutls_protocol_get_version (session) == GNUTLS_SSL3 &&
527 session->internals.selected_cert_list_length == 0)
528 {
529 ret =
530 gnutls_alert_send (session, GNUTLS_AL_WARNING,
531 GNUTLS_A_SSL3_NO_CERTIFICATE);
532
533 }
534 else
535 { /* TLS 1.0 or SSL 3.0 with a valid certificate
536 */
537 ret =
538 _gnutls_send_handshake (session, data, data_size,
539 GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
540 gnutls_free (data);
541 }
542
543 if (ret < 0)
544 {
545 gnutls_assert ();
546 return ret;
547 }
548
549 return data_size;
550}
551
552
553/* This is called when we want send our certificate
554 */
555int
556_gnutls_send_server_certificate (gnutls_session_t session, int again)
557{
558 uint8_t *data = NULL;
559 int data_size = 0;
560 int ret = 0;
561
562
563 if (session->internals.auth_struct->
564 gnutls_generate_server_certificate == NULL)
565 return 0;
566
567 data = NULL;
568 data_size = 0;
569
570 if (again == 0)
571 {
572 data_size =
573 session->internals.auth_struct->
574 gnutls_generate_server_certificate (session, &data);
575
576 if (data_size < 0)
577 {
578 gnutls_assert ();
579 return data_size;
580 }
581 }
582 ret =
583 _gnutls_send_handshake (session, data, data_size,
584 GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
585 gnutls_free (data);
586
587 if (ret < 0)
588 {
589 gnutls_assert ();
590 return ret;
591 }
592
593 return data_size;
594}
595
596
597int
598_gnutls_recv_client_certificate (gnutls_session_t session)
599{
600 int datasize;
601 opaque *data;
602 int ret = 0;
603 int optional;
604
605 if (session->internals.auth_struct->
606 gnutls_process_client_certificate != NULL)
607 {
608
609 /* if we have not requested a certificate then just return
610 */
611 if (session->internals.send_cert_req == 0)
612 {
613 return 0;
614 }
615
616 if (session->internals.send_cert_req == GNUTLS_CERT_REQUIRE)
617 optional = MANDATORY_PACKET;
618 else
619 optional = OPTIONAL_PACKET;
620
621 ret =
622 _gnutls_recv_handshake (session, &data,
623 &datasize,
624 GNUTLS_HANDSHAKE_CERTIFICATE_PKT, optional);
625
626 if (ret < 0)
627 {
628 /* Handle the case of old SSL3 clients who send
629 * a warning alert instead of an empty certificate to indicate
630 * no certificate.
631 */
632 if (optional == OPTIONAL_PACKET &&
633 ret == GNUTLS_E_WARNING_ALERT_RECEIVED &&
634 gnutls_protocol_get_version (session) == GNUTLS_SSL3 &&
635 gnutls_alert_get (session) == GNUTLS_A_SSL3_NO_CERTIFICATE)
636 {
637
638 /* SSL3 does not send an empty certificate,
639 * but this alert. So we just ignore it.
640 */
641 gnutls_assert ();
642 return 0;
643 }
644
645 /* certificate was required
646 */
647 if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED
648 || ret == GNUTLS_E_FATAL_ALERT_RECEIVED)
649 && optional == MANDATORY_PACKET)
650 {
651 gnutls_assert ();
652 return GNUTLS_E_NO_CERTIFICATE_FOUND;
653 }
654
655 return ret;
656 }
657
658 if (ret == 0 && datasize == 0 && optional == OPTIONAL_PACKET)
659 {
660 /* Client has not sent the certificate message.
661 * well I'm not sure we should accept this
662 * behaviour.
663 */
664 gnutls_assert ();
665 return 0;
666 }
667 ret =
668 session->internals.auth_struct->
669 gnutls_process_client_certificate (session, data, datasize);
670
671 gnutls_free (data);
672 if (ret < 0 && ret != GNUTLS_E_NO_CERTIFICATE_FOUND)
673 {
674 gnutls_assert ();
675 return ret;
676 }
677
678 /* ok we should expect a certificate verify message now
679 */
680 if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND && optional == OPTIONAL_PACKET)
681 ret = 0;
682 else
683 session->key->certificate_requested = 1;
684
685 }
686
687 return ret;
688}
689
690int
691_gnutls_recv_server_certificate (gnutls_session_t session)
692{
693 int datasize;
694 opaque *data;
695 int ret = 0;
696
697 if (session->internals.auth_struct->
698 gnutls_process_server_certificate != NULL)
699 {
700
701 ret =
702 _gnutls_recv_handshake (session, &data,
703 &datasize,
704 GNUTLS_HANDSHAKE_CERTIFICATE_PKT,
705 MANDATORY_PACKET);
706 if (ret < 0)
707 {
708 gnutls_assert ();
709 return ret;
710 }
711
712 ret =
713 session->internals.auth_struct->
714 gnutls_process_server_certificate (session, data, datasize);
715 gnutls_free (data);
716 if (ret < 0)
717 {
718 gnutls_assert ();
719 return ret;
720 }
721 }
722
723 return ret;
724}
725
726
727/* Recv the client certificate verify. This packet may not
728 * arrive if the peer did not send us a certificate.
729 */
730int
731_gnutls_recv_client_certificate_verify_message (gnutls_session_t session)
732{
733 uint8_t *data;
734 int datasize;
735 int ret = 0;
736
737
738 if (session->internals.auth_struct->gnutls_process_client_cert_vrfy != NULL)
739 {
740
741 if (session->internals.send_cert_req == 0 ||
742 session->key->certificate_requested == 0)
743 {
744 return 0;
745 }
746
747 ret =
748 _gnutls_recv_handshake (session, &data,
749 &datasize,
750 GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY,
751 OPTIONAL_PACKET);
752 if (ret < 0)
753 return ret;
754
755 if (ret == 0 && datasize == 0
756 && session->internals.send_cert_req == GNUTLS_CERT_REQUIRE)
757 {
758 /* certificate was required */
759 gnutls_assert ();
760 return GNUTLS_E_NO_CERTIFICATE_FOUND;
761 }
762
763 ret =
764 session->internals.auth_struct->
765 gnutls_process_client_cert_vrfy (session, data, datasize);
766 gnutls_free (data);
767 if (ret < 0)
768 return ret;
769
770 }
771
772 return ret;
773}
diff --git a/src/daemon/https/tls/gnutls_kx.h b/src/daemon/https/tls/gnutls_kx.h
new file mode 100644
index 00000000..45ba68bd
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_kx.h
@@ -0,0 +1,39 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25int _gnutls_send_server_kx_message (gnutls_session_t session, int again);
26int _gnutls_send_client_kx_message (gnutls_session_t session, int again);
27int _gnutls_recv_server_kx_message (gnutls_session_t session);
28int _gnutls_recv_client_kx_message (gnutls_session_t session);
29int _gnutls_send_client_certificate_verify (gnutls_session_t session,
30 int again);
31int _gnutls_send_server_certificate (gnutls_session_t session, int again);
32int _gnutls_generate_master (gnutls_session_t session, int keep_premaster);
33int _gnutls_recv_client_certificate (gnutls_session_t session);
34int _gnutls_recv_server_certificate (gnutls_session_t session);
35int _gnutls_send_client_certificate (gnutls_session_t session, int again);
36int _gnutls_recv_server_certificate_request (gnutls_session_t session);
37int _gnutls_send_server_certificate_request (gnutls_session_t session,
38 int again);
39int _gnutls_recv_client_certificate_verify_message (gnutls_session_t session);
diff --git a/src/daemon/https/tls/gnutls_mem.c b/src/daemon/https/tls/gnutls_mem.c
new file mode 100644
index 00000000..91a6fa3c
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_mem.c
@@ -0,0 +1,134 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_errors.h>
27#include <gnutls_num.h>
28
29gnutls_alloc_function gnutls_secure_malloc = malloc;
30gnutls_alloc_function gnutls_malloc = malloc;
31gnutls_free_function gnutls_free = free;
32gnutls_realloc_function gnutls_realloc = realloc;
33
34void *(*gnutls_calloc) (size_t, size_t) = calloc;
35char *(*gnutls_strdup) (const char *) = _gnutls_strdup;
36
37int
38_gnutls_is_secure_mem_null (const void *ign)
39{
40 return 0;
41}
42
43int (*_gnutls_is_secure_memory) (const void *) = _gnutls_is_secure_mem_null;
44
45
46void *
47_gnutls_calloc (size_t nmemb, size_t size)
48{
49 void *ret;
50 size *= nmemb;
51 ret = gnutls_malloc (size);
52 if (ret != NULL)
53 memset (ret, 0, size);
54 return ret;
55}
56
57svoid *
58gnutls_secure_calloc (size_t nmemb, size_t size)
59{
60 svoid *ret;
61 size *= nmemb;
62 ret = gnutls_secure_malloc (size);
63 if (ret != NULL)
64 memset (ret, 0, size);
65 return ret;
66}
67
68/* This realloc will free ptr in case realloc
69 * fails.
70 */
71void *
72gnutls_realloc_fast (void *ptr, size_t size)
73{
74 void *ret;
75
76 if (size == 0)
77 return ptr;
78
79 ret = gnutls_realloc (ptr, size);
80 if (ret == NULL)
81 {
82 gnutls_free (ptr);
83 }
84
85 return ret;
86}
87
88char *
89_gnutls_strdup (const char *str)
90{
91 size_t siz = strlen (str) + 1;
92 char *ret;
93
94 ret = gnutls_malloc (siz);
95 if (ret != NULL)
96 memcpy (ret, str, siz);
97 return ret;
98}
99
100
101#if 0
102/* don't use them. They are included for documentation.
103 */
104
105/**
106 * gnutls_malloc - Allocates and returns data
107 *
108 * This function will allocate 's' bytes data, and
109 * return a pointer to memory. This function is supposed
110 * to be used by callbacks.
111 *
112 * The allocation function used is the one set by gnutls_global_set_mem_functions().
113 *
114 **/
115void *
116gnutls_malloc (size_t s)
117{
118}
119
120/**
121 * gnutls_free - Returns a free() like function
122 * @d: pointer to memory
123 *
124 * This function will free data pointed by ptr.
125 *
126 * The deallocation function used is the one set by gnutls_global_set_mem_functions().
127 *
128 **/
129void
130gnutls_free (void *ptr)
131{
132}
133
134#endif
diff --git a/src/daemon/https/tls/gnutls_mem.h b/src/daemon/https/tls/gnutls_mem.h
new file mode 100644
index 00000000..f76081e5
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_mem.h
@@ -0,0 +1,70 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#ifndef GNUTLS_MEM_H
26# define GNUTLS_MEM_H
27
28#ifdef USE_DMALLOC
29# include <dmalloc.h>
30#endif
31
32typedef void svoid; /* for functions that allocate using gnutls_secure_malloc */
33
34/* Use gnutls_afree() when calling alloca, or
35 * memory leaks may occur in systems which do not
36 * support alloca.
37 */
38#ifdef USE_EFENCE
39# define gnutls_alloca gnutls_malloc
40# define gnutls_afree gnutls_free
41#endif
42
43#ifdef HAVE_ALLOCA
44# ifdef HAVE_ALLOCA_H
45# include <alloca.h>
46# endif
47# ifndef gnutls_alloca
48# define gnutls_alloca alloca
49# define gnutls_afree(x)
50# endif
51#else
52# ifndef gnutls_alloca
53# define gnutls_alloca gnutls_malloc
54# define gnutls_afree gnutls_free
55# endif
56#endif /* HAVE_ALLOCA */
57
58extern int (*_gnutls_is_secure_memory) (const void *);
59
60/* this realloc function will return ptr if size==0, and
61 * will free the ptr if the new allocation failed.
62 */
63void *gnutls_realloc_fast (void *ptr, size_t size);
64
65svoid *gnutls_secure_calloc (size_t nmemb, size_t size);
66
67void *_gnutls_calloc (size_t nmemb, size_t size);
68char *_gnutls_strdup (const char *);
69
70#endif /* GNUTLS_MEM_H */
diff --git a/src/daemon/https/tls/gnutls_mpi.c b/src/daemon/https/tls/gnutls_mpi.c
new file mode 100644
index 00000000..0d807a18
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_mpi.c
@@ -0,0 +1,285 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* Here lie everything that has to do with large numbers, libgcrypt and
26 * other stuff that didn't fit anywhere else.
27 */
28
29#include <gnutls_int.h>
30#include <libtasn1.h>
31#include <gnutls_errors.h>
32#include <gnutls_num.h>
33
34/* Functions that refer to the libgcrypt library.
35 */
36
37void
38_gnutls_mpi_release (mpi_t * x)
39{
40 if (*x == NULL)
41 return;
42 gcry_mpi_release (*x);
43 *x = NULL;
44}
45
46/* returns zero on success
47 */
48int
49_gnutls_mpi_scan (mpi_t * ret_mpi, const opaque * buffer, size_t * nbytes)
50{
51 int ret;
52
53 ret = gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, buffer, *nbytes, nbytes);
54 if (ret)
55 return GNUTLS_E_MPI_SCAN_FAILED;
56
57 return 0;
58}
59
60/* returns zero on success. Fails if the number is zero.
61 */
62int
63_gnutls_mpi_scan_nz (mpi_t * ret_mpi, const opaque * buffer, size_t * nbytes)
64{
65 int ret;
66
67 ret = gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, buffer, *nbytes, nbytes);
68 if (ret)
69 return GNUTLS_E_MPI_SCAN_FAILED;
70
71 /* MPIs with 0 bits are illegal
72 */
73 if (_gnutls_mpi_get_nbits (*ret_mpi) == 0)
74 {
75 _gnutls_mpi_release (ret_mpi);
76 return GNUTLS_E_MPI_SCAN_FAILED;
77 }
78
79 return 0;
80}
81
82int
83_gnutls_mpi_scan_pgp (mpi_t * ret_mpi, const opaque * buffer, size_t * nbytes)
84{
85 int ret;
86 ret = gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_PGP, buffer, *nbytes, nbytes);
87 if (ret)
88 return GNUTLS_E_MPI_SCAN_FAILED;
89
90 /* MPIs with 0 bits are illegal
91 */
92 if (_gnutls_mpi_get_nbits (*ret_mpi) == 0)
93 {
94 _gnutls_mpi_release (ret_mpi);
95 return GNUTLS_E_MPI_SCAN_FAILED;
96 }
97
98 return 0;
99}
100
101int
102_gnutls_mpi_print (void *buffer, size_t * nbytes, const mpi_t a)
103{
104 int ret;
105
106 if (nbytes == NULL || a == NULL)
107 return GNUTLS_E_INVALID_REQUEST;
108
109 ret = gcry_mpi_print (GCRYMPI_FMT_USG, buffer, *nbytes, nbytes, a);
110 if (!ret)
111 return 0;
112
113 return GNUTLS_E_MPI_PRINT_FAILED;
114}
115
116/* Always has the first bit zero */
117int
118_gnutls_mpi_print_lz (void *buffer, size_t * nbytes, const mpi_t a)
119{
120 int ret;
121
122 if (nbytes == NULL || a == NULL)
123 return GNUTLS_E_INVALID_REQUEST;
124
125 ret = gcry_mpi_print (GCRYMPI_FMT_STD, buffer, *nbytes, nbytes, a);
126 if (!ret)
127 return 0;
128
129 return GNUTLS_E_MPI_PRINT_FAILED;
130}
131
132/* Always has the first bit zero */
133int
134_gnutls_mpi_dprint_lz (gnutls_datum_t * dest, const mpi_t a)
135{
136 int ret;
137 opaque *buf = NULL;
138 size_t bytes = 0;
139
140 if (dest == NULL || a == NULL)
141 return GNUTLS_E_INVALID_REQUEST;
142
143 gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &bytes, a);
144
145 if (bytes != 0)
146 buf = gnutls_malloc (bytes);
147 if (buf == NULL)
148 return GNUTLS_E_MEMORY_ERROR;
149
150 ret = gcry_mpi_print (GCRYMPI_FMT_STD, buf, bytes, &bytes, a);
151 if (!ret)
152 {
153 dest->data = buf;
154 dest->size = bytes;
155 return 0;
156 }
157
158 gnutls_free (buf);
159 return GNUTLS_E_MPI_PRINT_FAILED;
160}
161
162int
163_gnutls_mpi_dprint (gnutls_datum_t * dest, const mpi_t a)
164{
165 int ret;
166 opaque *buf = NULL;
167 size_t bytes = 0;
168
169 if (dest == NULL || a == NULL)
170 return GNUTLS_E_INVALID_REQUEST;
171
172 gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &bytes, a);
173
174 if (bytes != 0)
175 buf = gnutls_malloc (bytes);
176 if (buf == NULL)
177 return GNUTLS_E_MEMORY_ERROR;
178
179 ret = gcry_mpi_print (GCRYMPI_FMT_USG, buf, bytes, &bytes, a);
180 if (!ret)
181 {
182 dest->data = buf;
183 dest->size = bytes;
184 return 0;
185 }
186
187 gnutls_free (buf);
188 return GNUTLS_E_MPI_PRINT_FAILED;
189}
190
191
192/* this function reads an integer
193 * from asn1 structs. Combines the read and mpi_scan
194 * steps.
195 */
196int
197_gnutls_x509_read_int (ASN1_TYPE node, const char *value, mpi_t * ret_mpi)
198{
199 int result;
200 size_t s_len;
201 opaque *tmpstr = NULL;
202 int tmpstr_size;
203
204 tmpstr_size = 0;
205 result = asn1_read_value (node, value, NULL, &tmpstr_size);
206 if (result != ASN1_MEM_ERROR)
207 {
208 gnutls_assert ();
209 return _gnutls_asn2err (result);
210 }
211
212 tmpstr = gnutls_alloca (tmpstr_size);
213 if (tmpstr == NULL)
214 {
215 gnutls_assert ();
216 return GNUTLS_E_MEMORY_ERROR;
217 }
218
219 result = asn1_read_value (node, value, tmpstr, &tmpstr_size);
220 if (result != ASN1_SUCCESS)
221 {
222 gnutls_assert ();
223 gnutls_afree (tmpstr);
224 return _gnutls_asn2err (result);
225 }
226
227 s_len = tmpstr_size;
228 if (_gnutls_mpi_scan (ret_mpi, tmpstr, &s_len) != 0)
229 {
230 gnutls_assert ();
231 gnutls_afree (tmpstr);
232 return GNUTLS_E_MPI_SCAN_FAILED;
233 }
234
235 gnutls_afree (tmpstr);
236
237 return 0;
238}
239
240/* Writes the specified integer into the specified node.
241 */
242int
243_gnutls_x509_write_int (ASN1_TYPE node, const char *value, mpi_t mpi, int lz)
244{
245 opaque *tmpstr;
246 size_t s_len;
247 int result;
248
249 s_len = 0;
250 if (lz)
251 result = _gnutls_mpi_print_lz (NULL, &s_len, mpi);
252 else
253 result = _gnutls_mpi_print (NULL, &s_len, mpi);
254
255 tmpstr = gnutls_alloca (s_len);
256 if (tmpstr == NULL)
257 {
258 gnutls_assert ();
259 return GNUTLS_E_MEMORY_ERROR;
260 }
261
262 if (lz)
263 result = _gnutls_mpi_print_lz (tmpstr, &s_len, mpi);
264 else
265 result = _gnutls_mpi_print (tmpstr, &s_len, mpi);
266
267 if (result != 0)
268 {
269 gnutls_assert ();
270 gnutls_afree (tmpstr);
271 return GNUTLS_E_MPI_PRINT_FAILED;
272 }
273
274 result = asn1_write_value (node, value, tmpstr, s_len);
275
276 gnutls_afree (tmpstr);
277
278 if (result != ASN1_SUCCESS)
279 {
280 gnutls_assert ();
281 return _gnutls_asn2err (result);
282 }
283
284 return 0;
285}
diff --git a/src/daemon/https/tls/gnutls_mpi.h b/src/daemon/https/tls/gnutls_mpi.h
new file mode 100644
index 00000000..de2a6f20
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_mpi.h
@@ -0,0 +1,78 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#ifndef GNUTLS_MPI_H
26# define GNUTLS_MPI_H
27
28# include <gnutls_int.h>
29# include <gcrypt.h>
30# include <libtasn1.h>
31/* lgl */
32# include "gc.h"
33
34typedef gcry_mpi_t mpi_t;
35
36#define _gnutls_mpi_cmp gcry_mpi_cmp
37#define _gnutls_mpi_cmp_ui gcry_mpi_cmp_ui
38#define _gnutls_mpi_mod gcry_mpi_mod
39#define _gnutls_mpi_new gcry_mpi_new
40#define _gnutls_mpi_snew gcry_mpi_snew
41#define _gnutls_mpi_copy gcry_mpi_copy
42#define _gnutls_mpi_set_ui gcry_mpi_set_ui
43#define _gnutls_mpi_set gcry_mpi_set
44#define _gnutls_mpi_randomize gcry_mpi_randomize
45#define _gnutls_mpi_get_nbits gcry_mpi_get_nbits
46#define _gnutls_mpi_powm gcry_mpi_powm
47#define _gnutls_mpi_invm gcry_mpi_invm
48#define _gnutls_mpi_addm gcry_mpi_addm
49#define _gnutls_mpi_subm gcry_mpi_subm
50#define _gnutls_mpi_sub_ui gcry_mpi_sub_ui
51#define _gnutls_mpi_mulm gcry_mpi_mulm
52#define _gnutls_mpi_mul gcry_mpi_mul
53#define _gnutls_mpi_add gcry_mpi_add
54#define _gnutls_mpi_add_ui gcry_mpi_add_ui
55#define _gnutls_mpi_sub_ui gcry_mpi_sub_ui
56#define _gnutls_mpi_mul_ui gcry_mpi_mul_ui
57#define _gnutls_prime_check gcry_prime_check
58#define _gnutls_mpi_div gcry_mpi_div
59
60#define _gnutls_mpi_alloc_like(x) _gnutls_mpi_new(_gnutls_mpi_get_nbits(x))
61#define _gnutls_mpi_salloc_like(x) _gnutls_mpi_snew(_gnutls_mpi_get_nbits(x))
62
63void _gnutls_mpi_release (mpi_t * x);
64
65int _gnutls_mpi_scan_nz (mpi_t * ret_mpi, const opaque * buffer,
66 size_t * nbytes);
67int _gnutls_mpi_scan (mpi_t * ret_mpi, const opaque * buffer,
68 size_t * nbytes);
69int _gnutls_mpi_scan_pgp (mpi_t * ret_mpi, const opaque * buffer,
70 size_t * nbytes);
71
72int _gnutls_mpi_print (void *buffer, size_t * nbytes, const mpi_t a);
73int _gnutls_mpi_print_lz (void *buffer, size_t * nbytes, const mpi_t a);
74
75int _gnutls_mpi_dprint_lz (gnutls_datum_t * dest, const mpi_t a);
76int _gnutls_mpi_dprint (gnutls_datum_t * dest, const mpi_t a);
77
78#endif
diff --git a/src/daemon/https/tls/gnutls_num.c b/src/daemon/https/tls/gnutls_num.c
new file mode 100644
index 00000000..474cb73b
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_num.c
@@ -0,0 +1,192 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file contains the functions needed for 64 bit integer support in
26 * TLS, and functions which ease the access to TLS vectors (data of given size).
27 */
28
29#include <gnutls_int.h>
30#include <gnutls_num.h>
31#include <gnutls_errors.h>
32
33/* This function will add one to uint64 x.
34 * Returns 0 on success, or -1 if the uint64 max limit
35 * has been reached.
36 */
37int
38_gnutls_uint64pp (uint64 * x)
39{
40 register int i, y = 0;
41
42 for (i = 7; i >= 0; i--)
43 {
44 y = 0;
45 if (x->i[i] == 0xff)
46 {
47 x->i[i] = 0;
48 y = 1;
49 }
50 else
51 x->i[i]++;
52
53 if (y == 0)
54 break;
55 }
56 if (y != 0)
57 return -1; /* over 64 bits! WOW */
58
59 return 0;
60}
61
62uint32_t
63_gnutls_uint24touint32 (uint24 num)
64{
65 uint32_t ret = 0;
66
67 ((uint8_t *) & ret)[1] = num.pint[0];
68 ((uint8_t *) & ret)[2] = num.pint[1];
69 ((uint8_t *) & ret)[3] = num.pint[2];
70 return ret;
71}
72
73uint24
74_gnutls_uint32touint24 (uint32_t num)
75{
76 uint24 ret;
77
78 ret.pint[0] = ((uint8_t *) & num)[1];
79 ret.pint[1] = ((uint8_t *) & num)[2];
80 ret.pint[2] = ((uint8_t *) & num)[3];
81 return ret;
82
83}
84
85/* data should be at least 3 bytes */
86uint32_t
87_gnutls_read_uint24 (const opaque * data)
88{
89 uint32_t res;
90 uint24 num;
91
92 num.pint[0] = data[0];
93 num.pint[1] = data[1];
94 num.pint[2] = data[2];
95
96 res = _gnutls_uint24touint32 (num);
97#ifndef WORDS_BIGENDIAN
98 res = byteswap32 (res);
99#endif
100 return res;
101}
102
103void
104_gnutls_write_uint24 (uint32_t num, opaque * data)
105{
106 uint24 tmp;
107
108#ifndef WORDS_BIGENDIAN
109 num = byteswap32 (num);
110#endif
111 tmp = _gnutls_uint32touint24 (num);
112
113 data[0] = tmp.pint[0];
114 data[1] = tmp.pint[1];
115 data[2] = tmp.pint[2];
116}
117
118uint32_t
119_gnutls_read_uint32 (const opaque * data)
120{
121 uint32_t res;
122
123 memcpy (&res, data, sizeof (uint32_t));
124#ifndef WORDS_BIGENDIAN
125 res = byteswap32 (res);
126#endif
127 return res;
128}
129
130void
131_gnutls_write_uint32 (uint32_t num, opaque * data)
132{
133
134#ifndef WORDS_BIGENDIAN
135 num = byteswap32 (num);
136#endif
137 memcpy (data, &num, sizeof (uint32_t));
138}
139
140uint16_t
141_gnutls_read_uint16 (const opaque * data)
142{
143 uint16_t res;
144 memcpy (&res, data, sizeof (uint16_t));
145#ifndef WORDS_BIGENDIAN
146 res = byteswap16 (res);
147#endif
148 return res;
149}
150
151void
152_gnutls_write_uint16 (uint16_t num, opaque * data)
153{
154
155#ifndef WORDS_BIGENDIAN
156 num = byteswap16 (num);
157#endif
158 memcpy (data, &num, sizeof (uint16_t));
159}
160
161uint32_t
162_gnutls_conv_uint32 (uint32_t data)
163{
164#ifndef WORDS_BIGENDIAN
165 return byteswap32 (data);
166#else
167 return data;
168#endif
169}
170
171uint16_t
172_gnutls_conv_uint16 (uint16_t data)
173{
174#ifndef WORDS_BIGENDIAN
175 return byteswap16 (data);
176#else
177 return data;
178#endif
179}
180
181uint32_t
182_gnutls_uint64touint32 (const uint64 * num)
183{
184 uint32_t ret;
185
186 memcpy (&ret, &num->i[4], 4);
187#ifndef WORDS_BIGENDIAN
188 ret = byteswap32 (ret);
189#endif
190
191 return ret;
192}
diff --git a/src/daemon/https/tls/gnutls_num.h b/src/daemon/https/tls/gnutls_num.h
new file mode 100644
index 00000000..3ab226ae
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_num.h
@@ -0,0 +1,49 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26
27#define rotl32(x,n) (((x) << ((uint16_t)(n))) | ((x) >> (32 - (uint16_t)(n))))
28#define rotr32(x,n) (((x) >> ((uint16_t)(n))) | ((x) << (32 - (uint16_t)(n))))
29#define rotl16(x,n) (((x) << ((uint16_t)(n))) | ((x) >> (16 - (uint16_t)(n))))
30#define rotr16(x,n) (((x) >> ((uint16_t)(n))) | ((x) << (16 - (uint16_t)(n))))
31
32#define byteswap16(x) ((rotl16(x, 8) & 0x00ff) | (rotr16(x, 8) & 0xff00))
33#define byteswap32(x) ((rotl32(x, 8) & 0x00ff00ffUL) | (rotr32(x, 8) & 0xff00ff00UL))
34
35uint32_t _gnutls_uint24touint32 (uint24 num);
36uint24 _gnutls_uint32touint24 (uint32_t num);
37uint32_t _gnutls_read_uint32 (const opaque * data);
38uint16_t _gnutls_read_uint16 (const opaque * data);
39uint32_t _gnutls_conv_uint32 (uint32_t data);
40uint16_t _gnutls_conv_uint16 (uint16_t data);
41uint32_t _gnutls_read_uint24 (const opaque * data);
42void _gnutls_write_uint24 (uint32_t num, opaque * data);
43void _gnutls_write_uint32 (uint32_t num, opaque * data);
44void _gnutls_write_uint16 (uint16_t num, opaque * data);
45uint32_t _gnutls_uint64touint32 (const uint64 *);
46
47int _gnutls_uint64pp (uint64 *);
48# define _gnutls_uint64zero(x) x.i[0] = x.i[1] = x.i[2] = x.i[3] = x.i[4] = x.i[5] = x.i[6] = x.i[7] = 0
49# define UINT64DATA(x) x.i
diff --git a/src/daemon/https/tls/gnutls_pk.c b/src/daemon/https/tls/gnutls_pk.c
new file mode 100644
index 00000000..cfec9463
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_pk.c
@@ -0,0 +1,915 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file contains the functions needed for RSA/DSA public key
26 * encryption and signatures.
27 */
28
29#include <gnutls_int.h>
30#include <gnutls_mpi.h>
31#include <gnutls_pk.h>
32#include <gnutls_errors.h>
33#include <gnutls_datum.h>
34#include <gnutls_global.h>
35#include <gnutls_num.h>
36#include "debug.h"
37#include <gc.h>
38
39/* x509 */
40#include "common.h"
41#include "mpi.h"
42
43static int _gnutls_pk_encrypt (int algo, mpi_t * resarr, mpi_t data,
44 mpi_t * pkey, int pkey_len);
45static int _gnutls_pk_sign (int algo, mpi_t * data, mpi_t hash,
46 mpi_t * pkey, int);
47static int _gnutls_pk_verify (int algo, mpi_t hash, mpi_t * data,
48 mpi_t * pkey, int);
49static int _gnutls_pk_decrypt (int algo, mpi_t * resarr, mpi_t data,
50 mpi_t * pkey, int);
51
52
53/* Do PKCS-1 RSA encryption.
54 * params is modulus, public exp.
55 */
56int
57_gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext,
58 const gnutls_datum_t * plaintext,
59 mpi_t * params, unsigned params_len,
60 unsigned btype)
61{
62 unsigned int i, pad;
63 int ret;
64 mpi_t m, res;
65 opaque *edata, *ps;
66 size_t k, psize;
67 size_t mod_bits;
68
69 mod_bits = _gnutls_mpi_get_nbits (params[0]);
70 k = mod_bits / 8;
71 if (mod_bits % 8 != 0)
72 k++;
73
74 if (plaintext->size > k - 11)
75 {
76 gnutls_assert ();
77 return GNUTLS_E_PK_ENCRYPTION_FAILED;
78 }
79
80 edata = gnutls_alloca (k);
81 if (edata == NULL)
82 {
83 gnutls_assert ();
84 return GNUTLS_E_MEMORY_ERROR;
85 }
86
87 /* EB = 00||BT||PS||00||D
88 * (use block type 'btype')
89 */
90
91 edata[0] = 0;
92 edata[1] = btype;
93 psize = k - 3 - plaintext->size;
94
95 ps = &edata[2];
96 switch (btype)
97 {
98 case 2:
99 /* using public key */
100 if (params_len < RSA_PUBLIC_PARAMS)
101 {
102 gnutls_assert ();
103 gnutls_afree (edata);
104 return GNUTLS_E_INTERNAL_ERROR;
105 }
106
107 if (gc_pseudo_random (ps, psize) != GC_OK)
108 {
109 gnutls_assert ();
110 gnutls_afree (edata);
111 return GNUTLS_E_RANDOM_FAILED;
112 }
113 for (i = 0; i < psize; i++)
114 while (ps[i] == 0)
115 {
116 if (gc_pseudo_random (&ps[i], 1) != GC_OK)
117 {
118 gnutls_assert ();
119 gnutls_afree (edata);
120 return GNUTLS_E_RANDOM_FAILED;
121 }
122 }
123 break;
124 case 1:
125 /* using private key */
126
127 if (params_len < RSA_PRIVATE_PARAMS)
128 {
129 gnutls_assert ();
130 gnutls_afree (edata);
131 return GNUTLS_E_INTERNAL_ERROR;
132 }
133
134 for (i = 0; i < psize; i++)
135 ps[i] = 0xff;
136 break;
137 default:
138 gnutls_assert ();
139 gnutls_afree (edata);
140 return GNUTLS_E_INTERNAL_ERROR;
141 }
142
143 ps[psize] = 0;
144 memcpy (&ps[psize + 1], plaintext->data, plaintext->size);
145
146 if (_gnutls_mpi_scan_nz (&m, edata, &k) != 0)
147 {
148 gnutls_assert ();
149 gnutls_afree (edata);
150 return GNUTLS_E_MPI_SCAN_FAILED;
151 }
152 gnutls_afree (edata);
153
154 if (btype == 2) /* encrypt */
155 ret = _gnutls_pk_encrypt (GCRY_PK_RSA, &res, m, params, params_len);
156 else /* sign */
157 ret = _gnutls_pk_sign (GCRY_PK_RSA, &res, m, params, params_len);
158
159 _gnutls_mpi_release (&m);
160
161 if (ret < 0)
162 {
163 gnutls_assert ();
164 return ret;
165 }
166
167 _gnutls_mpi_print (NULL, &psize, res);
168
169 if (psize < k)
170 {
171 /* padding psize */
172 pad = k - psize;
173 psize = k;
174 }
175 else if (psize == k)
176 {
177 pad = 0;
178 }
179 else
180 { /* psize > k !!! */
181 /* This is an impossible situation */
182 gnutls_assert ();
183 _gnutls_mpi_release (&res);
184 return GNUTLS_E_INTERNAL_ERROR;
185 }
186
187 ciphertext->data = gnutls_malloc (psize);
188 if (ciphertext->data == NULL)
189 {
190 gnutls_assert ();
191 _gnutls_mpi_release (&res);
192 return GNUTLS_E_MEMORY_ERROR;
193 }
194 _gnutls_mpi_print (&ciphertext->data[pad], &psize, res);
195 for (i = 0; i < pad; i++)
196 ciphertext->data[i] = 0;
197
198 ciphertext->size = k;
199
200 _gnutls_mpi_release (&res);
201
202 return 0;
203}
204
205
206/* Do PKCS-1 RSA decryption.
207 * params is modulus, public exp., private key
208 * Can decrypt block type 1 and type 2 packets.
209 */
210int
211_gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext,
212 const gnutls_datum_t * ciphertext,
213 mpi_t * params, unsigned params_len,
214 unsigned btype)
215{
216 unsigned k, i;
217 int ret;
218 mpi_t c, res;
219 opaque *edata;
220 size_t esize, mod_bits;
221
222 mod_bits = _gnutls_mpi_get_nbits (params[0]);
223 k = mod_bits / 8;
224 if (mod_bits % 8 != 0)
225 k++;
226
227 esize = ciphertext->size;
228
229 if (esize != k)
230 {
231 gnutls_assert ();
232 return GNUTLS_E_PK_DECRYPTION_FAILED;
233 }
234
235 if (_gnutls_mpi_scan_nz (&c, ciphertext->data, &esize) != 0)
236 {
237 gnutls_assert ();
238 return GNUTLS_E_MPI_SCAN_FAILED;
239 }
240
241 /* we can use btype to see if the private key is
242 * available.
243 */
244 if (btype == 2)
245 ret = _gnutls_pk_decrypt (GCRY_PK_RSA, &res, c, params, params_len);
246 else
247 {
248 ret = _gnutls_pk_encrypt (GCRY_PK_RSA, &res, c, params, params_len);
249 }
250 _gnutls_mpi_release (&c);
251
252 if (ret < 0)
253 {
254 gnutls_assert ();
255 return ret;
256 }
257
258 _gnutls_mpi_print (NULL, &esize, res);
259 edata = gnutls_alloca (esize + 1);
260 if (edata == NULL)
261 {
262 gnutls_assert ();
263 _gnutls_mpi_release (&res);
264 return GNUTLS_E_MEMORY_ERROR;
265 }
266 _gnutls_mpi_print (&edata[1], &esize, res);
267
268 _gnutls_mpi_release (&res);
269
270 /* EB = 00||BT||PS||00||D
271 * (use block type 'btype')
272 *
273 * From now on, return GNUTLS_E_DECRYPTION_FAILED on errors, to
274 * avoid attacks similar to the one described by Bleichenbacher in:
275 * "Chosen Ciphertext Attacks against Protocols Based on RSA
276 * Encryption Standard PKCS #1".
277 */
278
279
280 edata[0] = 0;
281 esize++;
282
283 if (edata[0] != 0 || edata[1] != btype)
284 {
285 gnutls_assert ();
286 gnutls_afree (edata);
287 return GNUTLS_E_DECRYPTION_FAILED;
288 }
289
290 ret = GNUTLS_E_DECRYPTION_FAILED;
291 switch (btype)
292 {
293 case 2:
294 for (i = 2; i < esize; i++)
295 {
296 if (edata[i] == 0)
297 {
298 ret = 0;
299 break;
300 }
301 }
302 break;
303 case 1:
304 for (i = 2; i < esize; i++)
305 {
306 if (edata[i] == 0 && i > 2)
307 {
308 ret = 0;
309 break;
310 }
311 if (edata[i] != 0xff)
312 {
313 _gnutls_handshake_log ("PKCS #1 padding error");
314 /* PKCS #1 padding error. Don't use
315 GNUTLS_E_PKCS1_WRONG_PAD here. */
316 break;
317 }
318 }
319 break;
320 default:
321 gnutls_assert ();
322 gnutls_afree (edata);
323 break;
324 }
325 i++;
326
327 if (ret < 0)
328 {
329 gnutls_assert ();
330 gnutls_afree (edata);
331 return GNUTLS_E_DECRYPTION_FAILED;
332 }
333
334 if (_gnutls_sset_datum (plaintext, &edata[i], esize - i) < 0)
335 {
336 gnutls_assert ();
337 gnutls_afree (edata);
338 return GNUTLS_E_MEMORY_ERROR;
339 }
340
341 gnutls_afree (edata);
342
343 return 0;
344}
345
346
347int
348_gnutls_rsa_verify (const gnutls_datum_t * vdata,
349 const gnutls_datum_t * ciphertext, mpi_t * params,
350 int params_len, int btype)
351{
352
353 gnutls_datum_t plain;
354 int ret;
355
356 /* decrypt signature */
357 if ((ret =
358 _gnutls_pkcs1_rsa_decrypt (&plain, ciphertext, params, params_len,
359 btype)) < 0)
360 {
361 gnutls_assert ();
362 return ret;
363 }
364
365 if (plain.size != vdata->size)
366 {
367 gnutls_assert ();
368 _gnutls_free_datum (&plain);
369 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
370 }
371
372 if (memcmp (plain.data, vdata->data, plain.size) != 0)
373 {
374 gnutls_assert ();
375 _gnutls_free_datum (&plain);
376 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
377 }
378
379 _gnutls_free_datum (&plain);
380
381 return 0; /* ok */
382}
383
384/* encodes the Dss-Sig-Value structure
385 */
386static int
387encode_ber_rs (gnutls_datum_t * sig_value, mpi_t r, mpi_t s)
388{
389 ASN1_TYPE sig;
390 int result, tot_len;
391
392 if ((result =
393 asn1_create_element (_gnutls_get_gnutls_asn (),
394 "GNUTLS.DSASignatureValue",
395 &sig)) != ASN1_SUCCESS)
396 {
397 gnutls_assert ();
398 return _gnutls_asn2err (result);
399 }
400
401 result = _gnutls_x509_write_int (sig, "r", r, 1);
402 if (result < 0)
403 {
404 gnutls_assert ();
405 asn1_delete_structure (&sig);
406 return result;
407 }
408
409 result = _gnutls_x509_write_int (sig, "s", s, 1);
410 if (result < 0)
411 {
412 gnutls_assert ();
413 asn1_delete_structure (&sig);
414 return result;
415 }
416
417 tot_len = 0;
418
419 result = _gnutls_x509_der_encode (sig, "", sig_value, 0);
420
421 asn1_delete_structure (&sig);
422
423 if (result < 0)
424 {
425 gnutls_assert ();
426 return result;
427 }
428
429 return 0;
430}
431
432
433/* Do DSA signature calculation. params is p, q, g, y, x in that order.
434 */
435int
436_gnutls_dsa_sign (gnutls_datum_t * signature,
437 const gnutls_datum_t * hash, mpi_t * params,
438 unsigned params_len)
439{
440 mpi_t rs[2], mdata;
441 int ret;
442 size_t k;
443
444 k = hash->size;
445 if (k < 20)
446 { /* SHA1 or better only */
447 gnutls_assert ();
448 return GNUTLS_E_PK_SIGN_FAILED;
449 }
450
451 if (_gnutls_mpi_scan_nz (&mdata, hash->data, &k) != 0)
452 {
453 gnutls_assert ();
454 return GNUTLS_E_MPI_SCAN_FAILED;
455 }
456
457 ret = _gnutls_pk_sign (GCRY_PK_DSA, rs, mdata, params, params_len);
458 /* rs[0], rs[1] now hold r,s */
459 _gnutls_mpi_release (&mdata);
460
461 if (ret < 0)
462 {
463 gnutls_assert ();
464 return ret;
465 }
466
467 ret = encode_ber_rs (signature, rs[0], rs[1]);
468
469 /* free r,s */
470 _gnutls_mpi_release (&rs[0]);
471 _gnutls_mpi_release (&rs[1]);
472
473 if (ret != 0)
474 {
475 gnutls_assert ();
476 return GNUTLS_E_MEMORY_ERROR;
477 }
478
479 return 0;
480}
481
482/* decodes the Dss-Sig-Value structure
483 */
484static int
485decode_ber_rs (const gnutls_datum_t * sig_value, mpi_t * r, mpi_t * s)
486{
487 ASN1_TYPE sig;
488 int result;
489
490 if ((result =
491 asn1_create_element (_gnutls_get_gnutls_asn (),
492 "GNUTLS.DSASignatureValue",
493 &sig)) != ASN1_SUCCESS)
494 {
495 gnutls_assert ();
496 return _gnutls_asn2err (result);
497 }
498
499 result = asn1_der_decoding (&sig, sig_value->data, sig_value->size, NULL);
500 if (result != ASN1_SUCCESS)
501 {
502 gnutls_assert ();
503 asn1_delete_structure (&sig);
504 return _gnutls_asn2err (result);
505 }
506
507 result = _gnutls_x509_read_int (sig, "r", r);
508 if (result < 0)
509 {
510 gnutls_assert ();
511 asn1_delete_structure (&sig);
512 return result;
513 }
514
515 result = _gnutls_x509_read_int (sig, "s", s);
516 if (result < 0)
517 {
518 gnutls_assert ();
519 _gnutls_mpi_release (s);
520 asn1_delete_structure (&sig);
521 return result;
522 }
523
524 asn1_delete_structure (&sig);
525
526 return 0;
527}
528
529/* params is p, q, g, y in that order
530 */
531int
532_gnutls_dsa_verify (const gnutls_datum_t * vdata,
533 const gnutls_datum_t * sig_value, mpi_t * params,
534 int params_len)
535{
536
537 mpi_t mdata;
538 int ret;
539 size_t k;
540 mpi_t rs[2];
541
542 if (vdata->size != 20)
543 { /* sha-1 only */
544 gnutls_assert ();
545 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
546 }
547
548 if (decode_ber_rs (sig_value, &rs[0], &rs[1]) != 0)
549 {
550 gnutls_assert ();
551 return GNUTLS_E_MPI_SCAN_FAILED;
552 }
553
554 k = vdata->size;
555 if (_gnutls_mpi_scan_nz (&mdata, vdata->data, &k) != 0)
556 {
557 gnutls_assert ();
558 _gnutls_mpi_release (&rs[0]);
559 _gnutls_mpi_release (&rs[1]);
560 return GNUTLS_E_MPI_SCAN_FAILED;
561 }
562
563 /* decrypt signature */
564 ret = _gnutls_pk_verify (GCRY_PK_DSA, mdata, rs, params, params_len);
565 _gnutls_mpi_release (&mdata);
566 _gnutls_mpi_release (&rs[0]);
567 _gnutls_mpi_release (&rs[1]);
568
569 if (ret < 0)
570 {
571 gnutls_assert ();
572 return ret;
573 }
574
575 return 0; /* ok */
576}
577
578
579/* this is taken from gnupg
580 */
581
582/****************
583 * Emulate our old PK interface here - sometime in the future we might
584 * change the internal design to directly fit to libgcrypt.
585 */
586static int
587_gnutls_pk_encrypt (int algo, mpi_t * resarr, mpi_t data,
588 mpi_t * pkey, int pkey_len)
589{
590 gcry_sexp_t s_ciph, s_data, s_pkey;
591 int rc = -1;
592
593 /* make a sexp from pkey */
594 switch (algo)
595 {
596 case GCRY_PK_RSA:
597 if (pkey_len >= 2)
598 rc = gcry_sexp_build (&s_pkey, NULL,
599 "(public-key(rsa(n%m)(e%m)))",
600 pkey[0], pkey[1]);
601 break;
602
603 default:
604 gnutls_assert ();
605 return GNUTLS_E_INTERNAL_ERROR;
606 }
607
608 if (rc != 0)
609 {
610 gnutls_assert ();
611 return GNUTLS_E_INTERNAL_ERROR;
612 }
613
614 /* put the data into a simple list */
615 if (gcry_sexp_build (&s_data, NULL, "%m", data))
616 {
617 gnutls_assert ();
618 gcry_sexp_release (s_pkey);
619 return GNUTLS_E_INTERNAL_ERROR;
620 }
621
622 /* pass it to libgcrypt */
623 rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey);
624 gcry_sexp_release (s_data);
625 gcry_sexp_release (s_pkey);
626
627 if (rc != 0)
628 {
629 gnutls_assert ();
630 return GNUTLS_E_PK_ENCRYPTION_FAILED;
631
632 }
633 else
634 { /* add better error handling or make gnupg use S-Exp directly */
635 gcry_sexp_t list = gcry_sexp_find_token (s_ciph, "a", 0);
636 if (list == NULL)
637 {
638 gnutls_assert ();
639 gcry_sexp_release (s_ciph);
640 return GNUTLS_E_INTERNAL_ERROR;
641 }
642
643 resarr[0] = gcry_sexp_nth_mpi (list, 1, 0);
644 gcry_sexp_release (list);
645
646 if (resarr[0] == NULL)
647 {
648 gnutls_assert ();
649 gcry_sexp_release (s_ciph);
650 return GNUTLS_E_INTERNAL_ERROR;
651 }
652 }
653
654 gcry_sexp_release (s_ciph);
655 return rc;
656}
657
658static int
659_gnutls_pk_decrypt (int algo, mpi_t * resarr, mpi_t data, mpi_t * pkey,
660 int pkey_len)
661{
662 gcry_sexp_t s_plain, s_data, s_pkey;
663 int rc = -1;
664
665 /* make a sexp from pkey */
666 switch (algo)
667 {
668 case GCRY_PK_RSA:
669 if (pkey_len >= 6)
670 rc = gcry_sexp_build (&s_pkey, NULL,
671 "(private-key(rsa((n%m)(e%m)(d%m)(p%m)(q%m)(u%m))))",
672 pkey[0], pkey[1], pkey[2], pkey[3],
673 pkey[4], pkey[5]);
674 break;
675
676 default:
677 gnutls_assert ();
678 return GNUTLS_E_INTERNAL_ERROR;
679 }
680
681 if (rc != 0)
682 {
683 gnutls_assert ();
684 return GNUTLS_E_INTERNAL_ERROR;
685 }
686
687 /* put the data into a simple list */
688 if (gcry_sexp_build (&s_data, NULL, "(enc-val(rsa(a%m)))", data))
689 {
690 gnutls_assert ();
691 gcry_sexp_release (s_pkey);
692 return GNUTLS_E_INTERNAL_ERROR;
693 }
694
695 /* pass it to libgcrypt */
696 rc = gcry_pk_decrypt (&s_plain, s_data, s_pkey);
697 gcry_sexp_release (s_data);
698 gcry_sexp_release (s_pkey);
699
700 if (rc != 0)
701 {
702 gnutls_assert ();
703 return GNUTLS_E_PK_DECRYPTION_FAILED;
704
705 }
706 else
707 { /* add better error handling or make gnupg use S-Exp directly */
708 resarr[0] = gcry_sexp_nth_mpi (s_plain, 0, 0);
709
710 if (resarr[0] == NULL)
711 {
712 gnutls_assert ();
713 gcry_sexp_release (s_plain);
714 return GNUTLS_E_INTERNAL_ERROR;
715 }
716 }
717
718 gcry_sexp_release (s_plain);
719 return rc;
720}
721
722
723/* in case of DSA puts into data, r,s
724 */
725static int
726_gnutls_pk_sign (int algo, mpi_t * data, mpi_t hash, mpi_t * pkey,
727 int pkey_len)
728{
729 gcry_sexp_t s_hash, s_key, s_sig;
730 int rc = -1;
731
732 /* make a sexp from pkey */
733 switch (algo)
734 {
735 case GCRY_PK_DSA:
736 if (pkey_len >= 5)
737 rc = gcry_sexp_build (&s_key, NULL,
738 "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
739 pkey[0], pkey[1], pkey[2], pkey[3], pkey[4]);
740 else
741 {
742 gnutls_assert ();
743 }
744
745 break;
746 case GCRY_PK_RSA:
747 if (pkey_len >= 6)
748 rc = gcry_sexp_build (&s_key, NULL,
749 "(private-key(rsa((n%m)(e%m)(d%m)(p%m)(q%m)(u%m))))",
750 pkey[0], pkey[1], pkey[2], pkey[3],
751 pkey[4], pkey[5]);
752 else
753 {
754 gnutls_assert ();
755 }
756 break;
757
758 default:
759 gnutls_assert ();
760 return GNUTLS_E_INTERNAL_ERROR;
761 }
762
763 if (rc != 0)
764 {
765 gnutls_assert ();
766 return GNUTLS_E_INTERNAL_ERROR;
767 }
768
769 /* put the data into a simple list */
770 if (gcry_sexp_build (&s_hash, NULL, "%m", hash))
771 {
772 gnutls_assert ();
773 return GNUTLS_E_INTERNAL_ERROR;
774 }
775
776 /* pass it to libgcrypt */
777 rc = gcry_pk_sign (&s_sig, s_hash, s_key);
778 gcry_sexp_release (s_hash);
779 gcry_sexp_release (s_key);
780
781 if (rc != 0)
782 {
783 gnutls_assert ();
784 return GNUTLS_E_PK_SIGN_FAILED;
785
786 }
787 else
788 {
789 gcry_sexp_t list;
790
791 if (algo == GCRY_PK_DSA)
792 {
793 list = gcry_sexp_find_token (s_sig, "r", 0);
794 if (list == NULL)
795 {
796 gnutls_assert ();
797 gcry_sexp_release (s_sig);
798 return GNUTLS_E_INTERNAL_ERROR;
799 }
800
801 data[0] = gcry_sexp_nth_mpi (list, 1, 0);
802 gcry_sexp_release (list);
803
804 list = gcry_sexp_find_token (s_sig, "s", 0);
805 if (list == NULL)
806 {
807 gnutls_assert ();
808 gcry_sexp_release (s_sig);
809 return GNUTLS_E_INTERNAL_ERROR;
810 }
811
812 data[1] = gcry_sexp_nth_mpi (list, 1, 0);
813 gcry_sexp_release (list);
814 }
815 else
816 { /* GCRY_PK_RSA */
817 list = gcry_sexp_find_token (s_sig, "s", 0);
818 if (list == NULL)
819 {
820 gnutls_assert ();
821 gcry_sexp_release (s_sig);
822 return GNUTLS_E_INTERNAL_ERROR;
823 }
824
825 data[0] = gcry_sexp_nth_mpi (list, 1, 0);
826 gcry_sexp_release (list);
827 }
828 }
829
830 gcry_sexp_release (s_sig);
831 return 0;
832}
833
834
835static int
836_gnutls_pk_verify (int algo, mpi_t hash, mpi_t * data,
837 mpi_t * pkey, int pkey_len)
838{
839 gcry_sexp_t s_sig, s_hash, s_pkey;
840 int rc = -1;
841
842 /* make a sexp from pkey */
843 switch (algo)
844 {
845 case GCRY_PK_DSA:
846 if (pkey_len >= 4)
847 rc = gcry_sexp_build (&s_pkey, NULL,
848 "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
849 pkey[0], pkey[1], pkey[2], pkey[3]);
850 break;
851 case GCRY_PK_RSA:
852 if (pkey_len >= 2)
853 rc = gcry_sexp_build (&s_pkey, NULL,
854 "(public-key(rsa(n%m)(e%m)))",
855 pkey[0], pkey[1]);
856 break;
857
858 default:
859 gnutls_assert ();
860 return GNUTLS_E_INTERNAL_ERROR;
861 }
862
863 if (rc != 0)
864 {
865 gnutls_assert ();
866 return GNUTLS_E_INTERNAL_ERROR;
867 }
868
869 /* put the data into a simple list */
870 if (gcry_sexp_build (&s_hash, NULL, "%m", hash))
871 {
872 gnutls_assert ();
873 gcry_sexp_release (s_pkey);
874 return GNUTLS_E_INTERNAL_ERROR;
875 }
876
877 switch (algo)
878 {
879 case GCRY_PK_DSA:
880 rc = gcry_sexp_build (&s_sig, NULL,
881 "(sig-val(dsa(r%m)(s%m)))", data[0], data[1]);
882 break;
883 case GCRY_PK_RSA:
884 rc = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s%m)))", data[0]);
885 break;
886
887 default:
888 gnutls_assert ();
889 gcry_sexp_release (s_pkey);
890 gcry_sexp_release (s_hash);
891 return GNUTLS_E_INTERNAL_ERROR;
892 }
893
894 if (rc != 0)
895 {
896 gnutls_assert ();
897 gcry_sexp_release (s_pkey);
898 gcry_sexp_release (s_hash);
899 return GNUTLS_E_INTERNAL_ERROR;
900 }
901
902 rc = gcry_pk_verify (s_sig, s_hash, s_pkey);
903
904 gcry_sexp_release (s_sig);
905 gcry_sexp_release (s_hash);
906 gcry_sexp_release (s_pkey);
907
908 if (rc != 0)
909 {
910 gnutls_assert ();
911 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
912 }
913
914 return 0;
915}
diff --git a/src/daemon/https/tls/gnutls_pk.h b/src/daemon/https/tls/gnutls_pk.h
new file mode 100644
index 00000000..e6f37b0e
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_pk.h
@@ -0,0 +1,46 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#ifndef GNUTLS_PK_H
26# define GNUTLS_PK_H
27
28int _gnutls_pkcs1_rsa_encrypt (gnutls_datum_t * ciphertext,
29 const gnutls_datum_t * plaintext,
30 mpi_t * params, unsigned params_len,
31 unsigned btype);
32int _gnutls_dsa_sign (gnutls_datum_t * signature,
33 const gnutls_datum_t * plaintext, mpi_t * params,
34 unsigned params_len);
35int _gnutls_pkcs1_rsa_decrypt (gnutls_datum_t * plaintext,
36 const gnutls_datum_t * ciphertext,
37 mpi_t * params, unsigned params_len,
38 unsigned btype);
39int _gnutls_rsa_verify (const gnutls_datum_t * vdata,
40 const gnutls_datum_t * ciphertext, mpi_t * params,
41 int params_len, int btype);
42int _gnutls_dsa_verify (const gnutls_datum_t * vdata,
43 const gnutls_datum_t * sig_value, mpi_t * params,
44 int params_len);
45
46#endif /* GNUTLS_PK_H */
diff --git a/src/daemon/https/tls/gnutls_priority.c b/src/daemon/https/tls/gnutls_priority.c
new file mode 100644
index 00000000..69019191
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_priority.c
@@ -0,0 +1,497 @@
1/*
2 * Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* Here lies the code of the gnutls_*_set_priority() functions.
26 */
27
28#include "gnutls_int.h"
29#include "gnutls_algorithms.h"
30#include "gnutls_errors.h"
31#include <gnutls_num.h>
32
33#define MAX_ELEMENTS 48
34
35static void break_comma_list (char *etag,
36 char **broken_etag,
37 int *elements, int max_elements, char sep);
38
39/**
40 * gnutls_cipher_set_priority - Sets the priority on the ciphers supported by gnutls.
41 * @session: is a #gnutls_session_t structure.
42 * @list: is a 0 terminated list of gnutls_cipher_algorithm_t elements.
43 *
44 * Sets the priority on the ciphers supported by gnutls.
45 * Priority is higher for elements specified before others.
46 * After specifying the ciphers you want, you must append a 0.
47 * Note that the priority is set on the client. The server does
48 * not use the algorithm's priority except for disabling
49 * algorithms that were not specified.
50 *
51 * Returns 0 on success.
52 *
53 **/
54int
55gnutls_cipher_set_priority (gnutls_session_t session, const int *list)
56{
57 int num = 0, i;
58
59 while (list[num] != 0)
60 num++;
61 if (num > MAX_ALGOS)
62 num = MAX_ALGOS;
63 session->internals.priorities.cipher.algorithms = num;
64
65 for (i = 0; i < num; i++)
66 {
67 session->internals.priorities.cipher.priority[i] = list[i];
68 }
69
70 return 0;
71}
72
73inline static int
74_set_priority (priority_st * st, const int *list)
75{
76 int num = 0, i;
77
78 while (list[num] != 0)
79 num++;
80 if (num > MAX_ALGOS)
81 num = MAX_ALGOS;
82 st->algorithms = num;
83
84 for (i = 0; i < num; i++)
85 {
86 st->priority[i] = list[i];
87 }
88
89 return 0;
90
91}
92
93/**
94 * gnutls_kx_set_priority - Sets the priority on the key exchange algorithms supported by gnutls.
95 * @session: is a #gnutls_session_t structure.
96 * @list: is a 0 terminated list of gnutls_kx_algorithm_t elements.
97 *
98 * Sets the priority on the key exchange algorithms supported by gnutls.
99 * Priority is higher for elements specified before others.
100 * After specifying the algorithms you want, you must append a 0.
101 * Note that the priority is set on the client. The server does
102 * not use the algorithm's priority except for disabling
103 * algorithms that were not specified.
104 *
105 * Returns 0 on success.
106 *
107 **/
108int
109gnutls_kx_set_priority (gnutls_session_t session, const int *list)
110{
111 return _set_priority (&session->internals.priorities.kx, list);
112}
113
114/**
115 * gnutls_mac_set_priority - Sets the priority on the mac algorithms supported by gnutls.
116 * @session: is a #gnutls_session_t structure.
117 * @list: is a 0 terminated list of gnutls_mac_algorithm_t elements.
118 *
119 * Sets the priority on the mac algorithms supported by gnutls.
120 * Priority is higher for elements specified before others.
121 * After specifying the algorithms you want, you must append a 0.
122 * Note that the priority is set on the client. The server does
123 * not use the algorithm's priority except for disabling
124 * algorithms that were not specified.
125 *
126 * Returns 0 on success.
127 *
128 **/
129int
130gnutls_mac_set_priority (gnutls_session_t session, const int *list)
131{
132 return _set_priority (&session->internals.priorities.mac, list);
133}
134
135/**
136 * gnutls_compression_set_priority - Sets the priority on the compression algorithms supported by gnutls.
137 * @session: is a #gnutls_session_t structure.
138 * @list: is a 0 terminated list of gnutls_compression_method_t elements.
139 *
140 * Sets the priority on the compression algorithms supported by gnutls.
141 * Priority is higher for elements specified before others.
142 * After specifying the algorithms you want, you must append a 0.
143 * Note that the priority is set on the client. The server does
144 * not use the algorithm's priority except for disabling
145 * algorithms that were not specified.
146 *
147 * TLS 1.0 does not define any compression algorithms except
148 * NULL. Other compression algorithms are to be considered
149 * as gnutls extensions.
150 *
151 * Returns 0 on success.
152 *
153 **/
154int
155gnutls_compression_set_priority (gnutls_session_t session, const int *list)
156{
157 return _set_priority (&session->internals.priorities.compression, list);
158}
159
160/**
161 * gnutls_protocol_set_priority - Sets the priority on the protocol versions supported by gnutls.
162 * @session: is a #gnutls_session_t structure.
163 * @list: is a 0 terminated list of gnutls_protocol_t elements.
164 *
165 * Sets the priority on the protocol versions supported by gnutls.
166 * This function actually enables or disables protocols. Newer protocol
167 * versions always have highest priority.
168 *
169 * Returns 0 on success.
170 *
171 **/
172int
173gnutls_protocol_set_priority (gnutls_session_t session, const int *list)
174{
175 int ret;
176
177 ret = _set_priority (&session->internals.priorities.protocol, list);
178
179 /* set the current version to the first in the chain.
180 * This will be overridden later.
181 */
182 if (list)
183 _gnutls_set_current_version (session, list[0]);
184
185 return ret;
186}
187
188/**
189 * gnutls_certificate_type_set_priority - Sets the priority on the certificate types supported by gnutls.
190 * @session: is a #gnutls_session_t structure.
191 * @list: is a 0 terminated list of gnutls_certificate_type_t elements.
192 *
193 * Sets the priority on the certificate types supported by gnutls.
194 * Priority is higher for elements specified before others.
195 * After specifying the types you want, you must append a 0.
196 * Note that the certificate type priority is set on the client.
197 * The server does not use the cert type priority except for disabling
198 * types that were not specified.
199 *
200 * Returns 0 on success.
201 *
202 **/
203int
204gnutls_certificate_type_set_priority (gnutls_session_t session,
205 const int *list)
206{
207#ifdef ENABLE_OPENPGP
208 return _set_priority (&session->internals.priorities.cert_type, list);
209
210#else
211
212 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
213
214#endif
215}
216
217static const int protocol_priority[] = { GNUTLS_TLS1_1,
218 GNUTLS_TLS1_0,
219 0
220};
221
222static const int cipher_priority_secure256[] = { GNUTLS_CIPHER_AES_256_CBC,
223 0
224};
225
226static const int kx_priority_secure[] = { GNUTLS_KX_RSA,
227 0
228};
229
230static const int mac_priority_secure[] = { GNUTLS_MAC_SHA1,
231 0
232};
233
234static int cert_type_priority[] = { GNUTLS_CRT_X509,
235 0
236};
237
238static const int comp_priority[] = { GNUTLS_COMP_NULL,
239 0
240};
241
242typedef void (rmadd_func) (priority_st * priority_list, int alg);
243
244/**
245 * gnutls_priority_set - Sets priorities for the cipher suites supported by gnutls.
246 * @session: is a #gnutls_session_t structure.
247 * @priority: is a #gnutls_priority_t structure.
248 *
249 * Sets the priorities to use on the ciphers, key exchange methods,
250 * macs and compression methods.
251 *
252 * On success 0 is returned.
253 *
254 **/
255int
256gnutls_priority_set (gnutls_session_t session, gnutls_priority_t priority)
257{
258 if (priority == NULL)
259 {
260 gnutls_assert ();
261 return GNUTLS_E_NO_CIPHER_SUITES;
262 }
263
264 memcpy (&session->internals.priorities, priority,
265 sizeof (struct gnutls_priority_st));
266
267 return 0;
268}
269
270/**
271 * gnutls_priority_init - Sets priorities for the cipher suites supported by gnutls.
272 * @priority_cache: is a #gnutls_prioritity_t structure.
273 * @priorities: is a string describing priorities
274 * @err_pos: In case of an error this will have the position in the string the error occured
275 *
276 * Sets priorities for the ciphers, key exchange methods, macs and
277 * compression methods. This is to avoid using the
278 * gnutls_*_priority() functions.
279 *
280 * The #priorities option allows you to specify a semi-colon
281 * separated list of the cipher priorities to enable.
282 *
283 * Unless the first keyword is "NONE" the defaults are:
284 * Protocols: TLS1.1, TLS1.0, and SSL3.0.
285 * Compression: NULL.
286 * Certificate types: X.509, OpenPGP.
287 *
288 * You can also use predefined sets of ciphersuites: "PERFORMANCE"
289 * all the "secure" ciphersuites are enabled, limited to 128 bit
290 * ciphers and sorted by terms of speed performance.
291 *
292 * "NORMAL" option enables all "secure" ciphersuites. The 256-bit ciphers
293 * are included as a fallback only. The ciphers are sorted by security margin.
294 *
295 * "SECURE128" flag enables all "secure" ciphersuites with ciphers up to
296 * 128 bits, sorted by security margin.
297 *
298 * "SECURE256" flag enables all "secure" ciphersuites including the 256 bit
299 * ciphers, sorted by security margin.
300 *
301 * "EXPORT" all the ciphersuites are enabled, including the
302 * low-security 40 bit ciphers.
303 *
304 * "NONE" nothing is enabled. This disables even protocols and
305 * compression methods.
306 *
307 * Special keywords:
308 * '!' or '-' appended with an algorithm will remove this algorithm.
309 * '+' appended with an algorithm will add this algorithm.
310 * '%COMPAT' will enable compatibility features for a server.
311 *
312 * To avoid collisions in order to specify a compression algorithm in
313 * this string you have to prefix it with "COMP-", protocol versions
314 * with "VERS-" and certificate types with "CTYPE-". All other
315 * algorithms don't need a prefix.
316 *
317 * For key exchange algorithms when in NORMAL or SECURE levels the
318 * perfect forward secrecy algorithms take precendence of the other
319 * protocols. In all cases all the supported key exchange algorithms
320 * are enabled (except for the RSA-EXPORT which is only enabled in
321 * EXPORT level).
322 *
323 * Note that although one can select very long key sizes (such as 256 bits)
324 * for symmetric algorithms, to actually increase security the public key
325 * algorithms have to use longer key sizes as well.
326 *
327 * Examples: "NORMAL:!AES-128-CBC",
328 * "EXPORT:!VERS-TLS1.0:+COMP-DEFLATE:+CTYPE-OPENPGP",
329 * "NONE:+VERS-TLS1.0:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL", "NORMAL",
330 * "NORMAL:%COMPAT".
331 *
332 * Returns: On syntax error GNUTLS_E_INVALID_REQUEST is returned and
333 * 0 on success.
334 **/
335int
336gnutls_priority_init (gnutls_priority_t * priority_cache,
337 const char *priorities, const char **err_pos)
338{
339 int broken_list_size, i, j;
340 char *darg;
341 int algo;
342
343 *priority_cache = gnutls_calloc (1, sizeof (struct gnutls_priority_st));
344 if (*priority_cache == NULL)
345 {
346 gnutls_assert ();
347 return GNUTLS_E_MEMORY_ERROR;
348 }
349
350 /* set mode to "SECURE256" */
351 _set_priority (&(*priority_cache)->protocol, protocol_priority);
352 _set_priority (&(*priority_cache)->cipher, cipher_priority_secure256);
353 _set_priority (&(*priority_cache)->kx, kx_priority_secure);
354 _set_priority (&(*priority_cache)->mac, mac_priority_secure);
355 _set_priority (&(*priority_cache)->cert_type, cert_type_priority);
356 _set_priority (&(*priority_cache)->compression, comp_priority);
357 (*priority_cache)->no_padding = 0;
358
359 return 0;
360}
361
362/**
363 * gnutls_priority_deinit - Deinitialize the priorities cache for the cipher suites supported by gnutls.
364 * @priority_cache: is a #gnutls_prioritity_t structure.
365 *
366 * Deinitializes the priority cache.
367 *
368 **/
369void
370gnutls_priority_deinit (gnutls_priority_t priority_cache)
371{
372 gnutls_free (priority_cache);
373}
374
375/**
376 * gnutls_priority_set_direct - Sets priorities for the cipher suites supported by gnutls.
377 * @session: is a #gnutls_session_t structure.
378 * @priorities: is a string describing priorities
379 * @err_pos: In case of an error this will have the position in the string the error occured
380 *
381 * Sets the priorities to use on the ciphers, key exchange methods,
382 * macs and compression methods. This function avoids keeping a
383 * priority cache and is used to directly set string priorities to a
384 * TLS session. For documentation check the gnutls_priority_init().
385 *
386 * On syntax error GNUTLS_E_INVALID_REQUEST is returned and 0 on success.
387 *
388 **/
389int
390gnutls_priority_set_direct (gnutls_session_t session,
391 const char *priorities, const char **err_pos)
392{
393 gnutls_priority_t prio;
394 int ret;
395
396 ret = gnutls_priority_init (&prio, priorities, err_pos);
397 if (ret < 0)
398 {
399 gnutls_assert ();
400 return ret;
401 }
402
403 ret = gnutls_priority_set (session, prio);
404 if (ret < 0)
405 {
406 gnutls_assert ();
407 return ret;
408 }
409
410 gnutls_priority_deinit (prio);
411
412 return 0;
413}
414
415/* Breaks a list of "xxx", "yyy", to a character array, of
416 * MAX_COMMA_SEP_ELEMENTS size; Note that the given string is modified.
417 */
418static void
419break_comma_list (char *etag,
420 char **broken_etag,
421 int *elements, int max_elements, char sep)
422{
423 char *p = etag;
424 if (sep == 0)
425 sep = ',';
426
427 *elements = 0;
428
429 do
430 {
431 broken_etag[*elements] = p;
432
433 (*elements)++;
434
435 p = strchr (p, sep);
436 if (p)
437 {
438 *p = 0;
439 p++; /* move to next entry and skip white
440 * space.
441 */
442 while (*p == ' ')
443 p++;
444 }
445 }
446 while (p != NULL && *elements < max_elements);
447}
448
449/**
450 * gnutls_set_default_priority - Sets some default priority on the cipher suites supported by gnutls.
451 * @session: is a #gnutls_session_t structure.
452 *
453 * Sets some default priority on the ciphers, key exchange methods,
454 * macs and compression methods.
455 *
456 * This is the same as calling:
457 *
458 * gnutls_priority_set_direct (session, "NORMAL", NULL);
459 *
460 * This function is kept around for backwards compatibility, but
461 * because of its wide use it is still fully supported. If you wish
462 * to allow users to provide a string that specify which ciphers to
463 * use (which is recommended), you should use
464 * gnutls_priority_set_direct() or gnutls_priority_set() instead.
465 *
466 * Returns 0 on success.
467 **/
468int
469gnutls_set_default_priority (gnutls_session_t session)
470{
471 return gnutls_priority_set_direct (session, "NORMAL", NULL);
472}
473
474/**
475 * gnutls_set_default_export_priority - Sets some default priority on the cipher suites supported by gnutls.
476 * @session: is a #gnutls_session_t structure.
477 *
478 * Sets some default priority on the ciphers, key exchange methods, macs
479 * and compression methods. This function also includes weak algorithms.
480 *
481 * This is the same as calling:
482 *
483 * gnutls_priority_set_direct (session, "EXPORT", NULL);
484 *
485 * This function is kept around for backwards compatibility, but
486 * because of its wide use it is still fully supported. If you wish
487 * to allow users to provide a string that specify which ciphers to
488 * use (which is recommended), you should use
489 * gnutls_priority_set_direct() or gnutls_priority_set() instead.
490 *
491 * Returns 0 on success.
492 **/
493int
494gnutls_set_default_export_priority (gnutls_session_t session)
495{
496 return gnutls_priority_set_direct (session, "EXPORT", NULL);
497}
diff --git a/src/daemon/https/tls/gnutls_record.c b/src/daemon/https/tls/gnutls_record.c
new file mode 100644
index 00000000..cacbdecc
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_record.c
@@ -0,0 +1,1204 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* Functions that are record layer specific, are included in this file.
26 */
27
28#include "gnutls_int.h"
29#include "gnutls_errors.h"
30#include "debug.h"
31#include "gnutls_compress.h"
32#include "gnutls_cipher.h"
33#include "gnutls_buffers.h"
34#include "gnutls_handshake.h"
35#include "gnutls_hash_int.h"
36#include "gnutls_cipher_int.h"
37#include "gnutls_algorithms.h"
38#include "gnutls_db.h"
39#include "gnutls_auth_int.h"
40#include "gnutls_num.h"
41#include "gnutls_record.h"
42#include "gnutls_datum.h"
43#include "ext_max_record.h"
44#include <gnutls_state.h>
45#include <gnutls_dh.h>
46
47/**
48 * gnutls_protocol_get_version - Returns the version of the currently used protocol
49 * @session: is a #gnutls_session_t structure.
50 *
51 * Returns: the version of the currently used protocol.
52 **/
53gnutls_protocol_t gnutls_protocol_get_version(gnutls_session_t session)
54{
55 return session->security_parameters.version;
56}
57
58void _gnutls_set_current_version(gnutls_session_t session,
59 gnutls_protocol_t version)
60{
61 session->security_parameters.version = version;
62}
63
64/**
65 * gnutls_transport_set_lowat - Used to set the lowat value in order for select to check for pending data.
66 * @session: is a #gnutls_session_t structure.
67 * @num: is the low water value.
68 *
69 * Used to set the lowat value in order for select to check if there
70 * are pending data to socket buffer. Used only if you have changed
71 * the default low water value (default is 1). Normally you will not
72 * need that function. This function is only useful if using
73 * berkeley style sockets. Otherwise it must be called and set lowat
74 * to zero.
75 **/
76void gnutls_transport_set_lowat(gnutls_session_t session,
77 int num)
78{
79 session->internals.lowat = num;
80}
81
82/**
83 * gnutls_record_disable_padding - Used to disabled padding in TLS 1.0 and above
84 * @session: is a #gnutls_session_t structure.
85 *
86 * Used to disabled padding in TLS 1.0 and above. Normally you do
87 * not need to use this function, but there are buggy clients that
88 * complain if a server pads the encrypted data. This of course will
89 * disable protection against statistical attacks on the data.
90 *
91 * Normally only servers that require maximum compatibility with everything
92 * out there, need to call this function.
93 **/
94void gnutls_record_disable_padding(gnutls_session_t session)
95{
96 session->internals.priorities.no_padding = 1;
97}
98
99/**
100 * gnutls_transport_set_ptr - Used to set first argument of the transport functions
101 * @session: is a #gnutls_session_t structure.
102 * @ptr: is the value.
103 *
104 * Used to set the first argument of the transport function (like
105 * PUSH and PULL). In berkeley style sockets this function will set
106 * the connection handle.
107 **/
108void gnutls_transport_set_ptr(gnutls_session_t session,
109 gnutls_transport_ptr_t ptr)
110{
111 session->internals.transport_recv_ptr = ptr;
112 session->internals.transport_send_ptr = ptr;
113}
114
115/**
116 * gnutls_transport_set_ptr2 - Used to set first argument of the transport functions
117 * @session: is a #gnutls_session_t structure.
118 * @recv_ptr: is the value for the pull function
119 * @send_ptr: is the value for the push function
120 *
121 * Used to set the first argument of the transport function (like
122 * PUSH and PULL). In berkeley style sockets this function will set
123 * the connection handle. With this function you can use two
124 * different pointers for receiving and sending.
125 **/
126void gnutls_transport_set_ptr2(gnutls_session_t session,
127 gnutls_transport_ptr_t recv_ptr,
128 gnutls_transport_ptr_t send_ptr)
129{
130 session->internals.transport_send_ptr = send_ptr;
131 session->internals.transport_recv_ptr = recv_ptr;
132}
133
134/**
135 * gnutls_transport_get_ptr - Used to return the first argument of the transport functions
136 * @session: is a #gnutls_session_t structure.
137 *
138 * Used to get the first argument of the transport function (like
139 * PUSH and PULL). This must have been set using
140 * gnutls_transport_set_ptr().
141 *
142 * Returns: first argument of the transport function.
143 **/
144gnutls_transport_ptr_t gnutls_transport_get_ptr(gnutls_session_t session)
145{
146 return session->internals.transport_recv_ptr;
147}
148
149/**
150 * gnutls_transport_get_ptr2 - Used to return the first argument of the transport functions
151 * @session: is a #gnutls_session_t structure.
152 * @recv_ptr: will hold the value for the pull function
153 * @send_ptr: will hold the value for the push function
154 *
155 * Used to get the arguments of the transport functions (like PUSH
156 * and PULL). These should have been set using
157 * gnutls_transport_set_ptr2().
158 **/
159void gnutls_transport_get_ptr2(gnutls_session_t session,
160 gnutls_transport_ptr_t * recv_ptr,
161 gnutls_transport_ptr_t * send_ptr)
162{
163
164 *recv_ptr = session->internals.transport_recv_ptr;
165 *send_ptr = session->internals.transport_send_ptr;
166}
167
168/**
169 * gnutls_bye - This function terminates the current TLS/SSL connection.
170 * @session: is a #gnutls_session_t structure.
171 * @how: is an integer
172 *
173 * Terminates the current TLS/SSL connection. The connection should
174 * have been initiated using gnutls_handshake(). @how should be one
175 * of %GNUTLS_SHUT_RDWR, %GNUTLS_SHUT_WR.
176 *
177 * In case of %GNUTLS_SHUT_RDWR then the TLS connection gets
178 * terminated and further receives and sends will be disallowed. If
179 * the return value is zero you may continue using the connection.
180 * %GNUTLS_SHUT_RDWR actually sends an alert containing a close
181 * request and waits for the peer to reply with the same message.
182 *
183 * In case of %GNUTLS_SHUT_WR then the TLS connection gets terminated
184 * and further sends will be disallowed. In order to reuse the
185 * connection you should wait for an EOF from the peer.
186 * %GNUTLS_SHUT_WR sends an alert containing a close request.
187 *
188 * Note that not all implementations will properly terminate a TLS
189 * connection. Some of them, usually for performance reasons, will
190 * terminate only the underlying transport layer, thus causing a
191 * transmission error to the peer. This error cannot be
192 * distinguished from a malicious party prematurely terminating the
193 * session, thus this behavior is not recommended.
194 *
195 * This function may also return %GNUTLS_E_AGAIN or
196 * %GNUTLS_E_INTERRUPTED; cf. gnutls_record_get_direction().
197 *
198 * Returns: %GNUTLS_E_SUCCESS on success, or an error code, see
199 * function documentation for entire semantics.
200 **/
201int gnutls_bye(gnutls_session_t session,
202 gnutls_close_request_t how)
203{
204 int ret = 0;
205
206 switch (STATE)
207 {
208 case STATE0:
209 case STATE60:
210 ret = _gnutls_io_write_flush(session);
211 STATE = STATE60;
212 if (ret < 0)
213 {
214 gnutls_assert ();
215 return ret;
216 }
217
218 case STATE61:
219 ret = gnutls_alert_send(session, GNUTLS_AL_WARNING, GNUTLS_A_CLOSE_NOTIFY);
220 STATE = STATE61;
221 if (ret < 0)
222 {
223 gnutls_assert ();
224 return ret;
225 }
226
227 case STATE62:
228 STATE = STATE62;
229 if (how == GNUTLS_SHUT_RDWR)
230 {
231 do
232 {
233 _gnutls_io_clear_peeked_data(session);
234 ret = _gnutls_recv_int(session, GNUTLS_ALERT, -1, NULL, 0);
235 } while (ret == GNUTLS_E_GOT_APPLICATION_DATA);
236
237 if (ret >= 0)
238 session->internals.may_not_read = 1;
239
240 if (ret < 0)
241 {
242 gnutls_assert ();
243 return ret;
244 }
245 }
246 STATE = STATE62;
247
248 break;
249 default:
250 gnutls_assert ()
251 ;
252 return GNUTLS_E_INTERNAL_ERROR;
253 }
254
255 STATE = STATE0;
256
257 session->internals.may_not_write = 1;
258 return 0;
259}
260
261inline static void session_invalidate(gnutls_session_t session)
262{
263 session->internals.valid_connection = VALID_FALSE;
264}
265
266inline static void session_unresumable(gnutls_session_t session)
267{
268 session->internals.resumable = RESUME_FALSE;
269}
270
271/* returns 0 if session is valid
272 */
273inline static int session_is_valid(gnutls_session_t session)
274{
275 if (session->internals.valid_connection == VALID_FALSE)
276 return GNUTLS_E_INVALID_SESSION;
277
278 return 0;
279}
280
281/* Copies the record version into the headers. The
282 * version must have 2 bytes at least.
283 */
284inline static void copy_record_version(gnutls_session_t session,
285 gnutls_handshake_description_t htype,
286 opaque version[2])
287{
288 gnutls_protocol_t lver;
289
290 if (htype != GNUTLS_HANDSHAKE_CLIENT_HELLO
291 || session->internals.default_record_version[0] == 0)
292 {
293 lver = gnutls_protocol_get_version(session);
294
295 version[0] = _gnutls_version_get_major(lver);
296 version[1] = _gnutls_version_get_minor(lver);
297 }
298 else
299 {
300 version[0] = session->internals.default_record_version[0];
301 version[1] = session->internals.default_record_version[1];
302 }
303}
304
305/* This function behaves exactly like write(). The only difference is
306 * that it accepts, the gnutls_session_t and the content_type_t of data to
307 * send (if called by the user the Content is specific)
308 * It is intended to transfer data, under the current session.
309 *
310 * Oct 30 2001: Removed capability to send data more than MAX_RECORD_SIZE.
311 * This makes the function much easier to read, and more error resistant
312 * (there were cases were the old function could mess everything up).
313 * --nmav
314 *
315 * This function may accept a NULL pointer for data, and 0 for size, if
316 * and only if the previous send was interrupted for some reason.
317 *
318 */
319ssize_t _gnutls_send_int(gnutls_session_t session,
320 content_type_t type,
321 gnutls_handshake_description_t htype,
322 const void *_data,
323 size_t sizeofdata)
324{
325 uint8_t *cipher;
326 int cipher_size;
327 int retval, ret;
328 int data2send_size;
329 uint8_t headers[5];
330 const uint8_t *data = _data;
331
332 /* Do not allow null pointer if the send buffer is empty.
333 * If the previous send was interrupted then a null pointer is
334 * ok, and means to resume.
335 */
336 if (session->internals.record_send_buffer.length == 0 && (sizeofdata == 0
337 && _data == NULL))
338 {
339 gnutls_assert ();
340 return GNUTLS_E_INVALID_REQUEST;
341 }
342
343 if (type != GNUTLS_ALERT) /* alert messages are sent anyway */
344 if (session_is_valid(session) || session->internals.may_not_write != 0)
345 {
346 gnutls_assert ();
347 return GNUTLS_E_INVALID_SESSION;
348 }
349
350 headers[0] = type;
351
352 /* Use the default record version, if it is
353 * set.
354 */
355 copy_record_version(session, htype, &headers[1]);
356
357 _gnutls_record_log
358 ("REC[%x]: Sending Packet[%d] %s(%d) with length: %d\n", session,
359 (int) _gnutls_uint64touint32 (&session->connection_state.
360 write_sequence_number),
361 _gnutls_packet2str (type), type, sizeofdata);
362
363 if (sizeofdata > MAX_RECORD_SEND_SIZE)
364 data2send_size = MAX_RECORD_SEND_SIZE;
365 else
366 data2send_size = sizeofdata;
367
368 /* Only encrypt if we don't have data to send
369 * from the previous run. - probably interrupted.
370 */
371 if (session->internals.record_send_buffer.length > 0)
372 {
373 ret = _gnutls_io_write_flush(session);
374 if (ret > 0)
375 cipher_size = ret;
376 else
377 cipher_size = 0;
378
379 cipher = NULL;
380
381 retval = session->internals.record_send_buffer_user_size;
382 }
383 else
384 {
385 /* now proceed to packet encryption
386 */
387 cipher_size = data2send_size + MAX_RECORD_OVERHEAD;cipher = gnutls_malloc (cipher_size);
388 if (cipher == NULL)
389 {
390 gnutls_assert ();
391 return GNUTLS_E_MEMORY_ERROR;
392 }
393
394 cipher_size =
395 _gnutls_encrypt (session, headers, RECORD_HEADER_SIZE, data,
396 data2send_size, cipher, cipher_size, type,
397 (session->internals.priorities.no_padding ==
398 0) ? 1 : 0);
399 if (cipher_size <= 0)
400 {
401 gnutls_assert ();
402 if (cipher_size == 0)
403 cipher_size = GNUTLS_E_ENCRYPTION_FAILED;
404 gnutls_free (cipher);
405 return cipher_size; /* error */
406 }
407
408 retval = data2send_size;
409 session->internals.record_send_buffer_user_size = data2send_size;
410
411 /* increase sequence number
412 */
413 if (_gnutls_uint64pp
414 (&session->connection_state.write_sequence_number) != 0)
415 {
416 session_invalidate (session);
417 gnutls_assert ();
418 gnutls_free (cipher);
419 return GNUTLS_E_RECORD_LIMIT_REACHED;
420 }
421
422 ret = _gnutls_io_write_buffered (session, cipher, cipher_size);
423 gnutls_free (cipher);
424 }
425
426 if (ret != cipher_size)
427 {
428 if (ret < 0 && gnutls_error_is_fatal (ret) == 0)
429 {
430 /* If we have sent any data then just return
431 * the error value. Do not invalidate the session.
432 */
433 gnutls_assert ();
434 return ret;
435 }
436
437 if (ret> 0)
438 {
439 gnutls_assert ();
440 ret = GNUTLS_E_INTERNAL_ERROR;
441 }
442 session_unresumable (session);
443 session->internals.may_not_write = 1;
444 gnutls_assert ();
445 return ret;
446 }
447
448 session->internals.record_send_buffer_user_size = 0;
449
450 _gnutls_record_log ("REC[%x]: Sent Packet[%d] %s(%d) with length: %d\n",
451 session,
452 (int) _gnutls_uint64touint32 (&session->
453 connection_state.
454 write_sequence_number),
455 _gnutls_packet2str (type), type, cipher_size);
456
457 return retval;
458}
459
460/* This function is to be called if the handshake was successfully
461 * completed. This sends a Change Cipher Spec packet to the peer.
462 */
463ssize_t _gnutls_send_change_cipher_spec(gnutls_session_t session,
464 int again)
465{
466 static const opaque data[1] =
467 {
468 GNUTLS_TYPE_CHANGE_CIPHER_SPEC };
469
470 _gnutls_handshake_log ("REC[%x]: Sent ChangeCipherSpec\n", session);
471
472 if (again == 0)
473 return _gnutls_send_int(session, GNUTLS_CHANGE_CIPHER_SPEC, -1, data, 1);
474 else
475 {
476 return _gnutls_io_write_flush(session);
477 }
478}
479
480inline static int check_recv_type(content_type_t recv_type)
481{
482 switch (recv_type)
483 {
484 case GNUTLS_CHANGE_CIPHER_SPEC:
485 case GNUTLS_ALERT:
486 case GNUTLS_HANDSHAKE:
487 case GNUTLS_APPLICATION_DATA:
488 case GNUTLS_INNER_APPLICATION:
489 return 0;
490 default:
491 gnutls_assert ()
492 ;
493 return GNUTLS_A_UNEXPECTED_MESSAGE;
494 }
495
496}
497
498/* Checks if there are pending data in the record buffers. If there are
499 * then it copies the data.
500 */
501static int check_buffers(gnutls_session_t session,
502 content_type_t type,
503 opaque * data,
504 int sizeofdata)
505{
506 if ((type == GNUTLS_APPLICATION_DATA || type == GNUTLS_HANDSHAKE || type
507 == GNUTLS_INNER_APPLICATION) && _gnutls_record_buffer_get_size(type,
508 session)
509 > 0)
510 {
511 int ret, ret2;
512 ret = _gnutls_record_buffer_get(type, session, data, sizeofdata);
513 if (ret < 0)
514 {
515 gnutls_assert ();
516 return ret;
517 }
518
519 /* if the buffer just got empty */
520 if (_gnutls_record_buffer_get_size(type, session) == 0)
521 {
522 if ((ret2 = _gnutls_io_clear_peeked_data(session)) < 0)
523 {
524 gnutls_assert ();
525 return ret2;
526 }
527 }
528
529 return ret;
530 }
531
532 return 0;
533}
534
535/* Checks the record headers and returns the length, version and
536 * content type.
537 */
538static int record_check_headers(gnutls_session_t session,
539 uint8_t headers[RECORD_HEADER_SIZE],
540 content_type_t type,
541 gnutls_handshake_description_t htype,
542 /*output */content_type_t * recv_type,
543 opaque version[2],
544 uint16_t * length,
545 uint16_t * header_size)
546{
547
548 /* Read the first two bytes to determine if this is a
549 * version 2 message
550 */
551
552 if (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO && type == GNUTLS_HANDSHAKE
553 && headers[0] > 127)
554 {
555
556 /* if msb set and expecting handshake message
557 * it should be SSL 2 hello
558 */
559 version[0] = 3; /* assume SSL 3.0 */
560 version[1] = 0;
561
562 *length = (((headers[0] & 0x7f) << 8)) | headers[1];
563
564 /* SSL 2.0 headers */
565 *header_size = 2;
566 *recv_type = GNUTLS_HANDSHAKE; /* we accept only v2 client hello
567 */
568
569 /* in order to assist the handshake protocol.
570 * V2 compatibility is a mess.
571 */
572 session->internals.v2_hello = *length;
573
574 _gnutls_record_log ("REC[%x]: V2 packet received. Length: %d\n",
575 session, *length);
576
577 }
578 else
579 {
580 /* version 3.x */
581 *recv_type = headers[0];
582 version[0] = headers[1];
583 version[1] = headers[2];
584
585 /* No DECR_LEN, since headers has enough size.
586 */
587 *length = _gnutls_read_uint16(&headers[3]);
588 }
589
590 return 0;
591}
592
593/* Here we check if the advertized version is the one we
594 * negotiated in the handshake.
595 */
596inline static int record_check_version(gnutls_session_t session,
597 gnutls_handshake_description_t htype,
598 opaque version[2])
599{
600 if (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO)
601 {
602 /* Reject hello packets with major version higher than 3.
603 */
604 if (version[0] > 3)
605 {
606 gnutls_assert ();
607 _gnutls_record_log
608 ("REC[%x]: INVALID VERSION PACKET: (%d) %d.%d\n", session,
609 htype, version[0], version[1]);
610 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
611 }
612 }
613 else if (htype != GNUTLS_HANDSHAKE_SERVER_HELLO
614 && gnutls_protocol_get_version(session)
615 != _gnutls_version_get(version[0], version[1]))
616 {
617 /* Reject record packets that have a different version than the
618 * one negotiated. Note that this version is not protected by any
619 * mac. I don't really think that this check serves any purpose.
620 */
621 gnutls_assert ();
622 _gnutls_record_log ("REC[%x]: INVALID VERSION PACKET: (%d) %d.%d\n",
623 session, htype, version[0], version[1]);
624
625 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
626 }
627
628 return 0;
629}
630
631/* This function will check if the received record type is
632 * the one we actually expect.
633 */
634static int record_check_type(gnutls_session_t session,
635 content_type_t recv_type,
636 content_type_t type,
637 gnutls_handshake_description_t htype,
638 opaque * data,
639 int data_size)
640{
641
642 int ret;
643
644 if ((recv_type == type) && (type == GNUTLS_APPLICATION_DATA || type
645 == GNUTLS_HANDSHAKE || type == GNUTLS_INNER_APPLICATION))
646 {
647 _gnutls_record_buffer_put(type, session, (void *) data, data_size);
648 }
649 else
650 {
651 switch (recv_type)
652 {
653 case GNUTLS_ALERT:
654
655 _gnutls_record_log
656 ("REC[%x]: Alert[%d|%d] - %s - was received\n", session,
657 data[0], data[1], gnutls_alert_get_name ((int) data[1]));
658
659 session->internals.last_alert = data[1];
660
661 /* if close notify is received and
662 * the alert is not fatal
663 */
664 if (data[1] == GNUTLS_A_CLOSE_NOTIFY && data[0] != GNUTLS_AL_FATAL)
665 {
666 /* If we have been expecting for an alert do
667 */
668 session->internals.read_eof = 1;
669 return GNUTLS_E_INT_RET_0; /* EOF */
670 }
671 else
672 {
673
674 /* if the alert is FATAL or WARNING
675 * return the apropriate message
676 */
677
678 gnutls_assert ();
679 ret = GNUTLS_E_WARNING_ALERT_RECEIVED;
680 if (data[0] == GNUTLS_AL_FATAL)
681 {
682 session_unresumable(session);
683 session_invalidate(session);
684 ret = GNUTLS_E_FATAL_ALERT_RECEIVED;
685 }
686
687 return ret;
688 }
689 break;
690
691 case GNUTLS_CHANGE_CIPHER_SPEC:
692 /* this packet is now handled in the recv_int()
693 * function
694 */
695 gnutls_assert ()
696 ;
697
698 return GNUTLS_E_UNEXPECTED_PACKET;
699
700 case GNUTLS_APPLICATION_DATA:
701 /* even if data is unexpected put it into the buffer */
702 if ((ret = _gnutls_record_buffer_put(recv_type, session, (void *) data,
703 data_size)) < 0)
704 {
705 gnutls_assert ();
706 return ret;
707 }
708
709 /* the got_application data is only returned
710 * if expecting client hello (for rehandshake
711 * reasons). Otherwise it is an unexpected packet
712 */
713 if (type == GNUTLS_ALERT || (htype == GNUTLS_HANDSHAKE_CLIENT_HELLO
714 && type == GNUTLS_HANDSHAKE))
715 return GNUTLS_E_GOT_APPLICATION_DATA;
716 else
717 {
718 gnutls_assert ();
719 return GNUTLS_E_UNEXPECTED_PACKET;
720 }
721
722 break;
723 case GNUTLS_HANDSHAKE:
724 /* This is legal if HELLO_REQUEST is received - and we are a client.
725 * If we are a server, a client may initiate a renegotiation at any time.
726 */
727 if (session->security_parameters.entity == GNUTLS_SERVER)
728 {
729 gnutls_assert ();
730 return GNUTLS_E_REHANDSHAKE;
731 }
732
733 /* If we are already in a handshake then a Hello
734 * Request is illegal. But here we don't really care
735 * since this message will never make it up here.
736 */
737
738 /* So we accept it */
739 return _gnutls_recv_hello_request(session, data, data_size);
740
741 break;
742 case GNUTLS_INNER_APPLICATION:
743 /* even if data is unexpected put it into the buffer */
744 if ((ret = _gnutls_record_buffer_put(recv_type, session, (void *) data,
745 data_size)) < 0)
746 {
747 gnutls_assert ();
748 return ret;
749 }
750 gnutls_assert ()
751 ;
752 return GNUTLS_E_UNEXPECTED_PACKET;
753 break;
754 default:
755
756 _gnutls_record_log
757 ("REC[%x]: Received Unknown packet %d expecting %d\n",
758 session, recv_type, type);
759
760 gnutls_assert ()
761 ;
762 return GNUTLS_E_INTERNAL_ERROR;
763 }
764 }
765
766 return 0;
767
768}
769
770/* This function will return the internal (per session) temporary
771 * recv buffer. If the buffer was not initialized before it will
772 * also initialize it.
773 */
774inline static int get_temp_recv_buffer(gnutls_session_t session,
775 gnutls_datum_t * tmp)
776{
777 size_t max_record_size;
778
779 if (gnutls_compression_get(session) != GNUTLS_COMP_NULL)
780 max_record_size = MAX_RECORD_RECV_SIZE + EXTRA_COMP_SIZE;
781 else
782 max_record_size = MAX_RECORD_RECV_SIZE;
783
784 /* We allocate MAX_RECORD_RECV_SIZE length
785 * because we cannot predict the output data by the record
786 * packet length (due to compression).
787 */
788
789 if (max_record_size > session->internals.recv_buffer.size
790 || session->internals.recv_buffer.data == NULL)
791 {
792
793 /* Initialize the internal buffer.
794 */
795 session->internals.recv_buffer.data
796 = gnutls_realloc(session->internals.recv_buffer.data, max_record_size);
797
798 if (session->internals.recv_buffer.data == NULL)
799 {
800 gnutls_assert ();
801 return GNUTLS_E_MEMORY_ERROR;
802 }
803
804 session->internals.recv_buffer.size = max_record_size;
805 }
806
807 tmp->data = session->internals.recv_buffer.data;
808 tmp->size = session->internals.recv_buffer.size;
809
810 return 0;
811}
812
813#define MAX_EMPTY_PACKETS_SEQUENCE 4
814
815/* This function behaves exactly like read(). The only difference is
816 * that it accepts the gnutls_session_t and the content_type_t of data to
817 * receive (if called by the user the Content is Userdata only)
818 * It is intended to receive data, under the current session.
819 *
820 * The gnutls_handshake_description_t was introduced to support SSL V2.0 client hellos.
821 */
822ssize_t _gnutls_recv_int(gnutls_session_t session,
823 content_type_t type,
824 gnutls_handshake_description_t htype,
825 opaque * data,
826 size_t sizeofdata)
827{
828 gnutls_datum_t tmp;
829 int decrypted_length;
830 opaque version[2];
831 uint8_t *headers;
832 content_type_t recv_type;
833 uint16_t length;
834 uint8_t *ciphertext;
835 uint8_t *recv_data;
836 int ret, ret2;
837 uint16_t header_size;
838 int empty_packet = 0;
839
840 if (type != GNUTLS_ALERT && (sizeofdata == 0 || data == NULL))
841 {
842 return GNUTLS_E_INVALID_REQUEST;
843 }
844
845 begin:
846
847 if (empty_packet > MAX_EMPTY_PACKETS_SEQUENCE)
848 {
849 gnutls_assert ();
850 return GNUTLS_E_TOO_MANY_EMPTY_PACKETS;
851 }
852
853 if (session->internals.read_eof != 0)
854 {
855 /* if we have already read an EOF
856 */
857 return 0;
858 }
859 else if (session_is_valid(session) != 0 || session->internals.may_not_read
860 != 0)
861 {
862 gnutls_assert ();
863 return GNUTLS_E_INVALID_SESSION;
864 }
865
866 /* If we have enough data in the cache do not bother receiving
867 * a new packet. (in order to flush the cache)
868 */
869 ret = check_buffers(session, type, data, sizeofdata);
870 if (ret != 0)
871 return ret;
872
873 /* default headers for TLS 1.0
874 */
875 header_size = RECORD_HEADER_SIZE;
876
877 if ((ret = _gnutls_io_read_buffered(session, &headers, header_size, -1))
878 != header_size)
879 {
880 if (ret < 0 && gnutls_error_is_fatal(ret) == 0)
881 return ret;
882
883 session_invalidate(session);
884 if (type == GNUTLS_ALERT)
885 {
886 gnutls_assert ();
887 return 0; /* we were expecting close notify */
888 }
889 session_unresumable(session);
890 gnutls_assert ();
891 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
892 }
893
894 if ((ret = record_check_headers(session, headers, type, htype, &recv_type,
895 version, &length, &header_size)) < 0)
896 {
897 gnutls_assert ();
898 return ret;
899 }
900
901 /* Here we check if the Type of the received packet is
902 * ok.
903 */
904 if ((ret = check_recv_type(recv_type)) < 0)
905 {
906 gnutls_assert ();
907 return ret;
908 }
909
910 /* Here we check if the advertized version is the one we
911 * negotiated in the handshake.
912 */
913 if ((ret = record_check_version(session, htype, version)) < 0)
914 {
915 gnutls_assert ();
916 session_invalidate(session);
917 return ret;
918 }
919
920 _gnutls_record_log
921 ("REC[%x]: Expected Packet[%d] %s(%d) with length: %d\n", session,
922 (int) _gnutls_uint64touint32 (&session->connection_state.
923 read_sequence_number),
924 _gnutls_packet2str (type), type, sizeofdata);
925 _gnutls_record_log
926 ("REC[%x]: Received Packet[%d] %s(%d) with length: %d\n", session,
927 (int) _gnutls_uint64touint32 (&session->connection_state.
928 read_sequence_number),
929 _gnutls_packet2str (recv_type), recv_type, length);
930
931 if (length > MAX_RECV_SIZE)
932 {
933 _gnutls_record_log
934 ("REC[%x]: FATAL ERROR: Received packet with length: %d\n",
935 session, length);
936
937 session_unresumable(session);
938 session_invalidate(session);
939 gnutls_assert ();
940 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
941 }
942
943 /* check if we have that data into buffer.
944 */
945 if ((ret = _gnutls_io_read_buffered(session, &recv_data,
946 header_size + length, recv_type))
947 != header_size + length)
948 {
949 if (ret < 0 && gnutls_error_is_fatal(ret) == 0)
950 return ret;
951
952 session_unresumable(session);
953 session_invalidate(session);
954 gnutls_assert ();
955 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
956 }
957
958 /* ok now we are sure that we can read all the data - so
959 * move on !
960 */
961 _gnutls_io_clear_read_buffer(session);
962 ciphertext = &recv_data[header_size];
963
964 ret = get_temp_recv_buffer(session, &tmp);
965 if (ret < 0)
966 {
967 gnutls_assert ();
968 return ret;
969 }
970
971 /* decrypt the data we got.
972 */
973 ret = _gnutls_decrypt(session, ciphertext, length, tmp.data, tmp.size,
974 recv_type);
975 if (ret < 0)
976 {
977 session_unresumable(session);
978 session_invalidate(session);
979 gnutls_assert ();
980 return ret;
981 }
982 decrypted_length = ret;
983
984 /* Check if this is a CHANGE_CIPHER_SPEC
985 */
986 if (type == GNUTLS_CHANGE_CIPHER_SPEC && recv_type
987 == GNUTLS_CHANGE_CIPHER_SPEC)
988 {
989
990 _gnutls_record_log
991 ("REC[%x]: ChangeCipherSpec Packet was received\n", session);
992
993 if ((size_t) ret != sizeofdata)
994 { /* sizeofdata should be 1 */
995 gnutls_assert ();
996 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
997 }
998 memcpy(data, tmp.data, sizeofdata);
999
1000 return ret;
1001 }
1002
1003 _gnutls_record_log
1004 ("REC[%x]: Decrypted Packet[%d] %s(%d) with length: %d\n", session,
1005 (int) _gnutls_uint64touint32 (&session->connection_state.
1006 read_sequence_number),
1007 _gnutls_packet2str (recv_type), recv_type, decrypted_length);
1008
1009 /* increase sequence number
1010 */
1011 if (_gnutls_uint64pp(&session->connection_state.read_sequence_number) != 0)
1012 {
1013 session_invalidate(session);
1014 gnutls_assert ();
1015 return GNUTLS_E_RECORD_LIMIT_REACHED;
1016 }
1017
1018 ret = record_check_type(session, recv_type, type, htype, tmp.data,
1019 decrypted_length);
1020 if (ret < 0)
1021 {
1022 if (ret == GNUTLS_E_INT_RET_0)
1023 return 0;
1024 gnutls_assert ();
1025 return ret;
1026 }
1027
1028 /* Get Application data from buffer
1029 */
1030 if ((recv_type == type) && (type == GNUTLS_APPLICATION_DATA || type
1031 == GNUTLS_HANDSHAKE || type == GNUTLS_INNER_APPLICATION))
1032 {
1033
1034 ret = _gnutls_record_buffer_get(type, session, data, sizeofdata);
1035 if (ret < 0)
1036 {
1037 gnutls_assert ();
1038 return ret;
1039 }
1040
1041 /* if the buffer just got empty
1042 */
1043 if (_gnutls_record_buffer_get_size(type, session) == 0)
1044 {
1045 if ((ret2 = _gnutls_io_clear_peeked_data(session)) < 0)
1046 {
1047 gnutls_assert ();
1048 return ret2;
1049 }
1050 }
1051 }
1052 else
1053 {
1054 gnutls_assert ();
1055 return GNUTLS_E_UNEXPECTED_PACKET;
1056 /* we didn't get what we wanted to
1057 */
1058 }
1059
1060 /* (originally for) TLS 1.0 CBC protection.
1061 * Actually this code is called if we just received
1062 * an empty packet. An empty TLS packet is usually
1063 * sent to protect some vulnerabilities in the CBC mode.
1064 * In that case we go to the beginning and start reading
1065 * the next packet.
1066 */
1067 if (ret == 0)
1068 {
1069 empty_packet++;
1070 goto begin;
1071 }
1072
1073 return ret;
1074}
1075
1076/**
1077 * gnutls_record_send - sends to the peer the specified data
1078 * @session: is a #gnutls_session_t structure.
1079 * @data: contains the data to send
1080 * @sizeofdata: is the length of the data
1081 *
1082 * This function has the similar semantics with send(). The only
1083 * difference is that is accepts a GNUTLS session, and uses different
1084 * error codes.
1085 *
1086 * Note that if the send buffer is full, send() will block this
1087 * function. See the send() documentation for full information. You
1088 * can replace the default push function by using
1089 * gnutls_transport_set_ptr2() with a call to send() with a
1090 * MSG_DONTWAIT flag if blocking is a problem.
1091 *
1092 * If the EINTR is returned by the internal push function (the
1093 * default is send()} then %GNUTLS_E_INTERRUPTED will be returned. If
1094 * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must
1095 * call this function again, with the same parameters; alternatively
1096 * you could provide a %NULL pointer for data, and 0 for
1097 * size. cf. gnutls_record_get_direction().
1098 *
1099 * Returns: the number of bytes sent, or a negative error code. The
1100 * number of bytes sent might be less than @sizeofdata. The maximum
1101 * number of bytes this function can send in a single call depends on
1102 * the negotiated maximum record size.
1103 **/
1104ssize_t gnutls_record_send(gnutls_session_t session,
1105 const void *data,
1106 size_t sizeofdata)
1107{
1108 return _gnutls_send_int(session, GNUTLS_APPLICATION_DATA, -1, data,
1109 sizeofdata);
1110}
1111
1112/**
1113 * gnutls_record_recv - reads data from the TLS record protocol
1114 * @session: is a #gnutls_session_t structure.
1115 * @data: the buffer that the data will be read into
1116 * @sizeofdata: the number of requested bytes
1117 *
1118 * This function has the similar semantics with recv(). The only
1119 * difference is that is accepts a GNUTLS session, and uses different
1120 * error codes.
1121 *
1122 * In the special case that a server requests a renegotiation, the
1123 * client may receive an error code of %GNUTLS_E_REHANDSHAKE. This
1124 * message may be simply ignored, replied with an alert containing
1125 * NO_RENEGOTIATION, or replied with a new handshake, depending on
1126 * the client's will.
1127 *
1128 * If %EINTR is returned by the internal push function (the default
1129 * is recv()) then %GNUTLS_E_INTERRUPTED will be returned. If
1130 * %GNUTLS_E_INTERRUPTED or %GNUTLS_E_AGAIN is returned, you must
1131 * call this function again to get the data. See also
1132 * gnutls_record_get_direction().
1133 *
1134 * A server may also receive %GNUTLS_E_REHANDSHAKE when a client has
1135 * initiated a handshake. In that case the server can only initiate a
1136 * handshake or terminate the connection.
1137 *
1138 * Returns: the number of bytes received and zero on EOF. A negative
1139 * error code is returned in case of an error. The number of bytes
1140 * received might be less than @sizeofdata.
1141 **/
1142ssize_t gnutls_record_recv(gnutls_session_t session,
1143 void *data,
1144 size_t sizeofdata)
1145{
1146 return _gnutls_recv_int(session, GNUTLS_APPLICATION_DATA, -1, data,
1147 sizeofdata);
1148}
1149
1150/**
1151 * gnutls_record_get_max_size - returns the maximum record size
1152 * @session: is a #gnutls_session_t structure.
1153 *
1154 * This function returns the maximum record packet size in this
1155 * connection. The maximum record size is negotiated by the client
1156 * after the first handshake message.
1157 **/
1158size_t gnutls_record_get_max_size(gnutls_session_t session)
1159{
1160 /* Recv will hold the negotiated max record size
1161 * always.
1162 */
1163 return session->security_parameters.max_record_recv_size;
1164}
1165
1166/**
1167 * gnutls_record_set_max_size - sets the maximum record size
1168 * @session: is a #gnutls_session_t structure.
1169 * @size: is the new size
1170 *
1171 * This function sets the maximum record packet size in this
1172 * connection. This property can only be set to clients. The server
1173 * may choose not to accept the requested size.
1174 *
1175 * Acceptable values are 512(=2^9), 1024(=2^10), 2048(=2^11) and
1176 * 4096(=2^12). Returns 0 on success. The requested record size does
1177 * get in effect immediately only while sending data. The receive
1178 * part will take effect after a successful handshake.
1179 *
1180 * This function uses a TLS extension called 'max record size'. Not
1181 * all TLS implementations use or even understand this extension.
1182 **/
1183ssize_t gnutls_record_set_max_size(gnutls_session_t session,
1184 size_t size)
1185{
1186 ssize_t new_size;
1187
1188 if (session->security_parameters.entity == GNUTLS_SERVER)
1189 return GNUTLS_E_INVALID_REQUEST;
1190
1191 new_size = _gnutls_mre_record2num(size);
1192
1193 if (new_size < 0)
1194 {
1195 gnutls_assert ();
1196 return new_size;
1197 }
1198
1199 session->security_parameters.max_record_send_size = size;
1200
1201 session->internals.proposed_record_size = size;
1202
1203 return 0;
1204}
diff --git a/src/daemon/https/tls/gnutls_record.h b/src/daemon/https/tls/gnutls_record.h
new file mode 100644
index 00000000..5595f32a
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_record.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25ssize_t _gnutls_send_int (gnutls_session_t session, content_type_t type,
26 gnutls_handshake_description_t htype,
27 const void *data, size_t sizeofdata);
28ssize_t _gnutls_recv_int (gnutls_session_t session, content_type_t type,
29 gnutls_handshake_description_t, opaque * data,
30 size_t sizeofdata);
31ssize_t _gnutls_send_change_cipher_spec (gnutls_session_t session, int again);
32void gnutls_transport_set_lowat (gnutls_session_t session, int num);
diff --git a/src/daemon/https/tls/gnutls_rsa_export.c b/src/daemon/https/tls/gnutls_rsa_export.c
new file mode 100644
index 00000000..66fad085
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_rsa_export.c
@@ -0,0 +1,361 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file contains code for RSA temporary keys. These keys are
26 * only used in export cipher suites.
27 */
28
29#include <gnutls_int.h>
30#include <gnutls_errors.h>
31#include <gnutls_datum.h>
32#include <gnutls_rsa_export.h>
33#include "debug.h"
34/* x509 */
35#include "x509.h"
36#include "privkey.h"
37
38/* This function takes a number of bits and returns a supported
39 * number of bits. Ie a number of bits that we have a prime in the
40 * dh_primes structure.
41 */
42
43#define MAX_SUPPORTED_BITS 512
44
45/* returns e and m, depends on the requested bits.
46 * We only support limited key sizes.
47 */
48const mpi_t *
49_gnutls_rsa_params_to_mpi (gnutls_rsa_params_t rsa_params)
50{
51 if (rsa_params == NULL)
52 {
53 return NULL;
54 }
55
56 return rsa_params->params;
57
58}
59
60/* resarr will contain: modulus(0), public exponent(1), private exponent(2),
61 * prime1 - p (3), prime2 - q(4), u (5).
62 */
63int
64_gnutls_rsa_generate_params (mpi_t * resarr, int *resarr_len, int bits)
65{
66
67 int ret;
68 gcry_sexp_t parms, key, list;
69
70 ret = gcry_sexp_build (&parms, NULL, "(genkey(rsa(nbits %d)))", bits);
71 if (ret != 0)
72 {
73 gnutls_assert ();
74 return GNUTLS_E_INTERNAL_ERROR;
75 }
76
77 /* generate the RSA key */
78 ret = gcry_pk_genkey (&key, parms);
79 gcry_sexp_release (parms);
80
81 if (ret != 0)
82 {
83 gnutls_assert ();
84 return GNUTLS_E_INTERNAL_ERROR;
85 }
86
87 list = gcry_sexp_find_token (key, "n", 0);
88 if (list == NULL)
89 {
90 gnutls_assert ();
91 gcry_sexp_release (key);
92 return GNUTLS_E_INTERNAL_ERROR;
93 }
94
95 resarr[0] = gcry_sexp_nth_mpi (list, 1, 0);
96 gcry_sexp_release (list);
97
98 list = gcry_sexp_find_token (key, "e", 0);
99 if (list == NULL)
100 {
101 gnutls_assert ();
102 gcry_sexp_release (key);
103 return GNUTLS_E_INTERNAL_ERROR;
104 }
105
106 resarr[1] = gcry_sexp_nth_mpi (list, 1, 0);
107 gcry_sexp_release (list);
108
109 list = gcry_sexp_find_token (key, "d", 0);
110 if (list == NULL)
111 {
112 gnutls_assert ();
113 gcry_sexp_release (key);
114 return GNUTLS_E_INTERNAL_ERROR;
115 }
116
117 resarr[2] = gcry_sexp_nth_mpi (list, 1, 0);
118 gcry_sexp_release (list);
119
120 list = gcry_sexp_find_token (key, "p", 0);
121 if (list == NULL)
122 {
123 gnutls_assert ();
124 gcry_sexp_release (key);
125 return GNUTLS_E_INTERNAL_ERROR;
126 }
127
128 resarr[3] = gcry_sexp_nth_mpi (list, 1, 0);
129 gcry_sexp_release (list);
130
131
132 list = gcry_sexp_find_token (key, "q", 0);
133 if (list == NULL)
134 {
135 gnutls_assert ();
136 gcry_sexp_release (key);
137 return GNUTLS_E_INTERNAL_ERROR;
138 }
139
140 resarr[4] = gcry_sexp_nth_mpi (list, 1, 0);
141 gcry_sexp_release (list);
142
143
144 list = gcry_sexp_find_token (key, "u", 0);
145 if (list == NULL)
146 {
147 gnutls_assert ();
148 gcry_sexp_release (key);
149 return GNUTLS_E_INTERNAL_ERROR;
150 }
151
152 resarr[5] = gcry_sexp_nth_mpi (list, 1, 0);
153 gcry_sexp_release (list);
154
155 gcry_sexp_release (key);
156
157 _gnutls_dump_mpi ("n: ", resarr[0]);
158 _gnutls_dump_mpi ("e: ", resarr[1]);
159 _gnutls_dump_mpi ("d: ", resarr[2]);
160 _gnutls_dump_mpi ("p: ", resarr[3]);
161 _gnutls_dump_mpi ("q: ", resarr[4]);
162 _gnutls_dump_mpi ("u: ", resarr[5]);
163
164 *resarr_len = 6;
165
166 return 0;
167
168}
169
170
171/**
172 * gnutls_rsa_params_import_raw - This function will replace the old RSA parameters
173 * @rsa_params: Is a structure will hold the parameters
174 * @m: holds the modulus
175 * @e: holds the public exponent
176 * @d: holds the private exponent
177 * @p: holds the first prime (p)
178 * @q: holds the second prime (q)
179 * @u: holds the coefficient
180 *
181 * This function will replace the parameters in the given structure.
182 * The new parameters should be stored in the appropriate gnutls_datum.
183 *
184 **/
185int
186gnutls_rsa_params_import_raw (gnutls_rsa_params_t rsa_params,
187 const gnutls_datum_t * m,
188 const gnutls_datum_t * e,
189 const gnutls_datum_t * d,
190 const gnutls_datum_t * p,
191 const gnutls_datum_t * q,
192 const gnutls_datum_t * u)
193{
194 return gnutls_x509_privkey_import_rsa_raw (rsa_params, m, e, d, p, q, u);
195}
196
197/**
198 * gnutls_rsa_params_init - This function will initialize the temporary RSA parameters
199 * @rsa_params: Is a structure that will hold the parameters
200 *
201 * This function will initialize the temporary RSA parameters structure.
202 *
203 **/
204int
205gnutls_rsa_params_init (gnutls_rsa_params_t * rsa_params)
206{
207 int ret;
208
209 ret = gnutls_x509_privkey_init (rsa_params);
210 if (ret < 0)
211 {
212 gnutls_assert ();
213 return ret;
214 }
215
216 (*rsa_params)->crippled = 1;
217
218 return 0;
219}
220
221/**
222 * gnutls_rsa_params_deinit - This function will deinitialize the RSA parameters
223 * @rsa_params: Is a structure that holds the parameters
224 *
225 * This function will deinitialize the RSA parameters structure.
226 *
227 **/
228void
229gnutls_rsa_params_deinit (gnutls_rsa_params_t rsa_params)
230{
231 gnutls_x509_privkey_deinit (rsa_params);
232}
233
234/**
235 * gnutls_rsa_params_cpy - This function will copy an RSA parameters structure
236 * @dst: Is the destination structure, which should be initialized.
237 * @src: Is the source structure
238 *
239 * This function will copy the RSA parameters structure from source
240 * to destination.
241 *
242 **/
243int
244gnutls_rsa_params_cpy (gnutls_rsa_params_t dst, gnutls_rsa_params_t src)
245{
246 return gnutls_x509_privkey_cpy (dst, src);
247}
248
249/**
250 * gnutls_rsa_params_generate2 - This function will generate temporary RSA parameters
251 * @params: The structure where the parameters will be stored
252 * @bits: is the prime's number of bits
253 *
254 * This function will generate new temporary RSA parameters for use in
255 * RSA-EXPORT ciphersuites. This function is normally slow.
256 *
257 * Note that if the parameters are to be used in export cipher suites the
258 * bits value should be 512 or less.
259 * Also note that the generation of new RSA parameters is only useful
260 * to servers. Clients use the parameters sent by the server, thus it's
261 * no use calling this in client side.
262 *
263 **/
264int
265gnutls_rsa_params_generate2 (gnutls_rsa_params_t params, unsigned int bits)
266{
267 return gnutls_x509_privkey_generate (params, GNUTLS_PK_RSA, bits, 0);
268}
269
270/**
271 * gnutls_rsa_params_import_pkcs1 - This function will import RSA params from a pkcs1 structure
272 * @params: A structure where the parameters will be copied to
273 * @pkcs1_params: should contain a PKCS1 RSAPublicKey structure PEM or DER encoded
274 * @format: the format of params. PEM or DER.
275 *
276 * This function will extract the RSAPublicKey found in a PKCS1 formatted
277 * structure.
278 *
279 * If the structure is PEM encoded, it should have a header
280 * of "BEGIN RSA PRIVATE KEY".
281 *
282 * In case of failure a negative value will be returned, and
283 * 0 on success.
284 *
285 **/
286int
287gnutls_rsa_params_import_pkcs1 (gnutls_rsa_params_t params,
288 const gnutls_datum_t * pkcs1_params,
289 gnutls_x509_crt_fmt_t format)
290{
291 return gnutls_x509_privkey_import (params, pkcs1_params, format);
292}
293
294
295/**
296 * gnutls_rsa_params_export_pkcs1 - This function will export RSA params to a pkcs1 structure
297 * @params: Holds the RSA parameters
298 * @format: the format of output params. One of PEM or DER.
299 * @params_data: will contain a PKCS1 RSAPublicKey structure PEM or DER encoded
300 * @params_data_size: holds the size of params_data (and will be replaced by the actual size of parameters)
301 *
302 * This function will export the given RSA parameters to a PKCS1
303 * RSAPublicKey structure. If the buffer provided is not long enough to
304 * hold the output, then GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
305 *
306 * If the structure is PEM encoded, it will have a header
307 * of "BEGIN RSA PRIVATE KEY".
308 *
309 * In case of failure a negative value will be returned, and
310 * 0 on success.
311 *
312 **/
313int
314gnutls_rsa_params_export_pkcs1 (gnutls_rsa_params_t params,
315 gnutls_x509_crt_fmt_t format,
316 unsigned char *params_data,
317 size_t * params_data_size)
318{
319 return gnutls_x509_privkey_export (params, format,
320 params_data, params_data_size);
321}
322
323
324/**
325 * gnutls_rsa_params_export_raw - This function will export the RSA parameters
326 * @params: a structure that holds the rsa parameters
327 * @m: will hold the modulus
328 * @e: will hold the public exponent
329 * @d: will hold the private exponent
330 * @p: will hold the first prime (p)
331 * @q: will hold the second prime (q)
332 * @u: will hold the coefficient
333 * @bits: if non null will hold the prime's number of bits
334 *
335 * This function will export the RSA parameters found in the given
336 * structure. The new parameters will be allocated using
337 * gnutls_malloc() and will be stored in the appropriate datum.
338 *
339 **/
340int
341gnutls_rsa_params_export_raw (gnutls_rsa_params_t params,
342 gnutls_datum_t * m, gnutls_datum_t * e,
343 gnutls_datum_t * d, gnutls_datum_t * p,
344 gnutls_datum_t * q, gnutls_datum_t * u,
345 unsigned int *bits)
346{
347 int ret;
348
349 ret = gnutls_x509_privkey_export_rsa_raw (params, m, e, d, p, q, u);
350 if (ret < 0)
351 {
352 gnutls_assert ();
353 return ret;
354 }
355
356 if (bits)
357 *bits = _gnutls_mpi_get_nbits (params->params[3]);
358
359 return 0;
360
361}
diff --git a/src/daemon/https/tls/gnutls_rsa_export.h b/src/daemon/https/tls/gnutls_rsa_export.h
new file mode 100644
index 00000000..b39e5e93
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_rsa_export.h
@@ -0,0 +1,27 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25const mpi_t *_gnutls_rsa_params_to_mpi (gnutls_rsa_params_t);
26int _gnutls_peers_cert_less_512 (gnutls_session_t session);
27int _gnutls_rsa_generate_params (mpi_t * resarr, int *resarr_len, int bits);
diff --git a/src/daemon/https/tls/gnutls_session.c b/src/daemon/https/tls/gnutls_session.c
new file mode 100644
index 00000000..541cc699
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_session.c
@@ -0,0 +1,199 @@
1/*
2 * Copyright (C) 2000, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24#include "gnutls_int.h"
25#include "gnutls_errors.h"
26#include "debug.h"
27#include <gnutls_session_pack.h>
28#include <gnutls_datum.h>
29
30/**
31 * gnutls_session_get_data - Returns all session parameters.
32 * @session: is a #gnutls_session_t structure.
33 * @session_data: is a pointer to space to hold the session.
34 * @session_data_size: is the session_data's size, or it will be set by the function.
35 *
36 * Returns all session parameters, in order to support resuming.
37 * The client should call this, and keep the returned session, if he wants to
38 * resume that current version later by calling gnutls_session_set_data()
39 * This function must be called after a successful handshake.
40 *
41 * Resuming sessions is really useful and speedups connections after a succesful one.
42 **/
43int
44gnutls_session_get_data (gnutls_session_t session,
45 void *session_data, size_t * session_data_size)
46{
47
48 gnutls_datum_t psession;
49 int ret;
50
51 if (session->internals.resumable == RESUME_FALSE)
52 return GNUTLS_E_INVALID_SESSION;
53
54 psession.data = session_data;
55
56 ret = _gnutls_session_pack (session, &psession);
57 if (ret < 0)
58 {
59 gnutls_assert ();
60 return ret;
61 }
62 *session_data_size = psession.size;
63
64 if (psession.size > *session_data_size)
65 {
66 ret = GNUTLS_E_SHORT_MEMORY_BUFFER;
67 goto error;
68 }
69
70 if (session_data != NULL)
71 memcpy (session_data, psession.data, psession.size);
72
73 ret = 0;
74
75error:
76 _gnutls_free_datum (&psession);
77 return ret;
78}
79
80/**
81 * gnutls_session_get_data2 - Returns all session parameters.
82 * @session: is a #gnutls_session_t structure.
83 * @session_data: is a pointer to a datum that will hold the session.
84 *
85 * Returns all session parameters, in order to support resuming.
86 * The client should call this, and keep the returned session, if he wants to
87 * resume that current version later by calling gnutls_session_set_data()
88 * This function must be called after a successful handshake. The returned
89 * datum must be freed with gnutls_free().
90 *
91 * Resuming sessions is really useful and speedups connections after a succesful one.
92 **/
93int
94gnutls_session_get_data2 (gnutls_session_t session, gnutls_datum_t * data)
95{
96
97 int ret;
98
99 if (data == NULL)
100 {
101 return GNUTLS_E_INVALID_REQUEST;
102 }
103
104 if (session->internals.resumable == RESUME_FALSE)
105 return GNUTLS_E_INVALID_SESSION;
106
107 ret = _gnutls_session_pack (session, data);
108 if (ret < 0)
109 {
110 gnutls_assert ();
111 return ret;
112 }
113
114 return 0;
115}
116
117
118/**
119 * gnutls_session_get_id - Returns session id.
120 * @session: is a #gnutls_session_t structure.
121 * @session_id: is a pointer to space to hold the session id.
122 * @session_id_size: is the session id's size, or it will be set by the function.
123 *
124 * Returns the current session id. This can be used if you want to check if
125 * the next session you tried to resume was actually resumed.
126 * This is because resumed sessions have the same sessionID with the
127 * original session.
128 *
129 * Session id is some data set by the server, that identify the current session.
130 * In TLS 1.0 and SSL 3.0 session id is always less than 32 bytes.
131 *
132 * Returns zero on success.
133 **/
134int
135gnutls_session_get_id (gnutls_session_t session,
136 void *session_id, size_t * session_id_size)
137{
138 size_t given_session_id_size = *session_id_size;
139
140 *session_id_size = session->security_parameters.session_id_size;
141
142 /* just return the session size */
143 if (session_id == NULL)
144 {
145 return 0;
146 }
147
148 if (given_session_id_size < session->security_parameters.session_id_size)
149 {
150 return GNUTLS_E_SHORT_MEMORY_BUFFER;
151 }
152
153 memcpy (session_id, &session->security_parameters.session_id,
154 *session_id_size);
155
156 return 0;
157}
158
159/**
160 * gnutls_session_set_data - Sets all session parameters
161 * @session: is a #gnutls_session_t structure.
162 * @session_data: is a pointer to space to hold the session.
163 * @session_data_size: is the session's size
164 *
165 * Sets all session parameters, in order to resume a previously established
166 * session. The session data given must be the one returned by gnutls_session_get_data().
167 * This function should be called before gnutls_handshake().
168 *
169 * Keep in mind that session resuming is advisory. The server may
170 * choose not to resume the session, thus a full handshake will be
171 * performed.
172 *
173 * Returns a negative value on error.
174 *
175 **/
176int
177gnutls_session_set_data (gnutls_session_t session,
178 const void *session_data, size_t session_data_size)
179{
180 int ret;
181 gnutls_datum_t psession;
182
183 psession.data = (opaque *) session_data;
184 psession.size = session_data_size;
185
186 if (session_data == NULL || session_data_size == 0)
187 {
188 gnutls_assert ();
189 return GNUTLS_E_INVALID_REQUEST;
190 }
191 ret = _gnutls_session_unpack (session, &psession);
192 if (ret < 0)
193 {
194 gnutls_assert ();
195 return ret;
196 }
197
198 return 0;
199}
diff --git a/src/daemon/https/tls/gnutls_session.h b/src/daemon/https/tls/gnutls_session.h
new file mode 100644
index 00000000..dae99edc
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_session.h
@@ -0,0 +1,23 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
diff --git a/src/daemon/https/tls/gnutls_session_pack.c b/src/daemon/https/tls/gnutls_session_pack.c
new file mode 100644
index 00000000..f18fe97a
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_session_pack.c
@@ -0,0 +1,1204 @@
1/*
2 * Copyright (C) 2000, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* Contains functions that are supposed to pack and unpack session data,
26 * before and after they are sent to the database backend.
27 */
28
29#include <gnutls_int.h>
30#ifdef ENABLE_SRP
31# include <auth_srp.h>
32#endif
33#ifdef ENABLE_PSK
34# include <auth_psk.h>
35#endif
36#include <auth_anon.h>
37#include <auth_cert.h>
38#include <gnutls_errors.h>
39#include <gnutls_auth_int.h>
40#include <gnutls_session_pack.h>
41#include <gnutls_datum.h>
42#include <gnutls_num.h>
43
44#define PACK_HEADER_SIZE 1
45#define MAX_SEC_PARAMS 7+MAX_SRP_USERNAME+MAX_SERVER_NAME_EXTENSIONS*(3+MAX_SERVER_NAME_SIZE)+165
46static int pack_certificate_auth_info (gnutls_session_t,
47 gnutls_datum_t * packed_session);
48static int unpack_certificate_auth_info (gnutls_session_t,
49 const gnutls_datum_t *
50 packed_session);
51
52static int unpack_srp_auth_info (gnutls_session_t session,
53 const gnutls_datum_t * packed_session);
54static int pack_srp_auth_info (gnutls_session_t session,
55 gnutls_datum_t * packed_session);
56
57static int unpack_psk_auth_info (gnutls_session_t session,
58 const gnutls_datum_t * packed_session);
59static int pack_psk_auth_info (gnutls_session_t session,
60 gnutls_datum_t * packed_session);
61
62static int unpack_anon_auth_info (gnutls_session_t session,
63 const gnutls_datum_t * packed_session);
64static int pack_anon_auth_info (gnutls_session_t session,
65 gnutls_datum_t * packed_session);
66
67static int unpack_security_parameters (gnutls_session_t session,
68 const gnutls_datum_t * packed_session);
69static int pack_security_parameters (gnutls_session_t session,
70 gnutls_datum_t * packed_session);
71
72
73/* Since auth_info structures contain malloced data, this function
74 * is required in order to pack these structures in a vector in
75 * order to store them to the DB.
76 *
77 * packed_session will contain the session data.
78 *
79 * The data will be in a platform independent format.
80 */
81int
82_gnutls_session_pack (gnutls_session_t session,
83 gnutls_datum_t * packed_session)
84{
85 int ret;
86
87 if (packed_session == NULL)
88 {
89 gnutls_assert ();
90 return GNUTLS_E_INTERNAL_ERROR;
91 }
92
93
94 switch (gnutls_auth_get_type (session))
95 {
96#ifdef ENABLE_SRP
97 case GNUTLS_CRD_SRP:
98 ret = pack_srp_auth_info (session, packed_session);
99 if (ret < 0)
100 {
101 gnutls_assert ();
102 return ret;
103 }
104 break;
105#endif
106#ifdef ENABLE_PSK
107 case GNUTLS_CRD_PSK:
108 ret = pack_psk_auth_info (session, packed_session);
109 if (ret < 0)
110 {
111 gnutls_assert ();
112 return ret;
113 }
114 break;
115#endif
116#ifdef ENABLE_ANON
117 case GNUTLS_CRD_ANON:
118 ret = pack_anon_auth_info (session, packed_session);
119 if (ret < 0)
120 {
121 gnutls_assert ();
122 return ret;
123 }
124 break;
125#endif
126 case GNUTLS_CRD_CERTIFICATE:
127 ret = pack_certificate_auth_info (session, packed_session);
128 if (ret < 0)
129 {
130 gnutls_assert ();
131 return ret;
132 }
133 break;
134 default:
135 return GNUTLS_E_INTERNAL_ERROR;
136
137 }
138
139 /* Auth_info structures copied. Now copy security_parameters_st.
140 * packed_session must have allocated space for the security parameters.
141 */
142 ret = pack_security_parameters (session, packed_session);
143 if (ret < 0)
144 {
145 gnutls_assert ();
146 _gnutls_free_datum (packed_session);
147 return ret;
148 }
149
150 return 0;
151}
152
153
154/* Load session data from a buffer.
155 */
156int
157_gnutls_session_unpack (gnutls_session_t session,
158 const gnutls_datum_t * packed_session)
159{
160 int ret;
161
162 if (packed_session == NULL || packed_session->size == 0)
163 {
164 gnutls_assert ();
165 return GNUTLS_E_INTERNAL_ERROR;
166 }
167
168 if (_gnutls_get_auth_info (session) != NULL)
169 {
170 _gnutls_free_auth_info (session);
171 }
172
173 switch (packed_session->data[0])
174 {
175#ifdef ENABLE_SRP
176 case GNUTLS_CRD_SRP:
177 ret = unpack_srp_auth_info (session, packed_session);
178 if (ret < 0)
179 {
180 gnutls_assert ();
181 return ret;
182 }
183 break;
184#endif
185#ifdef ENABLE_PSK
186 case GNUTLS_CRD_PSK:
187 ret = unpack_psk_auth_info (session, packed_session);
188 if (ret < 0)
189 {
190 gnutls_assert ();
191 return ret;
192 }
193 break;
194#endif
195#ifdef ENABLE_ANON
196 case GNUTLS_CRD_ANON:
197 ret = unpack_anon_auth_info (session, packed_session);
198 if (ret < 0)
199 {
200 gnutls_assert ();
201 return ret;
202 }
203 break;
204#endif
205 case GNUTLS_CRD_CERTIFICATE:
206 ret = unpack_certificate_auth_info (session, packed_session);
207 if (ret < 0)
208 {
209 gnutls_assert ();
210 return ret;
211 }
212 break;
213 default:
214 gnutls_assert ();
215 return GNUTLS_E_INTERNAL_ERROR;
216
217 }
218
219 /* Auth_info structures copied. Now copy security_parameters_st.
220 * packed_session must have allocated space for the security parameters.
221 */
222 ret = unpack_security_parameters (session, packed_session);
223 if (ret < 0)
224 {
225 gnutls_assert ();
226 return ret;
227 }
228
229 return 0;
230}
231
232
233/* Format:
234 * 1 byte the credentials type
235 * 4 bytes the size of the whole structure
236 * DH stuff
237 * 2 bytes the size of secret key in bits
238 * 4 bytes the size of the prime
239 * x bytes the prime
240 * 4 bytes the size of the generator
241 * x bytes the generator
242 * 4 bytes the size of the public key
243 * x bytes the public key
244 * RSA stuff
245 * 4 bytes the size of the modulus
246 * x bytes the modulus
247 * 4 bytes the size of the exponent
248 * x bytes the exponent
249 * CERTIFICATES
250 * 4 bytes the length of the certificate list
251 * 4 bytes the size of first certificate
252 * x bytes the certificate
253 * and so on...
254 */
255static int
256pack_certificate_auth_info (gnutls_session_t session,
257 gnutls_datum_t * packed_session)
258{
259 unsigned int pos = 0, i;
260 int cert_size, pack_size;
261 cert_auth_info_t info = _gnutls_get_auth_info (session);
262
263 if (info)
264 {
265 cert_size = 4;
266
267 for (i = 0; i < info->ncerts; i++)
268 cert_size += 4 + info->raw_certificate_list[i].size;
269
270 pack_size = 2 + 4 + info->dh.prime.size +
271 4 + info->dh.generator.size + 4 + info->dh.public_key.size +
272 4 + info->rsa_export.modulus.size +
273 4 + info->rsa_export.exponent.size + cert_size;
274 }
275 else
276 pack_size = 0;
277
278 packed_session->size = PACK_HEADER_SIZE + pack_size + sizeof (uint32_t);
279
280 /* calculate the size and allocate the data.
281 */
282 packed_session->data =
283 gnutls_malloc (packed_session->size + MAX_SEC_PARAMS);
284
285 if (packed_session->data == NULL)
286 {
287 gnutls_assert ();
288 return GNUTLS_E_MEMORY_ERROR;
289 }
290
291 packed_session->data[0] = GNUTLS_CRD_CERTIFICATE;
292 _gnutls_write_uint32 (pack_size, &packed_session->data[PACK_HEADER_SIZE]);
293 pos += 4 + PACK_HEADER_SIZE;
294
295
296 if (pack_size > 0)
297 {
298
299 _gnutls_write_uint16 (info->dh.secret_bits, &packed_session->data[pos]);
300 pos += 2;
301
302 _gnutls_write_datum32 (&packed_session->data[pos], info->dh.prime);
303 pos += 4 + info->dh.prime.size;
304 _gnutls_write_datum32 (&packed_session->data[pos], info->dh.generator);
305 pos += 4 + info->dh.generator.size;
306 _gnutls_write_datum32 (&packed_session->data[pos], info->dh.public_key);
307 pos += 4 + info->dh.public_key.size;
308
309 _gnutls_write_datum32 (&packed_session->data[pos],
310 info->rsa_export.modulus);
311 pos += 4 + info->rsa_export.modulus.size;
312 _gnutls_write_datum32 (&packed_session->data[pos],
313 info->rsa_export.exponent);
314 pos += 4 + info->rsa_export.exponent.size;
315
316 _gnutls_write_uint32 (info->ncerts, &packed_session->data[pos]);
317 pos += 4;
318
319 for (i = 0; i < info->ncerts; i++)
320 {
321 _gnutls_write_datum32 (&packed_session->data[pos],
322 info->raw_certificate_list[i]);
323 pos += sizeof (uint32_t) + info->raw_certificate_list[i].size;
324 }
325 }
326
327 return 0;
328}
329
330
331/* Upack certificate info.
332 */
333static int
334unpack_certificate_auth_info (gnutls_session_t session,
335 const gnutls_datum_t * packed_session)
336{
337 int pos = 0, size, ret;
338 unsigned int i = 0, j;
339 size_t pack_size;
340 cert_auth_info_t info;
341
342 if (packed_session->data[0] != GNUTLS_CRD_CERTIFICATE)
343 {
344 gnutls_assert ();
345 return GNUTLS_E_INVALID_REQUEST;
346 }
347
348 pack_size = _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]);
349 pos += PACK_HEADER_SIZE + 4;
350
351 if (pack_size == 0)
352 return 0; /* nothing to be done */
353
354 /* a simple check for integrity */
355 if (pack_size + PACK_HEADER_SIZE + 4 > packed_session->size)
356 {
357 gnutls_assert ();
358 return GNUTLS_E_INVALID_REQUEST;
359 }
360
361 /* client and server have the same auth_info here
362 */
363 ret =
364 _gnutls_auth_info_set (session, GNUTLS_CRD_CERTIFICATE,
365 sizeof (cert_auth_info_st), 1);
366 if (ret < 0)
367 {
368 gnutls_assert ();
369 return ret;
370 }
371
372 info = _gnutls_get_auth_info (session);
373 if (info == NULL)
374 {
375 gnutls_assert ();
376 return GNUTLS_E_INTERNAL_ERROR;
377 }
378
379 info->dh.secret_bits = _gnutls_read_uint16 (&packed_session->data[pos]);
380 pos += 2;
381
382 size = _gnutls_read_uint32 (&packed_session->data[pos]);
383 pos += 4;
384 ret = _gnutls_set_datum (&info->dh.prime, &packed_session->data[pos], size);
385 if (ret < 0)
386 {
387 gnutls_assert ();
388 goto error;
389 }
390 pos += size;
391
392 size = _gnutls_read_uint32 (&packed_session->data[pos]);
393 pos += 4;
394 ret =
395 _gnutls_set_datum (&info->dh.generator, &packed_session->data[pos], size);
396 if (ret < 0)
397 {
398 gnutls_assert ();
399 goto error;
400 }
401 pos += size;
402
403 size = _gnutls_read_uint32 (&packed_session->data[pos]);
404 pos += 4;
405 ret =
406 _gnutls_set_datum (&info->dh.public_key, &packed_session->data[pos],
407 size);
408 if (ret < 0)
409 {
410 gnutls_assert ();
411 goto error;
412 }
413 pos += size;
414
415 size = _gnutls_read_uint32 (&packed_session->data[pos]);
416 pos += 4;
417 ret =
418 _gnutls_set_datum (&info->rsa_export.modulus,
419 &packed_session->data[pos], size);
420 if (ret < 0)
421 {
422 gnutls_assert ();
423 goto error;
424 }
425 pos += size;
426
427 size = _gnutls_read_uint32 (&packed_session->data[pos]);
428 pos += 4;
429 ret =
430 _gnutls_set_datum (&info->rsa_export.exponent,
431 &packed_session->data[pos], size);
432 if (ret < 0)
433 {
434 gnutls_assert ();
435 goto error;
436 }
437 pos += size;
438
439 info->ncerts = _gnutls_read_uint32 (&packed_session->data[pos]);
440 pos += 4;
441
442 if (info->ncerts > 0)
443 {
444 info->raw_certificate_list =
445 gnutls_calloc (1, sizeof (gnutls_datum_t) * info->ncerts);
446 if (info->raw_certificate_list == NULL)
447 {
448 gnutls_assert ();
449 ret = GNUTLS_E_MEMORY_ERROR;
450 goto error;
451 }
452 }
453
454 for (i = 0; i < info->ncerts; i++)
455 {
456 size = _gnutls_read_uint32 (&packed_session->data[pos]);
457 pos += sizeof (uint32_t);
458
459 ret =
460 _gnutls_set_datum (&info->raw_certificate_list[i],
461 &packed_session->data[pos], size);
462 pos += size;
463
464 if (ret < 0)
465 {
466 gnutls_assert ();
467 goto error;
468 }
469 }
470
471
472 return 0;
473
474error:
475 _gnutls_free_datum (&info->dh.prime);
476 _gnutls_free_datum (&info->dh.generator);
477 _gnutls_free_datum (&info->dh.public_key);
478
479 _gnutls_free_datum (&info->rsa_export.modulus);
480 _gnutls_free_datum (&info->rsa_export.exponent);
481
482 for (j = 0; j < i; j++)
483 _gnutls_free_datum (&info->raw_certificate_list[j]);
484
485 gnutls_free (info->raw_certificate_list);
486
487 return ret;
488
489}
490
491#ifdef ENABLE_SRP
492/* Packs the SRP session authentication data.
493 */
494
495/* Format:
496 * 1 byte the credentials type
497 * 4 bytes the size of the SRP username (x)
498 * x bytes the SRP username
499 */
500static int
501pack_srp_auth_info (gnutls_session_t session, gnutls_datum_t * packed_session)
502{
503 srp_server_auth_info_t info = _gnutls_get_auth_info (session);
504 int pack_size;
505
506 if (info && info->username)
507 pack_size = strlen (info->username) + 1; /* include the terminating null */
508 else
509 pack_size = 0;
510
511 packed_session->size = PACK_HEADER_SIZE + pack_size + sizeof (uint32_t);
512
513 /* calculate the size and allocate the data.
514 */
515 packed_session->data =
516 gnutls_malloc (packed_session->size + MAX_SEC_PARAMS);
517
518 if (packed_session->data == NULL)
519 {
520 gnutls_assert ();
521 return GNUTLS_E_MEMORY_ERROR;
522 }
523
524 packed_session->data[0] = GNUTLS_CRD_SRP;
525 _gnutls_write_uint32 (pack_size, &packed_session->data[PACK_HEADER_SIZE]);
526
527 if (pack_size > 0)
528 memcpy (&packed_session->data[PACK_HEADER_SIZE + sizeof (uint32_t)],
529 info->username, pack_size + 1);
530
531 return 0;
532}
533
534
535static int
536unpack_srp_auth_info (gnutls_session_t session,
537 const gnutls_datum_t * packed_session)
538{
539 size_t username_size;
540 int ret;
541 srp_server_auth_info_t info;
542
543 if (packed_session->data[0] != GNUTLS_CRD_SRP)
544 {
545 gnutls_assert ();
546 return GNUTLS_E_INVALID_REQUEST;
547 }
548
549 username_size =
550 _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]);
551
552 if (username_size == 0)
553 return 0; /* nothing to be done */
554
555 /* a simple check for integrity */
556 if (username_size + 4 + PACK_HEADER_SIZE > packed_session->size)
557 {
558 gnutls_assert ();
559 return GNUTLS_E_INVALID_REQUEST;
560 }
561
562 ret =
563 _gnutls_auth_info_set (session, GNUTLS_CRD_SRP,
564 sizeof (srp_server_auth_info_st), 1);
565 if (ret < 0)
566 {
567 gnutls_assert ();
568 return ret;
569 }
570
571 info = _gnutls_get_auth_info (session);
572 if (info == NULL)
573 {
574 gnutls_assert ();
575 return GNUTLS_E_INTERNAL_ERROR;
576 }
577
578 memcpy (info->username,
579 &packed_session->data[PACK_HEADER_SIZE + sizeof (uint32_t)],
580 username_size);
581
582 return 0;
583}
584#endif
585
586
587#ifdef ENABLE_ANON
588/* Packs the ANON session authentication data.
589 */
590
591/* Format:
592 * 1 byte the credentials type
593 * 4 bytes the size of the whole structure
594 * 2 bytes the size of secret key in bits
595 * 4 bytes the size of the prime
596 * x bytes the prime
597 * 4 bytes the size of the generator
598 * x bytes the generator
599 * 4 bytes the size of the public key
600 * x bytes the public key
601 */
602static int
603pack_anon_auth_info (gnutls_session_t session,
604 gnutls_datum_t * packed_session)
605{
606 anon_auth_info_t info = _gnutls_get_auth_info (session);
607 int pos = 0;
608 size_t pack_size;
609
610 if (info)
611 pack_size = 2 + 4 * 3 + info->dh.prime.size +
612 info->dh.generator.size + info->dh.public_key.size;
613 else
614 pack_size = 0;
615
616 packed_session->size = PACK_HEADER_SIZE + pack_size + sizeof (uint32_t);
617
618 /* calculate the size and allocate the data.
619 */
620 packed_session->data =
621 gnutls_malloc (packed_session->size + MAX_SEC_PARAMS);
622
623 if (packed_session->data == NULL)
624 {
625 gnutls_assert ();
626 return GNUTLS_E_MEMORY_ERROR;
627 }
628
629 packed_session->data[0] = GNUTLS_CRD_ANON;
630 _gnutls_write_uint32 (pack_size, &packed_session->data[PACK_HEADER_SIZE]);
631 pos += 4 + PACK_HEADER_SIZE;
632
633 if (pack_size > 0)
634 {
635 _gnutls_write_uint16 (info->dh.secret_bits, &packed_session->data[pos]);
636 pos += 2;
637
638 _gnutls_write_datum32 (&packed_session->data[pos], info->dh.prime);
639 pos += 4 + info->dh.prime.size;
640 _gnutls_write_datum32 (&packed_session->data[pos], info->dh.generator);
641 pos += 4 + info->dh.generator.size;
642 _gnutls_write_datum32 (&packed_session->data[pos], info->dh.public_key);
643 pos += 4 + info->dh.public_key.size;
644
645 }
646
647 return 0;
648}
649
650
651static int
652unpack_anon_auth_info (gnutls_session_t session,
653 const gnutls_datum_t * packed_session)
654{
655 size_t pack_size;
656 int pos = 0, size, ret;
657 anon_auth_info_t info;
658
659 if (packed_session->data[0] != GNUTLS_CRD_ANON)
660 {
661 gnutls_assert ();
662 return GNUTLS_E_INVALID_REQUEST;
663 }
664
665 pack_size = _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]);
666 pos += PACK_HEADER_SIZE + 4;
667
668
669 if (pack_size == 0)
670 return 0; /* nothing to be done */
671
672 /* a simple check for integrity */
673 if (pack_size + PACK_HEADER_SIZE + 4 > packed_session->size)
674 {
675 gnutls_assert ();
676 return GNUTLS_E_INVALID_REQUEST;
677 }
678
679 /* client and serer have the same auth_info here
680 */
681 ret =
682 _gnutls_auth_info_set (session, GNUTLS_CRD_ANON,
683 sizeof (anon_auth_info_st), 1);
684 if (ret < 0)
685 {
686 gnutls_assert ();
687 return ret;
688 }
689
690 info = _gnutls_get_auth_info (session);
691 if (info == NULL)
692 {
693 gnutls_assert ();
694 return GNUTLS_E_INTERNAL_ERROR;
695 }
696
697 info->dh.secret_bits = _gnutls_read_uint16 (&packed_session->data[pos]);
698 pos += 2;
699
700 size = _gnutls_read_uint32 (&packed_session->data[pos]);
701 pos += 4;
702 ret = _gnutls_set_datum (&info->dh.prime, &packed_session->data[pos], size);
703 if (ret < 0)
704 {
705 gnutls_assert ();
706 goto error;
707 }
708 pos += size;
709
710 size = _gnutls_read_uint32 (&packed_session->data[pos]);
711 pos += 4;
712 ret =
713 _gnutls_set_datum (&info->dh.generator, &packed_session->data[pos], size);
714 if (ret < 0)
715 {
716 gnutls_assert ();
717 goto error;
718 }
719 pos += size;
720
721 size = _gnutls_read_uint32 (&packed_session->data[pos]);
722 pos += 4;
723 ret =
724 _gnutls_set_datum (&info->dh.public_key, &packed_session->data[pos],
725 size);
726 if (ret < 0)
727 {
728 gnutls_assert ();
729 goto error;
730 }
731 pos += size;
732
733 return 0;
734
735error:
736 _gnutls_free_datum (&info->dh.prime);
737 _gnutls_free_datum (&info->dh.generator);
738 _gnutls_free_datum (&info->dh.public_key);
739 return ret;
740}
741#endif /* ANON */
742
743#ifdef ENABLE_PSK
744/* Packs the PSK session authentication data.
745 */
746
747/* Format:
748 * 1 byte the credentials type
749 * 4 bytes the size of the whole structure
750 * 4 bytes the size of the PSK username (x)
751 * x bytes the PSK username
752 * 2 bytes the size of secret key in bits
753 * 4 bytes the size of the prime
754 * x bytes the prime
755 * 4 bytes the size of the generator
756 * x bytes the generator
757 * 4 bytes the size of the public key
758 * x bytes the public key
759 */
760static int
761pack_psk_auth_info (gnutls_session_t session, gnutls_datum_t * packed_session)
762{
763 psk_auth_info_t info;
764 int pack_size, username_size = 0, pos;
765
766 info = _gnutls_get_auth_info (session);
767
768 if (info)
769 {
770 username_size = strlen (info->username) + 1; /* include the terminating null */
771 pack_size = username_size +
772 2 + 4 * 3 + info->dh.prime.size + info->dh.generator.size +
773 info->dh.public_key.size;
774 }
775 else
776 pack_size = 0;
777
778 packed_session->size = PACK_HEADER_SIZE + pack_size + sizeof (uint32_t);
779
780 /* calculate the size and allocate the data.
781 */
782 packed_session->data =
783 gnutls_malloc (packed_session->size + MAX_SEC_PARAMS);
784
785 if (packed_session->data == NULL)
786 {
787 gnutls_assert ();
788 return GNUTLS_E_MEMORY_ERROR;
789 }
790
791 pos = 0;
792
793 packed_session->data[pos] = GNUTLS_CRD_PSK;
794 pos++;
795
796 _gnutls_write_uint32 (pack_size, &packed_session->data[pos]);
797 pos += 4;
798
799
800 if (pack_size > 0)
801 {
802 _gnutls_write_uint32 (username_size, &packed_session->data[pos]);
803 pos += 4;
804
805 memcpy (&packed_session->data[pos], info->username, username_size);
806 pos += username_size;
807
808 _gnutls_write_uint16 (info->dh.secret_bits, &packed_session->data[pos]);
809 pos += 2;
810
811 _gnutls_write_datum32 (&packed_session->data[pos], info->dh.prime);
812 pos += 4 + info->dh.prime.size;
813 _gnutls_write_datum32 (&packed_session->data[pos], info->dh.generator);
814 pos += 4 + info->dh.generator.size;
815 _gnutls_write_datum32 (&packed_session->data[pos], info->dh.public_key);
816 pos += 4 + info->dh.public_key.size;
817
818 }
819
820
821 return 0;
822}
823
824static int
825unpack_psk_auth_info (gnutls_session_t session,
826 const gnutls_datum_t * packed_session)
827{
828 size_t username_size;
829 size_t pack_size;
830 int pos = 0, size, ret;
831 psk_auth_info_t info;
832
833 if (packed_session->data[0] != GNUTLS_CRD_PSK)
834 {
835 gnutls_assert ();
836 return GNUTLS_E_INVALID_REQUEST;
837 }
838
839 pack_size = _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]);
840 pos += PACK_HEADER_SIZE + 4;
841
842
843 if (pack_size == 0)
844 return 0; /* nothing to be done */
845
846 /* a simple check for integrity */
847 if (pack_size + PACK_HEADER_SIZE + 4 > packed_session->size)
848 {
849 gnutls_assert ();
850 return GNUTLS_E_INVALID_REQUEST;
851 }
852
853 /* client and serer have the same auth_info here
854 */
855 ret =
856 _gnutls_auth_info_set (session, GNUTLS_CRD_PSK,
857 sizeof (psk_auth_info_st), 1);
858 if (ret < 0)
859 {
860 gnutls_assert ();
861 return ret;
862 }
863
864 info = _gnutls_get_auth_info (session);
865 if (info == NULL)
866 {
867 gnutls_assert ();
868 return GNUTLS_E_INTERNAL_ERROR;
869 }
870
871 username_size = _gnutls_read_uint32 (&packed_session->data[pos]);
872 pos += 4;
873
874 memcpy (info->username, &packed_session->data[pos], username_size);
875 pos += username_size;
876
877 info->dh.secret_bits = _gnutls_read_uint16 (&packed_session->data[pos]);
878 pos += 2;
879
880 size = _gnutls_read_uint32 (&packed_session->data[pos]);
881 pos += 4;
882 ret = _gnutls_set_datum (&info->dh.prime, &packed_session->data[pos], size);
883 if (ret < 0)
884 {
885 gnutls_assert ();
886 goto error;
887 }
888 pos += size;
889
890 size = _gnutls_read_uint32 (&packed_session->data[pos]);
891 pos += 4;
892 ret =
893 _gnutls_set_datum (&info->dh.generator, &packed_session->data[pos], size);
894 if (ret < 0)
895 {
896 gnutls_assert ();
897 goto error;
898 }
899 pos += size;
900
901 size = _gnutls_read_uint32 (&packed_session->data[pos]);
902 pos += 4;
903 ret =
904 _gnutls_set_datum (&info->dh.public_key, &packed_session->data[pos],
905 size);
906 if (ret < 0)
907 {
908 gnutls_assert ();
909 goto error;
910 }
911 pos += size;
912
913 return 0;
914
915error:
916 _gnutls_free_datum (&info->dh.prime);
917 _gnutls_free_datum (&info->dh.generator);
918 _gnutls_free_datum (&info->dh.public_key);
919 return ret;
920}
921#endif
922
923
924/* Packs the security parameters.
925 */
926
927/* Format:
928 * 4 bytes the total security data size
929 * 1 byte the entity type (client/server)
930 * 1 byte the key exchange algorithm used
931 * 1 byte the read cipher algorithm
932 * 1 byte the read mac algorithm
933 * 1 byte the read compression algorithm
934 *
935 * 1 byte the write cipher algorithm
936 * 1 byte the write mac algorithm
937 * 1 byte the write compression algorithm
938 *
939 * 1 byte the certificate type
940 * 1 byte the protocol version
941 *
942 * 2 bytes the cipher suite
943 *
944 * 48 bytes the master secret
945 *
946 * 32 bytes the client random
947 * 32 bytes the server random
948 *
949 * 1 byte the session ID size
950 * x bytes the session ID (32 bytes max)
951 *
952 * 4 bytes a timestamp
953 * -------------------
954 * MAX: 165 bytes
955 *
956 * EXTENSIONS:
957 * 2 bytes the record send size
958 * 2 bytes the record recv size
959 *
960 * 1 byte the SRP username size
961 * x bytes the SRP username (MAX_SRP_USERNAME)
962 *
963 * 2 bytes the number of server name extensions (up to MAX_SERVER_NAME_EXTENSIONS)
964 * 1 byte the first name type
965 * 2 bytes the size of the first name
966 * x bytes the first name (MAX_SERVER_NAME_SIZE)
967 * and so on...
968 *
969 * --------------------
970 * MAX: 7+MAX_SRP_USERNAME+MAX_SERVER_NAME_EXTENSIONS*(3+MAX_SERVER_NAME_SIZE)
971 */
972static int
973pack_security_parameters (gnutls_session_t session,
974 gnutls_datum_t * packed_session)
975{
976 int pos = 0;
977 size_t len, init, i;
978
979 /* move after the auth info stuff.
980 */
981 init =
982 _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]) + 4 +
983 PACK_HEADER_SIZE;
984
985 pos = init + 4; /* make some space to write later the size */
986
987 packed_session->data[pos++] = session->security_parameters.entity;
988 packed_session->data[pos++] = session->security_parameters.kx_algorithm;
989 packed_session->data[pos++] =
990 session->security_parameters.read_bulk_cipher_algorithm;
991 packed_session->data[pos++] =
992 session->security_parameters.read_mac_algorithm;
993 packed_session->data[pos++] =
994 session->security_parameters.read_compression_algorithm;
995 packed_session->data[pos++] =
996 session->security_parameters.write_bulk_cipher_algorithm;
997 packed_session->data[pos++] =
998 session->security_parameters.write_mac_algorithm;
999 packed_session->data[pos++] =
1000 session->security_parameters.write_compression_algorithm;
1001 packed_session->data[pos++] =
1002 session->security_parameters.current_cipher_suite.suite[0];
1003 packed_session->data[pos++] =
1004 session->security_parameters.current_cipher_suite.suite[1];
1005
1006 packed_session->data[pos++] = session->security_parameters.cert_type;
1007 packed_session->data[pos++] = session->security_parameters.version;
1008
1009 memcpy (&packed_session->data[pos],
1010 session->security_parameters.master_secret, TLS_MASTER_SIZE);
1011 pos += TLS_MASTER_SIZE;
1012
1013 memcpy (&packed_session->data[pos],
1014 session->security_parameters.client_random, TLS_RANDOM_SIZE);
1015 pos += TLS_RANDOM_SIZE;
1016 memcpy (&packed_session->data[pos],
1017 session->security_parameters.server_random, TLS_RANDOM_SIZE);
1018 pos += TLS_RANDOM_SIZE;
1019
1020 packed_session->data[pos++] = session->security_parameters.session_id_size;
1021 memcpy (&packed_session->data[pos], session->security_parameters.session_id,
1022 session->security_parameters.session_id_size);
1023 pos += session->security_parameters.session_id_size;
1024
1025 _gnutls_write_uint32 (session->security_parameters.timestamp,
1026 &packed_session->data[pos]);
1027 pos += 4;
1028
1029 /* Extensions */
1030 _gnutls_write_uint16 (session->security_parameters.max_record_send_size,
1031 &packed_session->data[pos]);
1032 pos += 2;
1033
1034 _gnutls_write_uint16 (session->security_parameters.max_record_recv_size,
1035 &packed_session->data[pos]);
1036 pos += 2;
1037
1038 /* SRP */
1039 len =
1040 strlen ((char *) session->security_parameters.extensions.srp_username);
1041 packed_session->data[pos++] = len;
1042 memcpy (&packed_session->data[pos],
1043 session->security_parameters.extensions.srp_username, len);
1044 pos += len;
1045
1046 _gnutls_write_uint16 (session->security_parameters.extensions.
1047 server_names_size, &packed_session->data[pos]);
1048 pos += 2;
1049
1050 for (i = 0; i < session->security_parameters.extensions.server_names_size;
1051 i++)
1052 {
1053 packed_session->data[pos++] =
1054 session->security_parameters.extensions.server_names[i].type;
1055 _gnutls_write_uint16 (session->security_parameters.extensions.
1056 server_names[i].name_length,
1057 &packed_session->data[pos]);
1058 pos += 2;
1059
1060 memcpy (&packed_session->data[pos],
1061 session->security_parameters.extensions.server_names[i].name,
1062 session->security_parameters.extensions.server_names[i].
1063 name_length);
1064 pos +=
1065 session->security_parameters.extensions.server_names[i].name_length;
1066 }
1067
1068 /* write the total size */
1069 _gnutls_write_uint32 (pos - init - 4, &packed_session->data[init]);
1070 packed_session->size += pos - init;
1071
1072 return 0;
1073}
1074
1075
1076static int
1077unpack_security_parameters (gnutls_session_t session,
1078 const gnutls_datum_t * packed_session)
1079{
1080 size_t pack_size, init, i;
1081 int pos = 0, len;
1082 time_t timestamp = time (0);
1083
1084
1085 /* skip the auth info stuff */
1086 init =
1087 _gnutls_read_uint32 (&packed_session->data[PACK_HEADER_SIZE]) + 4 +
1088 PACK_HEADER_SIZE;
1089
1090 pos = init;
1091
1092 pack_size = _gnutls_read_uint32 (&packed_session->data[pos]);
1093 pos += 4;
1094
1095
1096 if (pack_size == 0)
1097 return GNUTLS_E_INVALID_REQUEST;
1098
1099 /* a simple check for integrity */
1100 if (pack_size > MAX_SEC_PARAMS)
1101 {
1102 gnutls_assert ();
1103 return GNUTLS_E_INVALID_REQUEST;
1104 }
1105
1106 session->internals.resumed_security_parameters.entity =
1107 packed_session->data[pos++];
1108 session->internals.resumed_security_parameters.kx_algorithm =
1109 packed_session->data[pos++];
1110 session->internals.resumed_security_parameters.read_bulk_cipher_algorithm =
1111 packed_session->data[pos++];
1112 session->internals.resumed_security_parameters.read_mac_algorithm =
1113 packed_session->data[pos++];
1114 session->internals.resumed_security_parameters.read_compression_algorithm =
1115 packed_session->data[pos++];
1116 session->internals.resumed_security_parameters.write_bulk_cipher_algorithm =
1117 packed_session->data[pos++];
1118 session->internals.resumed_security_parameters.write_mac_algorithm =
1119 packed_session->data[pos++];
1120 session->internals.resumed_security_parameters.write_compression_algorithm =
1121 packed_session->data[pos++];
1122 session->internals.resumed_security_parameters.current_cipher_suite.
1123 suite[0] = packed_session->data[pos++];
1124 session->internals.resumed_security_parameters.current_cipher_suite.
1125 suite[1] = packed_session->data[pos++];
1126
1127 session->internals.resumed_security_parameters.cert_type =
1128 packed_session->data[pos++];
1129 session->internals.resumed_security_parameters.version =
1130 packed_session->data[pos++];
1131
1132 memcpy (session->internals.resumed_security_parameters.master_secret,
1133 &packed_session->data[pos], TLS_MASTER_SIZE);
1134 pos += TLS_MASTER_SIZE;
1135
1136 memcpy (session->internals.resumed_security_parameters.client_random,
1137 &packed_session->data[pos], TLS_RANDOM_SIZE);
1138 pos += TLS_RANDOM_SIZE;
1139 memcpy (session->internals.resumed_security_parameters.server_random,
1140 &packed_session->data[pos], TLS_RANDOM_SIZE);
1141 pos += TLS_RANDOM_SIZE;
1142
1143 session->internals.resumed_security_parameters.session_id_size =
1144 packed_session->data[pos++];
1145 memcpy (session->internals.resumed_security_parameters.session_id,
1146 &packed_session->data[pos],
1147 session->internals.resumed_security_parameters.session_id_size);
1148 pos += session->internals.resumed_security_parameters.session_id_size;
1149
1150 session->internals.resumed_security_parameters.timestamp =
1151 _gnutls_read_uint32 (&packed_session->data[pos]);
1152 pos += 4;
1153
1154 if (timestamp - session->internals.resumed_security_parameters.timestamp >
1155 session->internals.expire_time
1156 || session->internals.resumed_security_parameters.timestamp > timestamp)
1157 {
1158 gnutls_assert ();
1159 return GNUTLS_E_EXPIRED;
1160 }
1161
1162 /* Extensions */
1163 session->internals.resumed_security_parameters.max_record_send_size =
1164 _gnutls_read_uint16 (&packed_session->data[pos]);
1165 pos += 2;
1166
1167 session->internals.resumed_security_parameters.max_record_recv_size =
1168 _gnutls_read_uint16 (&packed_session->data[pos]);
1169 pos += 2;
1170
1171
1172 /* SRP */
1173 len = packed_session->data[pos++]; /* srp username length */
1174 memcpy (session->internals.resumed_security_parameters.extensions.
1175 srp_username, &packed_session->data[pos], len);
1176 session->internals.resumed_security_parameters.extensions.
1177 srp_username[len] = 0;
1178 pos += len;
1179
1180 session->internals.resumed_security_parameters.extensions.
1181 server_names_size = _gnutls_read_uint16 (&packed_session->data[pos]);
1182 pos += 2;
1183 for (i = 0;
1184 i <
1185 session->internals.resumed_security_parameters.extensions.
1186 server_names_size; i++)
1187 {
1188 session->internals.resumed_security_parameters.extensions.
1189 server_names[i].type = packed_session->data[pos++];
1190 session->internals.resumed_security_parameters.extensions.
1191 server_names[i].name_length =
1192 _gnutls_read_uint16 (&packed_session->data[pos]);
1193 pos += 2;
1194
1195 memcpy (session->internals.resumed_security_parameters.extensions.
1196 server_names[i].name, &packed_session->data[pos],
1197 session->internals.resumed_security_parameters.extensions.
1198 server_names[i].name_length);
1199 pos +=
1200 session->internals.resumed_security_parameters.extensions.
1201 server_names[i].name_length;
1202 }
1203 return 0;
1204}
diff --git a/src/daemon/https/tls/gnutls_session_pack.h b/src/daemon/https/tls/gnutls_session_pack.h
new file mode 100644
index 00000000..93dd32de
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_session_pack.h
@@ -0,0 +1,28 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25int _gnutls_session_pack (gnutls_session_t session,
26 gnutls_datum_t * packed_session);
27int _gnutls_session_unpack (gnutls_session_t session,
28 const gnutls_datum_t * packed_session);
diff --git a/src/daemon/https/tls/gnutls_sig.c b/src/daemon/https/tls/gnutls_sig.c
new file mode 100644
index 00000000..0456438f
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_sig.c
@@ -0,0 +1,473 @@
1/*
2 * Copyright (C) 2001, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_errors.h>
27#include <x509_b64.h>
28#include <auth_cert.h>
29#include <gnutls_cert.h>
30#include <libtasn1.h>
31#include <gnutls_datum.h>
32#include <gnutls_mpi.h>
33#include <gnutls_global.h>
34#include <gnutls_pk.h>
35#include <debug.h>
36#include <gnutls_buffers.h>
37#include <gnutls_sig.h>
38#include <gnutls_kx.h>
39
40static int _gnutls_tls_sign (gnutls_session_t session,
41 gnutls_cert * cert,
42 gnutls_privkey * pkey,
43 const gnutls_datum_t * hash_concat,
44 gnutls_datum_t * signature);
45
46/* Generates a signature of all the previous sent packets in the
47 * handshake procedure. (20040227: now it works for SSL 3.0 as well)
48 */
49int
50_gnutls_tls_sign_hdata (gnutls_session_t session,
51 gnutls_cert * cert,
52 gnutls_privkey * pkey, gnutls_datum_t * signature)
53{
54 gnutls_datum_t dconcat;
55 int ret;
56 opaque concat[36];
57 mac_hd_t td_md5;
58 mac_hd_t td_sha;
59 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
60
61 td_sha = _gnutls_hash_copy (session->internals.handshake_mac_handle_sha);
62 if (td_sha == NULL)
63 {
64 gnutls_assert ();
65 return GNUTLS_E_HASH_FAILED;
66 }
67
68 if (ver == GNUTLS_SSL3)
69 {
70 ret = _gnutls_generate_master (session, 1);
71 if (ret < 0)
72 {
73 gnutls_assert ();
74 return ret;
75 }
76
77 _gnutls_mac_deinit_ssl3_handshake (td_sha, &concat[16],
78 session->security_parameters.
79 master_secret, TLS_MASTER_SIZE);
80 }
81 else
82 _gnutls_hash_deinit (td_sha, &concat[16]);
83
84 switch (cert->subject_pk_algorithm)
85 {
86 case GNUTLS_PK_RSA:
87 td_md5 =
88 _gnutls_hash_copy (session->internals.handshake_mac_handle_md5);
89 if (td_md5 == NULL)
90 {
91 gnutls_assert ();
92 return GNUTLS_E_HASH_FAILED;
93 }
94
95 if (ver == GNUTLS_SSL3)
96 _gnutls_mac_deinit_ssl3_handshake (td_md5, concat,
97 session->security_parameters.
98 master_secret, TLS_MASTER_SIZE);
99 else
100 _gnutls_hash_deinit (td_md5, concat);
101
102 dconcat.data = concat;
103 dconcat.size = 36;
104 break;
105 default:
106 gnutls_assert ();
107 return GNUTLS_E_INTERNAL_ERROR;
108 }
109 ret = _gnutls_tls_sign (session, cert, pkey, &dconcat, signature);
110 if (ret < 0)
111 {
112 gnutls_assert ();
113 }
114
115 return ret;
116}
117
118/* Generates a signature of all the random data and the parameters.
119 * Used in DHE_* ciphersuites.
120 */
121int
122_gnutls_tls_sign_params (gnutls_session_t session,
123 gnutls_cert * cert,
124 gnutls_privkey * pkey,
125 gnutls_datum_t * params, gnutls_datum_t * signature)
126{
127 gnutls_datum_t dconcat;
128 int ret;
129 mac_hd_t td_sha;
130 opaque concat[36];
131 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
132
133 td_sha = _gnutls_hash_init (GNUTLS_MAC_SHA1);
134 if (td_sha == NULL)
135 {
136 gnutls_assert ();
137 return GNUTLS_E_HASH_FAILED;
138 }
139
140 _gnutls_hash (td_sha, session->security_parameters.client_random,
141 TLS_RANDOM_SIZE);
142 _gnutls_hash (td_sha, session->security_parameters.server_random,
143 TLS_RANDOM_SIZE);
144 _gnutls_hash (td_sha, params->data, params->size);
145
146 switch (cert->subject_pk_algorithm)
147 {
148 case GNUTLS_PK_RSA:
149 if (ver < GNUTLS_TLS1_2)
150 {
151 mac_hd_t td_md5 = _gnutls_hash_init (GNUTLS_MAC_MD5);
152 if (td_md5 == NULL)
153 {
154 gnutls_assert ();
155 return GNUTLS_E_HASH_FAILED;
156 }
157
158 _gnutls_hash (td_md5, session->security_parameters.client_random,
159 TLS_RANDOM_SIZE);
160 _gnutls_hash (td_md5, session->security_parameters.server_random,
161 TLS_RANDOM_SIZE);
162 _gnutls_hash (td_md5, params->data, params->size);
163
164 _gnutls_hash_deinit (td_md5, concat);
165 _gnutls_hash_deinit (td_sha, &concat[16]);
166
167 dconcat.size = 36;
168 }
169 else
170 {
171#if 1
172 /* Use NULL parameters. */
173 memcpy (concat,
174 "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14",
175 15);
176 _gnutls_hash_deinit (td_sha, &concat[15]);
177 dconcat.size = 35;
178#else
179 /* No parameters field. */
180 memcpy (concat,
181 "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14", 13);
182 _gnutls_hash_deinit (td_sha, &concat[13]);
183 dconcat.size = 33;
184#endif
185 }
186 dconcat.data = concat;
187 break;
188 default:
189 gnutls_assert ();
190 _gnutls_hash_deinit (td_sha, NULL);
191 return GNUTLS_E_INTERNAL_ERROR;
192 }
193 ret = _gnutls_tls_sign (session, cert, pkey, &dconcat, signature);
194 if (ret < 0)
195 {
196 gnutls_assert ();
197 }
198
199 return ret;
200
201}
202
203/* This will create a PKCS1 or DSA signature, using the given parameters, and the
204 * given data. The output will be allocated and be put in signature.
205 */
206int
207_gnutls_sign (gnutls_pk_algorithm_t algo,
208 mpi_t * params,
209 int params_size,
210 const gnutls_datum_t * data, gnutls_datum_t * signature)
211{
212 int ret;
213
214 switch (algo)
215 {
216 case GNUTLS_PK_RSA:
217 /* encrypt */
218 if ((ret =
219 _gnutls_pkcs1_rsa_encrypt (signature, data, params, params_size,
220 1)) < 0)
221 {
222 gnutls_assert ();
223 return ret;
224 }
225
226 break;
227 default:
228 gnutls_assert ();
229 return GNUTLS_E_INTERNAL_ERROR;
230 break;
231 }
232
233 return 0;
234}
235
236/* This will create a PKCS1 or DSA signature, as defined in the TLS protocol.
237 * Cert is the certificate of the corresponding private key. It is only checked if
238 * it supports signing.
239 */
240static int
241_gnutls_tls_sign (gnutls_session_t session,
242 gnutls_cert * cert,
243 gnutls_privkey * pkey,
244 const gnutls_datum_t * hash_concat,
245 gnutls_datum_t * signature)
246{
247
248 /* If our certificate supports signing
249 */
250
251 if (cert != NULL)
252 if (cert->key_usage != 0)
253 if (!(cert->key_usage & KEY_DIGITAL_SIGNATURE))
254 {
255 gnutls_assert ();
256 return GNUTLS_E_KEY_USAGE_VIOLATION;
257 }
258
259 /* External signing. */
260 if (!pkey || pkey->params_size == 0)
261 {
262 if (!session->internals.sign_func)
263 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
264
265 return (*session->internals.sign_func) (session,
266 session->internals.
267 sign_func_userdata,
268 cert->cert_type, &cert->raw,
269 hash_concat, signature);
270 }
271
272 return _gnutls_sign (pkey->pk_algorithm, pkey->params, pkey->params_size,
273 hash_concat, signature);
274}
275
276static int
277_gnutls_verify_sig (gnutls_cert * cert,
278 const gnutls_datum_t * hash_concat,
279 gnutls_datum_t * signature, size_t sha1pos)
280{
281 int ret;
282 gnutls_datum_t vdata;
283
284 if (cert->version == 0 || cert == NULL)
285 { /* this is the only way to check
286 * if it is initialized
287 */
288 gnutls_assert ();
289 return GNUTLS_E_CERTIFICATE_ERROR;
290 }
291
292 /* If the certificate supports signing continue.
293 */
294 if (cert != NULL)
295 if (cert->key_usage != 0)
296 if (!(cert->key_usage & KEY_DIGITAL_SIGNATURE))
297 {
298 gnutls_assert ();
299 return GNUTLS_E_KEY_USAGE_VIOLATION;
300 }
301
302 switch (cert->subject_pk_algorithm)
303 {
304 case GNUTLS_PK_RSA:
305
306 vdata.data = hash_concat->data;
307 vdata.size = hash_concat->size;
308
309 /* verify signature */
310 if ((ret = _gnutls_rsa_verify (&vdata, signature, cert->params,
311 cert->params_size, 1)) < 0)
312 {
313 gnutls_assert ();
314 return ret;
315 }
316
317 break;
318 default:
319 gnutls_assert ();
320 return GNUTLS_E_INTERNAL_ERROR;
321 }
322
323 return 0;
324}
325
326/* Verifies a TLS signature (like the one in the client certificate
327 * verify message).
328 */
329int
330_gnutls_verify_sig_hdata (gnutls_session_t session,
331 gnutls_cert * cert, gnutls_datum_t * signature)
332{
333 int ret;
334 opaque concat[36];
335 mac_hd_t td_md5;
336 mac_hd_t td_sha;
337 gnutls_datum_t dconcat;
338 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
339
340 td_md5 = _gnutls_hash_copy (session->internals.handshake_mac_handle_md5);
341 if (td_md5 == NULL)
342 {
343 gnutls_assert ();
344 return GNUTLS_E_HASH_FAILED;
345 }
346
347 td_sha = _gnutls_hash_copy (session->internals.handshake_mac_handle_sha);
348 if (td_sha == NULL)
349 {
350 gnutls_assert ();
351 _gnutls_hash_deinit (td_md5, NULL);
352 return GNUTLS_E_HASH_FAILED;
353 }
354
355 if (ver == GNUTLS_SSL3)
356 {
357 ret = _gnutls_generate_master (session, 1);
358 if (ret < 0)
359 {
360 gnutls_assert ();
361 return ret;
362 }
363
364 _gnutls_mac_deinit_ssl3_handshake (td_md5, concat,
365 session->security_parameters.
366 master_secret, TLS_MASTER_SIZE);
367 _gnutls_mac_deinit_ssl3_handshake (td_sha, &concat[16],
368 session->security_parameters.
369 master_secret, TLS_MASTER_SIZE);
370 }
371 else
372 {
373 _gnutls_hash_deinit (td_md5, concat);
374 _gnutls_hash_deinit (td_sha, &concat[16]);
375 }
376
377 dconcat.data = concat;
378 dconcat.size = 20 + 16; /* md5+ sha */
379
380 ret = _gnutls_verify_sig (cert, &dconcat, signature, 16);
381 if (ret < 0)
382 {
383 gnutls_assert ();
384 return ret;
385 }
386
387 return ret;
388
389}
390
391/* Generates a signature of all the random data and the parameters.
392 * Used in DHE_* ciphersuites.
393 */
394int
395_gnutls_verify_sig_params (gnutls_session_t session,
396 gnutls_cert * cert,
397 const gnutls_datum_t * params,
398 gnutls_datum_t * signature)
399{
400 gnutls_datum_t dconcat;
401 int ret;
402 mac_hd_t td_md5 = NULL;
403 mac_hd_t td_sha;
404 opaque concat[36];
405 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
406
407 if (ver < GNUTLS_TLS1_2)
408 {
409 td_md5 = _gnutls_hash_init (GNUTLS_MAC_MD5);
410 if (td_md5 == NULL)
411 {
412 gnutls_assert ();
413 return GNUTLS_E_HASH_FAILED;
414 }
415
416 _gnutls_hash (td_md5, session->security_parameters.client_random,
417 TLS_RANDOM_SIZE);
418 _gnutls_hash (td_md5, session->security_parameters.server_random,
419 TLS_RANDOM_SIZE);
420 _gnutls_hash (td_md5, params->data, params->size);
421 }
422
423 td_sha = _gnutls_hash_init (GNUTLS_MAC_SHA1);
424 if (td_sha == NULL)
425 {
426 gnutls_assert ();
427 if (td_md5)
428 _gnutls_hash_deinit (td_md5, NULL);
429 return GNUTLS_E_HASH_FAILED;
430 }
431
432 _gnutls_hash (td_sha, session->security_parameters.client_random,
433 TLS_RANDOM_SIZE);
434 _gnutls_hash (td_sha, session->security_parameters.server_random,
435 TLS_RANDOM_SIZE);
436 _gnutls_hash (td_sha, params->data, params->size);
437
438 if (ver < GNUTLS_TLS1_2)
439 {
440 _gnutls_hash_deinit (td_md5, concat);
441 _gnutls_hash_deinit (td_sha, &concat[16]);
442 dconcat.size = 36;
443 }
444 else
445 {
446#if 1
447 /* Use NULL parameters. */
448 memcpy (concat,
449 "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14",
450 15);
451 _gnutls_hash_deinit (td_sha, &concat[15]);
452 dconcat.size = 35;
453#else
454 /* No parameters field. */
455 memcpy (concat,
456 "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14", 13);
457 _gnutls_hash_deinit (td_sha, &concat[13]);
458 dconcat.size = 33;
459#endif
460 }
461
462 dconcat.data = concat;
463
464 ret = _gnutls_verify_sig (cert, &dconcat, signature, dconcat.size - 20);
465 if (ret < 0)
466 {
467 gnutls_assert ();
468 return ret;
469 }
470
471 return ret;
472
473}
diff --git a/src/daemon/https/tls/gnutls_sig.h b/src/daemon/https/tls/gnutls_sig.h
new file mode 100644
index 00000000..4d770716
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_sig.h
@@ -0,0 +1,51 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#ifndef GNUTLS_SIG_H
26# define GNUTLS_SIG_H
27
28int _gnutls_tls_sign_hdata (gnutls_session_t session,
29 gnutls_cert * cert,
30 gnutls_privkey * pkey,
31 gnutls_datum_t * signature);
32
33int _gnutls_tls_sign_params (gnutls_session_t session,
34 gnutls_cert * cert,
35 gnutls_privkey * pkey,
36 gnutls_datum_t * params,
37 gnutls_datum_t * signature);
38
39int _gnutls_verify_sig_hdata (gnutls_session_t session,
40 gnutls_cert * cert, gnutls_datum_t * signature);
41
42int _gnutls_verify_sig_params (gnutls_session_t session,
43 gnutls_cert * cert,
44 const gnutls_datum_t * params,
45 gnutls_datum_t * signature);
46
47int _gnutls_sign (gnutls_pk_algorithm_t algo,
48 mpi_t * params, int params_size,
49 const gnutls_datum_t * data, gnutls_datum_t * signature);
50
51#endif
diff --git a/src/daemon/https/tls/gnutls_state.c b/src/daemon/https/tls/gnutls_state.c
new file mode 100644
index 00000000..ccc865a1
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_state.c
@@ -0,0 +1,1219 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* Functions to manipulate the session (gnutls_int.h), and some other stuff
26 * are included here. The file's name is traditionally gnutls_state even if the
27 * state has been renamed to session.
28 */
29
30#include <gnutls_int.h>
31#include <gnutls_errors.h>
32#include <gnutls_auth_int.h>
33#include <gnutls_num.h>
34#include <gnutls_datum.h>
35#include <gnutls_db.h>
36#include <gnutls_record.h>
37#include <gnutls_handshake.h>
38#include <gnutls_dh.h>
39#include <gnutls_buffers.h>
40#include <gnutls_state.h>
41#include <auth_cert.h>
42#include <auth_anon.h>
43#include <gnutls_algorithms.h>
44#include <gnutls_rsa_export.h>
45
46void
47_gnutls_session_cert_type_set (gnutls_session_t session,
48 gnutls_certificate_type_t ct)
49{
50 session->security_parameters.cert_type = ct;
51}
52
53/**
54 * gnutls_cipher_get - Returns the currently used cipher.
55 * @session: is a #gnutls_session_t structure.
56 *
57 * Returns: the currently used cipher.
58 **/
59gnutls_cipher_algorithm_t
60gnutls_cipher_get (gnutls_session_t session)
61{
62 return session->security_parameters.read_bulk_cipher_algorithm;
63}
64
65/**
66 * gnutls_certificate_type_get - Returns the currently used certificate type.
67 * @session: is a #gnutls_session_t structure.
68 *
69 * The certificate type is by default X.509, unless it is negotiated
70 * as a TLS extension.
71 *
72 * Returns: the currently used %gnutls_certificate_type_t certificate
73 * type.
74 **/
75gnutls_certificate_type_t
76gnutls_certificate_type_get (gnutls_session_t session)
77{
78 return session->security_parameters.cert_type;
79}
80
81/**
82 * gnutls_kx_get - Returns the key exchange algorithm.
83 * @session: is a #gnutls_session_t structure.
84 *
85 * Returns: the key exchange algorithm used in the last handshake.
86 **/
87gnutls_kx_algorithm_t
88gnutls_kx_get (gnutls_session_t session)
89{
90 return session->security_parameters.kx_algorithm;
91}
92
93/**
94 * gnutls_mac_get - Returns the currently used mac algorithm.
95 * @session: is a #gnutls_session_t structure.
96 *
97 * Returns: the currently used mac algorithm.
98 **/
99gnutls_mac_algorithm_t
100gnutls_mac_get (gnutls_session_t session)
101{
102 return session->security_parameters.read_mac_algorithm;
103}
104
105/**
106 * gnutls_compression_get - Returns the currently used compression algorithm.
107 * @session: is a #gnutls_session_t structure.
108 *
109 * Returns: the currently used compression method.
110 **/
111gnutls_compression_method_t
112gnutls_compression_get (gnutls_session_t session)
113{
114 return session->security_parameters.read_compression_algorithm;
115}
116
117/* Check if the given certificate type is supported.
118 * This means that it is enabled by the priority functions,
119 * and a matching certificate exists.
120 */
121int
122_gnutls_session_cert_type_supported (gnutls_session_t session,
123 gnutls_certificate_type_t cert_type)
124{
125 unsigned i;
126 unsigned cert_found = 0;
127 gnutls_certificate_credentials_t cred;
128
129 if (session->security_parameters.entity == GNUTLS_SERVER)
130 {
131 cred
132 = (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key,
133 GNUTLS_CRD_CERTIFICATE,
134 NULL);
135
136 if (cred == NULL)
137 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
138
139 if (cred->server_get_cert_callback == NULL)
140 {
141 for (i = 0; i < cred->ncerts; i++)
142 {
143 if (cred->cert_list[i][0].cert_type == cert_type)
144 {
145 cert_found = 1;
146 break;
147 }
148 }
149
150 if (cert_found == 0)
151 /* no certificate is of that type.
152 */
153 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
154 }
155 }
156
157 if (session->internals.priorities.cert_type.algorithms == 0 && cert_type
158 == DEFAULT_CERT_TYPE)
159 return 0;
160
161 for (i = 0; i < session->internals.priorities.cert_type.algorithms; i++)
162 {
163 if (session->internals.priorities.cert_type.priority[i] == cert_type)
164 {
165 return 0; /* ok */
166 }
167 }
168
169 return GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
170}
171
172/* this function deinitializes all the internal parameters stored
173 * in a session struct.
174 */
175inline static void
176deinit_internal_params (gnutls_session_t session)
177{
178 if (session->internals.params.free_dh_params)
179 gnutls_dh_params_deinit (session->internals.params.dh_params);
180
181 if (session->internals.params.free_rsa_params)
182 gnutls_rsa_params_deinit (session->internals.params.rsa_params);
183
184 memset (&session->internals.params, 0, sizeof (session->internals.params));
185}
186
187/* This function will clear all the variables in internals
188 * structure within the session, which depend on the current handshake.
189 * This is used to allow further handshakes.
190 */
191void
192_gnutls_handshake_internal_state_clear (gnutls_session_t session)
193{
194 session->internals.extensions_sent_size = 0;
195
196 /* by default no selected certificate */
197 session->internals.proposed_record_size = DEFAULT_MAX_RECORD_SIZE;
198 session->internals.adv_version_major = 0;
199 session->internals.adv_version_minor = 0;
200 session->internals.v2_hello = 0;
201 memset (&session->internals.handshake_header_buffer, 0,
202 sizeof (handshake_header_buffer_st));
203 session->internals.adv_version_minor = 0;
204 session->internals.adv_version_minor = 0;
205 session->internals.direction = 0;
206
207 /* use out of band data for the last
208 * handshake messages received.
209 */
210 session->internals.last_handshake_in = -1;
211 session->internals.last_handshake_out = -1;
212
213 session->internals.resumable = RESUME_TRUE;
214 _gnutls_free_datum (&session->internals.recv_buffer);
215
216 deinit_internal_params (session);
217
218}
219
220#define MIN_DH_BITS 727
221/**
222 * gnutls_init - This function initializes the session to null (null encryption etc...).
223 * @con_end: indicate if this session is to be used for server or client.
224 * @session: is a pointer to a #gnutls_session_t structure.
225 *
226 * This function initializes the current session to null. Every
227 * session must be initialized before use, so internal structures can
228 * be allocated. This function allocates structures which can only
229 * be free'd by calling gnutls_deinit(). Returns zero on success.
230 *
231 * @con_end can be one of %GNUTLS_CLIENT and %GNUTLS_SERVER.
232 *
233 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
234 **/
235
236// TODO rm redundent pointer ref
237int
238gnutls_init (gnutls_session_t * session, gnutls_connection_end_t con_end)
239{
240 *session = gnutls_calloc (1, sizeof (struct gnutls_session_int));
241 if (*session == NULL)
242 return GNUTLS_E_MEMORY_ERROR;
243
244 (*session)->security_parameters.entity = con_end;
245
246 /* the default certificate type for TLS */
247 (*session)->security_parameters.cert_type = DEFAULT_CERT_TYPE;
248
249 /* Set the defaults for initial handshake */
250 (*session)->security_parameters.read_bulk_cipher_algorithm =
251 (*session)->security_parameters.write_bulk_cipher_algorithm =
252 GNUTLS_CIPHER_NULL;
253
254 (*session)->security_parameters.read_mac_algorithm =
255 (*session)->security_parameters.write_mac_algorithm = GNUTLS_MAC_NULL;
256
257 (*session)->security_parameters.read_compression_algorithm
258 = GNUTLS_COMP_NULL;
259 (*session)->security_parameters.write_compression_algorithm
260 = GNUTLS_COMP_NULL;
261
262 (*session)->internals.enable_private = 0;
263
264 /* Initialize buffers */
265 _gnutls_buffer_init (&(*session)->internals.application_data_buffer);
266 _gnutls_buffer_init (&(*session)->internals.handshake_data_buffer);
267 _gnutls_buffer_init (&(*session)->internals.handshake_hash_buffer);
268 _gnutls_buffer_init (&(*session)->internals.ia_data_buffer);
269
270 _gnutls_buffer_init (&(*session)->internals.record_send_buffer);
271 _gnutls_buffer_init (&(*session)->internals.record_recv_buffer);
272
273 _gnutls_buffer_init (&(*session)->internals.handshake_send_buffer);
274 _gnutls_buffer_init (&(*session)->internals.handshake_recv_buffer);
275
276 (*session)->key = gnutls_calloc (1, sizeof (struct gnutls_key_st));
277 if ((*session)->key == NULL)
278 {
279 cleanup_session:gnutls_free (*session);
280 *session = NULL;
281 return GNUTLS_E_MEMORY_ERROR;
282 }
283
284 (*session)->internals.expire_time = DEFAULT_EXPIRE_TIME; /* one hour default */
285
286 gnutls_dh_set_prime_bits ((*session), MIN_DH_BITS);
287
288 gnutls_transport_set_lowat ((*session), DEFAULT_LOWAT); /* the default for tcp */
289
290 gnutls_handshake_set_max_packet_length ((*session),
291 MAX_HANDSHAKE_PACKET_SIZE);
292
293 /* Allocate a minimum size for recv_data
294 * This is allocated in order to avoid small messages, making
295 * the receive procedure slow.
296 */
297 (*session)->internals.record_recv_buffer.data
298 = gnutls_malloc (INITIAL_RECV_BUFFER_SIZE);
299 if ((*session)->internals.record_recv_buffer.data == NULL)
300 {
301 gnutls_free ((*session)->key);
302 goto cleanup_session;
303 }
304
305 /* set the socket pointers to -1; */
306 (*session)->internals.transport_recv_ptr = (gnutls_transport_ptr_t) - 1;
307 (*session)->internals.transport_send_ptr = (gnutls_transport_ptr_t) - 1;
308
309 /* set the default maximum record size for TLS
310 */
311 (*session)->security_parameters.max_record_recv_size
312 = DEFAULT_MAX_RECORD_SIZE;
313 (*session)->security_parameters.max_record_send_size
314 = DEFAULT_MAX_RECORD_SIZE;
315
316 /* everything else not initialized here is initialized
317 * as NULL or 0. This is why calloc is used.
318 */
319
320 _gnutls_handshake_internal_state_clear (*session);
321
322 return 0;
323}
324
325/* returns RESUME_FALSE or RESUME_TRUE.
326 */
327int
328_gnutls_session_is_resumable (gnutls_session_t session)
329{
330 return session->internals.resumable;
331}
332
333/**
334 * gnutls_deinit - This function clears all buffers associated with a session
335 * @session: is a #gnutls_session_t structure.
336 *
337 * This function clears all buffers associated with the @session.
338 * This function will also remove session data from the session
339 * database if the session was terminated abnormally.
340 **/
341void
342gnutls_deinit (gnutls_session_t session)
343{
344
345 if (session == NULL)
346 return;
347
348 /* remove auth info firstly */
349 _gnutls_free_auth_info (session);
350
351 _gnutls_handshake_internal_state_clear (session);
352 _gnutls_handshake_io_buffer_clear (session);
353
354 _gnutls_free_datum (&session->connection_state.read_mac_secret);
355 _gnutls_free_datum (&session->connection_state.write_mac_secret);
356
357 _gnutls_buffer_clear (&session->internals.ia_data_buffer);
358 _gnutls_buffer_clear (&session->internals.handshake_hash_buffer);
359 _gnutls_buffer_clear (&session->internals.handshake_data_buffer);
360 _gnutls_buffer_clear (&session->internals.application_data_buffer);
361 _gnutls_buffer_clear (&session->internals.record_recv_buffer);
362 _gnutls_buffer_clear (&session->internals.record_send_buffer);
363
364 gnutls_credentials_clear (session);
365 _gnutls_selected_certs_deinit (session);
366
367 if (session->connection_state.read_cipher_state != NULL)
368 _gnutls_cipher_deinit (session->connection_state.read_cipher_state);
369 if (session->connection_state.write_cipher_state != NULL)
370 _gnutls_cipher_deinit (session->connection_state.write_cipher_state);
371
372 if (session->connection_state.read_compression_state != NULL)
373 _gnutls_comp_deinit (session->connection_state.read_compression_state, 1);
374 if (session->connection_state.write_compression_state != NULL)
375 _gnutls_comp_deinit (session->connection_state.
376 write_compression_state, 0);
377
378 _gnutls_free_datum (&session->cipher_specs.server_write_mac_secret);
379 _gnutls_free_datum (&session->cipher_specs.client_write_mac_secret);
380 _gnutls_free_datum (&session->cipher_specs.server_write_IV);
381 _gnutls_free_datum (&session->cipher_specs.client_write_IV);
382 _gnutls_free_datum (&session->cipher_specs.server_write_key);
383 _gnutls_free_datum (&session->cipher_specs.client_write_key);
384
385 if (session->key != NULL)
386 {
387 _gnutls_mpi_release (&session->key->KEY);
388 _gnutls_mpi_release (&session->key->client_Y);
389 _gnutls_mpi_release (&session->key->client_p);
390 _gnutls_mpi_release (&session->key->client_g);
391
392 _gnutls_mpi_release (&session->key->u);
393 _gnutls_mpi_release (&session->key->a);
394 _gnutls_mpi_release (&session->key->x);
395 _gnutls_mpi_release (&session->key->A);
396 _gnutls_mpi_release (&session->key->B);
397 _gnutls_mpi_release (&session->key->b);
398
399 /* RSA */
400 _gnutls_mpi_release (&session->key->rsa[0]);
401 _gnutls_mpi_release (&session->key->rsa[1]);
402
403 _gnutls_mpi_release (&session->key->dh_secret);
404 gnutls_free (session->key);
405
406 session->key = NULL;
407 }
408
409 gnutls_free (session->internals.srp_username);
410
411 if (session->internals.srp_password)
412 {
413 memset (session->internals.srp_password, 0,
414 strlen (session->internals.srp_password));
415 gnutls_free (session->internals.srp_password);
416 }
417
418 memset (session, 0, sizeof (struct gnutls_session_int));
419 gnutls_free (session);
420}
421
422/* Returns the minimum prime bits that are acceptable.
423 */
424int
425_gnutls_dh_get_allowed_prime_bits (gnutls_session_t session)
426{
427 return session->internals.dh_prime_bits;
428}
429
430int
431_gnutls_dh_set_peer_public (gnutls_session_t session, mpi_t public)
432{
433 dh_info_st *dh;
434 int ret;
435
436 switch (gnutls_auth_get_type (session))
437 {
438 case GNUTLS_CRD_ANON:
439 {
440 anon_auth_info_t info;
441 info = _gnutls_get_auth_info (session);
442 if (info == NULL)
443 return GNUTLS_E_INTERNAL_ERROR;
444
445 dh = &info->dh;
446 break;
447 }
448 case GNUTLS_CRD_CERTIFICATE:
449 {
450 cert_auth_info_t info;
451
452 info = _gnutls_get_auth_info (session);
453 if (info == NULL)
454 return GNUTLS_E_INTERNAL_ERROR;
455
456 dh = &info->dh;
457 break;
458 }
459 default:
460 gnutls_assert ();
461 return GNUTLS_E_INTERNAL_ERROR;
462 }
463
464 ret = _gnutls_mpi_dprint_lz (&dh->public_key, public);
465 if (ret < 0)
466 {
467 gnutls_assert ();
468 return ret;
469 }
470
471 return 0;
472}
473
474int
475_gnutls_dh_set_secret_bits (gnutls_session_t session, unsigned bits)
476{
477 switch (gnutls_auth_get_type (session))
478 {
479 case GNUTLS_CRD_ANON:
480 {
481 anon_auth_info_t info;
482 info = _gnutls_get_auth_info (session);
483 if (info == NULL)
484 return GNUTLS_E_INTERNAL_ERROR;
485 info->dh.secret_bits = bits;
486 break;
487 }
488 case GNUTLS_CRD_CERTIFICATE:
489 {
490 cert_auth_info_t info;
491
492 info = _gnutls_get_auth_info (session);
493 if (info == NULL)
494 return GNUTLS_E_INTERNAL_ERROR;
495
496 info->dh.secret_bits = bits;
497 break;
498 default:
499 gnutls_assert ();
500 return GNUTLS_E_INTERNAL_ERROR;
501 }
502 }
503
504 return 0;
505}
506
507/* This function will set in the auth info structure the
508 * RSA exponent and the modulus.
509 */
510int
511_gnutls_rsa_export_set_pubkey (gnutls_session_t session,
512 mpi_t exponent, mpi_t modulus)
513{
514 cert_auth_info_t info;
515 int ret;
516
517 info = _gnutls_get_auth_info (session);
518 if (info == NULL)
519 return GNUTLS_E_INTERNAL_ERROR;
520
521 ret = _gnutls_mpi_dprint_lz (&info->rsa_export.modulus, modulus);
522 if (ret < 0)
523 {
524 gnutls_assert ();
525 return ret;
526 }
527
528 ret = _gnutls_mpi_dprint_lz (&info->rsa_export.exponent, exponent);
529 if (ret < 0)
530 {
531 gnutls_assert ();
532 _gnutls_free_datum (&info->rsa_export.modulus);
533 return ret;
534 }
535
536 return 0;
537}
538
539/* Sets the prime and the generator in the auth info structure.
540 */
541int
542_gnutls_dh_set_group (gnutls_session_t session, mpi_t gen, mpi_t prime)
543{
544 dh_info_st *dh;
545 int ret;
546
547 switch (gnutls_auth_get_type (session))
548 {
549 case GNUTLS_CRD_ANON:
550 {
551 anon_auth_info_t info;
552 info = _gnutls_get_auth_info (session);
553 if (info == NULL)
554 return GNUTLS_E_INTERNAL_ERROR;
555
556 dh = &info->dh;
557 break;
558 }
559 case GNUTLS_CRD_CERTIFICATE:
560 {
561 cert_auth_info_t info;
562
563 info = _gnutls_get_auth_info (session);
564 if (info == NULL)
565 return GNUTLS_E_INTERNAL_ERROR;
566
567 dh = &info->dh;
568 break;
569 }
570 default:
571 gnutls_assert ();
572 return GNUTLS_E_INTERNAL_ERROR;
573 }
574
575 /* prime
576 */
577 ret = _gnutls_mpi_dprint_lz (&dh->prime, prime);
578 if (ret < 0)
579 {
580 gnutls_assert ();
581 return ret;
582 }
583
584 /* generator
585 */
586 ret = _gnutls_mpi_dprint_lz (&dh->generator, gen);
587 if (ret < 0)
588 {
589 gnutls_assert ();
590 _gnutls_free_datum (&dh->prime);
591 return ret;
592 }
593
594 return 0;
595}
596
597/**
598 * gnutls_openpgp_send_cert - This function will order gnutls to send the openpgp fingerprint instead of the key
599 * @session: is a pointer to a #gnutls_session_t structure.
600 * @status: is one of GNUTLS_OPENPGP_CERT, or GNUTLS_OPENPGP_CERT_FINGERPRINT
601 *
602 * This function will order gnutls to send the key fingerprint
603 * instead of the key in the initial handshake procedure. This should
604 * be used with care and only when there is indication or knowledge
605 * that the server can obtain the client's key.
606 **/
607void
608gnutls_openpgp_send_cert (gnutls_session_t session,
609 gnutls_openpgp_crt_status_t status)
610{
611 session->internals.pgp_fingerprint = status;
612}
613
614/**
615 * gnutls_certificate_send_x509_rdn_sequence - This function will order gnutls to send or not the x.509 rdn sequence
616 * @session: is a pointer to a #gnutls_session_t structure.
617 * @status: is 0 or 1
618 *
619 * If status is non zero, this function will order gnutls not to send
620 * the rdnSequence in the certificate request message. That is the
621 * server will not advertize it's trusted CAs to the peer. If status
622 * is zero then the default behaviour will take effect, which is to
623 * advertize the server's trusted CAs.
624 *
625 * This function has no effect in clients, and in authentication
626 * methods other than certificate with X.509 certificates.
627 **/
628void
629gnutls_certificate_send_x509_rdn_sequence (gnutls_session_t session,
630 int status)
631{
632 session->internals.ignore_rdn_sequence = status;
633}
634
635int
636_gnutls_openpgp_send_fingerprint (gnutls_session_t session)
637{
638 return session->internals.pgp_fingerprint;
639}
640
641/*-
642 * _gnutls_record_set_default_version - Used to set the default version for the first record packet
643 * @session: is a #gnutls_session_t structure.
644 * @major: is a tls major version
645 * @minor: is a tls minor version
646 *
647 * This function sets the default version that we will use in the first
648 * record packet (client hello). This function is only useful to people
649 * that know TLS internals and want to debug other implementations.
650 *
651 -*/
652void
653_gnutls_record_set_default_version (gnutls_session_t session,
654 unsigned char major, unsigned char minor)
655{
656 session->internals.default_record_version[0] = major;
657 session->internals.default_record_version[1] = minor;
658}
659
660/**
661 * gnutls_handshake_set_private_extensions - Used to enable the private cipher suites
662 * @session: is a #gnutls_session_t structure.
663 * @allow: is an integer (0 or 1)
664 *
665 * This function will enable or disable the use of private cipher
666 * suites (the ones that start with 0xFF). By default or if @allow
667 * is 0 then these cipher suites will not be advertized nor used.
668 *
669 * Unless this function is called with the option to allow (1), then
670 * no compression algorithms, like LZO. That is because these
671 * algorithms are not yet defined in any RFC or even internet draft.
672 *
673 * Enabling the private ciphersuites when talking to other than
674 * gnutls servers and clients may cause interoperability problems.
675 **/
676void
677gnutls_handshake_set_private_extensions (gnutls_session_t session, int allow)
678{
679 session->internals.enable_private = allow;
680}
681
682inline static int
683_gnutls_cal_PRF_A (gnutls_mac_algorithm_t algorithm,
684 const void *secret,
685 int secret_size,
686 const void *seed, int seed_size, void *result)
687{
688 mac_hd_t td1;
689
690 td1 = _gnutls_hmac_init (algorithm, secret, secret_size);
691 if (td1 == GNUTLS_MAC_FAILED)
692 {
693 gnutls_assert ();
694 return GNUTLS_E_INTERNAL_ERROR;
695 }
696
697 _gnutls_hmac (td1, seed, seed_size);
698 _gnutls_hmac_deinit (td1, result);
699
700 return 0;
701}
702
703#define MAX_SEED_SIZE 200
704
705/* Produces "total_bytes" bytes using the hash algorithm specified.
706 * (used in the PRF function)
707 */
708static int
709_gnutls_P_hash (gnutls_mac_algorithm_t algorithm,
710 const opaque * secret,
711 int secret_size,
712 const opaque * seed,
713 int seed_size, int total_bytes, opaque * ret)
714{
715
716 mac_hd_t td2;
717 int i, times, how, blocksize, A_size;
718 opaque final[20], Atmp[MAX_SEED_SIZE];
719 int output_bytes, result;
720
721 if (seed_size > MAX_SEED_SIZE || total_bytes <= 0)
722 {
723 gnutls_assert ();
724 return GNUTLS_E_INTERNAL_ERROR;
725 }
726
727 blocksize = _gnutls_hmac_get_algo_len (algorithm);
728
729 output_bytes = 0;
730 do
731 {
732 output_bytes += blocksize;
733 }
734 while (output_bytes < total_bytes);
735
736 /* calculate A(0) */
737
738 memcpy (Atmp, seed, seed_size);
739 A_size = seed_size;
740
741 times = output_bytes / blocksize;
742
743 for (i = 0; i < times; i++)
744 {
745 td2 = _gnutls_hmac_init (algorithm, secret, secret_size);
746 if (td2 == GNUTLS_MAC_FAILED)
747 {
748 gnutls_assert ();
749 return GNUTLS_E_INTERNAL_ERROR;
750 }
751
752 /* here we calculate A(i+1) */
753 if ((result = _gnutls_cal_PRF_A (algorithm, secret, secret_size, Atmp,
754 A_size, Atmp)) < 0)
755 {
756 gnutls_assert ();
757 _gnutls_hmac_deinit (td2, final);
758 return result;
759 }
760
761 A_size = blocksize;
762
763 _gnutls_hmac (td2, Atmp, A_size);
764 _gnutls_hmac (td2, seed, seed_size);
765 _gnutls_hmac_deinit (td2, final);
766
767 if ((1 + i) * blocksize < total_bytes)
768 {
769 how = blocksize;
770 }
771 else
772 {
773 how = total_bytes - (i) * blocksize;
774 }
775
776 if (how > 0)
777 {
778 memcpy (&ret[i * blocksize], final, how);
779 }
780 }
781
782 return 0;
783}
784
785/* Xor's two buffers and puts the output in the first one.
786 */
787inline static void
788_gnutls_xor (opaque * o1, opaque * o2, int length)
789{
790 int i;
791 for (i = 0; i < length; i++)
792 {
793 o1[i] ^= o2[i];
794 }
795}
796
797#define MAX_PRF_BYTES 200
798
799/* The PRF function expands a given secret
800 * needed by the TLS specification. ret must have a least total_bytes
801 * available.
802 */
803int
804_gnutls_PRF (gnutls_session_t session,
805 const opaque * secret,
806 int secret_size,
807 const char *label,
808 int label_size,
809 const opaque * seed, int seed_size, int total_bytes, void *ret)
810{
811 int l_s, s_seed_size;
812 const opaque *s1, *s2;
813 opaque s_seed[MAX_SEED_SIZE];
814 opaque o1[MAX_PRF_BYTES], o2[MAX_PRF_BYTES];
815 int result;
816 gnutls_protocol_t ver = gnutls_protocol_get_version (session);
817
818 if (total_bytes > MAX_PRF_BYTES)
819 {
820 gnutls_assert ();
821 return GNUTLS_E_INTERNAL_ERROR;
822 }
823 /* label+seed = s_seed */
824 s_seed_size = seed_size + label_size;
825
826 if (s_seed_size > MAX_SEED_SIZE)
827 {
828 gnutls_assert ();
829 return GNUTLS_E_INTERNAL_ERROR;
830 }
831
832 memcpy (s_seed, label, label_size);
833 memcpy (&s_seed[label_size], seed, seed_size);
834
835 if (ver >= GNUTLS_TLS1_2)
836 {
837 result = _gnutls_P_hash (GNUTLS_MAC_SHA1, secret, secret_size, s_seed,
838 s_seed_size, total_bytes, ret);
839 if (result < 0)
840 {
841 gnutls_assert ();
842 return result;
843 }
844 }
845 else
846 {
847 l_s = secret_size / 2;
848
849 s1 = &secret[0];
850 s2 = &secret[l_s];
851
852 if (secret_size % 2 != 0)
853 {
854 l_s++;
855 }
856
857 result = _gnutls_P_hash (GNUTLS_MAC_MD5, s1, l_s, s_seed, s_seed_size,
858 total_bytes, o1);
859 if (result < 0)
860 {
861 gnutls_assert ();
862 return result;
863 }
864
865 result = _gnutls_P_hash (GNUTLS_MAC_SHA1, s2, l_s, s_seed, s_seed_size,
866 total_bytes, o2);
867 if (result < 0)
868 {
869 gnutls_assert ();
870 return result;
871 }
872
873 _gnutls_xor (o1, o2, total_bytes);
874
875 memcpy (ret, o1, total_bytes);
876 }
877
878 return 0; /* ok */
879
880}
881
882/**
883 * gnutls_prf_raw - access the TLS PRF directly
884 * @session: is a #gnutls_session_t structure.
885 * @label_size: length of the @label variable.
886 * @label: label used in PRF computation, typically a short string.
887 * @seed_size: length of the @seed variable.
888 * @seed: optional extra data to seed the PRF with.
889 * @outsize: size of pre-allocated output buffer to hold the output.
890 * @out: pre-allocate buffer to hold the generated data.
891 *
892 * Apply the TLS Pseudo-Random-Function (PRF) using the master secret
893 * on some data.
894 *
895 * The @label variable usually contain a string denoting the purpose
896 * for the generated data. The @seed usually contain data such as the
897 * client and server random, perhaps together with some additional
898 * data that is added to guarantee uniqueness of the output for a
899 * particular purpose.
900 *
901 * Because the output is not guaranteed to be unique for a particular
902 * session unless @seed include the client random and server random
903 * fields (the PRF would output the same data on another connection
904 * resumed from the first one), it is not recommended to use this
905 * function directly. The gnutls_prf() function seed the PRF with the
906 * client and server random fields directly, and is recommended if you
907 * want to generate pseudo random data unique for each session.
908 *
909 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
910 **/
911int
912gnutls_prf_raw (gnutls_session_t session,
913 size_t label_size,
914 const char *label,
915 size_t seed_size, const char *seed, size_t outsize, char *out)
916{
917 int ret;
918
919 ret = _gnutls_PRF (session, session->security_parameters.master_secret,
920 TLS_MASTER_SIZE, label, label_size, (opaque *) seed,
921 seed_size, outsize, out);
922
923 return ret;
924}
925
926/**
927 * gnutls_prf - derive pseudo-random data using the TLS PRF
928 * @session: is a #gnutls_session_t structure.
929 * @label_size: length of the @label variable.
930 * @label: label used in PRF computation, typically a short string.
931 * @server_random_first: non-0 if server random field should be first in seed
932 * @extra_size: length of the @extra variable.
933 * @extra: optional extra data to seed the PRF with.
934 * @outsize: size of pre-allocated output buffer to hold the output.
935 * @out: pre-allocate buffer to hold the generated data.
936 *
937 * Apply the TLS Pseudo-Random-Function (PRF) using the master secret
938 * on some data, seeded with the client and server random fields.
939 *
940 * The @label variable usually contain a string denoting the purpose
941 * for the generated data. The @server_random_first indicate whether
942 * the client random field or the server random field should be first
943 * in the seed. Non-0 indicate that the server random field is first,
944 * 0 that the client random field is first.
945 *
946 * The @extra variable can be used to add more data to the seed, after
947 * the random variables. It can be used to tie make sure the
948 * generated output is strongly connected to some additional data
949 * (e.g., a string used in user authentication).
950 *
951 * The output is placed in *@OUT, which must be pre-allocated.
952 *
953 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
954 **/
955int
956gnutls_prf (gnutls_session_t session,
957 size_t label_size,
958 const char *label,
959 int server_random_first,
960 size_t extra_size, const char *extra, size_t outsize, char *out)
961{
962 int ret;
963 opaque *seed;
964 size_t seedsize = 2 * TLS_RANDOM_SIZE + extra_size;
965
966 seed = gnutls_malloc (seedsize);
967 if (!seed)
968 {
969 gnutls_assert ();
970 return GNUTLS_E_MEMORY_ERROR;
971 }
972
973 memcpy (seed,
974 server_random_first ? session->security_parameters.server_random
975 : session->security_parameters.client_random, TLS_RANDOM_SIZE);
976 memcpy (seed + TLS_RANDOM_SIZE,
977 server_random_first ? session->security_parameters.client_random
978 : session->security_parameters.server_random, TLS_RANDOM_SIZE);
979
980 memcpy (seed + 2 * TLS_RANDOM_SIZE, extra, extra_size);
981
982 ret = _gnutls_PRF (session, session->security_parameters.master_secret,
983 TLS_MASTER_SIZE, label, label_size, seed, seedsize,
984 outsize, out);
985
986 gnutls_free (seed);
987
988 return ret;
989}
990
991/**
992 * gnutls_session_get_client_random - get the session's client random value
993 * @session: is a #gnutls_session_t structure.
994 *
995 * Return a pointer to the 32-byte client random field used in the
996 * session. The pointer must not be modified or deallocated.
997 *
998 * If a client random value has not yet been established, the output
999 * will be garbage; in particular, a %NULL return value should not be
1000 * expected.
1001 *
1002 * Returns: pointer to client random data.
1003 **/
1004const void *
1005gnutls_session_get_client_random (gnutls_session_t session)
1006{
1007 return (char *) session->security_parameters.client_random;
1008}
1009
1010/**
1011 * gnutls_session_get_server_random - get the session's server random value
1012 * @session: is a #gnutls_session_t structure.
1013 *
1014 * Return a pointer to the 32-byte server random field used in the
1015 * session. The pointer must not be modified or deallocated.
1016 *
1017 * If a server random value has not yet been established, the output
1018 * will be garbage; in particular, a %NULL return value should not be
1019 * expected.
1020 *
1021 * Returns: pointer to server random data.
1022 **/
1023const void *
1024gnutls_session_get_server_random (gnutls_session_t session)
1025{
1026 return (char *) session->security_parameters.server_random;
1027}
1028
1029/**
1030 * gnutls_session_get_master_secret - get the session's master secret value
1031 * @session: is a #gnutls_session_t structure.
1032 *
1033 * Return a pointer to the 48-byte master secret in the session. The
1034 * pointer must not be modified or deallocated.
1035 *
1036 * If a master secret value has not yet been established, the output
1037 * will be garbage; in particular, a %NULL return value should not be
1038 * expected.
1039 *
1040 * Consider using gnutls_prf() rather than extracting the master
1041 * secret and use it to derive further data.
1042 *
1043 * Returns: pointer to master secret data.
1044 **/
1045const void *
1046gnutls_session_get_master_secret (gnutls_session_t session)
1047{
1048 return (char *) session->security_parameters.master_secret;
1049}
1050
1051/**
1052 * gnutls_session_is_resumed - Used to check whether this session is a resumed one
1053 * @session: is a #gnutls_session_t structure.
1054 *
1055 * Returns: non zero if this session is resumed, or a zero if this is
1056 * a new session.
1057 **/
1058int
1059gnutls_session_is_resumed (gnutls_session_t session)
1060{
1061 if (session->security_parameters.entity == GNUTLS_CLIENT)
1062 {
1063 if (session->security_parameters.session_id_size > 0
1064 && session->security_parameters.session_id_size
1065 == session->internals.resumed_security_parameters.session_id_size
1066 && memcmp (session->security_parameters.session_id,
1067 session->internals.resumed_security_parameters.
1068 session_id, session->security_parameters.session_id_size)
1069 == 0)
1070 return 1;
1071 }
1072 else
1073 {
1074 if (session->internals.resumed == RESUME_TRUE)
1075 return 1;
1076 }
1077
1078 return 0;
1079}
1080
1081/*-
1082 * _gnutls_session_is_export - Used to check whether this session is of export grade
1083 * @session: is a #gnutls_session_t structure.
1084 *
1085 * This function will return non zero if this session is of export grade.
1086 *
1087 -*/
1088int
1089_gnutls_session_is_export (gnutls_session_t session)
1090{
1091 gnutls_cipher_algorithm_t cipher;
1092
1093 cipher =
1094 _gnutls_cipher_suite_get_cipher_algo (&session->security_parameters.
1095 current_cipher_suite);
1096
1097 if (_gnutls_cipher_get_export_flag (cipher) != 0)
1098 return 1;
1099
1100 return 0;
1101}
1102
1103/**
1104 * gnutls_session_get_ptr - Used to get the user pointer from the session structure
1105 * @session: is a #gnutls_session_t structure.
1106 *
1107 * Returns: the user given pointer from the session structure. This
1108 * is the pointer set with gnutls_session_set_ptr().
1109 **/
1110void *
1111gnutls_session_get_ptr (gnutls_session_t session)
1112{
1113 return session->internals.user_ptr;
1114}
1115
1116/**
1117 * gnutls_session_set_ptr - Used to set the user pointer to the session structure
1118 * @session: is a #gnutls_session_t structure.
1119 * @ptr: is the user pointer
1120 *
1121 * This function will set (associate) the user given pointer to the
1122 * session structure. This is pointer can be accessed with
1123 * gnutls_session_get_ptr().
1124 **/
1125void
1126gnutls_session_set_ptr (gnutls_session_t session, void *ptr)
1127{
1128 session->internals.user_ptr = ptr;
1129}
1130
1131/**
1132 * gnutls_record_get_direction - This function will return the direction of the last interrupted function call
1133 * @session: is a #gnutls_session_t structure.
1134 *
1135 * This function provides information about the internals of the
1136 * record protocol and is only useful if a prior gnutls function call
1137 * (e.g. gnutls_handshake()) was interrupted for some reason, that
1138 * is, if a function returned %GNUTLS_E_INTERRUPTED or
1139 * %GNUTLS_E_AGAIN. In such a case, you might want to call select()
1140 * or poll() before calling the interrupted gnutls function again.
1141 * To tell you whether a file descriptor should be selected for
1142 * either reading or writing, gnutls_record_get_direction() returns 0
1143 * if the interrupted function was trying to read data, and 1 if it
1144 * was trying to write data.
1145 *
1146 * Returns: 0 if trying to read data, 1 if trying to write data.
1147 **/
1148int
1149gnutls_record_get_direction (gnutls_session_t session)
1150{
1151 return session->internals.direction;
1152}
1153
1154/*-
1155 * _gnutls_rsa_pms_set_version - Sets a version to be used at the RSA PMS
1156 * @session: is a #gnutls_session_t structure.
1157 * @major: is the major version to use
1158 * @minor: is the minor version to use
1159 *
1160 * This function will set the given version number to be used at the
1161 * RSA PMS secret. This is only useful to clients, which want to
1162 * test server's capabilities.
1163 *
1164 -*/
1165void
1166_gnutls_rsa_pms_set_version (gnutls_session_t session,
1167 unsigned char major, unsigned char minor)
1168{
1169 session->internals.rsa_pms_version[0] = major;
1170 session->internals.rsa_pms_version[1] = minor;
1171}
1172
1173/**
1174 * gnutls_handshake_set_post_client_hello_function - This function will a callback to be called after the client hello is received
1175 * @res: is a gnutls_anon_server_credentials_t structure
1176 * @func: is the function to be called
1177 *
1178 * This function will set a callback to be called after the client
1179 * hello has been received (callback valid in server side only). This
1180 * allows the server to adjust settings based on received extensions.
1181 *
1182 * Those settings could be ciphersuites, requesting certificate, or
1183 * anything else except for version negotiation (this is done before
1184 * the hello message is parsed).
1185 *
1186 * This callback must return 0 on success or a gnutls error code to
1187 * terminate the handshake.
1188 *
1189 * NOTE: You should not use this function to terminate the handshake
1190 * based on client input unless you know what you are doing. Before
1191 * the handshake is finished there is no way to know if there is a
1192 * man-in-the-middle attack being performed.
1193 *
1194 **/
1195void
1196gnutls_handshake_set_post_client_hello_function (gnutls_session_t session,
1197 gnutls_handshake_post_client_hello_func
1198 func)
1199{
1200 session->internals.user_hello_func = func;
1201}
1202
1203/**
1204 * gnutls_session_enable_compatibility_mode - Used to disable certain features in TLS in order to honour compatibility
1205 * @session: is a #gnutls_session_t structure.
1206 *
1207 * This function can be used to disable certain (security) features
1208 * in TLS in order to maintain maximum compatibility with buggy
1209 * clients. It is equivalent to calling:
1210 * gnutls_record_disable_padding()
1211 *
1212 * Normally only servers that require maximum compatibility with
1213 * everything out there, need to call this function.
1214 **/
1215void
1216gnutls_session_enable_compatibility_mode (gnutls_session_t session)
1217{
1218 gnutls_record_disable_padding (session);
1219}
diff --git a/src/daemon/https/tls/gnutls_state.h b/src/daemon/https/tls/gnutls_state.h
new file mode 100644
index 00000000..7a920ee4
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_state.h
@@ -0,0 +1,72 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#ifndef GNUTLS_STATE_H
26# define GNUTLS_STATE_H
27
28#include <gnutls_int.h>
29
30void _gnutls_session_cert_type_set (gnutls_session_t session,
31 gnutls_certificate_type_t);
32gnutls_kx_algorithm_t gnutls_kx_get (gnutls_session_t session);
33gnutls_cipher_algorithm_t gnutls_cipher_get (gnutls_session_t session);
34gnutls_certificate_type_t gnutls_certificate_type_get (gnutls_session_t);
35
36#include <gnutls_auth_int.h>
37
38#define CHECK_AUTH(auth, ret) if (gnutls_auth_get_type(session) != auth) { \
39 gnutls_assert(); \
40 return ret; \
41 }
42
43#endif
44
45int _gnutls_session_cert_type_supported (gnutls_session_t,
46 gnutls_certificate_type_t);
47
48int _gnutls_dh_set_secret_bits (gnutls_session_t session, unsigned bits);
49
50int _gnutls_dh_set_peer_public (gnutls_session_t session, mpi_t public);
51int _gnutls_dh_set_group (gnutls_session_t session, mpi_t gen, mpi_t prime);
52
53int _gnutls_dh_get_allowed_prime_bits (gnutls_session_t session);
54void _gnutls_handshake_internal_state_clear (gnutls_session_t);
55
56int _gnutls_rsa_export_set_pubkey (gnutls_session_t session,
57 mpi_t exponent, mpi_t modulus);
58
59int _gnutls_session_is_resumable (gnutls_session_t session);
60int _gnutls_session_is_export (gnutls_session_t session);
61
62int _gnutls_openpgp_send_fingerprint (gnutls_session_t session);
63
64int _gnutls_PRF (gnutls_session_t session,
65 const opaque * secret, int secret_size,
66 const char *label, int label_size,
67 const opaque * seed, int seed_size,
68 int total_bytes, void *ret);
69
70int gnutls_init (gnutls_session_t * session, gnutls_connection_end_t con_end);
71
72#define DEFAULT_CERT_TYPE GNUTLS_CRT_X509
diff --git a/src/daemon/https/tls/gnutls_str.c b/src/daemon/https/tls/gnutls_str.c
new file mode 100644
index 00000000..0ccf8445
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_str.c
@@ -0,0 +1,312 @@
1/*
2 * Copyright (C) 2002, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_errors.h>
27#include <gnutls_num.h>
28#include <gnutls_str.h>
29
30/* These function are like strcat, strcpy. They only
31 * do bound checking (they shouldn't cause buffer overruns),
32 * and they always produce null terminated strings.
33 *
34 * They should be used only with null terminated strings.
35 */
36void _gnutls_str_cat(char *dest,
37 size_t dest_tot_size,
38 const char *src)
39{
40 size_t str_size = strlen(src);
41 size_t dest_size = strlen(dest);
42
43 if (dest_tot_size - dest_size > str_size)
44 {
45 strcat(dest, src);
46 }
47 else
48 {
49 if (dest_tot_size - dest_size > 0)
50 {
51 strncat(dest, src, (dest_tot_size - dest_size) - 1);
52 dest[dest_tot_size - 1] = 0;
53 }
54 }
55}
56
57void _gnutls_str_cpy(char *dest,
58 size_t dest_tot_size,
59 const char *src)
60{
61 size_t str_size = strlen(src);
62
63 if (dest_tot_size > str_size)
64 {
65 strcpy(dest, src);
66 }
67 else
68 {
69 if (dest_tot_size > 0)
70 {
71 strncpy(dest, src, (dest_tot_size) - 1);
72 dest[dest_tot_size - 1] = 0;
73 }
74 }
75}
76
77void _gnutls_mem_cpy(char *dest,
78 size_t dest_tot_size,
79 const char *src,
80 size_t src_size)
81{
82
83 if (dest_tot_size >= src_size)
84 {
85 memcpy(dest, src, src_size);
86 }
87 else
88 {
89 if (dest_tot_size > 0)
90 {
91 memcpy(dest, src, dest_tot_size);
92 }
93 }
94}
95
96void _gnutls_string_init(gnutls_string * str,
97 gnutls_alloc_function alloc_func,
98 gnutls_realloc_function realloc_func,
99 gnutls_free_function free_func)
100{
101 str->data = NULL;
102 str->max_length = 0;
103 str->length = 0;
104
105 str->alloc_func = alloc_func;
106 str->free_func = free_func;
107 str->realloc_func = realloc_func;
108}
109
110void _gnutls_string_clear(gnutls_string * str)
111{
112 if (str == NULL || str->data == NULL)
113 return;
114 str->free_func(str->data);
115
116 str->data = NULL;
117 str->max_length = 0;
118 str->length = 0;
119}
120
121/* This one does not copy the string.
122 */
123gnutls_datum_t _gnutls_string2datum(gnutls_string * str)
124{
125 gnutls_datum_t ret;
126
127 ret.data = str->data;
128 ret.size = str->length;
129
130 return ret;
131}
132
133#define MIN_CHUNK 256
134
135int _gnutls_string_copy_str(gnutls_string * dest,
136 const char *src)
137{
138 size_t src_len = strlen(src);
139 size_t max;
140 if (dest->max_length >= src_len)
141 {
142 memcpy(dest->data, src, src_len);
143 dest->length = src_len;
144
145 return src_len;
146 }
147 else
148 {
149 max = (src_len > MIN_CHUNK) ? src_len : MIN_CHUNK;
150 dest->data = dest->realloc_func(dest->data, max);
151 if (dest->data == NULL)
152 {
153 gnutls_assert ();
154 return GNUTLS_E_MEMORY_ERROR;
155 }
156 dest->max_length = MAX (MIN_CHUNK, src_len);
157
158 memcpy(dest->data, src, src_len);
159 dest->length = src_len;
160
161 return src_len;
162 }
163}
164
165int _gnutls_string_append_str(gnutls_string * dest,
166 const char *src)
167{
168 size_t src_len = strlen(src);
169 size_t tot_len = src_len + dest->length;
170
171 if (dest->max_length >= tot_len)
172 {
173 memcpy(&dest->data[dest->length], src, src_len);
174 dest->length = tot_len;
175
176 return tot_len;
177 }
178 else
179 {
180 size_t new_len=
181 MAX (src_len, MIN_CHUNK) + MAX (dest->max_length, MIN_CHUNK);
182
183 dest->data = dest->realloc_func(dest->data, new_len);
184 if (dest->data == NULL)
185 {
186 gnutls_assert ();
187 return GNUTLS_E_MEMORY_ERROR;
188 }
189 dest->max_length = new_len;
190
191 memcpy(&dest->data[dest->length], src, src_len);
192 dest->length = tot_len;
193
194 return tot_len;
195 }
196}
197
198int _gnutls_string_append_data(gnutls_string * dest,
199 const void *data,
200 size_t data_size)
201{
202 size_t tot_len = data_size + dest->length;
203
204 if (dest->max_length >= tot_len)
205 {
206 memcpy(&dest->data[dest->length], data, data_size);
207 dest->length = tot_len;
208
209 return tot_len;
210 }
211 else
212 {
213 size_t new_len=
214 MAX (data_size, MIN_CHUNK) + MAX (dest->max_length, MIN_CHUNK);
215
216 dest->data = dest->realloc_func(dest->data, new_len);
217 if (dest->data == NULL)
218 {
219 gnutls_assert ();
220 return GNUTLS_E_MEMORY_ERROR;
221 }
222 dest->max_length = new_len;
223
224 memcpy(&dest->data[dest->length], data, data_size);
225 dest->length = tot_len;
226
227 return tot_len;
228 }
229}
230
231int _gnutls_string_append_printf(gnutls_string * dest,
232 const char *fmt,
233 ...)
234{
235 va_list args;
236 int len;
237 char *str;
238
239 va_start(args, fmt);
240 len = vasprintf(&str, fmt, args);
241 va_end(args);
242
243 if (len < 0 || !str)
244 return -1;
245
246 len = _gnutls_string_append_str(dest, str);
247
248 free(str);
249
250 return len;
251}
252
253/* Converts the given string (old) to hex. A buffer must be provided
254 * to hold the new hex string. The new string will be null terminated.
255 * If the buffer does not have enough space to hold the string, a
256 * truncated hex string is returned (always null terminated).
257 */
258char * _gnutls_bin2hex(const void *_old,
259 size_t oldlen,
260 char *buffer,
261 size_t buffer_size)
262{
263 unsigned int i, j;
264 const opaque *old = _old;
265
266 for (i = j = 0; i < oldlen && j + 2 < buffer_size; j += 2)
267 {
268 sprintf(&buffer[j], "%.2x", old[i]);
269 i++;
270 }
271 buffer[j] = '\0';
272
273 return buffer;
274}
275
276/* just a hex2bin function.
277 */
278int _gnutls_hex2bin(const opaque * hex_data,
279 int hex_size,
280 opaque * bin_data,
281 size_t * bin_size)
282{
283 int i, j;
284 opaque hex2_data[3];
285 unsigned long val;
286
287 /* FIXME: we don't handle whitespace.
288 */
289 hex_size /= 2;
290
291 if (*bin_size < (size_t) hex_size)
292 {
293 gnutls_assert ();
294 return GNUTLS_E_SHORT_MEMORY_BUFFER;
295 }
296
297 for (i = j = 0; j < hex_size; i += 2, j++)
298 {
299 hex2_data[0] = hex_data[i];
300 hex2_data[1] = hex_data[i + 1];
301 hex2_data[2] = 0;
302 val = strtoul((char *) hex2_data, NULL, 16);
303 if (val == ULONG_MAX)
304 {
305 gnutls_assert ();
306 return GNUTLS_E_SRP_PWD_PARSING_ERROR;
307 }
308 bin_data[j] = val;
309 }
310
311 return 0;
312}
diff --git a/src/daemon/https/tls/gnutls_str.h b/src/daemon/https/tls/gnutls_str.h
new file mode 100644
index 00000000..c805d70f
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_str.h
@@ -0,0 +1,67 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#ifndef GNUTLS_STR_H
26# define GNUTLS_STR_H
27
28#include <gnutls_int.h>
29
30#define MAX(X,Y) ((X) > (Y) ? (X) : (Y));
31
32void _gnutls_str_cpy (char *dest, size_t dest_tot_size, const char *src);
33void _gnutls_mem_cpy (char *dest, size_t dest_tot_size, const char *src,
34 size_t src_size);
35void _gnutls_str_cat (char *dest, size_t dest_tot_size, const char *src);
36
37typedef struct
38{
39 opaque * data;
40 size_t max_length;
41 size_t length;
42 gnutls_realloc_function realloc_func;
43 gnutls_alloc_function alloc_func;
44 gnutls_free_function free_func;
45} gnutls_string;
46
47void _gnutls_string_init (gnutls_string *, gnutls_alloc_function,
48 gnutls_realloc_function, gnutls_free_function);
49void _gnutls_string_clear (gnutls_string *);
50
51/* Beware, do not clear the string, after calling this
52 * function
53 */
54gnutls_datum_t _gnutls_string2datum (gnutls_string * str);
55
56int _gnutls_string_copy_str (gnutls_string * dest, const char *src);
57int _gnutls_string_append_str (gnutls_string *, const char *str);
58int _gnutls_string_append_data (gnutls_string *, const void *data,
59 size_t data_size);
60int _gnutls_string_append_printf (gnutls_string * dest, const char *fmt, ...);
61
62char *_gnutls_bin2hex (const void *old, size_t oldlen, char *buffer,
63 size_t buffer_size);
64int _gnutls_hex2bin (const opaque * hex_data, int hex_size, opaque * bin_data,
65 size_t * bin_size);
66
67#endif
diff --git a/src/daemon/https/tls/gnutls_supplemental.c b/src/daemon/https/tls/gnutls_supplemental.c
new file mode 100644
index 00000000..a47b9aaa
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_supplemental.c
@@ -0,0 +1,207 @@
1/*
2 * Copyright (C) 2007 Free Software Foundation
3 *
4 * Author: Simon Josefsson
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file contains support functions for 'TLS Handshake Message for
26 * Supplemental Data' (RFC 4680).
27 *
28 * The idea here is simple. gnutls_handshake() in gnuts_handshake.c
29 * will call _gnutls_gen_supplemental and _gnutls_parse_supplemental
30 * when some extension requested that supplemental data be sent or
31 * received. Extension request this by setting the flags
32 * do_recv_supplemental or do_send_supplemental in the session.
33 *
34 * The functions in this file iterate through the _gnutls_supplemental
35 * array, and calls the send/recv functions for each respective data
36 * type.
37 *
38 * The receive function of each data type is responsible for decoding
39 * its own data. If the extension did not expect to receive
40 * supplemental data, it should return GNUTLS_E_UNEXPECTED_PACKET.
41 * Otherwise, it just parse the data as normal.
42 *
43 * The send function needs to append the 2-byte data format type, and
44 * append the 2-byte length of its data, and the data. If it doesn't
45 * want to send any data, it is fine to return without doing anything.
46 */
47
48#include "gnutls_int.h"
49#include "gnutls_supplemental.h"
50#include "gnutls_errors.h"
51#include "gnutls_num.h"
52
53typedef int (*supp_recv_func) (gnutls_session_t session,
54 const opaque * data, size_t data_size);
55typedef int (*supp_send_func) (gnutls_session_t session, gnutls_buffer * buf);
56
57typedef struct
58{
59 const char *name;
60 gnutls_supplemental_data_format_type_t type;
61 supp_recv_func supp_recv_func;
62 supp_send_func supp_send_func;
63} gnutls_supplemental_entry;
64
65gnutls_supplemental_entry _gnutls_supplemental[] = {
66 {0, 0, 0, 0}
67};
68
69const char *
70gnutls_supplemental_get_name (gnutls_supplemental_data_format_type_t type)
71{
72 gnutls_supplemental_entry *p;
73
74 for (p = _gnutls_supplemental; p->name != NULL; p++)
75 if (p->type == type)
76 return p->name;
77
78 return NULL;
79}
80
81static supp_recv_func
82get_supp_func_recv (gnutls_supplemental_data_format_type_t type)
83{
84 gnutls_supplemental_entry *p;
85
86 for (p = _gnutls_supplemental; p->name != NULL; p++)
87 if (p->type == type)
88 return p->supp_recv_func;
89
90 return NULL;
91}
92
93int
94_gnutls_gen_supplemental (gnutls_session_t session, gnutls_buffer * buf)
95{
96 gnutls_supplemental_entry *p;
97 int ret;
98
99 /* Make room for 3 byte length field. */
100 ret = _gnutls_buffer_append (buf, "\0\0\0", 3);
101 if (ret < 0)
102 {
103 gnutls_assert ();
104 return ret;
105 }
106
107 for (p = _gnutls_supplemental; p->name; p++)
108 {
109 supp_send_func supp_send = p->supp_send_func;
110 size_t sizepos = buf->length;
111 int ret;
112
113 /* Make room for supplement type and length byte length field. */
114 ret = _gnutls_buffer_append (buf, "\0\0\0\0", 4);
115 if (ret < 0)
116 {
117 gnutls_assert ();
118 return ret;
119 }
120
121 ret = supp_send (session, buf);
122 if (ret < 0)
123 {
124 gnutls_assert ();
125 return ret;
126 }
127
128 /* If data were added, store type+length, otherwise reset. */
129 if (buf->length > sizepos + 4)
130 {
131 buf->data[sizepos] = 0;
132 buf->data[sizepos + 1] = p->type;
133 buf->data[sizepos + 2] = ((buf->length - sizepos - 4) >> 8) & 0xFF;
134 buf->data[sizepos + 3] = (buf->length - sizepos - 4) & 0xFF;
135 }
136 else
137 buf->length -= 4;
138 }
139
140 buf->data[0] = ((buf->length - 3) >> 16) & 0xFF;
141 buf->data[1] = ((buf->length - 3) >> 8) & 0xFF;
142 buf->data[2] = (buf->length - 3) & 0xFF;
143
144 _gnutls_debug_log ("EXT[%x]: Sending %d bytes of supplemental data\n",
145 session, buf->length);
146
147 return buf->length;
148}
149
150int
151_gnutls_parse_supplemental (gnutls_session_t session,
152 const uint8_t * data, int datalen)
153{
154 const opaque *p = data;
155 ssize_t dsize = datalen;
156 size_t total_size;
157
158 DECR_LEN (dsize, 3);
159 total_size = _gnutls_read_uint24 (p);
160 p += 3;
161
162 if (dsize != total_size)
163 {
164 gnutls_assert ();
165 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
166 }
167
168 do
169 {
170 uint16_t supp_data_type;
171 uint16_t supp_data_length;
172 supp_recv_func recv_func;
173
174 DECR_LEN (dsize, 2);
175 supp_data_type = _gnutls_read_uint16 (p);
176 p += 2;
177
178 DECR_LEN (dsize, 2);
179 supp_data_length = _gnutls_read_uint16 (p);
180 p += 2;
181
182 _gnutls_debug_log ("EXT[%x]: Got supplemental type=%02x length=%d\n",
183 session, supp_data_type, supp_data_length);
184
185 recv_func = get_supp_func_recv (supp_data_type);
186 if (recv_func)
187 {
188 int ret = recv_func (session, p, supp_data_length);
189 if (ret < 0)
190 {
191 gnutls_assert ();
192 return ret;
193 }
194 }
195 else
196 {
197 gnutls_assert ();
198 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER;
199 }
200
201 DECR_LEN (dsize, supp_data_length);
202 p += supp_data_length;
203 }
204 while (dsize > 0);
205
206 return 0;
207}
diff --git a/src/daemon/https/tls/gnutls_supplemental.h b/src/daemon/https/tls/gnutls_supplemental.h
new file mode 100644
index 00000000..0b9c1207
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_supplemental.h
@@ -0,0 +1,31 @@
1/*
2 * Copyright (C) 2007 Free Software Foundation
3 *
4 * Author: Simon Josefsson
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26
27int _gnutls_parse_supplemental (gnutls_session_t session,
28 const uint8_t *data,
29 int data_size);
30int _gnutls_gen_supplemental (gnutls_session_t session,
31 gnutls_buffer *buf);
diff --git a/src/daemon/https/tls/gnutls_ui.c b/src/daemon/https/tls/gnutls_ui.c
new file mode 100644
index 00000000..49ed2e96
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_ui.c
@@ -0,0 +1,627 @@
1/*
2 * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file contains certificate authentication functions to be exported in the
26 * API and did not fit elsewhere.
27 */
28
29#include <gnutls_int.h>
30#include <auth_anon.h>
31#include <auth_cert.h>
32#include <gnutls_errors.h>
33#include <gnutls_auth_int.h>
34#include <gnutls_state.h>
35#include <gnutls_datum.h>
36
37/* ANON & DHE */
38
39/**
40 * gnutls_dh_set_prime_bits - Used to set the bits for a DH ciphersuite
41 * @session: is a #gnutls_session_t structure.
42 * @bits: is the number of bits
43 *
44 * This function sets the number of bits, for use in an
45 * Diffie Hellman key exchange. This is used both in DH ephemeral and
46 * DH anonymous cipher suites. This will set the
47 * minimum size of the prime that will be used for the handshake.
48 *
49 * In the client side it sets the minimum accepted number of bits.
50 * If a server sends a prime with less bits than that
51 * GNUTLS_E_DH_PRIME_UNACCEPTABLE will be returned by the
52 * handshake.
53 *
54 **/
55void
56gnutls_dh_set_prime_bits (gnutls_session_t session, unsigned int bits)
57{
58 session->internals.dh_prime_bits = bits;
59}
60
61/**
62 * gnutls_dh_get_group - This function returns the group of the DH authentication
63 * @session: is a gnutls session
64 * @raw_gen: will hold the generator.
65 * @raw_prime: will hold the prime.
66 *
67 * This function will return the group parameters used in the last Diffie Hellman
68 * authentication with the peer. These are the prime and the generator used.
69 * This function should be used for both anonymous and ephemeral diffie Hellman.
70 * The output parameters must be freed with gnutls_free().
71 *
72 * Returns a negative value in case of an error.
73 *
74 **/
75int
76gnutls_dh_get_group (gnutls_session_t session,
77 gnutls_datum_t * raw_gen, gnutls_datum_t * raw_prime)
78{
79 dh_info_st *dh;
80 int ret;
81 anon_auth_info_t anon_info;
82 cert_auth_info_t cert_info;
83
84 switch (gnutls_auth_get_type (session))
85 {
86 case GNUTLS_CRD_ANON:
87 anon_info = _gnutls_get_auth_info (session);
88 if (anon_info == NULL)
89 return GNUTLS_E_INTERNAL_ERROR;
90 dh = &anon_info->dh;
91 break;
92 case GNUTLS_CRD_CERTIFICATE:
93 cert_info = _gnutls_get_auth_info (session);
94 if (cert_info == NULL)
95 return GNUTLS_E_INTERNAL_ERROR;
96 dh = &cert_info->dh;
97 break;
98 default:
99 gnutls_assert ();
100 return GNUTLS_E_INVALID_REQUEST;
101 }
102
103 ret = _gnutls_set_datum (raw_prime, dh->prime.data, dh->prime.size);
104 if (ret < 0)
105 {
106 gnutls_assert ();
107 return ret;
108 }
109
110 ret = _gnutls_set_datum (raw_gen, dh->generator.data, dh->generator.size);
111 if (ret < 0)
112 {
113 gnutls_assert ();
114 _gnutls_free_datum (raw_prime);
115 return ret;
116 }
117
118 return 0;
119}
120
121/**
122 * gnutls_dh_get_pubkey - This function returns the peer's public key used in DH authentication
123 * @session: is a gnutls session
124 * @raw_key: will hold the public key.
125 *
126 * This function will return the peer's public key used in the last Diffie Hellman authentication.
127 * This function should be used for both anonymous and ephemeral diffie Hellman.
128 * The output parameters must be freed with gnutls_free().
129 *
130 * Returns a negative value in case of an error.
131 *
132 **/
133int
134gnutls_dh_get_pubkey (gnutls_session_t session, gnutls_datum_t * raw_key)
135{
136 dh_info_st *dh;
137 anon_auth_info_t anon_info;
138 cert_auth_info_t cert_info;
139 cert_auth_info_t psk_info;
140
141 switch (gnutls_auth_get_type (session))
142 {
143 case GNUTLS_CRD_ANON:
144 {
145 anon_info = _gnutls_get_auth_info (session);
146 if (anon_info == NULL)
147 return GNUTLS_E_INTERNAL_ERROR;
148 dh = &anon_info->dh;
149 break;
150 }
151 case GNUTLS_CRD_PSK:
152 {
153 psk_info = _gnutls_get_auth_info (session);
154 if (psk_info == NULL)
155 return GNUTLS_E_INTERNAL_ERROR;
156 dh = &psk_info->dh;
157 break;
158 }
159 case GNUTLS_CRD_CERTIFICATE:
160 {
161
162 cert_info = _gnutls_get_auth_info (session);
163 if (cert_info == NULL)
164 return GNUTLS_E_INTERNAL_ERROR;
165 dh = &cert_info->dh;
166 break;
167 }
168 default:
169 gnutls_assert ();
170 return GNUTLS_E_INVALID_REQUEST;
171 }
172
173 return _gnutls_set_datum (raw_key, dh->public_key.data,
174 dh->public_key.size);
175}
176
177/**
178 * gnutls_rsa_export_get_pubkey - This function returns the peer's public key used in RSA-EXPORT authentication
179 * @session: is a gnutls session
180 * @exponent: will hold the exponent.
181 * @modulus: will hold the modulus.
182 *
183 * This function will return the peer's public key exponent and
184 * modulus used in the last RSA-EXPORT authentication. The output
185 * parameters must be freed with gnutls_free().
186 *
187 * Returns a negative value in case of an error.
188 *
189 **/
190int
191gnutls_rsa_export_get_pubkey (gnutls_session_t session,
192 gnutls_datum_t * exponent,
193 gnutls_datum_t * modulus)
194{
195 cert_auth_info_t info;
196 int ret;
197
198 if (gnutls_auth_get_type (session) == GNUTLS_CRD_CERTIFICATE)
199 {
200 info = _gnutls_get_auth_info (session);
201 if (info == NULL)
202 return GNUTLS_E_INTERNAL_ERROR;
203
204 ret = _gnutls_set_datum (modulus, info->rsa_export.modulus.data,
205 info->rsa_export.modulus.size);
206 if (ret < 0)
207 {
208 gnutls_assert ();
209 return ret;
210 }
211
212 ret = _gnutls_set_datum (exponent, info->rsa_export.exponent.data,
213 info->rsa_export.exponent.size);
214 if (ret < 0)
215 {
216 gnutls_assert ();
217 _gnutls_free_datum (modulus);
218 return ret;
219 }
220
221 return 0;
222 }
223
224 return GNUTLS_E_INVALID_REQUEST;
225}
226
227/**
228 * gnutls_dh_get_secret_bits - This function returns the bits used in DH authentication
229 * @session: is a gnutls session
230 *
231 * This function will return the bits used in the last Diffie Hellman authentication
232 * with the peer. Should be used for both anonymous and ephemeral diffie Hellman.
233 * Returns a negative value in case of an error.
234 *
235 **/
236int
237gnutls_dh_get_secret_bits (gnutls_session_t session)
238{
239 switch (gnutls_auth_get_type (session))
240 {
241 case GNUTLS_CRD_ANON:
242 {
243 anon_auth_info_t info;
244
245 info = _gnutls_get_auth_info (session);
246 if (info == NULL)
247 return GNUTLS_E_INTERNAL_ERROR;
248 return info->dh.secret_bits;
249 }
250 case GNUTLS_CRD_CERTIFICATE:
251 {
252 cert_auth_info_t info;
253
254 info = _gnutls_get_auth_info (session);
255 if (info == NULL)
256 return GNUTLS_E_INTERNAL_ERROR;
257
258 return info->dh.secret_bits;
259 }
260 default:
261 gnutls_assert ();
262 return GNUTLS_E_INVALID_REQUEST;
263 }
264}
265
266/**
267 * gnutls_dh_get_prime_bits - This function returns the bits used in DH authentication
268 * @session: is a gnutls session
269 *
270 * This function will return the bits of the prime used in the last Diffie Hellman authentication
271 * with the peer. Should be used for both anonymous and ephemeral diffie Hellman.
272 * Returns a negative value in case of an error.
273 *
274 **/
275int
276gnutls_dh_get_prime_bits (gnutls_session_t session)
277{
278 dh_info_st *dh;
279
280 switch (gnutls_auth_get_type (session))
281 {
282 case GNUTLS_CRD_ANON:
283 {
284 anon_auth_info_t info;
285
286 info = _gnutls_get_auth_info (session);
287 if (info == NULL)
288 return GNUTLS_E_INTERNAL_ERROR;
289 dh = &info->dh;
290 break;
291 }
292 case GNUTLS_CRD_CERTIFICATE:
293 {
294 cert_auth_info_t info;
295
296 info = _gnutls_get_auth_info (session);
297 if (info == NULL)
298 return GNUTLS_E_INTERNAL_ERROR;
299
300 dh = &info->dh;
301 break;
302 }
303 default:
304 gnutls_assert ();
305 return GNUTLS_E_INVALID_REQUEST;
306 }
307
308 return (dh->prime.size) * 8;
309
310}
311
312/**
313 * gnutls_rsa_export_get_modulus_bits - This function returns the bits used in RSA-export key exchange
314 * @session: is a gnutls session
315 *
316 * This function will return the bits used in the last RSA-EXPORT key exchange
317 * with the peer.
318 * Returns a negative value in case of an error.
319 *
320 **/
321int
322gnutls_rsa_export_get_modulus_bits (gnutls_session_t session)
323{
324 cert_auth_info_t info;
325
326 info = _gnutls_get_auth_info (session);
327 if (info == NULL)
328 return GNUTLS_E_INTERNAL_ERROR;
329
330 return info->rsa_export.modulus.size * 8;
331}
332
333/**
334 * gnutls_dh_get_peers_public_bits - This function returns the bits used in DH authentication
335 * @session: is a gnutls session
336 *
337 * This function will return the bits used in the last Diffie Hellman authentication
338 * with the peer. Should be used for both anonymous and ephemeral diffie Hellman.
339 * Returns a negative value in case of an error.
340 *
341 **/
342int
343gnutls_dh_get_peers_public_bits (gnutls_session_t session)
344{
345 dh_info_st *dh;
346
347 switch (gnutls_auth_get_type (session))
348 {
349 case GNUTLS_CRD_ANON:
350 {
351 anon_auth_info_t info;
352
353 info = _gnutls_get_auth_info (session);
354 if (info == NULL)
355 return GNUTLS_E_INTERNAL_ERROR;
356
357 dh = &info->dh;
358 break;
359 }
360 case GNUTLS_CRD_CERTIFICATE:
361 {
362 cert_auth_info_t info;
363
364 info = _gnutls_get_auth_info (session);
365 if (info == NULL)
366 return GNUTLS_E_INTERNAL_ERROR;
367
368 dh = &info->dh;
369 break;
370 }
371 default:
372 gnutls_assert ();
373 return GNUTLS_E_INVALID_REQUEST;
374 }
375
376 return dh->public_key.size * 8;
377
378}
379
380/* CERTIFICATE STUFF */
381
382/**
383 * gnutls_certificate_get_ours - This function returns the raw certificate sent in the last handshake
384 * @session: is a gnutls session
385 *
386 * This function will return the certificate as sent to the peer,
387 * in the last handshake. These certificates are in raw format.
388 * In X.509 this is a certificate list. In OpenPGP this is a single
389 * certificate.
390 * Returns NULL in case of an error, or if no certificate was used.
391 *
392 **/
393const gnutls_datum_t *
394gnutls_certificate_get_ours (gnutls_session_t session)
395{
396 gnutls_certificate_credentials_t cred;
397
398 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, NULL);
399
400 cred
401 = (gnutls_certificate_credentials_t) _gnutls_get_cred (session->key,
402 GNUTLS_CRD_CERTIFICATE,
403 NULL);
404 if (cred == NULL || cred->cert_list == NULL)
405 {
406 gnutls_assert ();
407 return NULL;
408 }
409
410 if (session->internals.selected_cert_list == NULL)
411 return NULL;
412
413 return &session->internals.selected_cert_list[0].raw;
414}
415
416/**
417 * gnutls_certificate_get_peers - This function returns the peer's raw certificate
418 * @session: is a gnutls session
419 * @list_size: is the length of the certificate list
420 *
421 * This function will return the peer's raw certificate (chain) as
422 * sent by the peer. These certificates are in raw format (DER encoded
423 * for X.509). In case of a X.509 then a certificate list may be present.
424 * The first certificate in the list is the peer's certificate,
425 * following the issuer's certificate, then the issuer's issuer etc.
426 *
427 * In case of OpenPGP keys a single key will be returned
428 * in raw format.
429 *
430 * Returns NULL in case of an error, or if no certificate was sent.
431 *
432 **/
433const gnutls_datum_t *
434gnutls_certificate_get_peers (gnutls_session_t
435 session, unsigned int *list_size)
436{
437 cert_auth_info_t info;
438
439 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, NULL);
440
441 info = _gnutls_get_auth_info (session);
442 if (info == NULL)
443 return NULL;
444
445 *list_size = info->ncerts;
446 return info->raw_certificate_list;
447}
448
449/**
450 * gnutls_certificate_client_get_request_status - This function returns the certificate request status
451 * @session: is a gnutls session
452 *
453 * This function will return 0 if the peer (server) did not request client
454 * authentication or 1 otherwise.
455 * Returns a negative value in case of an error.
456 *
457 **/
458int
459gnutls_certificate_client_get_request_status (gnutls_session_t session)
460{
461 cert_auth_info_t info;
462
463 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, 0);
464
465 info = _gnutls_get_auth_info (session);
466 if (info == NULL)
467 return GNUTLS_E_INTERNAL_ERROR;
468 return info->certificate_requested;
469}
470
471/**
472 * gnutls_fingerprint - This function calculates the fingerprint of the given data
473 * @algo: is a digest algorithm
474 * @data: is the data
475 * @result: is the place where the result will be copied (may be null).
476 * @result_size: should hold the size of the result. The actual size
477 * of the returned result will also be copied there.
478 *
479 * This function will calculate a fingerprint (actually a hash), of the
480 * given data. The result is not printable data. You should convert it
481 * to hex, or to something else printable.
482 *
483 * This is the usual way to calculate a fingerprint of an X.509
484 * DER encoded certificate. Note however that the fingerprint
485 * of an OpenPGP is not just a hash and cannot be calculated with
486 * this function.
487 *
488 * Returns a negative value in case of an error.
489 *
490 **/
491int
492gnutls_fingerprint (gnutls_digest_algorithm_t algo,
493 const gnutls_datum_t * data,
494 void *result, size_t * result_size)
495{
496 GNUTLS_HASH_HANDLE td;
497 int hash_len = _gnutls_hash_get_algo_len (HASH2MAC (algo));
498
499 if (hash_len < 0 || (unsigned) hash_len > *result_size || result == NULL)
500 {
501 *result_size = hash_len;
502 return GNUTLS_E_SHORT_MEMORY_BUFFER;
503 }
504 *result_size = hash_len;
505
506 if (result)
507 {
508 td = _gnutls_hash_init (HASH2MAC (algo));
509 if (td == NULL)
510 return GNUTLS_E_HASH_FAILED;
511
512 _gnutls_hash (td, data->data, data->size);
513
514 _gnutls_hash_deinit (td, result);
515 }
516
517 return 0;
518}
519
520/**
521 * gnutls_certificate_set_dh_params - This function will set the DH parameters for a server to use
522 * @res: is a gnutls_certificate_credentials_t structure
523 * @dh_params: is a structure that holds diffie hellman parameters.
524 *
525 * This function will set the diffie hellman parameters for a
526 * certificate server to use. These parameters will be used in
527 * Ephemeral Diffie Hellman cipher suites. Note that only a pointer
528 * to the parameters are stored in the certificate handle, so if you
529 * deallocate the parameters before the certificate is deallocated,
530 * you must change the parameters stored in the certificate first.
531 *
532 **/
533void
534gnutls_certificate_set_dh_params (gnutls_certificate_credentials_t res,
535 gnutls_dh_params_t dh_params)
536{
537 res->dh_params = dh_params;
538}
539
540/**
541 * gnutls_certificate_set_params_function - This function will set the DH or RSA parameters callback
542 * @res: is a gnutls_certificate_credentials_t structure
543 * @func: is the function to be called
544 *
545 * This function will set a callback in order for the server to get the
546 * diffie hellman or RSA parameters for certificate authentication. The callback
547 * should return zero on success.
548 *
549 **/
550void
551gnutls_certificate_set_params_function (gnutls_certificate_credentials_t res,
552 gnutls_params_function * func)
553{
554 res->params_func = func;
555}
556
557/**
558 * gnutls_certificate_set_verify_flags - This function will set the flags to be used at certificate verification
559 * @res: is a gnutls_certificate_credentials_t structure
560 * @flags: are the flags
561 *
562 * This function will set the flags to be used at verification of the
563 * certificates. Flags must be OR of the
564 * #gnutls_certificate_verify_flags enumerations.
565 *
566 **/
567void
568gnutls_certificate_set_verify_flags (gnutls_certificate_credentials_t
569 res, unsigned int flags)
570{
571 res->verify_flags = flags;
572}
573
574/**
575 * gnutls_certificate_set_verify_limits - This function will set the upper limits to be used at certificate verification
576 * @res: is a gnutls_certificate_credentials structure
577 * @max_bits: is the number of bits of an acceptable certificate (default 8200)
578 * @max_depth: is maximum depth of the verification of a certificate chain (default 5)
579 *
580 * This function will set some upper limits for the default verification function,
581 * gnutls_certificate_verify_peers2(), to avoid denial of service attacks.
582 * You can set them to zero to disable limits.
583 *
584 **/
585void
586gnutls_certificate_set_verify_limits (gnutls_certificate_credentials_t
587 res,
588 unsigned int max_bits,
589 unsigned int max_depth)
590{
591 res->verify_depth = max_depth;
592 res->verify_bits = max_bits;
593}
594
595/**
596 * gnutls_certificate_set_rsa_export_params - This function will set the RSA parameters for a server to use
597 * @res: is a gnutls_certificate_credentials_t structure
598 * @rsa_params: is a structure that holds temporary RSA parameters.
599 *
600 * This function will set the temporary RSA parameters for a certificate
601 * server to use. These parameters will be used in RSA-EXPORT
602 * cipher suites.
603 *
604 **/
605void
606gnutls_certificate_set_rsa_export_params (gnutls_certificate_credentials_t
607 res, gnutls_rsa_params_t rsa_params)
608{
609 res->rsa_params = rsa_params;
610}
611
612/**
613 * gnutls_anon_set_params_function - This function will set the DH or RSA parameters callback
614 * @res: is a gnutls_anon_server_credentials_t structure
615 * @func: is the function to be called
616 *
617 * This function will set a callback in order for the server to get the
618 * diffie hellman or RSA parameters for anonymous authentication. The callback
619 * should return zero on success.
620 *
621 **/
622void
623gnutls_anon_set_params_function (gnutls_anon_server_credentials_t res,
624 gnutls_params_function * func)
625{
626 res->params_func = func;
627}
diff --git a/src/daemon/https/tls/gnutls_v2_compat.c b/src/daemon/https/tls/gnutls_v2_compat.c
new file mode 100644
index 00000000..ecf8c936
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_v2_compat.c
@@ -0,0 +1,259 @@
1/*
2 * Copyright (C) 2001, 2004, 2005, 2006 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* Functions to parse the SSLv2.0 hello message.
26 */
27
28#include "gnutls_int.h"
29#include "gnutls_errors.h"
30#include "gnutls_dh.h"
31#include "debug.h"
32#include "gnutls_algorithms.h"
33#include "gnutls_compress.h"
34#include "gnutls_cipher.h"
35#include "gnutls_buffers.h"
36#include "gnutls_kx.h"
37#include "gnutls_handshake.h"
38#include "gnutls_num.h"
39#include "gnutls_hash_int.h"
40#include "gnutls_db.h"
41#include "gnutls_extensions.h"
42#include "gnutls_auth_int.h"
43
44/* This selects the best supported ciphersuite from the ones provided */
45static int
46_gnutls_handshake_select_v2_suite (gnutls_session_t session,
47 opaque * data, int datalen)
48{
49 int i, j, ret;
50 opaque *_data;
51 int _datalen;
52
53 _gnutls_handshake_log ("HSK[%x]: Parsing a version 2.0 client hello.\n",
54 session);
55
56 _data = gnutls_malloc (datalen);
57 if (_data == NULL)
58 {
59 gnutls_assert ();
60 return GNUTLS_E_MEMORY_ERROR;
61 }
62
63 if (datalen % 3 != 0)
64 {
65 gnutls_assert ();
66 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
67 }
68
69 i = _datalen = 0;
70 for (j = 0; j < datalen; j += 3)
71 {
72 if (data[j] == 0)
73 {
74 memcpy (&_data[i], &data[j + 1], 2);
75 i += 2;
76 _datalen += 2;
77 }
78 }
79
80 ret = _gnutls_server_select_suite (session, _data, _datalen);
81 gnutls_free (_data);
82
83 return ret;
84
85}
86
87
88/* Read a v2 client hello. Some browsers still use that beast!
89 * However they set their version to 3.0 or 3.1.
90 */
91int
92_gnutls_read_client_hello_v2 (gnutls_session_t session, opaque * data,
93 int datalen)
94{
95 uint16_t session_id_len = 0;
96 int pos = 0;
97 int ret = 0;
98 uint16_t sizeOfSuites;
99 gnutls_protocol_t adv_version;
100 opaque rnd[TLS_RANDOM_SIZE];
101 int len = datalen;
102 int err;
103 uint16_t challenge;
104 opaque session_id[TLS_MAX_SESSION_ID_SIZE];
105
106 /* we only want to get here once - only in client hello */
107 session->internals.v2_hello = 0;
108
109 DECR_LEN (len, 2);
110
111 _gnutls_handshake_log
112 ("HSK[%x]: SSL 2.0 Hello: Client's version: %d.%d\n", session,
113 data[pos], data[pos + 1]);
114
115 set_adv_version (session, data[pos], data[pos + 1]);
116
117 adv_version = _gnutls_version_get (data[pos], data[pos + 1]);
118
119 ret = _gnutls_negotiate_version (session, adv_version);
120 if (ret < 0)
121 {
122 gnutls_assert ();
123 return ret;
124 }
125
126 pos += 2;
127
128 /* Read uint16_t cipher_spec_length */
129 DECR_LEN (len, 2);
130 sizeOfSuites = _gnutls_read_uint16 (&data[pos]);
131 pos += 2;
132
133 /* read session id length */
134 DECR_LEN (len, 2);
135 session_id_len = _gnutls_read_uint16 (&data[pos]);
136 pos += 2;
137
138 if (session_id_len > TLS_MAX_SESSION_ID_SIZE)
139 {
140 gnutls_assert ();
141 return GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
142 }
143
144 /* read challenge length */
145 DECR_LEN (len, 2);
146 challenge = _gnutls_read_uint16 (&data[pos]);
147 pos += 2;
148
149 if (challenge < 16 || challenge > TLS_RANDOM_SIZE)
150 {
151 gnutls_assert ();
152 return GNUTLS_E_UNSUPPORTED_VERSION_PACKET;
153 }
154
155 /* call the user hello callback
156 */
157 ret = _gnutls_user_hello_func (session, adv_version);
158 if (ret < 0)
159 {
160 gnutls_assert ();
161 return ret;
162 }
163
164 /* find an appropriate cipher suite */
165
166 DECR_LEN (len, sizeOfSuites);
167 ret = _gnutls_handshake_select_v2_suite (session, &data[pos], sizeOfSuites);
168
169 pos += sizeOfSuites;
170 if (ret < 0)
171 {
172 gnutls_assert ();
173 return ret;
174 }
175
176 /* check if the credentials (username, public key etc.) are ok
177 */
178 if (_gnutls_get_kx_cred
179 (session,
180 _gnutls_cipher_suite_get_kx_algo (&session->security_parameters.
181 current_cipher_suite),
182 &err) == NULL && err != 0)
183 {
184 gnutls_assert ();
185 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
186 }
187
188 /* set the mod_auth_st to the appropriate struct
189 * according to the KX algorithm. This is needed since all the
190 * handshake functions are read from there;
191 */
192 session->internals.auth_struct =
193 _gnutls_kx_auth_struct (_gnutls_cipher_suite_get_kx_algo
194 (&session->security_parameters.
195 current_cipher_suite));
196 if (session->internals.auth_struct == NULL)
197 {
198
199 _gnutls_handshake_log
200 ("HSK[%x]: SSL 2.0 Hello: Cannot find the appropriate handler for the KX algorithm\n",
201 session);
202
203 gnutls_assert ();
204 return GNUTLS_E_INTERNAL_ERROR;
205 }
206
207
208
209 /* read random new values -skip session id for now */
210 DECR_LEN (len, session_id_len); /* skip session id for now */
211 memcpy (session_id, &data[pos], session_id_len);
212 pos += session_id_len;
213
214 DECR_LEN (len, challenge);
215 memset (rnd, 0, TLS_RANDOM_SIZE);
216
217 memcpy (&rnd[TLS_RANDOM_SIZE - challenge], &data[pos], challenge);
218
219 _gnutls_set_client_random (session, rnd);
220
221 /* generate server random value */
222
223 _gnutls_tls_create_random (rnd);
224 _gnutls_set_server_random (session, rnd);
225
226 session->security_parameters.timestamp = time (NULL);
227
228
229 /* RESUME SESSION */
230
231 DECR_LEN (len, session_id_len);
232 ret = _gnutls_server_restore_session (session, session_id, session_id_len);
233
234 if (ret == 0)
235 { /* resumed! */
236 /* get the new random values */
237 memcpy (session->internals.resumed_security_parameters.
238 server_random, session->security_parameters.server_random,
239 TLS_RANDOM_SIZE);
240 memcpy (session->internals.resumed_security_parameters.
241 client_random, session->security_parameters.client_random,
242 TLS_RANDOM_SIZE);
243
244 session->internals.resumed = RESUME_TRUE;
245 return 0;
246 }
247 else
248 {
249 _gnutls_generate_session_id (session->security_parameters.
250 session_id,
251 &session->security_parameters.
252 session_id_size);
253 session->internals.resumed = RESUME_FALSE;
254 }
255
256 session->internals.compression_method = GNUTLS_COMP_NULL;
257
258 return 0;
259}
diff --git a/src/daemon/https/tls/gnutls_v2_compat.h b/src/daemon/https/tls/gnutls_v2_compat.h
new file mode 100644
index 00000000..59ee6130
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_v2_compat.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25int _gnutls_read_client_hello_v2 (gnutls_session_t session, opaque * data,
26 int datalen);
diff --git a/src/daemon/https/tls/gnutls_x509.c b/src/daemon/https/tls/gnutls_x509.c
new file mode 100644
index 00000000..29d20957
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_x509.c
@@ -0,0 +1,1991 @@
1/*
2 * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26#include "gnutls_auth_int.h"
27#include "gnutls_errors.h"
28#include <gnutls_cert.h>
29#include <auth_cert.h>
30#include "gnutls_dh.h"
31#include "gnutls_num.h"
32#include "libtasn1.h"
33#include "gnutls_datum.h"
34#include <gnutls_pk.h>
35#include <gnutls_algorithms.h>
36#include <gnutls_global.h>
37#include <gnutls_record.h>
38#include <gnutls_sig.h>
39#include <gnutls_state.h>
40#include <gnutls_pk.h>
41#include <gnutls_str.h>
42#include <debug.h>
43#include <x509_b64.h>
44#include <gnutls_x509.h>
45#include <read-file.h>
46
47/* x509 */
48#include "common.h"
49#include "x509.h"
50#include "verify.h"
51#include "mpi.h"
52#include "pkcs7.h"
53#include "privkey.h"
54
55
56/*
57 * some x509 certificate parsing functions.
58 */
59
60/* Check if the number of bits of the key in the certificate
61 * is unacceptable.
62 */
63inline static int
64check_bits (gnutls_x509_crt_t crt, unsigned int max_bits)
65{
66 int ret;
67 unsigned int bits;
68
69 ret = gnutls_x509_crt_get_pk_algorithm (crt, &bits);
70 if (ret < 0)
71 {
72 gnutls_assert ();
73 return ret;
74 }
75
76 if (bits > max_bits && max_bits > 0)
77 {
78 gnutls_assert ();
79 return GNUTLS_E_CONSTRAINT_ERROR;
80 }
81
82 return 0;
83}
84
85
86#define CLEAR_CERTS for(x=0;x<peer_certificate_list_size;x++) { \
87 if (peer_certificate_list[x]) \
88 gnutls_x509_crt_deinit(peer_certificate_list[x]); \
89 } \
90 gnutls_free( peer_certificate_list)
91
92/*-
93 * _gnutls_x509_cert_verify_peers - This function returns the peer's certificate status
94 * @session: is a gnutls session
95 *
96 * This function will try to verify the peer's certificate and return its status (TRUSTED, REVOKED etc.).
97 * The return value (status) should be one of the gnutls_certificate_status_t enumerated elements.
98 * However you must also check the peer's name in order to check if the verified certificate belongs to the
99 * actual peer. Returns a negative error code in case of an error, or GNUTLS_E_NO_CERTIFICATE_FOUND if no certificate was sent.
100 *
101 -*/
102int
103_gnutls_x509_cert_verify_peers (gnutls_session_t session,
104 unsigned int *status)
105{
106 cert_auth_info_t info;
107 gnutls_certificate_credentials_t cred;
108 gnutls_x509_crt_t *peer_certificate_list;
109 int peer_certificate_list_size, i, x, ret;
110
111 CHECK_AUTH (GNUTLS_CRD_CERTIFICATE, GNUTLS_E_INVALID_REQUEST);
112
113 info = _gnutls_get_auth_info (session);
114 if (info == NULL)
115 {
116 gnutls_assert ();
117 return GNUTLS_E_INVALID_REQUEST;
118 }
119
120 cred = (gnutls_certificate_credentials_t)
121 _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
122 if (cred == NULL)
123 {
124 gnutls_assert ();
125 return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
126 }
127
128 if (info->raw_certificate_list == NULL || info->ncerts == 0)
129 return GNUTLS_E_NO_CERTIFICATE_FOUND;
130
131 if (info->ncerts > cred->verify_depth && cred->verify_depth > 0)
132 {
133 gnutls_assert ();
134 return GNUTLS_E_CONSTRAINT_ERROR;
135 }
136
137 /* generate a list of gnutls_certs based on the auth info
138 * raw certs.
139 */
140 peer_certificate_list_size = info->ncerts;
141 peer_certificate_list =
142 gnutls_calloc (1,
143 peer_certificate_list_size * sizeof (gnutls_x509_crt_t));
144 if (peer_certificate_list == NULL)
145 {
146 gnutls_assert ();
147 return GNUTLS_E_MEMORY_ERROR;
148 }
149
150 for (i = 0; i < peer_certificate_list_size; i++)
151 {
152 ret = gnutls_x509_crt_init (&peer_certificate_list[i]);
153 if (ret < 0)
154 {
155 gnutls_assert ();
156 CLEAR_CERTS;
157 return ret;
158 }
159
160 ret =
161 gnutls_x509_crt_import (peer_certificate_list[i],
162 &info->raw_certificate_list[i],
163 GNUTLS_X509_FMT_DER);
164 if (ret < 0)
165 {
166 gnutls_assert ();
167 CLEAR_CERTS;
168 return ret;
169 }
170
171 ret = check_bits (peer_certificate_list[i], cred->verify_bits);
172 if (ret < 0)
173 {
174 gnutls_assert ();
175 CLEAR_CERTS;
176 return ret;
177 }
178
179 }
180
181 /* Verify certificate
182 */
183 ret =
184 gnutls_x509_crt_list_verify (peer_certificate_list,
185 peer_certificate_list_size,
186 cred->x509_ca_list, cred->x509_ncas,
187 cred->x509_crl_list, cred->x509_ncrls,
188 cred->verify_flags, status);
189
190 CLEAR_CERTS;
191
192 if (ret < 0)
193 {
194 gnutls_assert ();
195 return ret;
196 }
197
198 return 0;
199}
200
201/*
202 * Read certificates and private keys, from files, memory etc.
203 */
204
205/* returns error if the certificate has different algorithm than
206 * the given key parameters.
207 */
208static int
209_gnutls_check_key_cert_match (gnutls_certificate_credentials_t res)
210{
211 gnutls_datum_t cid;
212 gnutls_datum_t kid;
213 unsigned pk = res->cert_list[res->ncerts - 1][0].subject_pk_algorithm;
214
215 if (res->pkey[res->ncerts - 1].pk_algorithm != pk)
216 {
217 gnutls_assert ();
218 return GNUTLS_E_CERTIFICATE_KEY_MISMATCH;
219 }
220
221 _gnutls_x509_write_rsa_params (res->pkey[res->ncerts - 1].params,
222 res->pkey[res->ncerts -
223 1].params_size, &kid);
224
225
226 _gnutls_x509_write_rsa_params (res->cert_list[res->ncerts - 1][0].
227 params,
228 res->cert_list[res->ncerts -
229 1][0].params_size, &cid);
230
231 if (cid.size != kid.size)
232 {
233 gnutls_assert ();
234 _gnutls_free_datum (&kid);
235 _gnutls_free_datum (&cid);
236 return GNUTLS_E_CERTIFICATE_KEY_MISMATCH;
237 }
238
239 if (memcmp (kid.data, cid.data, kid.size) != 0)
240 {
241 gnutls_assert ();
242 _gnutls_free_datum (&kid);
243 _gnutls_free_datum (&cid);
244 return GNUTLS_E_CERTIFICATE_KEY_MISMATCH;
245 }
246
247 _gnutls_free_datum (&kid);
248 _gnutls_free_datum (&cid);
249 return 0;
250}
251
252/* Reads a DER encoded certificate list from memory and stores it to
253 * a gnutls_cert structure. This is only called if PKCS7 read fails.
254 * returns the number of certificates parsed (1)
255 */
256static int
257parse_crt_mem (gnutls_cert ** cert_list, unsigned *ncerts,
258 gnutls_x509_crt_t cert)
259{
260 int i;
261 int ret;
262
263 i = *ncerts + 1;
264
265 *cert_list =
266 (gnutls_cert *) gnutls_realloc_fast (*cert_list,
267 i * sizeof (gnutls_cert));
268
269 if (*cert_list == NULL)
270 {
271 gnutls_assert ();
272 return GNUTLS_E_MEMORY_ERROR;
273 }
274
275 ret = _gnutls_x509_crt_to_gcert (&cert_list[0][i - 1], cert, 0);
276 if (ret < 0)
277 {
278 gnutls_assert ();
279 return ret;
280 }
281
282 *ncerts = i;
283
284 return 1; /* one certificate parsed */
285}
286
287/* Reads a DER encoded certificate list from memory and stores it to
288 * a gnutls_cert structure. This is only called if PKCS7 read fails.
289 * returns the number of certificates parsed (1)
290 */
291static int
292parse_der_cert_mem (gnutls_cert ** cert_list, unsigned *ncerts,
293 const void *input_cert, int input_cert_size)
294{
295 gnutls_datum_t tmp;
296 gnutls_x509_crt_t cert;
297 int ret;
298
299 ret = gnutls_x509_crt_init (&cert);
300 if (ret < 0)
301 {
302 gnutls_assert ();
303 return ret;
304 }
305
306 tmp.data = (opaque *) input_cert;
307 tmp.size = input_cert_size;
308
309 ret = gnutls_x509_crt_import (cert, &tmp, GNUTLS_X509_FMT_DER);
310 if (ret < 0)
311 {
312 gnutls_assert ();
313 gnutls_x509_crt_deinit (cert);
314 return ret;
315 }
316
317 ret = parse_crt_mem (cert_list, ncerts, cert);
318 gnutls_x509_crt_deinit (cert);
319
320 return ret;
321}
322
323#define CERT_PEM 1
324
325
326/* Reads a PKCS7 base64 encoded certificate list from memory and stores it to
327 * a gnutls_cert structure.
328 * returns the number of certificate parsed
329 */
330static int
331parse_pkcs7_cert_mem (gnutls_cert ** cert_list, unsigned *ncerts, const
332 void *input_cert, int input_cert_size, int flags)
333{
334#ifdef ENABLE_PKI
335 int i, j, count;
336 gnutls_datum_t tmp, tmp2;
337 int ret;
338 opaque *pcert = NULL;
339 size_t pcert_size;
340 gnutls_pkcs7_t pkcs7;
341
342 ret = gnutls_pkcs7_init (&pkcs7);
343 if (ret < 0)
344 {
345 gnutls_assert ();
346 return ret;
347 }
348
349 if (flags & CERT_PEM)
350 ret = gnutls_pkcs7_import (pkcs7, &tmp, GNUTLS_X509_FMT_PEM);
351 else
352 ret = gnutls_pkcs7_import (pkcs7, &tmp, GNUTLS_X509_FMT_DER);
353 if (ret < 0)
354 {
355 /* if we failed to read the structure,
356 * then just try to decode a plain DER
357 * certificate.
358 */
359 gnutls_assert ();
360 gnutls_pkcs7_deinit (pkcs7);
361#endif
362 return parse_der_cert_mem (cert_list, ncerts,
363 input_cert, input_cert_size);
364#ifdef ENABLE_PKI
365 }
366
367 i = *ncerts + 1;
368
369 /* tmp now contains the decoded certificate list */
370 tmp.data = (opaque *) input_cert;
371 tmp.size = input_cert_size;
372
373 ret = gnutls_pkcs7_get_crt_count (pkcs7);
374
375 if (ret < 0)
376 {
377 gnutls_assert ();
378 gnutls_pkcs7_deinit (pkcs7);
379 return ret;
380 }
381 count = ret;
382
383 j = count - 1;
384 do
385 {
386 pcert_size = 0;
387 ret = gnutls_pkcs7_get_crt_raw (pkcs7, j, NULL, &pcert_size);
388 if (ret != GNUTLS_E_MEMORY_ERROR)
389 {
390 count--;
391 continue;
392 }
393
394 pcert = gnutls_malloc (pcert_size);
395 if (ret == GNUTLS_E_MEMORY_ERROR)
396 {
397 gnutls_assert ();
398 count--;
399 continue;
400 }
401
402 /* read the certificate
403 */
404 ret = gnutls_pkcs7_get_crt_raw (pkcs7, j, pcert, &pcert_size);
405
406 j--;
407
408 if (ret >= 0)
409 {
410 *cert_list =
411 (gnutls_cert *) gnutls_realloc_fast (*cert_list,
412 i * sizeof (gnutls_cert));
413
414 if (*cert_list == NULL)
415 {
416 gnutls_assert ();
417 gnutls_free (pcert);
418 return GNUTLS_E_MEMORY_ERROR;
419 }
420
421 tmp2.data = pcert;
422 tmp2.size = pcert_size;
423
424 ret =
425 _gnutls_x509_raw_cert_to_gcert (&cert_list[0][i - 1], &tmp2, 0);
426
427 if (ret < 0)
428 {
429 gnutls_assert ();
430 gnutls_pkcs7_deinit (pkcs7);
431 gnutls_free (pcert);
432 return ret;
433 }
434
435 i++;
436 }
437
438 gnutls_free (pcert);
439
440 }
441 while (ret >= 0 && j >= 0);
442
443 *ncerts = i - 1;
444
445 gnutls_pkcs7_deinit (pkcs7);
446 return count;
447#endif
448}
449
450/* Reads a base64 encoded certificate list from memory and stores it to
451 * a gnutls_cert structure. Returns the number of certificate parsed.
452 */
453static int
454parse_pem_cert_mem (gnutls_cert ** cert_list, unsigned *ncerts,
455 const char *input_cert, int input_cert_size)
456{
457 int size, siz2, i;
458 const char *ptr;
459 opaque *ptr2;
460 gnutls_datum_t tmp;
461 int ret, count;
462
463#ifdef ENABLE_PKI
464 if ((ptr = memmem (input_cert, input_cert_size,
465 PEM_PKCS7_SEP, sizeof (PEM_PKCS7_SEP) - 1)) != NULL)
466 {
467 size = strlen (ptr);
468
469 ret = parse_pkcs7_cert_mem (cert_list, ncerts, ptr, size, CERT_PEM);
470
471 return ret;
472 }
473#endif
474
475 /* move to the certificate
476 */
477 ptr = memmem (input_cert, input_cert_size,
478 PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
479 if (ptr == NULL)
480 ptr = memmem (input_cert, input_cert_size,
481 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
482
483 if (ptr == NULL)
484 {
485 gnutls_assert ();
486 return GNUTLS_E_BASE64_DECODING_ERROR;
487 }
488 size = input_cert_size - (ptr - input_cert);
489
490 i = *ncerts + 1;
491 count = 0;
492
493 do
494 {
495
496 siz2 = _gnutls_fbase64_decode (NULL, ptr, size, &ptr2);
497
498 if (siz2 < 0)
499 {
500 gnutls_assert ();
501 return GNUTLS_E_BASE64_DECODING_ERROR;
502 }
503
504 *cert_list =
505 (gnutls_cert *) gnutls_realloc_fast (*cert_list,
506 i * sizeof (gnutls_cert));
507
508 if (*cert_list == NULL)
509 {
510 gnutls_assert ();
511 return GNUTLS_E_MEMORY_ERROR;
512 }
513
514 tmp.data = ptr2;
515 tmp.size = siz2;
516
517 ret = _gnutls_x509_raw_cert_to_gcert (&cert_list[0][i - 1], &tmp, 0);
518 if (ret < 0)
519 {
520 gnutls_assert ();
521 return ret;
522 }
523 _gnutls_free_datum (&tmp); /* free ptr2 */
524
525 /* now we move ptr after the pem header
526 */
527 ptr++;
528 /* find the next certificate (if any)
529 */
530 size = input_cert_size - (ptr - input_cert);
531
532 if (size > 0)
533 {
534 char *ptr3;
535
536 ptr3 = memmem (ptr, size, PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
537 if (ptr3 == NULL)
538 ptr3 = memmem (ptr, size, PEM_CERT_SEP2,
539 sizeof (PEM_CERT_SEP2) - 1);
540
541 ptr = ptr3;
542 }
543 else
544 ptr = NULL;
545
546 i++;
547 count++;
548
549 }
550 while (ptr != NULL);
551
552 *ncerts = i - 1;
553
554 return count;
555}
556
557
558
559/* Reads a DER or PEM certificate from memory
560 */
561static int
562read_cert_mem (gnutls_certificate_credentials_t res, const void *cert,
563 int cert_size, gnutls_x509_crt_fmt_t type)
564{
565 int ret;
566
567 /* allocate space for the certificate to add
568 */
569 res->cert_list = gnutls_realloc_fast (res->cert_list,
570 (1 +
571 res->ncerts) *
572 sizeof (gnutls_cert *));
573 if (res->cert_list == NULL)
574 {
575 gnutls_assert ();
576 return GNUTLS_E_MEMORY_ERROR;
577 }
578
579 res->cert_list_length = gnutls_realloc_fast (res->cert_list_length,
580 (1 +
581 res->ncerts) * sizeof (int));
582 if (res->cert_list_length == NULL)
583 {
584 gnutls_assert ();
585 return GNUTLS_E_MEMORY_ERROR;
586 }
587
588 res->cert_list[res->ncerts] = NULL; /* for realloc */
589 res->cert_list_length[res->ncerts] = 0;
590
591 if (type == GNUTLS_X509_FMT_DER)
592 ret = parse_pkcs7_cert_mem (&res->cert_list[res->ncerts],
593 &res->cert_list_length[res->ncerts],
594 cert, cert_size, 0);
595 else
596 ret =
597 parse_pem_cert_mem (&res->cert_list[res->ncerts],
598 &res->cert_list_length[res->ncerts], cert,
599 cert_size);
600
601 if (ret < 0)
602 {
603 gnutls_assert ();
604 return ret;
605 }
606
607 return ret;
608}
609
610
611int
612_gnutls_x509_privkey_to_gkey (gnutls_privkey * dest,
613 gnutls_x509_privkey_t src)
614{
615 int i, ret;
616
617 memset (dest, 0, sizeof (gnutls_privkey));
618
619 for (i = 0; i < src->params_size; i++)
620 {
621 dest->params[i] = _gnutls_mpi_copy (src->params[i]);
622 if (dest->params[i] == NULL)
623 {
624 gnutls_assert ();
625 ret = GNUTLS_E_MEMORY_ERROR;
626 goto cleanup;
627 }
628 }
629
630 dest->pk_algorithm = src->pk_algorithm;
631 dest->params_size = src->params_size;
632
633 return 0;
634
635cleanup:
636
637 for (i = 0; i < src->params_size; i++)
638 {
639 _gnutls_mpi_release (&dest->params[i]);
640 }
641 return ret;
642}
643
644void
645_gnutls_gkey_deinit (gnutls_privkey * key)
646{
647 int i;
648 if (key == NULL)
649 return;
650
651 for (i = 0; i < key->params_size; i++)
652 {
653 _gnutls_mpi_release (&key->params[i]);
654 }
655}
656
657int
658_gnutls_x509_raw_privkey_to_gkey (gnutls_privkey * privkey,
659 const gnutls_datum_t * raw_key,
660 gnutls_x509_crt_fmt_t type)
661{
662 gnutls_x509_privkey_t tmpkey;
663 int ret;
664
665 ret = gnutls_x509_privkey_init (&tmpkey);
666 if (ret < 0)
667 {
668 gnutls_assert ();
669 return ret;
670 }
671
672 ret = gnutls_x509_privkey_import (tmpkey, raw_key, type);
673
674 /* If normal key decoding doesn't work try decoding a plain PKCS #8 key */
675 if (ret < 0)
676 ret =
677 gnutls_x509_privkey_import_pkcs8 (tmpkey, raw_key, type, NULL,
678 GNUTLS_PKCS_PLAIN);
679
680 if (ret < 0)
681 {
682 gnutls_assert ();
683 gnutls_x509_privkey_deinit (tmpkey);
684 return ret;
685 }
686
687 ret = _gnutls_x509_privkey_to_gkey (privkey, tmpkey);
688 if (ret < 0)
689 {
690 gnutls_assert ();
691 gnutls_x509_privkey_deinit (tmpkey);
692 return ret;
693 }
694
695 gnutls_x509_privkey_deinit (tmpkey);
696
697 return 0;
698}
699
700/* Reads a PEM encoded PKCS-1 RSA/DSA private key from memory. Type
701 * indicates the certificate format. KEY can be NULL, to indicate
702 * that GnuTLS doesn't know the private key.
703 */
704static int
705read_key_mem (gnutls_certificate_credentials_t res,
706 const void *key, int key_size, gnutls_x509_crt_fmt_t type)
707{
708 int ret;
709 gnutls_datum_t tmp;
710
711 /* allocate space for the pkey list
712 */
713 res->pkey =
714 gnutls_realloc_fast (res->pkey,
715 (res->ncerts + 1) * sizeof (gnutls_privkey));
716 if (res->pkey == NULL)
717 {
718 gnutls_assert ();
719 return GNUTLS_E_MEMORY_ERROR;
720 }
721
722 if (key)
723 {
724 tmp.data = (opaque *) key;
725 tmp.size = key_size;
726
727 ret =
728 _gnutls_x509_raw_privkey_to_gkey (&res->pkey[res->ncerts], &tmp,
729 type);
730 if (ret < 0)
731 {
732 gnutls_assert ();
733 return ret;
734 }
735 }
736 else
737 memset (&res->pkey[res->ncerts], 0, sizeof (gnutls_privkey));
738
739 return 0;
740}
741
742/* Reads a certificate file
743 */
744static int
745read_cert_file (gnutls_certificate_credentials_t res,
746 const char *certfile, gnutls_x509_crt_fmt_t type)
747{
748 int ret;
749 size_t size;
750 char *data = read_binary_file (certfile, &size);
751
752 if (data == NULL)
753 {
754 gnutls_assert ();
755 return GNUTLS_E_FILE_ERROR;
756 }
757
758 ret = read_cert_mem (res, data, size, type);
759 free (data);
760
761 return ret;
762
763}
764
765
766
767/* Reads PKCS-1 RSA private key file or a DSA file (in the format openssl
768 * stores it).
769 */
770static int
771read_key_file (gnutls_certificate_credentials_t res,
772 const char *keyfile, gnutls_x509_crt_fmt_t type)
773{
774 int ret;
775 size_t size;
776 char *data = read_binary_file (keyfile, &size);
777
778 if (data == NULL)
779 {
780 gnutls_assert ();
781 return GNUTLS_E_FILE_ERROR;
782 }
783
784 ret = read_key_mem (res, data, size, type);
785 free (data);
786
787 return ret;
788}
789
790/**
791 * gnutls_certificate_set_x509_key_mem - Used to set keys in a gnutls_certificate_credentials_t structure
792 * @res: is an #gnutls_certificate_credentials_t structure.
793 * @cert: contains a certificate list (path) for the specified private key
794 * @key: is the private key, or %NULL
795 * @type: is PEM or DER
796 *
797 * This function sets a certificate/private key pair in the
798 * gnutls_certificate_credentials_t structure. This function may be called
799 * more than once (in case multiple keys/certificates exist for the
800 * server).
801 *
802 * Currently are supported: RSA PKCS-1 encoded private keys,
803 * DSA private keys.
804 *
805 * DSA private keys are encoded the OpenSSL way, which is an ASN.1
806 * DER sequence of 6 INTEGERs - version, p, q, g, pub, priv.
807 *
808 * Note that the keyUsage (2.5.29.15) PKIX extension in X.509 certificates
809 * is supported. This means that certificates intended for signing cannot
810 * be used for ciphersuites that require encryption.
811 *
812 * If the certificate and the private key are given in PEM encoding
813 * then the strings that hold their values must be null terminated.
814 *
815 * The @key may be %NULL if you are using a sign callback, see
816 * gnutls_sign_callback_set().
817 *
818 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
819 **/
820int
821gnutls_certificate_set_x509_key_mem (gnutls_certificate_credentials_t
822 res, const gnutls_datum_t * cert,
823 const gnutls_datum_t * key,
824 gnutls_x509_crt_fmt_t type)
825{
826 int ret;
827
828 /* this should be first
829 */
830 if ((ret = read_key_mem (res, key ? key->data : NULL,
831 key ? key->size : 0, type)) < 0)
832 return ret;
833
834 if ((ret = read_cert_mem (res, cert->data, cert->size, type)) < 0)
835 return ret;
836
837 res->ncerts++;
838
839 if (key && (ret = _gnutls_check_key_cert_match (res)) < 0)
840 {
841 gnutls_assert ();
842 return ret;
843 }
844
845 return 0;
846}
847
848/**
849 * gnutls_certificate_set_x509_key - Used to set keys in a gnutls_certificate_credentials_t structure
850 * @res: is an #gnutls_certificate_credentials_t structure.
851 * @cert_list: contains a certificate list (path) for the specified private key
852 * @cert_list_size: holds the size of the certificate list
853 * @key: is a gnutls_x509_privkey_t key
854 *
855 * This function sets a certificate/private key pair in the
856 * gnutls_certificate_credentials_t structure. This function may be
857 * called more than once (in case multiple keys/certificates exist
858 * for the server).
859 *
860 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
861 **/
862int
863gnutls_certificate_set_x509_key (gnutls_certificate_credentials_t res,
864 gnutls_x509_crt_t * cert_list,
865 int cert_list_size,
866 gnutls_x509_privkey_t key)
867{
868 int ret, i;
869
870 /* this should be first
871 */
872
873 res->pkey =
874 gnutls_realloc_fast (res->pkey,
875 (res->ncerts + 1) * sizeof (gnutls_privkey));
876 if (res->pkey == NULL)
877 {
878 gnutls_assert ();
879 return GNUTLS_E_MEMORY_ERROR;
880 }
881
882 ret = _gnutls_x509_privkey_to_gkey (&res->pkey[res->ncerts], key);
883 if (ret < 0)
884 {
885 gnutls_assert ();
886 return ret;
887 }
888
889 res->cert_list = gnutls_realloc_fast (res->cert_list,
890 (1 +
891 res->ncerts) *
892 sizeof (gnutls_cert *));
893 if (res->cert_list == NULL)
894 {
895 gnutls_assert ();
896 return GNUTLS_E_MEMORY_ERROR;
897 }
898
899 res->cert_list_length = gnutls_realloc_fast (res->cert_list_length,
900 (1 +
901 res->ncerts) * sizeof (int));
902 if (res->cert_list_length == NULL)
903 {
904 gnutls_assert ();
905 return GNUTLS_E_MEMORY_ERROR;
906 }
907
908 res->cert_list[res->ncerts] = NULL; /* for realloc */
909 res->cert_list_length[res->ncerts] = 0;
910
911
912 for (i = 0; i < cert_list_size; i++)
913 {
914 ret = parse_crt_mem (&res->cert_list[res->ncerts],
915 &res->cert_list_length[res->ncerts], cert_list[i]);
916 if (ret < 0)
917 {
918 gnutls_assert ();
919 return ret;
920 }
921 }
922 res->ncerts++;
923
924 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
925 {
926 gnutls_assert ();
927 return ret;
928 }
929
930 return 0;
931}
932
933/**
934 * gnutls_certificate_set_x509_key_file - Used to set keys in a gnutls_certificate_credentials_t structure
935 * @res: is an #gnutls_certificate_credentials_t structure.
936 * @CERTFILE: is a file that containing the certificate list (path) for
937 * the specified private key, in PKCS7 format, or a list of certificates
938 * @KEYFILE: is a file that contains the private key
939 * @type: is PEM or DER
940 *
941 * This function sets a certificate/private key pair in the
942 * gnutls_certificate_credentials_t structure. This function may be
943 * called more than once (in case multiple keys/certificates exist
944 * for the server).
945 *
946 * Currently only PKCS-1 encoded RSA and DSA private keys are accepted by
947 * this function.
948 *
949 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
950 **/
951int
952gnutls_certificate_set_x509_key_file (gnutls_certificate_credentials_t
953 res, const char *CERTFILE,
954 const char *KEYFILE,
955 gnutls_x509_crt_fmt_t type)
956{
957 int ret;
958
959 /* this should be first
960 */
961 if ((ret = read_key_file (res, KEYFILE, type)) < 0)
962 return ret;
963
964 if ((ret = read_cert_file (res, CERTFILE, type)) < 0)
965 return ret;
966
967 res->ncerts++;
968
969 if ((ret = _gnutls_check_key_cert_match (res)) < 0)
970 {
971 gnutls_assert ();
972 return ret;
973 }
974
975 return 0;
976}
977
978static int
979generate_rdn_seq (gnutls_certificate_credentials_t res)
980{
981 gnutls_datum_t tmp;
982 int ret;
983 unsigned size, i;
984 opaque *pdata;
985
986 /* Generate the RDN sequence
987 * This will be sent to clients when a certificate
988 * request message is sent.
989 */
990
991 /* FIXME: in case of a client it is not needed
992 * to do that. This would save time and memory.
993 * However we don't have that information available
994 * here.
995 */
996
997 size = 0;
998 for (i = 0; i < res->x509_ncas; i++)
999 {
1000 if ((ret = gnutls_x509_crt_get_raw_dn (res->x509_ca_list[i], &tmp)) < 0)
1001 {
1002 gnutls_assert ();
1003 return ret;
1004 }
1005 size += (2 + tmp.size);
1006 _gnutls_free_datum (&tmp);
1007 }
1008
1009 if (res->x509_rdn_sequence.data != NULL)
1010 gnutls_free (res->x509_rdn_sequence.data);
1011
1012 res->x509_rdn_sequence.data = gnutls_malloc (size);
1013 if (res->x509_rdn_sequence.data == NULL)
1014 {
1015 gnutls_assert ();
1016 return GNUTLS_E_MEMORY_ERROR;
1017 }
1018 res->x509_rdn_sequence.size = size;
1019
1020 pdata = res->x509_rdn_sequence.data;
1021
1022 for (i = 0; i < res->x509_ncas; i++)
1023 {
1024 if ((ret = gnutls_x509_crt_get_raw_dn (res->x509_ca_list[i], &tmp)) < 0)
1025 {
1026 _gnutls_free_datum (&res->x509_rdn_sequence);
1027 gnutls_assert ();
1028 return ret;
1029 }
1030
1031 _gnutls_write_datum16 (pdata, tmp);
1032 pdata += (2 + tmp.size);
1033 _gnutls_free_datum (&tmp);
1034 }
1035
1036 return 0;
1037}
1038
1039
1040
1041
1042/* Returns 0 if it's ok to use the gnutls_kx_algorithm_t with this
1043 * certificate (uses the KeyUsage field).
1044 */
1045int
1046_gnutls_check_key_usage (const gnutls_cert * cert, gnutls_kx_algorithm_t alg)
1047{
1048 unsigned int key_usage = 0;
1049 int encipher_type;
1050
1051 if (cert == NULL)
1052 {
1053 gnutls_assert ();
1054 return GNUTLS_E_INTERNAL_ERROR;
1055 }
1056
1057 if (_gnutls_map_kx_get_cred (alg, 1) == GNUTLS_CRD_CERTIFICATE ||
1058 _gnutls_map_kx_get_cred (alg, 0) == GNUTLS_CRD_CERTIFICATE)
1059 {
1060
1061 key_usage = cert->key_usage;
1062
1063 encipher_type = _gnutls_kx_encipher_type (alg);
1064
1065 if (key_usage != 0 && encipher_type != CIPHER_IGN)
1066 {
1067 /* If key_usage has been set in the certificate
1068 */
1069
1070 if (encipher_type == CIPHER_ENCRYPT)
1071 {
1072 /* If the key exchange method requires an encipher
1073 * type algorithm, and key's usage does not permit
1074 * encipherment, then fail.
1075 */
1076 if (!(key_usage & KEY_KEY_ENCIPHERMENT))
1077 {
1078 gnutls_assert ();
1079 return GNUTLS_E_KEY_USAGE_VIOLATION;
1080 }
1081 }
1082
1083 if (encipher_type == CIPHER_SIGN)
1084 {
1085 /* The same as above, but for sign only keys
1086 */
1087 if (!(key_usage & KEY_DIGITAL_SIGNATURE))
1088 {
1089 gnutls_assert ();
1090 return GNUTLS_E_KEY_USAGE_VIOLATION;
1091 }
1092 }
1093 }
1094 }
1095 return 0;
1096}
1097
1098
1099
1100static int
1101parse_pem_ca_mem (gnutls_x509_crt_t ** cert_list, unsigned *ncerts,
1102 const opaque * input_cert, int input_cert_size)
1103{
1104 int i, size;
1105 const opaque *ptr;
1106 gnutls_datum_t tmp;
1107 int ret, count;
1108
1109 /* move to the certificate
1110 */
1111 ptr = memmem (input_cert, input_cert_size,
1112 PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
1113 if (ptr == NULL)
1114 ptr = memmem (input_cert, input_cert_size,
1115 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
1116
1117 if (ptr == NULL)
1118 {
1119 gnutls_assert ();
1120 return GNUTLS_E_BASE64_DECODING_ERROR;
1121 }
1122 size = input_cert_size - (ptr - input_cert);
1123
1124 i = *ncerts + 1;
1125 count = 0;
1126
1127 do
1128 {
1129
1130 *cert_list =
1131 (gnutls_x509_crt_t *) gnutls_realloc_fast (*cert_list,
1132 i *
1133 sizeof
1134 (gnutls_x509_crt_t));
1135
1136 if (*cert_list == NULL)
1137 {
1138 gnutls_assert ();
1139 return GNUTLS_E_MEMORY_ERROR;
1140 }
1141
1142 ret = gnutls_x509_crt_init (&cert_list[0][i - 1]);
1143 if (ret < 0)
1144 {
1145 gnutls_assert ();
1146 return ret;
1147 }
1148
1149 tmp.data = (opaque *) ptr;
1150 tmp.size = size;
1151
1152 ret =
1153 gnutls_x509_crt_import (cert_list[0][i - 1],
1154 &tmp, GNUTLS_X509_FMT_PEM);
1155 if (ret < 0)
1156 {
1157 gnutls_assert ();
1158 return ret;
1159 }
1160
1161 /* now we move ptr after the pem header
1162 */
1163 ptr++;
1164 size--;
1165 /* find the next certificate (if any)
1166 */
1167
1168 if (size > 0)
1169 {
1170 char *ptr3;
1171
1172 ptr3 = memmem (ptr, size, PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
1173 if (ptr3 == NULL)
1174 ptr3 = memmem (ptr, size,
1175 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
1176
1177 ptr = ptr3;
1178 size = input_cert_size - (ptr - input_cert);
1179 }
1180 else
1181 ptr = NULL;
1182
1183 i++;
1184 count++;
1185
1186 }
1187 while (ptr != NULL);
1188
1189 *ncerts = i - 1;
1190
1191 return count;
1192}
1193
1194/* Reads a DER encoded certificate list from memory and stores it to
1195 * a gnutls_cert structure. This is only called if PKCS7 read fails.
1196 * returns the number of certificates parsed (1)
1197 */
1198static int
1199parse_der_ca_mem (gnutls_x509_crt_t ** cert_list, unsigned *ncerts,
1200 const void *input_cert, int input_cert_size)
1201{
1202 int i;
1203 gnutls_datum_t tmp;
1204 int ret;
1205
1206 i = *ncerts + 1;
1207
1208 *cert_list =
1209 (gnutls_x509_crt_t *) gnutls_realloc_fast (*cert_list,
1210 i *
1211 sizeof (gnutls_x509_crt_t));
1212
1213 if (*cert_list == NULL)
1214 {
1215 gnutls_assert ();
1216 return GNUTLS_E_MEMORY_ERROR;
1217 }
1218
1219 tmp.data = (opaque *) input_cert;
1220 tmp.size = input_cert_size;
1221
1222 ret = gnutls_x509_crt_init (&cert_list[0][i - 1]);
1223 if (ret < 0)
1224 {
1225 gnutls_assert ();
1226 return ret;
1227 }
1228
1229 ret =
1230 gnutls_x509_crt_import (cert_list[0][i - 1], &tmp, GNUTLS_X509_FMT_DER);
1231 if (ret < 0)
1232 {
1233 gnutls_assert ();
1234 return ret;
1235 }
1236
1237 *ncerts = i;
1238
1239 return 1; /* one certificate parsed */
1240}
1241
1242/**
1243 * gnutls_certificate_set_x509_trust_mem - Used to add trusted CAs in a gnutls_certificate_credentials_t structure
1244 * @res: is an #gnutls_certificate_credentials_t structure.
1245 * @ca: is a list of trusted CAs or a DER certificate
1246 * @type: is DER or PEM
1247 *
1248 * This function adds the trusted CAs in order to verify client or
1249 * server certificates. In case of a client this is not required to
1250 * be called if the certificates are not verified using
1251 * gnutls_certificate_verify_peers2(). This function may be called
1252 * multiple times.
1253 *
1254 * In case of a server the CAs set here will be sent to the client if
1255 * a certificate request is sent. This can be disabled using
1256 * gnutls_certificate_send_x509_rdn_sequence().
1257 *
1258 * Returns: the number of certificates processed or a negative value
1259 * on error.
1260 **/
1261int
1262gnutls_certificate_set_x509_trust_mem (gnutls_certificate_credentials_t
1263 res, const gnutls_datum_t * ca,
1264 gnutls_x509_crt_fmt_t type)
1265{
1266 int ret, ret2;
1267
1268 if (type == GNUTLS_X509_FMT_DER)
1269 ret = parse_der_ca_mem (&res->x509_ca_list, &res->x509_ncas,
1270 ca->data, ca->size);
1271 else
1272 ret = parse_pem_ca_mem (&res->x509_ca_list, &res->x509_ncas,
1273 ca->data, ca->size);
1274
1275 if ((ret2 = generate_rdn_seq (res)) < 0)
1276 return ret2;
1277
1278 return ret;
1279}
1280
1281/**
1282 * gnutls_certificate_set_x509_trust - Used to add trusted CAs in a gnutls_certificate_credentials_t structure
1283 * @res: is an #gnutls_certificate_credentials_t structure.
1284 * @ca_list: is a list of trusted CAs
1285 * @ca_list_size: holds the size of the CA list
1286 *
1287 * This function adds the trusted CAs in order to verify client
1288 * or server certificates. In case of a client this is not required
1289 * to be called if the certificates are not verified using
1290 * gnutls_certificate_verify_peers2().
1291 * This function may be called multiple times.
1292 *
1293 * In case of a server the CAs set here will be sent to the client if
1294 * a certificate request is sent. This can be disabled using
1295 * gnutls_certificate_send_x509_rdn_sequence().
1296 *
1297 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
1298 **/
1299int
1300gnutls_certificate_set_x509_trust (gnutls_certificate_credentials_t res,
1301 gnutls_x509_crt_t * ca_list,
1302 int ca_list_size)
1303{
1304 int ret, i, ret2;
1305
1306 res->x509_ca_list = gnutls_realloc_fast (res->x509_ca_list,
1307 (ca_list_size +
1308 res->x509_ncas) *
1309 sizeof (gnutls_x509_crt_t));
1310 if (res->x509_ca_list == NULL)
1311 {
1312 gnutls_assert ();
1313 return GNUTLS_E_MEMORY_ERROR;
1314 }
1315
1316 for (i = 0; i < ca_list_size; i++)
1317 {
1318 ret = gnutls_x509_crt_init (&res->x509_ca_list[res->x509_ncas]);
1319 if (ret < 0)
1320 {
1321 gnutls_assert ();
1322 return ret;
1323 }
1324
1325 ret = _gnutls_x509_crt_cpy (res->x509_ca_list[res->x509_ncas],
1326 ca_list[i]);
1327 if (ret < 0)
1328 {
1329 gnutls_assert ();
1330 gnutls_x509_crt_deinit (res->x509_ca_list[res->x509_ncas]);
1331 return ret;
1332 }
1333 res->x509_ncas++;
1334 }
1335
1336 if ((ret2 = generate_rdn_seq (res)) < 0)
1337 return ret2;
1338
1339 return 0;
1340}
1341
1342/**
1343 * gnutls_certificate_set_x509_trust_file - Used to add trusted CAs in a gnutls_certificate_credentials_t structure
1344 * @res: is an #gnutls_certificate_credentials_t structure.
1345 * @cafile: is a file containing the list of trusted CAs (DER or PEM list)
1346 * @type: is PEM or DER
1347 *
1348 * This function adds the trusted CAs in order to verify client or
1349 * server certificates. In case of a client this is not required to
1350 * be called if the certificates are not verified using
1351 * gnutls_certificate_verify_peers2(). This function may be called
1352 * multiple times.
1353 *
1354 * In case of a server the names of the CAs set here will be sent to
1355 * the client if a certificate request is sent. This can be disabled
1356 * using gnutls_certificate_send_x509_rdn_sequence().
1357 *
1358 * Returns: number of certificates processed, or a negative value on
1359 * error.
1360 **/
1361int
1362gnutls_certificate_set_x509_trust_file (gnutls_certificate_credentials_t
1363 res, const char *cafile,
1364 gnutls_x509_crt_fmt_t type)
1365{
1366 int ret, ret2;
1367 size_t size;
1368 char *data = read_binary_file (cafile, &size);
1369
1370 if (data == NULL)
1371 {
1372 gnutls_assert ();
1373 return GNUTLS_E_FILE_ERROR;
1374 }
1375
1376 if (type == GNUTLS_X509_FMT_DER)
1377 ret = parse_der_ca_mem (&res->x509_ca_list, &res->x509_ncas, data, size);
1378 else
1379 ret = parse_pem_ca_mem (&res->x509_ca_list, &res->x509_ncas, data, size);
1380
1381 free (data);
1382
1383 if (ret < 0)
1384 {
1385 gnutls_assert ();
1386 return ret;
1387 }
1388
1389 if ((ret2 = generate_rdn_seq (res)) < 0)
1390 return ret2;
1391
1392 return ret;
1393}
1394
1395#ifdef ENABLE_PKI
1396
1397static int
1398parse_pem_crl_mem (gnutls_x509_crl_t ** crl_list, unsigned *ncrls,
1399 const opaque * input_crl, int input_crl_size)
1400{
1401 int size, i;
1402 const opaque *ptr;
1403 gnutls_datum_t tmp;
1404 int ret, count;
1405
1406 /* move to the certificate
1407 */
1408 ptr = memmem (input_crl, input_crl_size,
1409 PEM_CRL_SEP, sizeof (PEM_CRL_SEP) - 1);
1410 if (ptr == NULL)
1411 {
1412 gnutls_assert ();
1413 return GNUTLS_E_BASE64_DECODING_ERROR;
1414 }
1415
1416 size = input_crl_size - (ptr - input_crl);
1417
1418 i = *ncrls + 1;
1419 count = 0;
1420
1421 do
1422 {
1423
1424 *crl_list =
1425 (gnutls_x509_crl_t *) gnutls_realloc_fast (*crl_list,
1426 i *
1427 sizeof
1428 (gnutls_x509_crl_t));
1429
1430 if (*crl_list == NULL)
1431 {
1432 gnutls_assert ();
1433 return GNUTLS_E_MEMORY_ERROR;
1434 }
1435
1436 ret = gnutls_x509_crl_init (&crl_list[0][i - 1]);
1437 if (ret < 0)
1438 {
1439 gnutls_assert ();
1440 return ret;
1441 }
1442
1443 tmp.data = (char *) ptr;
1444 tmp.size = size;
1445
1446 ret =
1447 gnutls_x509_crl_import (crl_list[0][i - 1],
1448 &tmp, GNUTLS_X509_FMT_PEM);
1449 if (ret < 0)
1450 {
1451 gnutls_assert ();
1452 return ret;
1453 }
1454
1455 /* now we move ptr after the pem header
1456 */
1457 ptr++;
1458 /* find the next certificate (if any)
1459 */
1460
1461 size = input_crl_size - (ptr - input_crl);
1462
1463 if (size > 0)
1464 ptr = memmem (ptr, size, PEM_CRL_SEP, sizeof (PEM_CRL_SEP) - 1);
1465 else
1466 ptr = NULL;
1467 i++;
1468 count++;
1469
1470 }
1471 while (ptr != NULL);
1472
1473 *ncrls = i - 1;
1474
1475 return count;
1476}
1477
1478/* Reads a DER encoded certificate list from memory and stores it to
1479 * a gnutls_cert structure. This is only called if PKCS7 read fails.
1480 * returns the number of certificates parsed (1)
1481 */
1482static int
1483parse_der_crl_mem (gnutls_x509_crl_t ** crl_list, unsigned *ncrls,
1484 const void *input_crl, int input_crl_size)
1485{
1486 int i;
1487 gnutls_datum_t tmp;
1488 int ret;
1489
1490 i = *ncrls + 1;
1491
1492 *crl_list =
1493 (gnutls_x509_crl_t *) gnutls_realloc_fast (*crl_list,
1494 i *
1495 sizeof (gnutls_x509_crl_t));
1496
1497 if (*crl_list == NULL)
1498 {
1499 gnutls_assert ();
1500 return GNUTLS_E_MEMORY_ERROR;
1501 }
1502
1503 tmp.data = (opaque *) input_crl;
1504 tmp.size = input_crl_size;
1505
1506 ret = gnutls_x509_crl_init (&crl_list[0][i - 1]);
1507 if (ret < 0)
1508 {
1509 gnutls_assert ();
1510 return ret;
1511 }
1512
1513 ret =
1514 gnutls_x509_crl_import (crl_list[0][i - 1], &tmp, GNUTLS_X509_FMT_DER);
1515 if (ret < 0)
1516 {
1517 gnutls_assert ();
1518 return ret;
1519 }
1520
1521 *ncrls = i;
1522
1523 return 1; /* one certificate parsed */
1524}
1525
1526
1527/* Reads a DER or PEM CRL from memory
1528 */
1529static int
1530read_crl_mem (gnutls_certificate_credentials_t res, const void *crl,
1531 int crl_size, gnutls_x509_crt_fmt_t type)
1532{
1533 int ret;
1534
1535 /* allocate space for the certificate to add
1536 */
1537 res->x509_crl_list = gnutls_realloc_fast (res->x509_crl_list,
1538 (1 +
1539 res->x509_ncrls) *
1540 sizeof (gnutls_x509_crl_t));
1541 if (res->x509_crl_list == NULL)
1542 {
1543 gnutls_assert ();
1544 return GNUTLS_E_MEMORY_ERROR;
1545 }
1546
1547 if (type == GNUTLS_X509_FMT_DER)
1548 ret = parse_der_crl_mem (&res->x509_crl_list,
1549 &res->x509_ncrls, crl, crl_size);
1550 else
1551 ret = parse_pem_crl_mem (&res->x509_crl_list,
1552 &res->x509_ncrls, crl, crl_size);
1553
1554 if (ret < 0)
1555 {
1556 gnutls_assert ();
1557 return ret;
1558 }
1559
1560 return ret;
1561}
1562
1563/**
1564 * gnutls_certificate_set_x509_crl_mem - Used to add CRLs in a gnutls_certificate_credentials_t structure
1565 * @res: is an #gnutls_certificate_credentials_t structure.
1566 * @CRL: is a list of trusted CRLs. They should have been verified before.
1567 * @type: is DER or PEM
1568 *
1569 * This function adds the trusted CRLs in order to verify client or
1570 * server certificates. In case of a client this is not required to
1571 * be called if the certificates are not verified using
1572 * gnutls_certificate_verify_peers2(). This function may be called
1573 * multiple times.
1574 *
1575 * Returns: number of CRLs processed, or a negative value on error.
1576 **/
1577int
1578gnutls_certificate_set_x509_crl_mem (gnutls_certificate_credentials_t
1579 res, const gnutls_datum_t * CRL,
1580 gnutls_x509_crt_fmt_t type)
1581{
1582 int ret;
1583
1584 if ((ret = read_crl_mem (res, CRL->data, CRL->size, type)) < 0)
1585 return ret;
1586
1587 return ret;
1588}
1589
1590/**
1591 * gnutls_certificate_set_x509_crl - Used to add CRLs in a gnutls_certificate_credentials_t structure
1592 * @res: is an #gnutls_certificate_credentials_t structure.
1593 * @crl_list: is a list of trusted CRLs. They should have been verified before.
1594 * @crl_list_size: holds the size of the crl_list
1595 *
1596 * This function adds the trusted CRLs in order to verify client or
1597 * server certificates. In case of a client this is not required to
1598 * be called if the certificates are not verified using
1599 * gnutls_certificate_verify_peers2(). This function may be called
1600 * multiple times.
1601 *
1602 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
1603 **/
1604int
1605gnutls_certificate_set_x509_crl (gnutls_certificate_credentials_t res,
1606 gnutls_x509_crl_t * crl_list,
1607 int crl_list_size)
1608{
1609 int ret, i;
1610
1611 res->x509_crl_list = gnutls_realloc_fast (res->x509_crl_list,
1612 (crl_list_size +
1613 res->x509_ncrls) *
1614 sizeof (gnutls_x509_crl_t));
1615 if (res->x509_crl_list == NULL)
1616 {
1617 gnutls_assert ();
1618 return GNUTLS_E_MEMORY_ERROR;
1619 }
1620
1621 for (i = 0; i < crl_list_size; i++)
1622 {
1623 ret = gnutls_x509_crl_init (&res->x509_crl_list[res->x509_ncrls]);
1624 if (ret < 0)
1625 {
1626 gnutls_assert ();
1627 return ret;
1628 }
1629
1630 ret = _gnutls_x509_crl_cpy (res->x509_crl_list[res->x509_ncrls],
1631 crl_list[i]);
1632 if (ret < 0)
1633 {
1634 gnutls_assert ();
1635 return ret;
1636 }
1637 res->x509_ncrls++;
1638 }
1639
1640 return 0;
1641}
1642
1643/**
1644 * gnutls_certificate_set_x509_crl_file - Used to add CRLs in a gnutls_certificate_credentials_t structure
1645 * @res: is an #gnutls_certificate_credentials_t structure.
1646 * @crlfile: is a file containing the list of verified CRLs (DER or PEM list)
1647 * @type: is PEM or DER
1648 *
1649 * This function adds the trusted CRLs in order to verify client or server
1650 * certificates. In case of a client this is not required
1651 * to be called if the certificates are not verified using
1652 * gnutls_certificate_verify_peers2().
1653 * This function may be called multiple times.
1654 *
1655 * Returns: number of CRLs processed or a negative value on error.
1656 **/
1657int
1658gnutls_certificate_set_x509_crl_file (gnutls_certificate_credentials_t
1659 res, const char *crlfile,
1660 gnutls_x509_crt_fmt_t type)
1661{
1662 int ret;
1663 size_t size;
1664 char *data = read_binary_file (crlfile, &size);
1665
1666 if (data == NULL)
1667 {
1668 gnutls_assert ();
1669 return GNUTLS_E_FILE_ERROR;
1670 }
1671
1672 if (type == GNUTLS_X509_FMT_DER)
1673 ret = parse_der_crl_mem (&res->x509_crl_list, &res->x509_ncrls,
1674 data, size);
1675 else
1676 ret = parse_pem_crl_mem (&res->x509_crl_list, &res->x509_ncrls,
1677 data, size);
1678
1679 free (data);
1680
1681 if (ret < 0)
1682 {
1683 gnutls_assert ();
1684 return ret;
1685 }
1686
1687 return ret;
1688}
1689
1690#include <pkcs12.h>
1691
1692static int
1693parse_pkcs12 (gnutls_certificate_credentials_t res,
1694 gnutls_pkcs12_t p12,
1695 const char *password,
1696 gnutls_x509_privkey_t * key,
1697 gnutls_x509_crt_t * cert, gnutls_x509_crl_t * crl)
1698{
1699 gnutls_pkcs12_bag_t bag = NULL;
1700 int index = 0;
1701 int ret;
1702
1703 for (;;)
1704 {
1705 int elements_in_bag;
1706 int i;
1707
1708 ret = gnutls_pkcs12_bag_init (&bag);
1709 if (ret < 0)
1710 {
1711 bag = NULL;
1712 gnutls_assert ();
1713 goto done;
1714 }
1715
1716 ret = gnutls_pkcs12_get_bag (p12, index, bag);
1717 if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
1718 break;
1719 if (ret < 0)
1720 {
1721 gnutls_assert ();
1722 goto done;
1723 }
1724
1725 ret = gnutls_pkcs12_bag_get_type (bag, 0);
1726 if (ret < 0)
1727 {
1728 gnutls_assert ();
1729 goto done;
1730 }
1731
1732 if (ret == GNUTLS_BAG_ENCRYPTED)
1733 {
1734 ret = gnutls_pkcs12_bag_decrypt (bag, password);
1735 if (ret < 0)
1736 {
1737 gnutls_assert ();
1738 goto done;
1739 }
1740 }
1741
1742 elements_in_bag = gnutls_pkcs12_bag_get_count (bag);
1743 if (elements_in_bag < 0)
1744 {
1745 gnutls_assert ();
1746 goto done;
1747 }
1748
1749 for (i = 0; i < elements_in_bag; i++)
1750 {
1751 int type;
1752 gnutls_datum_t data;
1753
1754 type = gnutls_pkcs12_bag_get_type (bag, i);
1755 if (type < 0)
1756 {
1757 gnutls_assert ();
1758 goto done;
1759 }
1760
1761 ret = gnutls_pkcs12_bag_get_data (bag, i, &data);
1762 if (ret < 0)
1763 {
1764 gnutls_assert ();
1765 goto done;
1766 }
1767
1768 switch (type)
1769 {
1770 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
1771 case GNUTLS_BAG_PKCS8_KEY:
1772 ret = gnutls_x509_privkey_init (key);
1773 if (ret < 0)
1774 {
1775 gnutls_assert ();
1776 goto done;
1777 }
1778
1779 ret = gnutls_x509_privkey_import_pkcs8
1780 (*key, &data, GNUTLS_X509_FMT_DER, password,
1781 type == GNUTLS_BAG_PKCS8_KEY ? GNUTLS_PKCS_PLAIN : 0);
1782 if (ret < 0)
1783 {
1784 gnutls_assert ();
1785 goto done;
1786 }
1787 break;
1788
1789 case GNUTLS_BAG_CERTIFICATE:
1790 ret = gnutls_x509_crt_init (cert);
1791 if (ret < 0)
1792 {
1793 gnutls_assert ();
1794 goto done;
1795 }
1796
1797 ret =
1798 gnutls_x509_crt_import (*cert, &data, GNUTLS_X509_FMT_DER);
1799 if (ret < 0)
1800 {
1801 gnutls_assert ();
1802 goto done;
1803 }
1804 break;
1805
1806 case GNUTLS_BAG_CRL:
1807 ret = gnutls_x509_crl_init (crl);
1808 if (ret < 0)
1809 {
1810 gnutls_assert ();
1811 goto done;
1812 }
1813
1814 ret = gnutls_x509_crl_import (*crl, &data, GNUTLS_X509_FMT_DER);
1815 if (ret < 0)
1816 {
1817 gnutls_assert ();
1818 goto done;
1819 }
1820 break;
1821
1822 case GNUTLS_BAG_ENCRYPTED:
1823 /* XXX Bother to recurse one level down? Unlikely to
1824 use the same password anyway. */
1825 case GNUTLS_BAG_EMPTY:
1826 default:
1827 break;
1828 }
1829 }
1830
1831 index++;
1832 gnutls_pkcs12_bag_deinit (bag);
1833 }
1834
1835 ret = 0;
1836
1837done:
1838 if (bag)
1839 gnutls_pkcs12_bag_deinit (bag);
1840
1841 return ret;
1842}
1843
1844/**
1845 * gnutls_certificate_set_x509_simple_pkcs12_file:
1846 * @res: is an #gnutls_certificate_credentials_t structure.
1847 * @pkcs12file: filename of file containing PKCS#12 blob.
1848 * @type: is PEM or DER of the @pkcs12file.
1849 * @password: optional password used to decrypt PKCS#12 file, bags and keys.
1850 *
1851 * This function sets a certificate/private key pair and/or a CRL in
1852 * the gnutls_certificate_credentials_t structure. This function may
1853 * be called more than once (in case multiple keys/certificates exist
1854 * for the server).
1855 *
1856 * MAC:ed PKCS#12 files are supported. Encrypted PKCS#12 bags are
1857 * supported. Encrypted PKCS#8 private keys are supported. However,
1858 * only password based security, and the same password for all
1859 * operations, are supported.
1860 *
1861 * The private keys may be RSA PKCS#1 or DSA private keys encoded in
1862 * the OpenSSL way.
1863 *
1864 * PKCS#12 file may contain many keys and/or certificates, and there
1865 * is no way to identify which key/certificate pair you want. You
1866 * should make sure the PKCS#12 file only contain one key/certificate
1867 * pair and/or one CRL.
1868 *
1869 * It is believed that the limitations of this function is acceptable
1870 * for most usage, and that any more flexibility would introduce
1871 * complexity that would make it harder to use this functionality at
1872 * all.
1873 *
1874 * Returns: %GNUTLS_E_SUCCESS on success, or an error code.
1875 **/
1876int
1877 gnutls_certificate_set_x509_simple_pkcs12_file
1878 (gnutls_certificate_credentials_t res, const char *pkcs12file,
1879 gnutls_x509_crt_fmt_t type, const char *password)
1880{
1881 gnutls_pkcs12_t p12;
1882 gnutls_datum_t p12blob;
1883 gnutls_x509_privkey_t key = NULL;
1884 gnutls_x509_crt_t cert = NULL;
1885 gnutls_x509_crl_t crl = NULL;
1886 int ret;
1887 size_t size;
1888
1889 ret = gnutls_pkcs12_init (&p12);
1890 if (ret < 0)
1891 {
1892 gnutls_assert ();
1893 return ret;
1894 }
1895
1896 p12blob.data = read_binary_file (pkcs12file, &size);
1897 p12blob.size = (unsigned int) size;
1898 if (p12blob.data == NULL)
1899 {
1900 gnutls_assert ();
1901 gnutls_pkcs12_deinit (p12);
1902 return GNUTLS_E_FILE_ERROR;
1903 }
1904
1905 ret = gnutls_pkcs12_import (p12, &p12blob, type, 0);
1906 free (p12blob.data);
1907 if (ret < 0)
1908 {
1909 gnutls_assert ();
1910 gnutls_pkcs12_deinit (p12);
1911 return ret;
1912 }
1913
1914 if (password)
1915 {
1916 ret = gnutls_pkcs12_verify_mac (p12, password);
1917 if (ret < 0)
1918 {
1919 gnutls_assert ();
1920 gnutls_pkcs12_deinit (p12);
1921 return ret;
1922 }
1923 }
1924
1925 ret = parse_pkcs12 (res, p12, password, &key, &cert, &crl);
1926 gnutls_pkcs12_deinit (p12);
1927 if (ret < 0)
1928 {
1929 gnutls_assert ();
1930 return ret;
1931 }
1932
1933 if (key && cert)
1934 {
1935 ret = gnutls_certificate_set_x509_key (res, &cert, 1, key);
1936 if (ret < 0)
1937 {
1938 gnutls_assert ();
1939 goto done;
1940 }
1941 }
1942
1943 if (crl)
1944 {
1945 ret = gnutls_certificate_set_x509_crl (res, &crl, 1);
1946 if (ret < 0)
1947 {
1948 gnutls_assert ();
1949 goto done;
1950 }
1951 }
1952
1953 ret = 0;
1954
1955done:
1956 if (cert)
1957 gnutls_x509_crt_deinit (cert);
1958 if (key)
1959 gnutls_x509_privkey_deinit (key);
1960 if (crl)
1961 gnutls_x509_crl_deinit (crl);
1962
1963 return ret;
1964}
1965
1966
1967/**
1968 * gnutls_certificate_free_crls - Used to free all the CRLs from a gnutls_certificate_credentials_t structure
1969 * @sc: is an #gnutls_certificate_credentials_t structure.
1970 *
1971 * This function will delete all the CRLs associated
1972 * with the given credentials.
1973 *
1974 **/
1975void
1976gnutls_certificate_free_crls (gnutls_certificate_credentials_t sc)
1977{
1978 unsigned j;
1979
1980 for (j = 0; j < sc->x509_ncrls; j++)
1981 {
1982 gnutls_x509_crl_deinit (sc->x509_crl_list[j]);
1983 }
1984
1985 sc->x509_ncrls = 0;
1986
1987 gnutls_free (sc->x509_crl_list);
1988 sc->x509_crl_list = NULL;
1989}
1990
1991#endif
diff --git a/src/daemon/https/tls/gnutls_x509.h b/src/daemon/https/tls/gnutls_x509.h
new file mode 100644
index 00000000..3aa0d915
--- /dev/null
+++ b/src/daemon/https/tls/gnutls_x509.h
@@ -0,0 +1,49 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <libtasn1.h>
26
27int _gnutls_x509_cert_verify_peers (gnutls_session_t session,
28 unsigned int *status);
29
30#define PEM_CERT_SEP2 "-----BEGIN X509 CERTIFICATE"
31#define PEM_CERT_SEP "-----BEGIN CERTIFICATE"
32#define PEM_PKCS7_SEP "-----BEGIN PKCS7"
33
34#define PEM_CRL_SEP "-----BEGIN X509 CRL"
35
36#define PEM_KEY_RSA_SEP "-----BEGIN RSA"
37#define PEM_KEY_DSA_SEP "-----BEGIN DSA"
38
39int _gnutls_check_key_usage (const gnutls_cert * cert,
40 gnutls_kx_algorithm_t alg);
41
42int _gnutls_x509_read_rsa_params (opaque * der, int dersize, mpi_t * params);
43int _gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, mpi_t * params);
44
45int _gnutls_x509_raw_privkey_to_gkey (gnutls_privkey * privkey,
46 const gnutls_datum_t * raw_key,
47 gnutls_x509_crt_fmt_t type);
48int _gnutls_x509_privkey_to_gkey (gnutls_privkey * privkey,
49 gnutls_x509_privkey_t);
diff --git a/src/daemon/https/tls/gnutlsxx.cpp b/src/daemon/https/tls/gnutlsxx.cpp
new file mode 100644
index 00000000..70621a43
--- /dev/null
+++ b/src/daemon/https/tls/gnutlsxx.cpp
@@ -0,0 +1,907 @@
1#include <gnutlsxx.h>
2
3using namespace gnutls;
4
5inline int RETWRAP_NET(int ret)
6{
7 if (gnutls_error_is_fatal(ret)) throw(exception(ret));
8 else return ret;
9}
10
11inline int RETWRAP(int ret)
12{
13 if (ret < 0) throw(exception(ret));
14 return ret;
15}
16
17session::session( gnutls_connection_end_t end)
18{
19 RETWRAP(gnutls_init( &this->s, end));
20}
21
22session::session( session& s)
23{
24 this->s = s.s;
25}
26
27session::~session()
28{
29 gnutls_deinit( this->s);
30}
31
32int session::bye( gnutls_close_request_t how)
33{
34 return RETWRAP_NET( gnutls_bye( this->s, how));
35}
36
37int session::handshake ()
38{
39 return RETWRAP_NET( gnutls_handshake( this->s));
40}
41
42
43server_session::server_session() : session( GNUTLS_SERVER)
44{
45}
46
47int server_session::rehandshake()
48{
49 return RETWRAP_NET( gnutls_rehandshake( this->s));
50}
51
52gnutls_alert_description_t session::get_alert() const
53{
54 return gnutls_alert_get( this->s);
55}
56
57int session::send_alert ( gnutls_alert_level_t level,
58 gnutls_alert_description_t desc)
59{
60 return RETWRAP_NET(gnutls_alert_send( this->s, level, desc));
61}
62
63int session::send_appropriate_alert (int err)
64{
65 return RETWRAP_NET(gnutls_alert_send_appropriate( this->s, err));
66}
67
68gnutls_cipher_algorithm_t session::get_cipher() const
69{
70 return gnutls_cipher_get( this->s);
71}
72
73gnutls_kx_algorithm_t session::get_kx () const
74{
75 return gnutls_kx_get( this->s);
76}
77
78gnutls_mac_algorithm_t session::get_mac () const
79{
80 return gnutls_mac_get( this->s);
81}
82
83gnutls_compression_method_t session::get_compression() const
84{
85 return gnutls_compression_get( this->s);
86}
87
88gnutls_certificate_type_t session::get_certificate_type() const
89{
90 return gnutls_certificate_type_get( this->s);
91}
92
93void session::set_private_extensions ( bool allow)
94{
95 gnutls_handshake_set_private_extensions( this->s, (int)allow);
96}
97
98gnutls_handshake_description_t session::get_handshake_last_out() const
99{
100 return gnutls_handshake_get_last_out( this->s);
101}
102
103gnutls_handshake_description_t session::get_handshake_last_in() const
104{
105 return gnutls_handshake_get_last_in( this->s);
106}
107
108ssize_t session::send (const void *data, size_t sizeofdata)
109{
110 return RETWRAP_NET(gnutls_record_send( this->s, data, sizeofdata));
111}
112
113ssize_t session::recv (void *data, size_t sizeofdata)
114{
115 return RETWRAP_NET(gnutls_record_recv( this->s, data, sizeofdata));
116}
117
118bool session::get_record_direction() const
119{
120 return gnutls_record_get_direction(this->s);
121}
122
123 // maximum packet size
124size_t session::get_max_size () const
125{
126 return gnutls_record_get_max_size( this->s);
127}
128
129void session::set_max_size(size_t size)
130{
131 RETWRAP( gnutls_record_set_max_size( this->s, size));
132}
133
134size_t session::check_pending () const
135{
136 return gnutls_record_check_pending( this->s);
137}
138
139
140void session::prf (size_t label_size, const char *label,
141 int server_random_first,
142 size_t extra_size, const char *extra,
143 size_t outsize, char *out)
144{
145 RETWRAP(gnutls_prf( this->s, label_size, label, server_random_first,
146 extra_size, extra, outsize, out));
147}
148
149void session::prf_raw ( size_t label_size, const char *label,
150 size_t seed_size, const char *seed,
151 size_t outsize, char *out)
152{
153 RETWRAP( gnutls_prf_raw( this->s, label_size, label, seed_size, seed, outsize, out));
154}
155
156
157void session::set_cipher_priority (const int *list)
158{
159 RETWRAP( gnutls_cipher_set_priority( this->s, list));
160}
161
162void session::set_mac_priority (const int *list)
163{
164 RETWRAP( gnutls_mac_set_priority( this->s, list));
165}
166
167void session::set_compression_priority (const int *list)
168{
169 RETWRAP( gnutls_compression_set_priority( this->s, list));
170}
171
172void session::set_kx_priority (const int *list)
173{
174 RETWRAP( gnutls_kx_set_priority( this->s, list));
175}
176
177void session::set_protocol_priority (const int *list)
178{
179 RETWRAP( gnutls_protocol_set_priority( this->s, list));
180}
181
182void session::set_certificate_type_priority (const int *list)
183{
184 RETWRAP( gnutls_certificate_type_set_priority( this->s, list));
185}
186
187
188/* if you just want some defaults, use the following.
189 */
190void session::set_priority(const char* prio, const char** err_pos)
191{
192 RETWRAP(gnutls_priority_set_direct( this->s, prio, err_pos));
193}
194
195void session::set_priority(gnutls_priority_t p)
196{
197 RETWRAP(gnutls_priority_set( this->s, p));
198}
199
200gnutls_protocol_t session::get_protocol_version() const
201{
202 return gnutls_protocol_get_version( this->s);
203}
204
205void session::set_data ( const void *session_data,
206 size_t session_data_size)
207{
208 RETWRAP(gnutls_session_set_data( this->s, session_data, session_data_size));
209}
210
211void session::get_data (void *session_data,
212 size_t * session_data_size) const
213{
214 RETWRAP(gnutls_session_get_data( this->s, session_data, session_data_size));
215}
216
217void session::get_data(gnutls_session_t session,
218 gnutls_datum_t & data) const
219{
220 RETWRAP(gnutls_session_get_data2( this->s, &data));
221
222}
223
224void session::get_id ( void *session_id,
225 size_t * session_id_size) const
226{
227 RETWRAP( gnutls_session_get_id( this->s, session_id, session_id_size));
228}
229
230bool session::is_resumed() const
231{
232 int ret = gnutls_session_is_resumed( this->s);
233
234 if (ret != 0) return true;
235 return false;
236}
237
238
239bool session::get_peers_certificate(std::vector<gnutls_datum_t> &out_certs) const
240{
241 const gnutls_datum_t *certs;
242 unsigned int certs_size;
243
244 certs = gnutls_certificate_get_peers (this->s, &certs_size);
245
246 if (certs==NULL) return false;
247
248 for(unsigned int i=0;i<certs_size;i++)
249 out_certs.push_back( certs[i]);
250
251 return true;
252}
253
254bool session::get_peers_certificate(const gnutls_datum_t** certs, unsigned int *certs_size) const
255{
256 *certs = gnutls_certificate_get_peers (this->s, certs_size);
257
258 if (*certs==NULL) return false;
259 return true;
260}
261
262void session::get_our_certificate(gnutls_datum_t& cert) const
263{
264const gnutls_datum_t *d;
265
266 d = gnutls_certificate_get_ours(this->s);
267 if (d==NULL)
268 throw(exception( GNUTLS_E_INVALID_REQUEST));
269 cert = *d;
270}
271
272time_t session::get_peers_certificate_activation_time() const
273{
274 return gnutls_certificate_activation_time_peers( this->s);
275}
276
277time_t session::get_peers_certificate_expiration_time() const
278{
279 return gnutls_certificate_expiration_time_peers( this->s);
280}
281void session::verify_peers_certificate( unsigned int& status) const
282{
283 RETWRAP( gnutls_certificate_verify_peers2( this->s, &status));
284}
285
286
287client_session::client_session() : session( GNUTLS_CLIENT)
288{
289}
290
291// client session
292void client_session::set_server_name (gnutls_server_name_type_t type,
293 const void *name, size_t name_length)
294{
295 RETWRAP( gnutls_server_name_set( this->s, type, name, name_length));
296}
297
298bool client_session::get_request_status()
299{
300 return RETWRAP(gnutls_certificate_client_get_request_status (this->s));
301}
302
303// server_session
304void server_session::get_server_name (void *data, size_t * data_length,
305 unsigned int *type, unsigned int indx) const
306{
307 RETWRAP( gnutls_server_name_get( this->s, data, data_length, type, indx));
308}
309
310// internal DB stuff
311static int store_function(void *_db, gnutls_datum_t key, gnutls_datum_t data)
312{
313 try {
314 DB* db = static_cast<DB*>(_db);
315
316 if (db->store( key, data)==false) return -1;
317 } catch(...) {
318 return -1;
319 }
320
321 return 0;
322}
323
324const static gnutls_datum_t null_datum = { NULL, 0 };
325
326static gnutls_datum_t retrieve_function(void *_db, gnutls_datum_t key)
327{
328 gnutls_datum_t data;
329
330 try {
331 DB* db = static_cast<DB*>(_db);
332
333 if (db->retrieve( key, data)==false) return null_datum;
334
335 } catch(...) {
336 return null_datum;
337 }
338
339 return data;
340}
341
342static int remove_function(void *_db, gnutls_datum_t key)
343{
344 try {
345 DB* db = static_cast<DB*>(_db);
346
347 if (db->remove( key)==false) return -1;
348 } catch(...) {
349 return -1;
350 }
351
352 return 0;
353}
354
355void server_session::set_db( const DB& db)
356{
357 gnutls_db_set_ptr( this->s, const_cast<DB*>(&db));
358 gnutls_db_set_store_function( this->s, store_function);
359 gnutls_db_set_retrieve_function( this->s, retrieve_function);
360 gnutls_db_set_remove_function( this->s, remove_function);
361}
362
363void server_session::set_db_cache_expiration (unsigned int seconds)
364{
365 gnutls_db_set_cache_expiration( this->s, seconds);
366}
367
368void server_session::db_remove () const
369{
370 gnutls_db_remove_session( this->s);
371}
372
373bool server_session::db_check_entry ( gnutls_datum_t &session_data) const
374{
375 int ret = gnutls_db_check_entry( this->s, session_data);
376
377 if (ret != 0) return true;
378 return false;
379}
380
381void session::set_max_handshake_packet_length ( size_t max)
382{
383 gnutls_handshake_set_max_packet_length( this->s, max);
384}
385
386void session::clear_credentials()
387{
388 gnutls_credentials_clear( this->s);
389}
390
391void session::set_credentials( credentials &cred)
392{
393 RETWRAP(gnutls_credentials_set( this->s, cred.get_type(), cred.ptr()));
394}
395
396const char* server_session::get_srp_username() const
397{
398 return gnutls_srp_server_get_username( this->s);
399}
400
401const char* server_session::get_psk_username() const
402{
403 return gnutls_psk_server_get_username( this->s);
404}
405
406
407void session::set_transport_ptr( gnutls_transport_ptr_t ptr)
408{
409 gnutls_transport_set_ptr( this->s, ptr);
410}
411
412void session::set_transport_ptr( gnutls_transport_ptr_t recv_ptr, gnutls_transport_ptr_t send_ptr)
413{
414 gnutls_transport_set_ptr2( this->s, recv_ptr, send_ptr);
415}
416
417
418gnutls_transport_ptr_t session::get_transport_ptr () const
419{
420 return gnutls_transport_get_ptr (this->s);
421}
422
423void session::get_transport_ptr( gnutls_transport_ptr_t & recv_ptr,
424 gnutls_transport_ptr_t & send_ptr) const
425{
426 gnutls_transport_get_ptr2 (this->s, &recv_ptr, &send_ptr);
427}
428
429void session::set_transport_lowat( size_t num)
430{
431 gnutls_transport_set_lowat (this->s, num);
432}
433
434void session::set_transport_push_function( gnutls_push_func push_func)
435{
436 gnutls_transport_set_push_function ( this->s, push_func);
437}
438
439void session::set_transport_pull_function( gnutls_pull_func pull_func)
440{
441 gnutls_transport_set_pull_function ( this->s, pull_func);
442}
443
444void session::set_user_ptr( void* ptr)
445{
446 gnutls_session_set_ptr( this->s, ptr);
447}
448
449void* session::get_user_ptr( ) const
450{
451 return gnutls_session_get_ptr(this->s);
452}
453
454void session::send_openpgp_cert( gnutls_openpgp_crt_status_t status)
455{
456 gnutls_openpgp_send_cert(this->s, status);
457}
458
459
460void session::set_dh_prime_bits( unsigned int bits)
461{
462 gnutls_dh_set_prime_bits( this->s, bits);
463}
464
465unsigned int session::get_dh_secret_bits() const
466{
467 return RETWRAP( gnutls_dh_get_secret_bits( this->s));
468}
469
470unsigned int session::get_dh_peers_public_bits() const
471{
472 return RETWRAP(gnutls_dh_get_peers_public_bits( this->s));
473}
474
475unsigned int session::get_dh_prime_bits() const
476{
477 return RETWRAP( gnutls_dh_get_prime_bits( this->s));
478}
479
480void session::get_dh_group( gnutls_datum_t & gen, gnutls_datum_t & prime) const
481{
482 RETWRAP( gnutls_dh_get_group( this->s, &gen, &prime));
483}
484
485void session::get_dh_pubkey( gnutls_datum_t & raw_key) const
486{
487 RETWRAP(gnutls_dh_get_pubkey( this->s, &raw_key));
488}
489
490void session::get_rsa_export_pubkey( gnutls_datum_t& exponent, gnutls_datum_t& modulus) const
491{
492 RETWRAP( gnutls_rsa_export_get_pubkey( this->s, &exponent, &modulus));
493}
494
495unsigned int session::get_rsa_export_modulus_bits() const
496{
497 return RETWRAP(gnutls_rsa_export_get_modulus_bits( this->s));
498}
499
500void server_session::set_certificate_request( gnutls_certificate_request_t req)
501{
502 gnutls_certificate_server_set_request (this->s, req);
503}
504
505
506
507
508gnutls_credentials_type_t session::get_auth_type() const
509{
510 return gnutls_auth_get_type( this->s);
511}
512
513gnutls_credentials_type_t session::get_server_auth_type() const
514{
515 return gnutls_auth_server_get_type( this->s);
516}
517
518gnutls_credentials_type_t session::get_client_auth_type() const
519{
520 return gnutls_auth_client_get_type( this->s);
521}
522
523
524void* certificate_credentials::ptr() const
525{
526 return this->cred;
527}
528
529void certificate_credentials::set_ptr(void* p)
530{
531 this->cred = static_cast<gnutls_certificate_credentials_t> (p);
532}
533
534certificate_credentials::~certificate_credentials()
535{
536 gnutls_certificate_free_credentials (this->cred);
537}
538
539certificate_credentials::certificate_credentials() : credentials(GNUTLS_CRD_CERTIFICATE)
540{
541 RETWRAP(gnutls_certificate_allocate_credentials ( &this->cred));
542}
543
544void certificate_server_credentials::set_params_function( gnutls_params_function* func)
545{
546 gnutls_certificate_set_params_function( this->cred, func);
547}
548
549anon_server_credentials::anon_server_credentials() : credentials(GNUTLS_CRD_ANON)
550{
551 RETWRAP(gnutls_anon_allocate_server_credentials( &this->cred));
552}
553
554anon_server_credentials::~anon_server_credentials()
555{
556 gnutls_anon_free_server_credentials( this->cred);
557}
558
559void anon_server_credentials::set_dh_params( const dh_params& params)
560{
561 gnutls_anon_set_server_dh_params (this->cred, params.get_params_t());
562}
563
564void anon_server_credentials::set_params_function ( gnutls_params_function * func)
565{
566 gnutls_anon_set_server_params_function ( this->cred, func);
567}
568
569anon_client_credentials::anon_client_credentials() : credentials(GNUTLS_CRD_ANON)
570{
571 RETWRAP(gnutls_anon_allocate_client_credentials( &this->cred));
572}
573
574anon_client_credentials::~anon_client_credentials()
575{
576 gnutls_anon_free_client_credentials( this->cred);
577}
578
579void certificate_credentials::free_keys ()
580{
581 gnutls_certificate_free_keys( this->cred);
582}
583
584void certificate_credentials::free_cas ()
585{
586 gnutls_certificate_free_cas( this->cred);
587}
588
589void certificate_credentials::free_ca_names ()
590{
591 gnutls_certificate_free_ca_names( this->cred);
592}
593
594void certificate_credentials::free_crls ()
595{
596 gnutls_certificate_free_crls( this->cred);
597}
598
599
600void certificate_credentials::set_dh_params ( const dh_params& params)
601{
602 gnutls_certificate_set_dh_params( this->cred, params.get_params_t());
603}
604
605void certificate_credentials::set_rsa_export_params ( const rsa_params & params)
606{
607 gnutls_certificate_set_rsa_export_params( this->cred, params.get_params_t());
608}
609
610void certificate_credentials::set_verify_flags ( unsigned int flags)
611{
612 gnutls_certificate_set_verify_flags( this->cred, flags);
613}
614
615void certificate_credentials::set_verify_limits ( unsigned int max_bits, unsigned int max_depth)
616{
617 gnutls_certificate_set_verify_limits( this->cred, max_bits, max_depth);
618}
619
620void certificate_credentials::set_x509_trust_file(const char *cafile, gnutls_x509_crt_fmt_t type)
621{
622 RETWRAP( gnutls_certificate_set_x509_trust_file( this->cred, cafile, type));
623}
624
625void certificate_credentials::set_x509_trust(const gnutls_datum_t & CA, gnutls_x509_crt_fmt_t type)
626{
627 RETWRAP( gnutls_certificate_set_x509_trust_mem( this->cred, &CA, type));
628}
629
630
631void certificate_credentials::set_x509_crl_file( const char *crlfile, gnutls_x509_crt_fmt_t type)
632{
633 RETWRAP( gnutls_certificate_set_x509_crl_file( this->cred, crlfile, type));
634}
635
636void certificate_credentials::set_x509_crl(const gnutls_datum_t & CRL, gnutls_x509_crt_fmt_t type)
637{
638 RETWRAP( gnutls_certificate_set_x509_crl_mem( this->cred, &CRL, type));
639}
640
641void certificate_credentials::set_x509_key_file(const char *certfile, const char *keyfile, gnutls_x509_crt_fmt_t type)
642{
643 RETWRAP( gnutls_certificate_set_x509_key_file( this->cred, certfile, keyfile, type));
644}
645
646void certificate_credentials::set_x509_key(const gnutls_datum_t & CERT, const gnutls_datum_t & KEY, gnutls_x509_crt_fmt_t type)
647{
648 RETWRAP( gnutls_certificate_set_x509_key_mem( this->cred, &CERT, &KEY, type));
649}
650
651void certificate_credentials::set_simple_pkcs12_file( const char *pkcs12file,
652 gnutls_x509_crt_fmt_t type, const char *password)
653{
654 RETWRAP( gnutls_certificate_set_x509_simple_pkcs12_file( this->cred, pkcs12file, type, password));
655}
656
657void certificate_credentials::set_x509_key ( gnutls_x509_crt_t * cert_list, int cert_list_size,
658 gnutls_x509_privkey_t key)
659{
660 RETWRAP( gnutls_certificate_set_x509_key( this->cred, cert_list, cert_list_size, key));
661}
662
663void certificate_credentials::set_x509_trust ( gnutls_x509_crt_t * ca_list, int ca_list_size)
664{
665 RETWRAP( gnutls_certificate_set_x509_trust( this->cred, ca_list, ca_list_size));
666}
667
668void certificate_credentials::set_x509_crl ( gnutls_x509_crl_t * crl_list, int crl_list_size)
669{
670 RETWRAP( gnutls_certificate_set_x509_crl( this->cred, crl_list, crl_list_size));
671}
672
673void certificate_server_credentials::set_retrieve_function( gnutls_certificate_server_retrieve_function* func)
674{
675 gnutls_certificate_server_set_retrieve_function( this->cred, func);
676}
677
678void certificate_client_credentials::set_retrieve_function( gnutls_certificate_client_retrieve_function* func)
679{
680 gnutls_certificate_client_set_retrieve_function( this->cred, func);
681}
682
683// SRP
684
685srp_server_credentials::srp_server_credentials() : credentials(GNUTLS_CRD_SRP)
686{
687 RETWRAP(gnutls_srp_allocate_server_credentials( &this->cred));
688}
689
690srp_server_credentials::~srp_server_credentials()
691{
692 gnutls_srp_free_server_credentials( this->cred);
693}
694
695void* srp_server_credentials::ptr() const
696{
697 return this->cred;
698}
699
700void srp_server_credentials::set_ptr(void* p)
701{
702 this->cred = static_cast<gnutls_srp_server_credentials_t> (p);
703}
704
705srp_client_credentials::srp_client_credentials() : credentials(GNUTLS_CRD_SRP)
706{
707 RETWRAP(gnutls_srp_allocate_client_credentials( &this->cred));
708}
709
710srp_client_credentials::~srp_client_credentials()
711{
712 gnutls_srp_free_client_credentials( this->cred);
713}
714
715void* srp_client_credentials::ptr() const
716{
717 return this->cred;
718}
719
720void srp_client_credentials::set_ptr(void* p)
721{
722 this->cred = static_cast<gnutls_srp_client_credentials_t> (p);
723}
724
725void srp_client_credentials::set_credentials( const char* username, const char* password)
726{
727 RETWRAP(gnutls_srp_set_client_credentials (this->cred, username, password));
728}
729
730void srp_server_credentials::set_credentials_file (
731 const char *password_file, const char *password_conf_file)
732{
733 RETWRAP( gnutls_srp_set_server_credentials_file( this->cred, password_file, password_conf_file));
734}
735
736
737void srp_server_credentials::set_credentials_function(gnutls_srp_server_credentials_function * func)
738{
739 gnutls_srp_set_server_credentials_function( this->cred, func);
740}
741
742void srp_client_credentials::set_credentials_function(gnutls_srp_client_credentials_function * func)
743{
744 gnutls_srp_set_client_credentials_function( this->cred, func);
745}
746
747credentials::credentials(gnutls_credentials_type_t t) : type(t)
748{
749}
750
751#if !(defined(__APPLE__) || defined(__MACOS__))
752/* FIXME: This #if is due to a compile bug in Mac OS X. Give it some
753 time and then remove this cruft. See also
754 includes/gnutls/gnutlsxx.h. */
755credentials::credentials( credentials& c)
756{
757 this->type = c.type;
758 this->set_ptr( c.ptr());
759}
760#endif
761
762gnutls_credentials_type_t credentials::get_type() const
763{
764 return type;
765}
766
767exception::exception( int x)
768{
769 retcode = x;
770}
771
772int exception::get_code()
773{
774 return retcode;
775}
776
777const char* exception::what() const throw()
778{
779 return gnutls_strerror(retcode);
780}
781
782
783
784
785dh_params::dh_params()
786{
787 RETWRAP(gnutls_dh_params_init( &params));
788}
789
790dh_params::~dh_params()
791{
792 gnutls_dh_params_deinit(params);
793}
794
795void dh_params::import_raw( const gnutls_datum_t & prime,
796 const gnutls_datum_t & generator)
797{
798 RETWRAP( gnutls_dh_params_import_raw( params, &prime, &generator));
799}
800
801void dh_params::import_pkcs3( const gnutls_datum_t & pkcs3_params,
802 gnutls_x509_crt_fmt_t format)
803{
804 RETWRAP(gnutls_dh_params_import_pkcs3( params, &pkcs3_params, format));
805}
806
807void dh_params::generate( unsigned int bits)
808{
809 RETWRAP(gnutls_dh_params_generate2( params, bits));
810}
811
812void dh_params::export_pkcs3( gnutls_x509_crt_fmt_t format, unsigned char *params_data, size_t * params_data_size)
813{
814 RETWRAP( gnutls_dh_params_export_pkcs3( params, format, params_data, params_data_size));
815}
816
817void dh_params::export_raw( gnutls_datum_t& prime, gnutls_datum_t &generator)
818{
819 RETWRAP( gnutls_dh_params_export_raw( params, &prime, &generator, NULL));
820}
821
822gnutls_dh_params_t dh_params::get_params_t() const
823{
824 return params;
825}
826
827dh_params & dh_params::operator=(const dh_params& src)
828{
829 dh_params* dst = new dh_params;
830 int ret;
831
832 ret = gnutls_dh_params_cpy( dst->params, src.params);
833
834 if (ret < 0) {
835 delete dst;
836 throw(ret);
837 }
838
839 return *dst;
840}
841
842
843// RSA
844
845rsa_params::rsa_params()
846{
847 RETWRAP(gnutls_rsa_params_init( &params));
848}
849
850rsa_params::~rsa_params()
851{
852 gnutls_rsa_params_deinit(params);
853}
854
855void rsa_params::import_pkcs1( const gnutls_datum_t & pkcs1_params,
856 gnutls_x509_crt_fmt_t format)
857{
858 RETWRAP(gnutls_rsa_params_import_pkcs1( params, &pkcs1_params, format));
859}
860
861void rsa_params::generate( unsigned int bits)
862{
863 RETWRAP(gnutls_rsa_params_generate2( params, bits));
864}
865
866void rsa_params::export_pkcs1( gnutls_x509_crt_fmt_t format, unsigned char *params_data, size_t * params_data_size)
867{
868 RETWRAP( gnutls_rsa_params_export_pkcs1( params, format, params_data, params_data_size));
869}
870
871gnutls_rsa_params_t rsa_params::get_params_t() const
872{
873 return params;
874}
875
876rsa_params & rsa_params::operator=(const rsa_params& src)
877{
878 rsa_params* dst = new rsa_params;
879 int ret;
880
881 ret = gnutls_rsa_params_cpy( dst->params, src.params);
882
883 if (ret < 0)
884 delete dst;
885 throw(ret);
886
887 return *dst;
888}
889
890void rsa_params::import_raw( const gnutls_datum_t & m,
891 const gnutls_datum_t & e,
892 const gnutls_datum_t & d,
893 const gnutls_datum_t & p,
894 const gnutls_datum_t & q,
895 const gnutls_datum_t & u)
896{
897
898 RETWRAP(gnutls_rsa_params_import_raw ( params, &m, &e, &d, &p, &q, &u));
899}
900
901
902void rsa_params::export_raw( gnutls_datum_t & m, gnutls_datum_t & e,
903 gnutls_datum_t & d, gnutls_datum_t & p,
904 gnutls_datum_t & q, gnutls_datum_t & u)
905{
906 RETWRAP( gnutls_rsa_params_export_raw ( params, &m, &e, &d, &p, &q, &u, NULL));
907}
diff --git a/src/daemon/https/tls/io_debug.h b/src/daemon/https/tls/io_debug.h
new file mode 100644
index 00000000..9800565e
--- /dev/null
+++ b/src/daemon/https/tls/io_debug.h
@@ -0,0 +1,79 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This debug file was contributed by
26 * Paul Sheer <psheer@icon.co.za>. Some changes were made by nmav.
27 * Its purpose is to debug non blocking behaviour of gnutls. The included
28 * send() and recv() functions return EAGAIN errors in random.
29 *
30 */
31
32#ifdef IO_DEBUG
33
34#include <gnutls_int.h>
35
36#define EDUNNO EAGAIN /* EAGAIN */
37
38extern int errno;
39static int initialized_rand = 0;
40
41#define INITIALIZE_RAND if (initialized_rand==0) {\
42 srand(time(0)); \
43 initialized_rand = 1; \
44 }
45static int
46recv_debug (int fd, char *buf, int len, int flags)
47{
48 INITIALIZE_RAND;
49
50 if (!(rand () % IO_DEBUG))
51 {
52 errno = EDUNNO;
53 return -1;
54 }
55 if (len > 1)
56 len = 1;
57 return recv (fd, buf, len, flags);
58}
59
60#define recv recv_debug
61
62static int
63send_debug (int fd, const char *buf, int len, int flags)
64{
65 INITIALIZE_RAND;
66
67 if (!(rand () % IO_DEBUG))
68 {
69 errno = EDUNNO;
70 return -1;
71 }
72 if (len > 10)
73 len = 10;
74 return send (fd, buf, len, flags);
75}
76
77#define send send_debug
78
79#endif
diff --git a/src/daemon/https/tls/libgnutls-config b/src/daemon/https/tls/libgnutls-config
new file mode 100644
index 00000000..80580a89
--- /dev/null
+++ b/src/daemon/https/tls/libgnutls-config
@@ -0,0 +1,104 @@
1#!/bin/sh
2
3prefix=/home/lama/workbench/programming/c/gnunet/gnutls-2.2.3/build
4exec_prefix=${prefix}
5exec_prefix_set=no
6
7gnutls_libs="-L${exec_prefix}/lib -lgnutls -L/usr/lib -ltasn1 -lgcrypt "
8gnutls_cflags=" -I/usr/include -I${prefix}/include"
9gnutls_la_file="${exec_prefix}/lib/libgnutls.la"
10
11usage()
12{
13 cat <<EOF
14Usage: libgnutls-config [OPTIONS]
15Options:
16 [--prefix[=DIR]]
17 [--exec-prefix[=DIR]]
18 [--version]
19 [--libs]
20 [--cflags]
21EOF
22 exit $1
23}
24
25if test $# -eq 0; then
26 usage 1 1>&2
27fi
28
29while test $# -gt 0; do
30 case "$1" in
31 -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
32 *) optarg= ;;
33 esac
34
35 case $1 in
36 --prefix=*)
37 prefix=$optarg
38 if test $exec_prefix_set = no ; then
39 exec_prefix=$optarg
40 fi
41 ;;
42 --prefix)
43 echo_prefix=yes
44 ;;
45 --exec-prefix=*)
46 exec_prefix=$optarg
47 exec_prefix_set=yes
48 ;;
49 --exec-prefix)
50 echo_exec_prefix=yes
51 ;;
52 --version)
53 echo "2.2.3"
54 exit 0
55 ;;
56 --cflags)
57 echo_cflags=yes
58 ;;
59 --libs)
60 echo_libs=yes
61 ;;
62 --la-file)
63 echo_la_file=yes
64 ;;
65 --help)
66 usage 0
67 ;;
68 *)
69 usage 1 1>&2
70 ;;
71 esac
72 shift
73done
74
75if test "$echo_prefix" = "yes"; then
76 echo $prefix
77fi
78
79if test "$echo_exec_prefix" = "yes"; then
80 echo $exec_prefix
81fi
82
83if test "$echo_cflags" = "yes"; then
84 if test "${prefix}/include" != "/usr/include" ; then
85 includes="-I${prefix}/include"
86 for i in $gnutls_cflags ; do
87 if test "$i" = "-I${prefix}/include" ; then
88 includes=""
89 fi
90 done
91 fi
92 echo $includes $gnutls_cflags
93fi
94
95if test "$echo_la_file" = "yes"; then
96 echo ${gnutls_la_file}
97fi
98
99if test "$echo_libs" = "yes"; then
100 echo ${gnutls_libs}
101fi
102
103
104
diff --git a/src/daemon/https/tls/libgnutls.m4 b/src/daemon/https/tls/libgnutls.m4
new file mode 100644
index 00000000..1851ca23
--- /dev/null
+++ b/src/daemon/https/tls/libgnutls.m4
@@ -0,0 +1,160 @@
1dnl Autoconf macros for libgnutls
2dnl $id$
3
4# Modified for LIBGNUTLS -- nmav
5# Configure paths for LIBGCRYPT
6# Shamelessly stolen from the one of XDELTA by Owen Taylor
7# Werner Koch 99-12-09
8
9dnl AM_PATH_LIBGNUTLS([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
10dnl Test for libgnutls, and define LIBGNUTLS_CFLAGS and LIBGNUTLS_LIBS
11dnl
12AC_DEFUN([AM_PATH_LIBGNUTLS],
13[dnl
14dnl Get the cflags and libraries from the libgnutls-config script
15dnl
16AC_ARG_WITH(libgnutls-prefix,
17 [ --with-libgnutls-prefix=PFX Prefix where libgnutls is installed (optional)],
18 libgnutls_config_prefix="$withval", libgnutls_config_prefix="")
19
20 if test x$libgnutls_config_prefix != x ; then
21 if test x${LIBGNUTLS_CONFIG+set} != xset ; then
22 LIBGNUTLS_CONFIG=$libgnutls_config_prefix/bin/libgnutls-config
23 fi
24 fi
25
26 AC_PATH_PROG(LIBGNUTLS_CONFIG, libgnutls-config, no)
27 min_libgnutls_version=ifelse([$1], ,0.1.0,$1)
28 AC_MSG_CHECKING(for libgnutls - version >= $min_libgnutls_version)
29 no_libgnutls=""
30 if test "$LIBGNUTLS_CONFIG" = "no" ; then
31 no_libgnutls=yes
32 else
33 LIBGNUTLS_CFLAGS=`$LIBGNUTLS_CONFIG $libgnutls_config_args --cflags`
34 LIBGNUTLS_LIBS=`$LIBGNUTLS_CONFIG $libgnutls_config_args --libs`
35 libgnutls_config_version=`$LIBGNUTLS_CONFIG $libgnutls_config_args --version`
36
37
38 ac_save_CFLAGS="$CFLAGS"
39 ac_save_LIBS="$LIBS"
40 CFLAGS="$CFLAGS $LIBGNUTLS_CFLAGS"
41 LIBS="$LIBS $LIBGNUTLS_LIBS"
42dnl
43dnl Now check if the installed libgnutls is sufficiently new. Also sanity
44dnl checks the results of libgnutls-config to some extent
45dnl
46 rm -f conf.libgnutlstest
47 AC_TRY_RUN([
48#include <stdio.h>
49#include <stdlib.h>
50#include <string.h>
51#include <gnutls.h>
52
53int
54main ()
55{
56 system ("touch conf.libgnutlstest");
57
58 if( strcmp( gnutls_check_version(NULL), "$libgnutls_config_version" ) )
59 {
60 printf("\n*** 'libgnutls-config --version' returned %s, but LIBGNUTLS (%s)\n",
61 "$libgnutls_config_version", gnutls_check_version(NULL) );
62 printf("*** was found! If libgnutls-config was correct, then it is best\n");
63 printf("*** to remove the old version of LIBGNUTLS. You may also be able to fix the error\n");
64 printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n");
65 printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n");
66 printf("*** required on your system.\n");
67 printf("*** If libgnutls-config was wrong, set the environment variable LIBGNUTLS_CONFIG\n");
68 printf("*** to point to the correct copy of libgnutls-config, and remove the file config.cache\n");
69 printf("*** before re-running configure\n");
70 }
71 else if ( strcmp(gnutls_check_version(NULL), LIBGNUTLS_VERSION ) )
72 {
73 printf("\n*** LIBGNUTLS header file (version %s) does not match\n", LIBGNUTLS_VERSION);
74 printf("*** library (version %s)\n", gnutls_check_version(NULL) );
75 }
76 else
77 {
78 if ( gnutls_check_version( "$min_libgnutls_version" ) )
79 {
80 return 0;
81 }
82 else
83 {
84 printf("no\n*** An old version of LIBGNUTLS (%s) was found.\n",
85 gnutls_check_version(NULL) );
86 printf("*** You need a version of LIBGNUTLS newer than %s. The latest version of\n",
87 "$min_libgnutls_version" );
88 printf("*** LIBGNUTLS is always available from ftp://gnutls.hellug.gr/pub/gnutls.\n");
89 printf("*** \n");
90 printf("*** If you have already installed a sufficiently new version, this error\n");
91 printf("*** probably means that the wrong copy of the libgnutls-config shell script is\n");
92 printf("*** being found. The easiest way to fix this is to remove the old version\n");
93 printf("*** of LIBGNUTLS, but you can also set the LIBGNUTLS_CONFIG environment to point to the\n");
94 printf("*** correct copy of libgnutls-config. (In this case, you will have to\n");
95 printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
96 printf("*** so that the correct libraries are found at run-time))\n");
97 }
98 }
99 return 1;
100}
101],, no_libgnutls=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
102 CFLAGS="$ac_save_CFLAGS"
103 LIBS="$ac_save_LIBS"
104 fi
105
106 if test "x$no_libgnutls" = x ; then
107 AC_MSG_RESULT(yes)
108 ifelse([$2], , :, [$2])
109 else
110 if test -f conf.libgnutlstest ; then
111 :
112 else
113 AC_MSG_RESULT(no)
114 fi
115 if test "$LIBGNUTLS_CONFIG" = "no" ; then
116 echo "*** The libgnutls-config script installed by LIBGNUTLS could not be found"
117 echo "*** If LIBGNUTLS was installed in PREFIX, make sure PREFIX/bin is in"
118 echo "*** your path, or set the LIBGNUTLS_CONFIG environment variable to the"
119 echo "*** full path to libgnutls-config."
120 else
121 if test -f conf.libgnutlstest ; then
122 :
123 else
124 echo "*** Could not run libgnutls test program, checking why..."
125 CFLAGS="$CFLAGS $LIBGNUTLS_CFLAGS"
126 LIBS="$LIBS $LIBGNUTLS_LIBS"
127 AC_TRY_LINK([
128#include <stdio.h>
129#include <stdlib.h>
130#include <string.h>
131#include <gnutls.h>
132], [ return !!gnutls_check_version(NULL); ],
133 [ echo "*** The test program compiled, but did not run. This usually means"
134 echo "*** that the run-time linker is not finding LIBGNUTLS or finding the wrong"
135 echo "*** version of LIBGNUTLS. If it is not finding LIBGNUTLS, you'll need to set your"
136 echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
137 echo "*** to the installed location Also, make sure you have run ldconfig if that"
138 echo "*** is required on your system"
139 echo "***"
140 echo "*** If you have an old version installed, it is best to remove it, although"
141 echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"
142 echo "***" ],
143 [ echo "*** The test program failed to compile or link. See the file config.log for the"
144 echo "*** exact error that occured. This usually means LIBGNUTLS was incorrectly installed"
145 echo "*** or that you have moved LIBGNUTLS since it was installed. In the latter case, you"
146 echo "*** may want to edit the libgnutls-config script: $LIBGNUTLS_CONFIG" ])
147 CFLAGS="$ac_save_CFLAGS"
148 LIBS="$ac_save_LIBS"
149 fi
150 fi
151 LIBGNUTLS_CFLAGS=""
152 LIBGNUTLS_LIBS=""
153 ifelse([$3], , :, [$3])
154 fi
155 rm -f conf.libgnutlstest
156 AC_SUBST(LIBGNUTLS_CFLAGS)
157 AC_SUBST(LIBGNUTLS_LIBS)
158])
159
160dnl *-*wedit:notab*-* Please keep this as the last line.
diff --git a/src/daemon/https/tls/libgnutls.vers b/src/daemon/https/tls/libgnutls.vers
new file mode 100644
index 00000000..f793617b
--- /dev/null
+++ b/src/daemon/https/tls/libgnutls.vers
@@ -0,0 +1,27 @@
1# libgnutls.vers -- Versioning script to control what symbols to export.
2# Copyright (C) 2005, 2006, 2007 Free Software Foundation
3#
4# Author: Simon Josefsson
5#
6# This file is part of GNUTLS.
7#
8# The GNUTLS library is free software; you can redistribute it and/or
9# modify it under the terms of the GNU Lesser General Public License
10# as published by the Free Software Foundation; either version 2.1 of
11# the License, or (at your option) any later version.
12#
13# The GNUTLS library is distributed in the hope that it will be
14#useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15#of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16#Lesser General Public License for more details.
17#
18# You should have received a copy of the GNU Lesser General Public
19# License along with the GNUTLS library; if not, write to the Free
20# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21# MA 02110-1301, USA
22
23GNUTLS_1_4
24{
25 global: _gnutls*; gnutls*;
26 local: *;
27};
diff --git a/src/daemon/https/tls/libgnutlsxx.vers b/src/daemon/https/tls/libgnutlsxx.vers
new file mode 100644
index 00000000..8b8af51d
--- /dev/null
+++ b/src/daemon/https/tls/libgnutlsxx.vers
@@ -0,0 +1,30 @@
1# libgnutlsxx.vers -- Versioning script to control what symbols to export.
2# Copyright (C) 2005, 2006 Free Software Foundation
3#
4# Author: Simon Josefsson
5#
6# This file is part of GNUTLS.
7#
8# The GNUTLS library is free software; you can redistribute it and/or
9# modify it under the terms of the GNU Lesser General Public License
10# as published by the Free Software Foundation; either version 2.1 of
11# the License, or (at your option) any later version.
12#
13# The GNUTLS library is distributed in the hope that it will be
14#useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15#of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16#Lesser General Public License for more details.
17#
18# You should have received a copy of the GNU Lesser General Public
19# License along with the GNUTLS library; if not, write to the Free
20# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21# MA 02110-1301, USA
22
23GNUTLS_1_6
24{
25 global:
26 extern "C++" {
27 gnutls*;
28 };
29 local: *;
30};
diff --git a/src/daemon/https/tls/pkix.asn b/src/daemon/https/tls/pkix.asn
new file mode 100644
index 00000000..d46dfa07
--- /dev/null
+++ b/src/daemon/https/tls/pkix.asn
@@ -0,0 +1,1241 @@
1
2PKIX1 { }
3
4DEFINITIONS IMPLICIT TAGS ::=
5
6BEGIN
7
8-- This contains both PKIX1Implicit88 and RFC2630 ASN.1 modules.
9
10-- ISO arc for standard certificate and CRL extensions
11
12id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29}
13
14
15-- authority key identifier OID and syntax
16
17id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 }
18
19AuthorityKeyIdentifier ::= SEQUENCE {
20 keyIdentifier [0] KeyIdentifier OPTIONAL,
21 authorityCertIssuer [1] GeneralNames OPTIONAL,
22 authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL }
23 -- authorityCertIssuer and authorityCertSerialNumber shall both
24 -- be present or both be absgent
25
26KeyIdentifier ::= OCTET STRING
27
28-- subject key identifier OID and syntax
29
30id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 }
31
32SubjectKeyIdentifier ::= KeyIdentifier
33
34-- key usage extension OID and syntax
35
36id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 }
37
38KeyUsage ::= BIT STRING {
39 digitalSignature (0),
40 nonRepudiation (1),
41 keyEncipherment (2),
42 dataEncipherment (3),
43 keyAgreement (4),
44 keyCertSign (5),
45 cRLSign (6),
46 encipherOnly (7),
47 decipherOnly (8) }
48
49-- private key usage period extension OID and syntax
50
51id-ce-privateKeyUsagePeriod OBJECT IDENTIFIER ::= { id-ce 16 }
52
53PrivateKeyUsagePeriod ::= SEQUENCE {
54 notBefore [0] GeneralizedTime OPTIONAL,
55 notAfter [1] GeneralizedTime OPTIONAL }
56 -- either notBefore or notAfter shall be present
57
58-- certificate policies extension OID and syntax
59
60id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 }
61
62CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
63
64PolicyInformation ::= SEQUENCE {
65 policyIdentifier CertPolicyId,
66 policyQualifiers SEQUENCE SIZE (1..MAX) OF
67 PolicyQualifierInfo OPTIONAL }
68
69CertPolicyId ::= OBJECT IDENTIFIER
70
71PolicyQualifierInfo ::= SEQUENCE {
72 policyQualifierId PolicyQualifierId,
73 qualifier ANY DEFINED BY policyQualifierId }
74
75-- Implementations that recognize additional policy qualifiers shall
76-- augment the following definition for PolicyQualifierId
77
78PolicyQualifierId ::=
79 OBJECT IDENTIFIER -- ( id-qt-cps | id-qt-unotice )
80
81-- CPS pointer qualifier
82
83CPSuri ::= IA5String
84
85-- user notice qualifier
86
87UserNotice ::= SEQUENCE {
88 noticeRef NoticeReference OPTIONAL,
89 explicitText DisplayText OPTIONAL}
90
91NoticeReference ::= SEQUENCE {
92 organization DisplayText,
93 noticeNumbers SEQUENCE OF INTEGER }
94
95DisplayText ::= CHOICE {
96 visibleString VisibleString (SIZE (1..200)),
97 bmpString BMPString (SIZE (1..200)),
98 utf8String UTF8String (SIZE (1..200)) }
99
100-- policy mapping extension OID and syntax
101
102id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 }
103
104PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
105 issuerDomainPolicy CertPolicyId,
106 subjectDomainPolicy CertPolicyId }
107
108-- subject alternative name extension OID and syntax
109
110-- Directory string type --
111
112DirectoryString ::= CHOICE {
113 teletexString TeletexString (SIZE (1..MAX)),
114 printableString PrintableString (SIZE (1..MAX)),
115 universalString UniversalString (SIZE (1..MAX)),
116 utf8String UTF8String (SIZE (1..MAX)),
117 bmpString BMPString (SIZE(1..MAX)),
118 -- IA5String is added here to handle old UID encoded as ia5String --
119 -- See tests/userid/ for more information. It shouldn't be here, --
120 -- so if it causes problems, considering dropping it. --
121 ia5String IA5String (SIZE(1..MAX)) }
122
123id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 }
124
125SubjectAltName ::= GeneralNames
126
127GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
128
129GeneralName ::= CHOICE {
130 otherName [0] AnotherName,
131 rfc822Name [1] IA5String,
132 dNSName [2] IA5String,
133 x400Address [3] ORAddress,
134-- Changed to work with the libtasn1 parser.
135 directoryName [4] EXPLICIT RDNSequence, --Name,
136 ediPartyName [5] EDIPartyName,
137 uniformResourceIdentifier [6] IA5String,
138 iPAddress [7] OCTET STRING,
139 registeredID [8] OBJECT IDENTIFIER }
140
141-- AnotherName replaces OTHER-NAME ::= TYPE-IDENTIFIER, as
142-- TYPE-IDENTIFIER is not supported in the '88 ASN.1 syntax
143
144AnotherName ::= SEQUENCE {
145 type-id OBJECT IDENTIFIER,
146 value [0] EXPLICIT ANY DEFINED BY type-id }
147
148EDIPartyName ::= SEQUENCE {
149 nameAssigner [0] DirectoryString OPTIONAL,
150 partyName [1] DirectoryString }
151
152-- issuer alternative name extension OID and syntax
153
154id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 }
155
156IssuerAltName ::= GeneralNames
157
158id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 }
159
160SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF Attribute
161
162-- basic constraints extension OID and syntax
163
164id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 }
165
166BasicConstraints ::= SEQUENCE {
167 cA BOOLEAN DEFAULT FALSE,
168 pathLenConstraint INTEGER (0..MAX) OPTIONAL }
169
170-- name constraints extension OID and syntax
171
172id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 }
173
174NameConstraints ::= SEQUENCE {
175 permittedSubtrees [0] GeneralSubtrees OPTIONAL,
176 excludedSubtrees [1] GeneralSubtrees OPTIONAL }
177
178GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
179
180GeneralSubtree ::= SEQUENCE {
181 base GeneralName,
182 minimum [0] BaseDistance DEFAULT 0,
183 maximum [1] BaseDistance OPTIONAL }
184
185BaseDistance ::= INTEGER (0..MAX)
186
187-- policy constraints extension OID and syntax
188
189id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 }
190
191PolicyConstraints ::= SEQUENCE {
192 requireExplicitPolicy [0] SkipCerts OPTIONAL,
193 inhibitPolicyMapping [1] SkipCerts OPTIONAL }
194
195SkipCerts ::= INTEGER (0..MAX)
196
197-- CRL distribution points extension OID and syntax
198
199id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= {id-ce 31}
200
201CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
202
203DistributionPoint ::= SEQUENCE {
204 distributionPoint [0] EXPLICIT DistributionPointName OPTIONAL,
205 reasons [1] ReasonFlags OPTIONAL,
206 cRLIssuer [2] GeneralNames OPTIONAL
207}
208
209DistributionPointName ::= CHOICE {
210 fullName [0] GeneralNames,
211 nameRelativeToCRLIssuer [1] RelativeDistinguishedName
212}
213
214ReasonFlags ::= BIT STRING {
215 unused (0),
216 keyCompromise (1),
217 cACompromise (2),
218 affiliationChanged (3),
219 superseded (4),
220 cessationOfOperation (5),
221 certificateHold (6),
222 privilegeWithdrawn (7),
223 aACompromise (8) }
224
225-- extended key usage extension OID and syntax
226
227id-ce-extKeyUsage OBJECT IDENTIFIER ::= {id-ce 37}
228
229ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
230
231KeyPurposeId ::= OBJECT IDENTIFIER
232
233-- extended key purpose OIDs
234id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 }
235id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 }
236id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 }
237id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 }
238id-kp-ipsecEndSystem OBJECT IDENTIFIER ::= { id-kp 5 }
239id-kp-ipsecTunnel OBJECT IDENTIFIER ::= { id-kp 6 }
240id-kp-ipsecUser OBJECT IDENTIFIER ::= { id-kp 7 }
241id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 }
242
243-- authority info access
244
245id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
246
247AuthorityInfoAccessSyntax ::=
248 SEQUENCE SIZE (1..MAX) OF AccessDescription
249
250AccessDescription ::= SEQUENCE {
251 accessMethod OBJECT IDENTIFIER,
252 accessLocation GeneralName }
253
254-- CRL number extension OID and syntax
255
256id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 }
257
258CRLNumber ::= INTEGER (0..MAX)
259
260-- issuing distribution point extension OID and syntax
261
262id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-ce 28 }
263
264IssuingDistributionPoint ::= SEQUENCE {
265 distributionPoint [0] DistributionPointName OPTIONAL,
266 onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE,
267 onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE,
268 onlySomeReasons [3] ReasonFlags OPTIONAL,
269 indirectCRL [4] BOOLEAN DEFAULT FALSE }
270
271
272id-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= { id-ce 27 }
273
274-- deltaCRLIndicator ::= BaseCRLNumber
275
276BaseCRLNumber ::= CRLNumber
277
278-- CRL reasons extension OID and syntax
279
280id-ce-cRLReasons OBJECT IDENTIFIER ::= { id-ce 21 }
281
282CRLReason ::= ENUMERATED {
283 unspecified (0),
284 keyCompromise (1),
285 cACompromise (2),
286 affiliationChanged (3),
287 superseded (4),
288 cessationOfOperation (5),
289 certificateHold (6),
290 removeFromCRL (8) }
291
292-- certificate issuer CRL entry extension OID and syntax
293
294id-ce-certificateIssuer OBJECT IDENTIFIER ::= { id-ce 29 }
295
296CertificateIssuer ::= GeneralNames
297
298-- hold instruction extension OID and syntax
299
300id-ce-holdInstructionCode OBJECT IDENTIFIER ::= { id-ce 23 }
301
302HoldInstructionCode ::= OBJECT IDENTIFIER
303
304-- ANSI x9 holdinstructions
305
306-- ANSI x9 arc holdinstruction arc
307holdInstruction OBJECT IDENTIFIER ::=
308 {joint-iso-itu-t(2) member-body(2) us(840) x9cm(10040) 2}
309
310-- ANSI X9 holdinstructions referenced by this standard
311id-holdinstruction-none OBJECT IDENTIFIER ::=
312 {holdInstruction 1} -- deprecated
313id-holdinstruction-callissuer OBJECT IDENTIFIER ::=
314 {holdInstruction 2}
315id-holdinstruction-reject OBJECT IDENTIFIER ::=
316 {holdInstruction 3}
317
318-- invalidity date CRL entry extension OID and syntax
319
320id-ce-invalidityDate OBJECT IDENTIFIER ::= { id-ce 24 }
321
322InvalidityDate ::= GeneralizedTime
323
324
325-- --------------------------------------
326-- EXPLICIT
327-- --------------------------------------
328
329-- UNIVERSAL Types defined in '93 and '98 ASN.1
330-- but required by this specification
331
332VisibleString ::= [UNIVERSAL 26] IMPLICIT OCTET STRING
333
334NumericString ::= [UNIVERSAL 18] IMPLICIT OCTET STRING
335
336IA5String ::= [UNIVERSAL 22] IMPLICIT OCTET STRING
337
338TeletexString ::= [UNIVERSAL 20] IMPLICIT OCTET STRING
339
340PrintableString ::= [UNIVERSAL 19] IMPLICIT OCTET STRING
341
342UniversalString ::= [UNIVERSAL 28] IMPLICIT OCTET STRING
343 -- UniversalString is defined in ASN.1:1993
344
345BMPString ::= [UNIVERSAL 30] IMPLICIT OCTET STRING
346 -- BMPString is the subtype of UniversalString and models
347 -- the Basic Multilingual Plane of ISO/IEC/ITU 10646-1
348
349UTF8String ::= [UNIVERSAL 12] IMPLICIT OCTET STRING
350 -- The content of this type conforms to RFC 2279.
351
352
353-- PKIX specific OIDs
354
355id-pkix OBJECT IDENTIFIER ::=
356 { iso(1) identified-organization(3) dod(6) internet(1)
357 security(5) mechanisms(5) pkix(7) }
358
359-- PKIX arcs
360
361id-pe OBJECT IDENTIFIER ::= { id-pkix 1 }
362 -- arc for private certificate extensions
363id-qt OBJECT IDENTIFIER ::= { id-pkix 2 }
364 -- arc for policy qualifier types
365id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
366 -- arc for extended key purpose OIDS
367id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }
368 -- arc for access descriptors
369
370-- policyQualifierIds for Internet policy qualifiers
371
372id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 }
373 -- OID for CPS qualifier
374id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 }
375 -- OID for user notice qualifier
376
377-- access descriptor definitions
378
379id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 }
380id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 }
381
382-- attribute data types --
383
384Attribute ::= SEQUENCE {
385 type AttributeType,
386 values SET OF AttributeValue
387 -- at least one value is required --
388}
389
390AttributeType ::= OBJECT IDENTIFIER
391
392AttributeValue ::= ANY DEFINED BY type
393
394AttributeTypeAndValue ::= SEQUENCE {
395 type AttributeType,
396 value AttributeValue }
397
398-- suggested naming attributes: Definition of the following
399-- information object set may be augmented to meet local
400-- requirements. Note that deleting members of the set may
401-- prevent interoperability with conforming implementations.
402-- presented in pairs: the AttributeType followed by the
403-- type definition for the corresponding AttributeValue
404
405-- Arc for standard naming attributes
406id-at OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 4}
407
408-- Attributes of type NameDirectoryString
409id-at-initials AttributeType ::= { id-at 43 }
410X520initials ::= DirectoryString
411
412id-at-generationQualifier AttributeType ::= { id-at 44 }
413X520generationQualifier ::= DirectoryString
414
415id-at-surname AttributeType ::= { id-at 4 }
416X520surName ::= DirectoryString
417
418id-at-givenName AttributeType ::= { id-at 42 }
419X520givenName ::= DirectoryString
420
421id-at-name AttributeType ::= { id-at 41 }
422X520name ::= DirectoryString
423
424id-at-commonName AttributeType ::= {id-at 3}
425X520CommonName ::= DirectoryString
426
427id-at-localityName AttributeType ::= {id-at 7}
428X520LocalityName ::= DirectoryString
429
430id-at-stateOrProvinceName AttributeType ::= {id-at 8}
431X520StateOrProvinceName ::= DirectoryString
432
433id-at-organizationName AttributeType ::= {id-at 10}
434X520OrganizationName ::= DirectoryString
435
436id-at-organizationalUnitName AttributeType ::= {id-at 11}
437X520OrganizationalUnitName ::= DirectoryString
438
439id-at-title AttributeType ::= {id-at 12}
440X520Title ::= DirectoryString
441
442id-at-description AttributeType ::= {id-at 13}
443X520Description ::= DirectoryString
444
445id-at-dnQualifier AttributeType ::= {id-at 46}
446X520dnQualifier ::= PrintableString
447
448id-at-countryName AttributeType ::= {id-at 6}
449X520countryName ::= PrintableString (SIZE (2)) -- IS 3166 codes
450
451id-at-serialNumber AttributeType ::= {id-at 5}
452X520serialNumber ::= PrintableString
453
454id-at-telephoneNumber AttributeType ::= {id-at 20}
455X520telephoneNumber ::= PrintableString
456
457id-at-facsimileTelephoneNumber AttributeType ::= {id-at 23}
458X520facsimileTelephoneNumber ::= PrintableString
459
460id-at-pseudonym AttributeType ::= {id-at 65}
461X520pseudonym ::= DirectoryString
462
463id-at-name AttributeType ::= {id-at 41}
464X520name ::= DirectoryString
465
466id-at-streetAddress AttributeType ::= {id-at 9}
467X520streetAddress ::= DirectoryString
468
469id-at-postalAddress AttributeType ::= {id-at 16}
470X520postalAddress ::= PostalAddress
471
472PostalAddress ::= SEQUENCE OF DirectoryString
473
474
475 -- Legacy attributes
476
477pkcs OBJECT IDENTIFIER ::=
478 { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) }
479
480pkcs-9 OBJECT IDENTIFIER ::=
481 { pkcs 9 }
482
483
484emailAddress AttributeType ::= { pkcs-9 1 }
485
486Pkcs9email ::= IA5String (SIZE (1..ub-emailaddress-length))
487
488-- naming data types --
489
490Name ::= CHOICE { -- only one possibility for now --
491 rdnSequence RDNSequence }
492
493RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
494
495DistinguishedName ::= RDNSequence
496
497RelativeDistinguishedName ::=
498 SET SIZE (1 .. MAX) OF AttributeTypeAndValue
499
500
501
502-- --------------------------------------------------------
503-- certificate and CRL specific structures begin here
504-- --------------------------------------------------------
505
506Certificate ::= SEQUENCE {
507 tbsCertificate TBSCertificate,
508 signatureAlgorithm AlgorithmIdentifier,
509 signature BIT STRING }
510
511TBSCertificate ::= SEQUENCE {
512 version [0] EXPLICIT Version DEFAULT v1,
513 serialNumber CertificateSerialNumber,
514 signature AlgorithmIdentifier,
515 issuer Name,
516 validity Validity,
517 subject Name,
518 subjectPublicKeyInfo SubjectPublicKeyInfo,
519 issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
520 -- If present, version shall be v2 or v3
521 subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
522 -- If present, version shall be v2 or v3
523 extensions [3] EXPLICIT Extensions OPTIONAL
524 -- If present, version shall be v3 --
525}
526
527Version ::= INTEGER { v1(0), v2(1), v3(2) }
528
529CertificateSerialNumber ::= INTEGER
530
531Validity ::= SEQUENCE {
532 notBefore Time,
533 notAfter Time }
534
535Time ::= CHOICE {
536 utcTime UTCTime,
537 generalTime GeneralizedTime }
538
539UniqueIdentifier ::= BIT STRING
540
541SubjectPublicKeyInfo ::= SEQUENCE {
542 algorithm AlgorithmIdentifier,
543 subjectPublicKey BIT STRING }
544
545Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
546
547Extension ::= SEQUENCE {
548 extnID OBJECT IDENTIFIER,
549 critical BOOLEAN DEFAULT FALSE,
550 extnValue OCTET STRING }
551
552
553-- ------------------------------------------
554-- CRL structures
555-- ------------------------------------------
556
557CertificateList ::= SEQUENCE {
558 tbsCertList TBSCertList,
559 signatureAlgorithm AlgorithmIdentifier,
560 signature BIT STRING }
561
562TBSCertList ::= SEQUENCE {
563 version Version OPTIONAL,
564 -- if present, shall be v2
565 signature AlgorithmIdentifier,
566 issuer Name,
567 thisUpdate Time,
568 nextUpdate Time OPTIONAL,
569 revokedCertificates SEQUENCE OF SEQUENCE {
570 userCertificate CertificateSerialNumber,
571 revocationDate Time,
572 crlEntryExtensions Extensions OPTIONAL
573 -- if present, shall be v2
574 } OPTIONAL,
575 crlExtensions [0] EXPLICIT Extensions OPTIONAL
576 -- if present, shall be v2 --
577}
578
579-- Version, Time, CertificateSerialNumber, and Extensions were
580-- defined earlier for use in the certificate structure
581
582AlgorithmIdentifier ::= SEQUENCE {
583 algorithm OBJECT IDENTIFIER,
584 parameters ANY DEFINED BY algorithm OPTIONAL }
585 -- contains a value of the type
586 -- registered for use with the
587 -- algorithm object identifier value
588
589-- Algorithm OIDs and parameter structures
590
591pkcs-1 OBJECT IDENTIFIER ::= {
592 pkcs 1 }
593
594rsaEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 }
595
596md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 }
597
598md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 }
599
600sha1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 }
601
602id-dsa-with-sha1 OBJECT IDENTIFIER ::= {
603 iso(1) member-body(2) us(840) x9-57 (10040) x9algorithm(4) 3 }
604
605Dss-Sig-Value ::= SEQUENCE {
606 r INTEGER,
607 s INTEGER
608}
609
610dhpublicnumber OBJECT IDENTIFIER ::= {
611 iso(1) member-body(2) us(840) ansi-x942(10046) number-type(2) 1 }
612
613DomainParameters ::= SEQUENCE {
614 p INTEGER, -- odd prime, p=jq +1
615 g INTEGER, -- generator, g
616 q INTEGER, -- factor of p-1
617 j INTEGER OPTIONAL, -- subgroup factor, j>= 2
618 validationParms ValidationParms OPTIONAL }
619
620ValidationParms ::= SEQUENCE {
621 seed BIT STRING,
622 pgenCounter INTEGER }
623
624id-dsa OBJECT IDENTIFIER ::= {
625 iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) 1 }
626
627Dss-Parms ::= SEQUENCE {
628 p INTEGER,
629 q INTEGER,
630 g INTEGER }
631
632-- x400 address syntax starts here
633-- OR Names
634
635ORAddress ::= SEQUENCE {
636 built-in-standard-attributes BuiltInStandardAttributes,
637 built-in-domain-defined-attributes
638 BuiltInDomainDefinedAttributes OPTIONAL,
639 -- see also teletex-domain-defined-attributes
640 extension-attributes ExtensionAttributes OPTIONAL }
641-- The OR-address is semantically absent from the OR-name if the
642-- built-in-standard-attribute sequence is empty and the
643-- built-in-domain-defined-attributes and extension-attributes are
644-- both omitted.
645
646-- Built-in Standard Attributes
647
648BuiltInStandardAttributes ::= SEQUENCE {
649 country-name CountryName OPTIONAL,
650 administration-domain-name AdministrationDomainName OPTIONAL,
651 network-address [0] EXPLICIT NetworkAddress OPTIONAL,
652 -- see also extended-network-address
653 terminal-identifier [1] EXPLICIT TerminalIdentifier OPTIONAL,
654 private-domain-name [2] EXPLICIT PrivateDomainName OPTIONAL,
655 organization-name [3] EXPLICIT OrganizationName OPTIONAL,
656 -- see also teletex-organization-name
657 numeric-user-identifier [4] EXPLICIT NumericUserIdentifier OPTIONAL,
658 personal-name [5] EXPLICIT PersonalName OPTIONAL,
659 -- see also teletex-personal-name
660 organizational-unit-names [6] EXPLICIT OrganizationalUnitNames OPTIONAL
661 -- see also teletex-organizational-unit-names --
662}
663
664CountryName ::= [APPLICATION 1] CHOICE {
665 x121-dcc-code NumericString
666 (SIZE (ub-country-name-numeric-length)),
667 iso-3166-alpha2-code PrintableString
668 (SIZE (ub-country-name-alpha-length)) }
669
670AdministrationDomainName ::= [APPLICATION 2] EXPLICIT CHOICE {
671 numeric NumericString (SIZE (0..ub-domain-name-length)),
672 printable PrintableString (SIZE (0..ub-domain-name-length)) }
673
674NetworkAddress ::= X121Address -- see also extended-network-address
675
676X121Address ::= NumericString (SIZE (1..ub-x121-address-length))
677
678TerminalIdentifier ::= PrintableString (SIZE (1..ub-terminal-id-length))
679
680PrivateDomainName ::= CHOICE {
681 numeric NumericString (SIZE (1..ub-domain-name-length)),
682 printable PrintableString (SIZE (1..ub-domain-name-length)) }
683
684OrganizationName ::= PrintableString
685 (SIZE (1..ub-organization-name-length))
686-- see also teletex-organization-name
687
688NumericUserIdentifier ::= NumericString
689 (SIZE (1..ub-numeric-user-id-length))
690
691PersonalName ::= SET {
692 surname [0] PrintableString (SIZE (1..ub-surname-length)),
693 given-name [1] PrintableString
694 (SIZE (1..ub-given-name-length)) OPTIONAL,
695 initials [2] PrintableString (SIZE (1..ub-initials-length)) OPTIONAL,
696 generation-qualifier [3] PrintableString
697 (SIZE (1..ub-generation-qualifier-length)) OPTIONAL }
698-- see also teletex-personal-name
699
700OrganizationalUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units)
701 OF OrganizationalUnitName
702-- see also teletex-organizational-unit-names
703
704OrganizationalUnitName ::= PrintableString (SIZE
705 (1..ub-organizational-unit-name-length))
706
707-- Built-in Domain-defined Attributes
708
709BuiltInDomainDefinedAttributes ::= SEQUENCE SIZE
710 (1..ub-domain-defined-attributes) OF
711 BuiltInDomainDefinedAttribute
712
713BuiltInDomainDefinedAttribute ::= SEQUENCE {
714 type PrintableString (SIZE
715 (1..ub-domain-defined-attribute-type-length)),
716 value PrintableString (SIZE
717 (1..ub-domain-defined-attribute-value-length))}
718
719-- Extension Attributes
720
721ExtensionAttributes ::= SET SIZE (1..ub-extension-attributes) OF
722 ExtensionAttribute
723
724ExtensionAttribute ::= SEQUENCE {
725 extension-attribute-type [0] EXPLICIT INTEGER (0..ub-extension-attributes),
726 extension-attribute-value [1] EXPLICIT
727 ANY DEFINED BY extension-attribute-type }
728
729-- Extension types and attribute values
730--
731
732common-name INTEGER ::= 1
733
734CommonName ::= PrintableString (SIZE (1..ub-common-name-length))
735
736teletex-common-name INTEGER ::= 2
737
738TeletexCommonName ::= TeletexString (SIZE (1..ub-common-name-length))
739
740teletex-organization-name INTEGER ::= 3
741
742TeletexOrganizationName ::=
743 TeletexString (SIZE (1..ub-organization-name-length))
744
745teletex-personal-name INTEGER ::= 4
746
747TeletexPersonalName ::= SET {
748 surname [0] EXPLICIT TeletexString (SIZE (1..ub-surname-length)),
749 given-name [1] EXPLICIT TeletexString
750 (SIZE (1..ub-given-name-length)) OPTIONAL,
751 initials [2] EXPLICIT TeletexString (SIZE (1..ub-initials-length)) OPTIONAL,
752 generation-qualifier [3] EXPLICIT TeletexString (SIZE
753 (1..ub-generation-qualifier-length)) OPTIONAL }
754
755teletex-organizational-unit-names INTEGER ::= 5
756
757TeletexOrganizationalUnitNames ::= SEQUENCE SIZE
758 (1..ub-organizational-units) OF TeletexOrganizationalUnitName
759
760TeletexOrganizationalUnitName ::= TeletexString
761 (SIZE (1..ub-organizational-unit-name-length))
762
763pds-name INTEGER ::= 7
764
765PDSName ::= PrintableString (SIZE (1..ub-pds-name-length))
766
767physical-delivery-country-name INTEGER ::= 8
768
769PhysicalDeliveryCountryName ::= CHOICE {
770 x121-dcc-code NumericString (SIZE (ub-country-name-numeric-length)),
771 iso-3166-alpha2-code PrintableString
772 (SIZE (ub-country-name-alpha-length)) }
773
774postal-code INTEGER ::= 9
775
776PostalCode ::= CHOICE {
777 numeric-code NumericString (SIZE (1..ub-postal-code-length)),
778 printable-code PrintableString (SIZE (1..ub-postal-code-length)) }
779
780physical-delivery-office-name INTEGER ::= 10
781
782PhysicalDeliveryOfficeName ::= PDSParameter
783
784physical-delivery-office-number INTEGER ::= 11
785
786PhysicalDeliveryOfficeNumber ::= PDSParameter
787
788extension-OR-address-components INTEGER ::= 12
789
790ExtensionORAddressComponents ::= PDSParameter
791
792physical-delivery-personal-name INTEGER ::= 13
793
794PhysicalDeliveryPersonalName ::= PDSParameter
795
796physical-delivery-organization-name INTEGER ::= 14
797
798PhysicalDeliveryOrganizationName ::= PDSParameter
799
800extension-physical-delivery-address-components INTEGER ::= 15
801
802ExtensionPhysicalDeliveryAddressComponents ::= PDSParameter
803
804unformatted-postal-address INTEGER ::= 16
805
806UnformattedPostalAddress ::= SET {
807 printable-address SEQUENCE SIZE (1..ub-pds-physical-address-lines) OF
808 PrintableString (SIZE (1..ub-pds-parameter-length)) OPTIONAL,
809 teletex-string TeletexString
810 (SIZE (1..ub-unformatted-address-length)) OPTIONAL }
811
812street-address INTEGER ::= 17
813
814StreetAddress ::= PDSParameter
815
816post-office-box-address INTEGER ::= 18
817
818PostOfficeBoxAddress ::= PDSParameter
819
820poste-restante-address INTEGER ::= 19
821
822PosteRestanteAddress ::= PDSParameter
823
824unique-postal-name INTEGER ::= 20
825
826UniquePostalName ::= PDSParameter
827
828local-postal-attributes INTEGER ::= 21
829
830LocalPostalAttributes ::= PDSParameter
831
832PDSParameter ::= SET {
833 printable-string PrintableString
834 (SIZE(1..ub-pds-parameter-length)) OPTIONAL,
835 teletex-string TeletexString
836 (SIZE(1..ub-pds-parameter-length)) OPTIONAL }
837
838extended-network-address INTEGER ::= 22
839
840ExtendedNetworkAddress ::= CHOICE {
841 e163-4-address SEQUENCE {
842 number [0] EXPLICIT NumericString (SIZE (1..ub-e163-4-number-length)),
843 sub-address [1] EXPLICIT NumericString
844 (SIZE (1..ub-e163-4-sub-address-length)) OPTIONAL },
845 psap-address [0] EXPLICIT PresentationAddress }
846
847PresentationAddress ::= SEQUENCE {
848 pSelector [0] EXPLICIT OCTET STRING OPTIONAL,
849 sSelector [1] EXPLICIT OCTET STRING OPTIONAL,
850 tSelector [2] EXPLICIT OCTET STRING OPTIONAL,
851 nAddresses [3] EXPLICIT SET SIZE (1..MAX) OF OCTET STRING }
852
853terminal-type INTEGER ::= 23
854
855TerminalType ::= INTEGER {
856 telex (3),
857 teletex (4),
858 g3-facsimile (5),
859 g4-facsimile (6),
860 ia5-terminal (7),
861 videotex (8) } -- (0..ub-integer-options)
862
863-- Extension Domain-defined Attributes
864
865teletex-domain-defined-attributes INTEGER ::= 6
866
867TeletexDomainDefinedAttributes ::= SEQUENCE SIZE
868 (1..ub-domain-defined-attributes) OF TeletexDomainDefinedAttribute
869
870TeletexDomainDefinedAttribute ::= SEQUENCE {
871 type TeletexString
872 (SIZE (1..ub-domain-defined-attribute-type-length)),
873 value TeletexString
874 (SIZE (1..ub-domain-defined-attribute-value-length)) }
875
876-- specifications of Upper Bounds shall be regarded as mandatory
877-- from Annex B of ITU-T X.411 Reference Definition of MTS Parameter
878-- Upper Bounds
879
880-- Upper Bounds
881ub-name INTEGER ::= 32768
882ub-common-name INTEGER ::= 64
883ub-locality-name INTEGER ::= 128
884ub-state-name INTEGER ::= 128
885ub-organization-name INTEGER ::= 64
886ub-organizational-unit-name INTEGER ::= 64
887ub-title INTEGER ::= 64
888ub-match INTEGER ::= 128
889
890ub-emailaddress-length INTEGER ::= 128
891
892ub-common-name-length INTEGER ::= 64
893ub-country-name-alpha-length INTEGER ::= 2
894ub-country-name-numeric-length INTEGER ::= 3
895ub-domain-defined-attributes INTEGER ::= 4
896ub-domain-defined-attribute-type-length INTEGER ::= 8
897ub-domain-defined-attribute-value-length INTEGER ::= 128
898ub-domain-name-length INTEGER ::= 16
899ub-extension-attributes INTEGER ::= 256
900ub-e163-4-number-length INTEGER ::= 15
901ub-e163-4-sub-address-length INTEGER ::= 40
902ub-generation-qualifier-length INTEGER ::= 3
903ub-given-name-length INTEGER ::= 16
904ub-initials-length INTEGER ::= 5
905ub-integer-options INTEGER ::= 256
906ub-numeric-user-id-length INTEGER ::= 32
907ub-organization-name-length INTEGER ::= 64
908ub-organizational-unit-name-length INTEGER ::= 32
909ub-organizational-units INTEGER ::= 4
910ub-pds-name-length INTEGER ::= 16
911ub-pds-parameter-length INTEGER ::= 30
912ub-pds-physical-address-lines INTEGER ::= 6
913ub-postal-code-length INTEGER ::= 16
914ub-surname-length INTEGER ::= 40
915ub-terminal-id-length INTEGER ::= 24
916ub-unformatted-address-length INTEGER ::= 180
917ub-x121-address-length INTEGER ::= 16
918
919-- Note - upper bounds on string types, such as TeletexString, are
920-- measured in characters. Excepting PrintableString or IA5String, a
921-- significantly greater number of octets will be required to hold
922-- such a value. As a minimum, 16 octets, or twice the specified upper
923-- bound, whichever is the larger, should be allowed for TeletexString.
924-- For UTF8String or UniversalString at least four times the upper
925-- bound should be allowed.
926
927
928
929-- END of PKIX1Implicit88
930
931
932-- BEGIN of RFC2630
933
934-- Cryptographic Message Syntax
935
936pkcs-7-ContentInfo ::= SEQUENCE {
937 contentType pkcs-7-ContentType,
938 content [0] EXPLICIT ANY DEFINED BY contentType }
939
940pkcs-7-DigestInfo ::= SEQUENCE {
941 digestAlgorithm pkcs-7-DigestAlgorithmIdentifier,
942 digest pkcs-7-Digest
943}
944
945pkcs-7-Digest ::= OCTET STRING
946
947pkcs-7-ContentType ::= OBJECT IDENTIFIER
948
949pkcs-7-SignedData ::= SEQUENCE {
950 version pkcs-7-CMSVersion,
951 digestAlgorithms pkcs-7-DigestAlgorithmIdentifiers,
952 encapContentInfo pkcs-7-EncapsulatedContentInfo,
953 certificates [0] IMPLICIT pkcs-7-CertificateSet OPTIONAL,
954 crls [1] IMPLICIT pkcs-7-CertificateRevocationLists OPTIONAL,
955 signerInfos pkcs-7-SignerInfos
956}
957
958pkcs-7-CMSVersion ::= INTEGER { v0(0), v1(1), v2(2), v3(3), v4(4) }
959
960pkcs-7-DigestAlgorithmIdentifiers ::= SET OF pkcs-7-DigestAlgorithmIdentifier
961
962pkcs-7-DigestAlgorithmIdentifier ::= AlgorithmIdentifier
963
964pkcs-7-EncapsulatedContentInfo ::= SEQUENCE {
965 eContentType pkcs-7-ContentType,
966 eContent [0] EXPLICIT OCTET STRING OPTIONAL }
967
968-- We don't use CertificateList here since we only want
969-- to read the raw data.
970pkcs-7-CertificateRevocationLists ::= SET OF ANY
971
972pkcs-7-CertificateChoices ::= CHOICE {
973-- Although the paper uses Certificate type, we
974-- don't use it since, we don't need to parse it.
975-- We only need to read and store it.
976 certificate ANY
977}
978
979pkcs-7-CertificateSet ::= SET OF pkcs-7-CertificateChoices
980
981pkcs-7-SignerInfos ::= SET OF ANY -- this is not correct but we don't use it
982 -- anyway
983
984
985-- BEGIN of RFC2986
986
987-- Certificate requests
988pkcs-10-CertificationRequestInfo ::= SEQUENCE {
989 version INTEGER { v1(0) },
990 subject Name,
991 subjectPKInfo SubjectPublicKeyInfo,
992 attributes [0] Attributes
993}
994
995Attributes ::= SET OF Attribute
996
997pkcs-10-CertificationRequest ::= SEQUENCE {
998 certificationRequestInfo pkcs-10-CertificationRequestInfo,
999 signatureAlgorithm AlgorithmIdentifier,
1000 signature BIT STRING
1001}
1002
1003-- stuff from PKCS#9
1004
1005pkcs-9-ub-challengePassword INTEGER ::= 255
1006
1007pkcs-9-certTypes OBJECT IDENTIFIER ::= {pkcs-9 22}
1008pkcs-9-crlTypes OBJECT IDENTIFIER ::= {pkcs-9 23}
1009
1010pkcs-9-at-challengePassword OBJECT IDENTIFIER ::= {pkcs-9 7}
1011
1012pkcs-9-challengePassword ::= CHOICE {
1013 printableString PrintableString (SIZE (1..pkcs-9-ub-challengePassword)),
1014 utf8String UTF8String (SIZE (1..pkcs-9-ub-challengePassword)) }
1015
1016pkcs-9-at-localKeyId OBJECT IDENTIFIER ::= {pkcs-9 21}
1017
1018pkcs-9-localKeyId ::= OCTET STRING
1019
1020pkcs-9-at-friendlyName OBJECT IDENTIFIER ::= {pkcs-9 20}
1021
1022pkcs-9-friendlyName ::= BMPString (SIZE (1..255))
1023
1024-- PKCS #8 stuff
1025
1026-- Private-key information syntax
1027
1028pkcs-8-PrivateKeyInfo ::= SEQUENCE {
1029 version pkcs-8-Version,
1030 privateKeyAlgorithm AlgorithmIdentifier,
1031 privateKey pkcs-8-PrivateKey,
1032 attributes [0] Attributes OPTIONAL }
1033
1034pkcs-8-Version ::= INTEGER {v1(0)}
1035
1036pkcs-8-PrivateKey ::= OCTET STRING
1037
1038pkcs-8-Attributes ::= SET OF Attribute
1039
1040-- Encrypted private-key information syntax
1041
1042pkcs-8-EncryptedPrivateKeyInfo ::= SEQUENCE {
1043 encryptionAlgorithm AlgorithmIdentifier,
1044 encryptedData pkcs-8-EncryptedData
1045}
1046
1047pkcs-8-EncryptedData ::= OCTET STRING
1048
1049-- PKCS #5 stuff
1050
1051pkcs-5 OBJECT IDENTIFIER ::=
1052 { pkcs 5 }
1053
1054pkcs-5-encryptionAlgorithm OBJECT IDENTIFIER ::=
1055 { iso(1) member-body(2) us(840) rsadsi(113549) 3 }
1056
1057pkcs-5-des-EDE3-CBC OBJECT IDENTIFIER ::= {pkcs-5-encryptionAlgorithm 7}
1058
1059pkcs-5-des-EDE3-CBC-params ::= OCTET STRING (SIZE(8))
1060
1061pkcs-5-id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13}
1062
1063pkcs-5-PBES2-params ::= SEQUENCE {
1064 keyDerivationFunc AlgorithmIdentifier,
1065 encryptionScheme AlgorithmIdentifier }
1066
1067-- PBKDF2
1068
1069pkcs-5-id-PBKDF2 OBJECT IDENTIFIER ::= {pkcs-5 12}
1070
1071-- pkcs-5-id-hmacWithSHA1 OBJECT IDENTIFIER ::= {iso(1) member-body(2) us(840) rsadsi(113549) 2 7}
1072
1073-- pkcs-5-algid-hmacWithSHA1 AlgorithmIdentifier ::=
1074-- {algorithm pkcs-5-id-hmacWithSHA1, parameters NULL : NULL}
1075
1076pkcs-5-PBKDF2-params ::= SEQUENCE {
1077 salt CHOICE {
1078 specified OCTET STRING,
1079 otherSource AlgorithmIdentifier
1080 },
1081 iterationCount INTEGER (1..MAX),
1082 keyLength INTEGER (1..MAX) OPTIONAL,
1083 prf AlgorithmIdentifier OPTIONAL -- DEFAULT pkcs-5-id-hmacWithSHA1
1084}
1085
1086-- PKCS #12 stuff
1087
1088pkcs-12 OBJECT IDENTIFIER ::= {pkcs 12}
1089
1090pkcs-12-PFX ::= SEQUENCE {
1091 version INTEGER {v3(3)},
1092 authSafe pkcs-7-ContentInfo,
1093 macData pkcs-12-MacData OPTIONAL
1094}
1095
1096pkcs-12-PbeParams ::= SEQUENCE {
1097 salt OCTET STRING,
1098 iterations INTEGER
1099}
1100
1101pkcs-12-MacData ::= SEQUENCE {
1102 mac pkcs-7-DigestInfo,
1103 macSalt OCTET STRING,
1104 iterations INTEGER DEFAULT 1
1105-- Note: The default is for historical reasons and its use is
1106-- deprecated. A higher value, like 1024 is recommended.
1107}
1108
1109pkcs-12-AuthenticatedSafe ::= SEQUENCE OF pkcs-7-ContentInfo
1110 -- Data if unencrypted
1111 -- EncryptedData if password-encrypted
1112 -- EnvelopedData if public key-encrypted
1113
1114pkcs-12-SafeContents ::= SEQUENCE OF pkcs-12-SafeBag
1115
1116pkcs-12-SafeBag ::= SEQUENCE {
1117 bagId OBJECT IDENTIFIER,
1118 bagValue [0] EXPLICIT ANY DEFINED BY badId,
1119 bagAttributes SET OF pkcs-12-PKCS12Attribute OPTIONAL
1120}
1121
1122-- Bag types
1123
1124
1125pkcs-12-bagtypes OBJECT IDENTIFIER ::= {pkcs-12 10 1}
1126
1127pkcs-12-keyBag OBJECT IDENTIFIER ::= {pkcs-12-bagtypes 1}
1128pkcs-12-pkcs8ShroudedKeyBag OBJECT IDENTIFIER ::= {pkcs-12-bagtypes 2}
1129pkcs-12-certBag OBJECT IDENTIFIER ::= {pkcs-12-bagtypes 3}
1130pkcs-12-crlBag OBJECT IDENTIFIER ::= {pkcs-12-bagtypes 4}
1131
1132pkcs-12-KeyBag ::= pkcs-8-PrivateKeyInfo
1133
1134-- Shrouded KeyBag
1135
1136pkcs-12-PKCS8ShroudedKeyBag ::= pkcs-8-EncryptedPrivateKeyInfo
1137
1138-- CertBag
1139
1140pkcs-12-CertBag ::= SEQUENCE {
1141 certId OBJECT IDENTIFIER,
1142 certValue [0] EXPLICIT ANY DEFINED BY certId
1143}
1144
1145-- x509Certificate BAG-TYPE ::= {OCTET STRING IDENTIFIED BY {pkcs-9-certTypes 1}}
1146-- DER-encoded X.509 certificate stored in OCTET STRING
1147
1148pkcs-12-CRLBag ::= SEQUENCE {
1149 crlId OBJECT IDENTIFIER,
1150 crlValue [0] EXPLICIT ANY DEFINED BY crlId
1151}
1152
1153-- x509CRL BAG-TYPE ::=
1154-- {OCTET STRING IDENTIFIED BY {pkcs-9-crlTypes 1}}
1155-- DER-encoded X.509 CRL stored in OCTET STRING
1156
1157pkcs-12-PKCS12Attribute ::= Attribute
1158
1159-- PKCS #7 stuff (needed in PKCS 12)
1160
1161pkcs-7-data OBJECT IDENTIFIER ::= { iso(1) member-body(2)
1162 us(840) rsadsi(113549) pkcs(1) pkcs7(7) 1 }
1163
1164pkcs-7-encryptedData OBJECT IDENTIFIER ::= { iso(1) member-body(2)
1165 us(840) rsadsi(113549) pkcs(1) pkcs7(7) 6 }
1166
1167pkcs-7-Data ::= OCTET STRING
1168
1169pkcs-7-EncryptedData ::= SEQUENCE {
1170 version pkcs-7-CMSVersion,
1171 encryptedContentInfo pkcs-7-EncryptedContentInfo,
1172 unprotectedAttrs [1] IMPLICIT pkcs-7-UnprotectedAttributes OPTIONAL }
1173
1174pkcs-7-EncryptedContentInfo ::= SEQUENCE {
1175 contentType pkcs-7-ContentType,
1176 contentEncryptionAlgorithm pkcs-7-ContentEncryptionAlgorithmIdentifier,
1177 encryptedContent [0] IMPLICIT pkcs-7-EncryptedContent OPTIONAL }
1178
1179pkcs-7-ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
1180
1181pkcs-7-EncryptedContent ::= OCTET STRING
1182
1183pkcs-7-UnprotectedAttributes ::= SET SIZE (1..MAX) OF Attribute
1184
1185-- LDAP stuff
1186-- may not be correct
1187
1188id-at-ldap-DC AttributeType ::= { 0 9 2342 19200300 100 1 25 }
1189
1190ldap-DC ::= IA5String
1191
1192id-at-ldap-UID AttributeType ::= { 0 9 2342 19200300 100 1 1 }
1193
1194ldap-UID ::= DirectoryString
1195
1196-- rfc3039
1197
1198id-pda OBJECT IDENTIFIER ::= { id-pkix 9 }
1199
1200id-pda-dateOfBirth AttributeType ::= { id-pda 1 }
1201DateOfBirth ::= GeneralizedTime
1202
1203id-pda-placeOfBirth AttributeType ::= { id-pda 2 }
1204PlaceOfBirth ::= DirectoryString
1205
1206id-pda-gender AttributeType ::= { id-pda 3 }
1207Gender ::= PrintableString (SIZE(1))
1208 -- "M", "F", "m" or "f"
1209
1210id-pda-countryOfCitizenship AttributeType ::= { id-pda 4 }
1211CountryOfCitizenship ::= PrintableString (SIZE (2))
1212 -- ISO 3166 Country Code
1213
1214id-pda-countryOfResidence AttributeType ::= { id-pda 5 }
1215CountryOfResidence ::= PrintableString (SIZE (2))
1216 -- ISO 3166 Country Code
1217
1218-- rfc3820
1219
1220id-pe-proxyCertInfo OBJECT IDENTIFIER ::= { id-pe 14 }
1221
1222id-ppl-inheritAll OBJECT IDENTIFIER ::= { id-pkix 21 1 }
1223id-ppl-independent OBJECT IDENTIFIER ::= { id-pkix 21 2 }
1224
1225ProxyCertInfo ::= SEQUENCE {
1226 pCPathLenConstraint INTEGER (0..MAX) OPTIONAL,
1227 proxyPolicy ProxyPolicy }
1228
1229ProxyPolicy ::= SEQUENCE {
1230 policyLanguage OBJECT IDENTIFIER,
1231 policy OCTET STRING OPTIONAL }
1232
1233-- rfc3920 section 5.1.1
1234
1235id-on OBJECT IDENTIFIER ::= { id-pkix 8 } -- other name forms
1236
1237id-on-xmppAddr OBJECT IDENTIFIER ::= { id-on 5 }
1238
1239XmppAddr ::= UTF8String
1240
1241END
diff --git a/src/daemon/https/tls/pkix_asn1_tab.c b/src/daemon/https/tls/pkix_asn1_tab.c
new file mode 100644
index 00000000..3370bb46
--- /dev/null
+++ b/src/daemon/https/tls/pkix_asn1_tab.c
@@ -0,0 +1,1130 @@
1#if HAVE_CONFIG_H
2# include "config.h"
3#endif
4
5#include <libtasn1.h>
6
7extern const ASN1_ARRAY_TYPE pkix_asn1_tab[] = {
8 {"PKIX1", 536875024, 0},
9 {0, 1073741836, 0},
10 {"id-ce", 1879048204, 0},
11 {"joint-iso-ccitt", 1073741825, "2"},
12 {"ds", 1073741825, "5"},
13 {0, 1, "29"},
14 {"id-ce-authorityKeyIdentifier", 1879048204, 0},
15 {0, 1073741825, "id-ce"},
16 {0, 1, "35"},
17 {"AuthorityKeyIdentifier", 1610612741, 0},
18 {"keyIdentifier", 1610637314, "KeyIdentifier"},
19 {0, 4104, "0"},
20 {"authorityCertIssuer", 1610637314, "GeneralNames"},
21 {0, 4104, "1"},
22 {"authorityCertSerialNumber", 536895490, "CertificateSerialNumber"},
23 {0, 4104, "2"},
24 {"KeyIdentifier", 1073741831, 0},
25 {"id-ce-subjectKeyIdentifier", 1879048204, 0},
26 {0, 1073741825, "id-ce"},
27 {0, 1, "14"},
28 {"SubjectKeyIdentifier", 1073741826, "KeyIdentifier"},
29 {"id-ce-keyUsage", 1879048204, 0},
30 {0, 1073741825, "id-ce"},
31 {0, 1, "15"},
32 {"KeyUsage", 1610874886, 0},
33 {"digitalSignature", 1073741825, "0"},
34 {"nonRepudiation", 1073741825, "1"},
35 {"keyEncipherment", 1073741825, "2"},
36 {"dataEncipherment", 1073741825, "3"},
37 {"keyAgreement", 1073741825, "4"},
38 {"keyCertSign", 1073741825, "5"},
39 {"cRLSign", 1073741825, "6"},
40 {"encipherOnly", 1073741825, "7"},
41 {"decipherOnly", 1, "8"},
42 {"id-ce-privateKeyUsagePeriod", 1879048204, 0},
43 {0, 1073741825, "id-ce"},
44 {0, 1, "16"},
45 {"PrivateKeyUsagePeriod", 1610612741, 0},
46 {"notBefore", 1619025937, 0},
47 {0, 4104, "0"},
48 {"notAfter", 545284113, 0},
49 {0, 4104, "1"},
50 {"id-ce-certificatePolicies", 1879048204, 0},
51 {0, 1073741825, "id-ce"},
52 {0, 1, "32"},
53 {"CertificatePolicies", 1612709899, 0},
54 {"MAX", 1074266122, "1"},
55 {0, 2, "PolicyInformation"},
56 {"PolicyInformation", 1610612741, 0},
57 {"policyIdentifier", 1073741826, "CertPolicyId"},
58 {"policyQualifiers", 538984459, 0},
59 {"MAX", 1074266122, "1"},
60 {0, 2, "PolicyQualifierInfo"},
61 {"CertPolicyId", 1073741836, 0},
62 {"PolicyQualifierInfo", 1610612741, 0},
63 {"policyQualifierId", 1073741826, "PolicyQualifierId"},
64 {"qualifier", 541065229, 0},
65 {"policyQualifierId", 1, 0},
66 {"PolicyQualifierId", 1073741836, 0},
67 {"CPSuri", 1073741826, "IA5String"},
68 {"UserNotice", 1610612741, 0},
69 {"noticeRef", 1073758210, "NoticeReference"},
70 {"explicitText", 16386, "DisplayText"},
71 {"NoticeReference", 1610612741, 0},
72 {"organization", 1073741826, "DisplayText"},
73 {"noticeNumbers", 536870923, 0},
74 {0, 3, 0},
75 {"DisplayText", 1610612754, 0},
76 {"visibleString", 1612709890, "VisibleString"},
77 {"200", 524298, "1"},
78 {"bmpString", 1612709890, "BMPString"},
79 {"200", 524298, "1"},
80 {"utf8String", 538968066, "UTF8String"},
81 {"200", 524298, "1"},
82 {"id-ce-policyMappings", 1879048204, 0},
83 {0, 1073741825, "id-ce"},
84 {0, 1, "33"},
85 {"PolicyMappings", 1612709899, 0},
86 {"MAX", 1074266122, "1"},
87 {0, 536870917, 0},
88 {"issuerDomainPolicy", 1073741826, "CertPolicyId"},
89 {"subjectDomainPolicy", 2, "CertPolicyId"},
90 {"DirectoryString", 1610612754, 0},
91 {"teletexString", 1612709890, "TeletexString"},
92 {"MAX", 524298, "1"},
93 {"printableString", 1612709890, "PrintableString"},
94 {"MAX", 524298, "1"},
95 {"universalString", 1612709890, "UniversalString"},
96 {"MAX", 524298, "1"},
97 {"utf8String", 1612709890, "UTF8String"},
98 {"MAX", 524298, "1"},
99 {"bmpString", 1612709890, "BMPString"},
100 {"MAX", 524298, "1"},
101 {"ia5String", 538968066, "IA5String"},
102 {"MAX", 524298, "1"},
103 {"id-ce-subjectAltName", 1879048204, 0},
104 {0, 1073741825, "id-ce"},
105 {0, 1, "17"},
106 {"SubjectAltName", 1073741826, "GeneralNames"},
107 {"GeneralNames", 1612709899, 0},
108 {"MAX", 1074266122, "1"},
109 {0, 2, "GeneralName"},
110 {"GeneralName", 1610612754, 0},
111 {"otherName", 1610620930, "AnotherName"},
112 {0, 4104, "0"},
113 {"rfc822Name", 1610620930, "IA5String"},
114 {0, 4104, "1"},
115 {"dNSName", 1610620930, "IA5String"},
116 {0, 4104, "2"},
117 {"x400Address", 1610620930, "ORAddress"},
118 {0, 4104, "3"},
119 {"directoryName", 1610620930, "RDNSequence"},
120 {0, 2056, "4"},
121 {"ediPartyName", 1610620930, "EDIPartyName"},
122 {0, 4104, "5"},
123 {"uniformResourceIdentifier", 1610620930, "IA5String"},
124 {0, 4104, "6"},
125 {"iPAddress", 1610620935, 0},
126 {0, 4104, "7"},
127 {"registeredID", 536879116, 0},
128 {0, 4104, "8"},
129 {"AnotherName", 1610612741, 0},
130 {"type-id", 1073741836, 0},
131 {"value", 541073421, 0},
132 {0, 1073743880, "0"},
133 {"type-id", 1, 0},
134 {"EDIPartyName", 1610612741, 0},
135 {"nameAssigner", 1610637314, "DirectoryString"},
136 {0, 4104, "0"},
137 {"partyName", 536879106, "DirectoryString"},
138 {0, 4104, "1"},
139 {"id-ce-issuerAltName", 1879048204, 0},
140 {0, 1073741825, "id-ce"},
141 {0, 1, "18"},
142 {"IssuerAltName", 1073741826, "GeneralNames"},
143 {"id-ce-subjectDirectoryAttributes", 1879048204, 0},
144 {0, 1073741825, "id-ce"},
145 {0, 1, "9"},
146 {"SubjectDirectoryAttributes", 1612709899, 0},
147 {"MAX", 1074266122, "1"},
148 {0, 2, "Attribute"},
149 {"id-ce-basicConstraints", 1879048204, 0},
150 {0, 1073741825, "id-ce"},
151 {0, 1, "19"},
152 {"BasicConstraints", 1610612741, 0},
153 {"cA", 1610645508, 0},
154 {0, 131081, 0},
155 {"pathLenConstraint", 537411587, 0},
156 {"0", 10, "MAX"},
157 {"id-ce-nameConstraints", 1879048204, 0},
158 {0, 1073741825, "id-ce"},
159 {0, 1, "30"},
160 {"NameConstraints", 1610612741, 0},
161 {"permittedSubtrees", 1610637314, "GeneralSubtrees"},
162 {0, 4104, "0"},
163 {"excludedSubtrees", 536895490, "GeneralSubtrees"},
164 {0, 4104, "1"},
165 {"GeneralSubtrees", 1612709899, 0},
166 {"MAX", 1074266122, "1"},
167 {0, 2, "GeneralSubtree"},
168 {"GeneralSubtree", 1610612741, 0},
169 {"base", 1073741826, "GeneralName"},
170 {"minimum", 1610653698, "BaseDistance"},
171 {0, 1073741833, "0"},
172 {0, 4104, "0"},
173 {"maximum", 536895490, "BaseDistance"},
174 {0, 4104, "1"},
175 {"BaseDistance", 1611137027, 0},
176 {"0", 10, "MAX"},
177 {"id-ce-policyConstraints", 1879048204, 0},
178 {0, 1073741825, "id-ce"},
179 {0, 1, "36"},
180 {"PolicyConstraints", 1610612741, 0},
181 {"requireExplicitPolicy", 1610637314, "SkipCerts"},
182 {0, 4104, "0"},
183 {"inhibitPolicyMapping", 536895490, "SkipCerts"},
184 {0, 4104, "1"},
185 {"SkipCerts", 1611137027, 0},
186 {"0", 10, "MAX"},
187 {"id-ce-cRLDistributionPoints", 1879048204, 0},
188 {0, 1073741825, "id-ce"},
189 {0, 1, "31"},
190 {"CRLDistributionPoints", 1612709899, 0},
191 {"MAX", 1074266122, "1"},
192 {0, 2, "DistributionPoint"},
193 {"DistributionPoint", 1610612741, 0},
194 {"distributionPoint", 1610637314, "DistributionPointName"},
195 {0, 2056, "0"},
196 {"reasons", 1610637314, "ReasonFlags"},
197 {0, 4104, "1"},
198 {"cRLIssuer", 536895490, "GeneralNames"},
199 {0, 4104, "2"},
200 {"DistributionPointName", 1610612754, 0},
201 {"fullName", 1610620930, "GeneralNames"},
202 {0, 4104, "0"},
203 {"nameRelativeToCRLIssuer", 536879106, "RelativeDistinguishedName"},
204 {0, 4104, "1"},
205 {"ReasonFlags", 1610874886, 0},
206 {"unused", 1073741825, "0"},
207 {"keyCompromise", 1073741825, "1"},
208 {"cACompromise", 1073741825, "2"},
209 {"affiliationChanged", 1073741825, "3"},
210 {"superseded", 1073741825, "4"},
211 {"cessationOfOperation", 1073741825, "5"},
212 {"certificateHold", 1073741825, "6"},
213 {"privilegeWithdrawn", 1073741825, "7"},
214 {"aACompromise", 1, "8"},
215 {"id-ce-extKeyUsage", 1879048204, 0},
216 {0, 1073741825, "id-ce"},
217 {0, 1, "37"},
218 {"ExtKeyUsageSyntax", 1612709899, 0},
219 {"MAX", 1074266122, "1"},
220 {0, 2, "KeyPurposeId"},
221 {"KeyPurposeId", 1073741836, 0},
222 {"id-kp-serverAuth", 1879048204, 0},
223 {0, 1073741825, "id-kp"},
224 {0, 1, "1"},
225 {"id-kp-clientAuth", 1879048204, 0},
226 {0, 1073741825, "id-kp"},
227 {0, 1, "2"},
228 {"id-kp-codeSigning", 1879048204, 0},
229 {0, 1073741825, "id-kp"},
230 {0, 1, "3"},
231 {"id-kp-emailProtection", 1879048204, 0},
232 {0, 1073741825, "id-kp"},
233 {0, 1, "4"},
234 {"id-kp-ipsecEndSystem", 1879048204, 0},
235 {0, 1073741825, "id-kp"},
236 {0, 1, "5"},
237 {"id-kp-ipsecTunnel", 1879048204, 0},
238 {0, 1073741825, "id-kp"},
239 {0, 1, "6"},
240 {"id-kp-ipsecUser", 1879048204, 0},
241 {0, 1073741825, "id-kp"},
242 {0, 1, "7"},
243 {"id-kp-timeStamping", 1879048204, 0},
244 {0, 1073741825, "id-kp"},
245 {0, 1, "8"},
246 {"id-pe-authorityInfoAccess", 1879048204, 0},
247 {0, 1073741825, "id-pe"},
248 {0, 1, "1"},
249 {"AuthorityInfoAccessSyntax", 1612709899, 0},
250 {"MAX", 1074266122, "1"},
251 {0, 2, "AccessDescription"},
252 {"AccessDescription", 1610612741, 0},
253 {"accessMethod", 1073741836, 0},
254 {"accessLocation", 2, "GeneralName"},
255 {"id-ce-cRLNumber", 1879048204, 0},
256 {0, 1073741825, "id-ce"},
257 {0, 1, "20"},
258 {"CRLNumber", 1611137027, 0},
259 {"0", 10, "MAX"},
260 {"id-ce-issuingDistributionPoint", 1879048204, 0},
261 {0, 1073741825, "id-ce"},
262 {0, 1, "28"},
263 {"IssuingDistributionPoint", 1610612741, 0},
264 {"distributionPoint", 1610637314, "DistributionPointName"},
265 {0, 4104, "0"},
266 {"onlyContainsUserCerts", 1610653700, 0},
267 {0, 1073872905, 0},
268 {0, 4104, "1"},
269 {"onlyContainsCACerts", 1610653700, 0},
270 {0, 1073872905, 0},
271 {0, 4104, "2"},
272 {"onlySomeReasons", 1610637314, "ReasonFlags"},
273 {0, 4104, "3"},
274 {"indirectCRL", 536911876, 0},
275 {0, 1073872905, 0},
276 {0, 4104, "4"},
277 {"id-ce-deltaCRLIndicator", 1879048204, 0},
278 {0, 1073741825, "id-ce"},
279 {0, 1, "27"},
280 {"BaseCRLNumber", 1073741826, "CRLNumber"},
281 {"id-ce-cRLReasons", 1879048204, 0},
282 {0, 1073741825, "id-ce"},
283 {0, 1, "21"},
284 {"CRLReason", 1610874901, 0},
285 {"unspecified", 1073741825, "0"},
286 {"keyCompromise", 1073741825, "1"},
287 {"cACompromise", 1073741825, "2"},
288 {"affiliationChanged", 1073741825, "3"},
289 {"superseded", 1073741825, "4"},
290 {"cessationOfOperation", 1073741825, "5"},
291 {"certificateHold", 1073741825, "6"},
292 {"removeFromCRL", 1, "8"},
293 {"id-ce-certificateIssuer", 1879048204, 0},
294 {0, 1073741825, "id-ce"},
295 {0, 1, "29"},
296 {"CertificateIssuer", 1073741826, "GeneralNames"},
297 {"id-ce-holdInstructionCode", 1879048204, 0},
298 {0, 1073741825, "id-ce"},
299 {0, 1, "23"},
300 {"HoldInstructionCode", 1073741836, 0},
301 {"holdInstruction", 1879048204, 0},
302 {"joint-iso-itu-t", 1073741825, "2"},
303 {"member-body", 1073741825, "2"},
304 {"us", 1073741825, "840"},
305 {"x9cm", 1073741825, "10040"},
306 {0, 1, "2"},
307 {"id-holdinstruction-none", 1879048204, 0},
308 {0, 1073741825, "holdInstruction"},
309 {0, 1, "1"},
310 {"id-holdinstruction-callissuer", 1879048204, 0},
311 {0, 1073741825, "holdInstruction"},
312 {0, 1, "2"},
313 {"id-holdinstruction-reject", 1879048204, 0},
314 {0, 1073741825, "holdInstruction"},
315 {0, 1, "3"},
316 {"id-ce-invalidityDate", 1879048204, 0},
317 {0, 1073741825, "id-ce"},
318 {0, 1, "24"},
319 {"InvalidityDate", 1082130449, 0},
320 {"VisibleString", 1610620935, 0},
321 {0, 4360, "26"},
322 {"NumericString", 1610620935, 0},
323 {0, 4360, "18"},
324 {"IA5String", 1610620935, 0},
325 {0, 4360, "22"},
326 {"TeletexString", 1610620935, 0},
327 {0, 4360, "20"},
328 {"PrintableString", 1610620935, 0},
329 {0, 4360, "19"},
330 {"UniversalString", 1610620935, 0},
331 {0, 4360, "28"},
332 {"BMPString", 1610620935, 0},
333 {0, 4360, "30"},
334 {"UTF8String", 1610620935, 0},
335 {0, 4360, "12"},
336 {"id-pkix", 1879048204, 0},
337 {"iso", 1073741825, "1"},
338 {"identified-organization", 1073741825, "3"},
339 {"dod", 1073741825, "6"},
340 {"internet", 1073741825, "1"},
341 {"security", 1073741825, "5"},
342 {"mechanisms", 1073741825, "5"},
343 {"pkix", 1, "7"},
344 {"id-pe", 1879048204, 0},
345 {0, 1073741825, "id-pkix"},
346 {0, 1, "1"},
347 {"id-qt", 1879048204, 0},
348 {0, 1073741825, "id-pkix"},
349 {0, 1, "2"},
350 {"id-kp", 1879048204, 0},
351 {0, 1073741825, "id-pkix"},
352 {0, 1, "3"},
353 {"id-ad", 1879048204, 0},
354 {0, 1073741825, "id-pkix"},
355 {0, 1, "48"},
356 {"id-qt-cps", 1879048204, 0},
357 {0, 1073741825, "id-qt"},
358 {0, 1, "1"},
359 {"id-qt-unotice", 1879048204, 0},
360 {0, 1073741825, "id-qt"},
361 {0, 1, "2"},
362 {"id-ad-ocsp", 1879048204, 0},
363 {0, 1073741825, "id-ad"},
364 {0, 1, "1"},
365 {"id-ad-caIssuers", 1879048204, 0},
366 {0, 1073741825, "id-ad"},
367 {0, 1, "2"},
368 {"Attribute", 1610612741, 0},
369 {"type", 1073741826, "AttributeType"},
370 {"values", 536870927, 0},
371 {0, 2, "AttributeValue"},
372 {"AttributeType", 1073741836, 0},
373 {"AttributeValue", 1614807053, 0},
374 {"type", 1, 0},
375 {"AttributeTypeAndValue", 1610612741, 0},
376 {"type", 1073741826, "AttributeType"},
377 {"value", 2, "AttributeValue"},
378 {"id-at", 1879048204, 0},
379 {"joint-iso-ccitt", 1073741825, "2"},
380 {"ds", 1073741825, "5"},
381 {0, 1, "4"},
382 {"id-at-initials", 1880096780, "AttributeType"},
383 {0, 1073741825, "id-at"},
384 {0, 1, "43"},
385 {"X520initials", 1073741826, "DirectoryString"},
386 {"id-at-generationQualifier", 1880096780, "AttributeType"},
387 {0, 1073741825, "id-at"},
388 {0, 1, "44"},
389 {"X520generationQualifier", 1073741826, "DirectoryString"},
390 {"id-at-surname", 1880096780, "AttributeType"},
391 {0, 1073741825, "id-at"},
392 {0, 1, "4"},
393 {"X520surName", 1073741826, "DirectoryString"},
394 {"id-at-givenName", 1880096780, "AttributeType"},
395 {0, 1073741825, "id-at"},
396 {0, 1, "42"},
397 {"X520givenName", 1073741826, "DirectoryString"},
398 {"id-at-name", 1880096780, "AttributeType"},
399 {0, 1073741825, "id-at"},
400 {0, 1, "41"},
401 {"X520name", 1073741826, "DirectoryString"},
402 {"id-at-commonName", 1880096780, "AttributeType"},
403 {0, 1073741825, "id-at"},
404 {0, 1, "3"},
405 {"X520CommonName", 1073741826, "DirectoryString"},
406 {"id-at-localityName", 1880096780, "AttributeType"},
407 {0, 1073741825, "id-at"},
408 {0, 1, "7"},
409 {"X520LocalityName", 1073741826, "DirectoryString"},
410 {"id-at-stateOrProvinceName", 1880096780, "AttributeType"},
411 {0, 1073741825, "id-at"},
412 {0, 1, "8"},
413 {"X520StateOrProvinceName", 1073741826, "DirectoryString"},
414 {"id-at-organizationName", 1880096780, "AttributeType"},
415 {0, 1073741825, "id-at"},
416 {0, 1, "10"},
417 {"X520OrganizationName", 1073741826, "DirectoryString"},
418 {"id-at-organizationalUnitName", 1880096780, "AttributeType"},
419 {0, 1073741825, "id-at"},
420 {0, 1, "11"},
421 {"X520OrganizationalUnitName", 1073741826, "DirectoryString"},
422 {"id-at-title", 1880096780, "AttributeType"},
423 {0, 1073741825, "id-at"},
424 {0, 1, "12"},
425 {"X520Title", 1073741826, "DirectoryString"},
426 {"id-at-description", 1880096780, "AttributeType"},
427 {0, 1073741825, "id-at"},
428 {0, 1, "13"},
429 {"X520Description", 1073741826, "DirectoryString"},
430 {"id-at-dnQualifier", 1880096780, "AttributeType"},
431 {0, 1073741825, "id-at"},
432 {0, 1, "46"},
433 {"X520dnQualifier", 1073741826, "PrintableString"},
434 {"id-at-countryName", 1880096780, "AttributeType"},
435 {0, 1073741825, "id-at"},
436 {0, 1, "6"},
437 {"X520countryName", 1612709890, "PrintableString"},
438 {0, 1048586, "2"},
439 {"id-at-serialNumber", 1880096780, "AttributeType"},
440 {0, 1073741825, "id-at"},
441 {0, 1, "5"},
442 {"X520serialNumber", 1073741826, "PrintableString"},
443 {"id-at-telephoneNumber", 1880096780, "AttributeType"},
444 {0, 1073741825, "id-at"},
445 {0, 1, "20"},
446 {"X520telephoneNumber", 1073741826, "PrintableString"},
447 {"id-at-facsimileTelephoneNumber", 1880096780, "AttributeType"},
448 {0, 1073741825, "id-at"},
449 {0, 1, "23"},
450 {"X520facsimileTelephoneNumber", 1073741826, "PrintableString"},
451 {"id-at-pseudonym", 1880096780, "AttributeType"},
452 {0, 1073741825, "id-at"},
453 {0, 1, "65"},
454 {"X520pseudonym", 1073741826, "DirectoryString"},
455 {"id-at-name", 1880096780, "AttributeType"},
456 {0, 1073741825, "id-at"},
457 {0, 1, "41"},
458 {"X520name", 1073741826, "DirectoryString"},
459 {"id-at-streetAddress", 1880096780, "AttributeType"},
460 {0, 1073741825, "id-at"},
461 {0, 1, "9"},
462 {"X520streetAddress", 1073741826, "DirectoryString"},
463 {"id-at-postalAddress", 1880096780, "AttributeType"},
464 {0, 1073741825, "id-at"},
465 {0, 1, "16"},
466 {"X520postalAddress", 1073741826, "PostalAddress"},
467 {"PostalAddress", 1610612747, 0},
468 {0, 2, "DirectoryString"},
469 {"pkcs", 1879048204, 0},
470 {"iso", 1073741825, "1"},
471 {"member-body", 1073741825, "2"},
472 {"us", 1073741825, "840"},
473 {"rsadsi", 1073741825, "113549"},
474 {"pkcs", 1, "1"},
475 {"pkcs-9", 1879048204, 0},
476 {0, 1073741825, "pkcs"},
477 {0, 1, "9"},
478 {"emailAddress", 1880096780, "AttributeType"},
479 {0, 1073741825, "pkcs-9"},
480 {0, 1, "1"},
481 {"Pkcs9email", 1612709890, "IA5String"},
482 {"ub-emailaddress-length", 524298, "1"},
483 {"Name", 1610612754, 0},
484 {"rdnSequence", 2, "RDNSequence"},
485 {"RDNSequence", 1610612747, 0},
486 {0, 2, "RelativeDistinguishedName"},
487 {"DistinguishedName", 1073741826, "RDNSequence"},
488 {"RelativeDistinguishedName", 1612709903, 0},
489 {"MAX", 1074266122, "1"},
490 {0, 2, "AttributeTypeAndValue"},
491 {"Certificate", 1610612741, 0},
492 {"tbsCertificate", 1073741826, "TBSCertificate"},
493 {"signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
494 {"signature", 6, 0},
495 {"TBSCertificate", 1610612741, 0},
496 {"version", 1610653698, "Version"},
497 {0, 1073741833, "v1"},
498 {0, 2056, "0"},
499 {"serialNumber", 1073741826, "CertificateSerialNumber"},
500 {"signature", 1073741826, "AlgorithmIdentifier"},
501 {"issuer", 1073741826, "Name"},
502 {"validity", 1073741826, "Validity"},
503 {"subject", 1073741826, "Name"},
504 {"subjectPublicKeyInfo", 1073741826, "SubjectPublicKeyInfo"},
505 {"issuerUniqueID", 1610637314, "UniqueIdentifier"},
506 {0, 4104, "1"},
507 {"subjectUniqueID", 1610637314, "UniqueIdentifier"},
508 {0, 4104, "2"},
509 {"extensions", 536895490, "Extensions"},
510 {0, 2056, "3"},
511 {"Version", 1610874883, 0},
512 {"v1", 1073741825, "0"},
513 {"v2", 1073741825, "1"},
514 {"v3", 1, "2"},
515 {"CertificateSerialNumber", 1073741827, 0},
516 {"Validity", 1610612741, 0},
517 {"notBefore", 1073741826, "Time"},
518 {"notAfter", 2, "Time"},
519 {"Time", 1610612754, 0},
520 {"utcTime", 1090519057, 0},
521 {"generalTime", 8388625, 0},
522 {"UniqueIdentifier", 1073741830, 0},
523 {"SubjectPublicKeyInfo", 1610612741, 0},
524 {"algorithm", 1073741826, "AlgorithmIdentifier"},
525 {"subjectPublicKey", 6, 0},
526 {"Extensions", 1612709899, 0},
527 {"MAX", 1074266122, "1"},
528 {0, 2, "Extension"},
529 {"Extension", 1610612741, 0},
530 {"extnID", 1073741836, 0},
531 {"critical", 1610645508, 0},
532 {0, 131081, 0},
533 {"extnValue", 7, 0},
534 {"CertificateList", 1610612741, 0},
535 {"tbsCertList", 1073741826, "TBSCertList"},
536 {"signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
537 {"signature", 6, 0},
538 {"TBSCertList", 1610612741, 0},
539 {"version", 1073758210, "Version"},
540 {"signature", 1073741826, "AlgorithmIdentifier"},
541 {"issuer", 1073741826, "Name"},
542 {"thisUpdate", 1073741826, "Time"},
543 {"nextUpdate", 1073758210, "Time"},
544 {"revokedCertificates", 1610629131, 0},
545 {0, 536870917, 0},
546 {"userCertificate", 1073741826, "CertificateSerialNumber"},
547 {"revocationDate", 1073741826, "Time"},
548 {"crlEntryExtensions", 16386, "Extensions"},
549 {"crlExtensions", 536895490, "Extensions"},
550 {0, 2056, "0"},
551 {"AlgorithmIdentifier", 1610612741, 0},
552 {"algorithm", 1073741836, 0},
553 {"parameters", 541081613, 0},
554 {"algorithm", 1, 0},
555 {"pkcs-1", 1879048204, 0},
556 {0, 1073741825, "pkcs"},
557 {0, 1, "1"},
558 {"rsaEncryption", 1879048204, 0},
559 {0, 1073741825, "pkcs-1"},
560 {0, 1, "1"},
561 {"md2WithRSAEncryption", 1879048204, 0},
562 {0, 1073741825, "pkcs-1"},
563 {0, 1, "2"},
564 {"md5WithRSAEncryption", 1879048204, 0},
565 {0, 1073741825, "pkcs-1"},
566 {0, 1, "4"},
567 {"sha1WithRSAEncryption", 1879048204, 0},
568 {0, 1073741825, "pkcs-1"},
569 {0, 1, "5"},
570 {"id-dsa-with-sha1", 1879048204, 0},
571 {"iso", 1073741825, "1"},
572 {"member-body", 1073741825, "2"},
573 {"us", 1073741825, "840"},
574 {"x9-57", 1073741825, "10040"},
575 {"x9algorithm", 1073741825, "4"},
576 {0, 1, "3"},
577 {"Dss-Sig-Value", 1610612741, 0},
578 {"r", 1073741827, 0},
579 {"s", 3, 0},
580 {"dhpublicnumber", 1879048204, 0},
581 {"iso", 1073741825, "1"},
582 {"member-body", 1073741825, "2"},
583 {"us", 1073741825, "840"},
584 {"ansi-x942", 1073741825, "10046"},
585 {"number-type", 1073741825, "2"},
586 {0, 1, "1"},
587 {"DomainParameters", 1610612741, 0},
588 {"p", 1073741827, 0},
589 {"g", 1073741827, 0},
590 {"q", 1073741827, 0},
591 {"j", 1073758211, 0},
592 {"validationParms", 16386, "ValidationParms"},
593 {"ValidationParms", 1610612741, 0},
594 {"seed", 1073741830, 0},
595 {"pgenCounter", 3, 0},
596 {"id-dsa", 1879048204, 0},
597 {"iso", 1073741825, "1"},
598 {"member-body", 1073741825, "2"},
599 {"us", 1073741825, "840"},
600 {"x9-57", 1073741825, "10040"},
601 {"x9algorithm", 1073741825, "4"},
602 {0, 1, "1"},
603 {"Dss-Parms", 1610612741, 0},
604 {"p", 1073741827, 0},
605 {"q", 1073741827, 0},
606 {"g", 3, 0},
607 {"ORAddress", 1610612741, 0},
608 {"built-in-standard-attributes", 1073741826, "BuiltInStandardAttributes"},
609 {"built-in-domain-defined-attributes", 1073758210,
610 "BuiltInDomainDefinedAttributes"},
611 {"extension-attributes", 16386, "ExtensionAttributes"},
612 {"BuiltInStandardAttributes", 1610612741, 0},
613 {"country-name", 1073758210, "CountryName"},
614 {"administration-domain-name", 1073758210, "AdministrationDomainName"},
615 {"network-address", 1610637314, "NetworkAddress"},
616 {0, 2056, "0"},
617 {"terminal-identifier", 1610637314, "TerminalIdentifier"},
618 {0, 2056, "1"},
619 {"private-domain-name", 1610637314, "PrivateDomainName"},
620 {0, 2056, "2"},
621 {"organization-name", 1610637314, "OrganizationName"},
622 {0, 2056, "3"},
623 {"numeric-user-identifier", 1610637314, "NumericUserIdentifier"},
624 {0, 2056, "4"},
625 {"personal-name", 1610637314, "PersonalName"},
626 {0, 2056, "5"},
627 {"organizational-unit-names", 536895490, "OrganizationalUnitNames"},
628 {0, 2056, "6"},
629 {"CountryName", 1610620946, 0},
630 {0, 1073746952, "1"},
631 {"x121-dcc-code", 1612709890, "NumericString"},
632 {0, 1048586, "ub-country-name-numeric-length"},
633 {"iso-3166-alpha2-code", 538968066, "PrintableString"},
634 {0, 1048586, "ub-country-name-alpha-length"},
635 {"AdministrationDomainName", 1610620946, 0},
636 {0, 1073744904, "2"},
637 {"numeric", 1612709890, "NumericString"},
638 {"ub-domain-name-length", 524298, "0"},
639 {"printable", 538968066, "PrintableString"},
640 {"ub-domain-name-length", 524298, "0"},
641 {"NetworkAddress", 1073741826, "X121Address"},
642 {"X121Address", 1612709890, "NumericString"},
643 {"ub-x121-address-length", 524298, "1"},
644 {"TerminalIdentifier", 1612709890, "PrintableString"},
645 {"ub-terminal-id-length", 524298, "1"},
646 {"PrivateDomainName", 1610612754, 0},
647 {"numeric", 1612709890, "NumericString"},
648 {"ub-domain-name-length", 524298, "1"},
649 {"printable", 538968066, "PrintableString"},
650 {"ub-domain-name-length", 524298, "1"},
651 {"OrganizationName", 1612709890, "PrintableString"},
652 {"ub-organization-name-length", 524298, "1"},
653 {"NumericUserIdentifier", 1612709890, "NumericString"},
654 {"ub-numeric-user-id-length", 524298, "1"},
655 {"PersonalName", 1610612750, 0},
656 {"surname", 1814044674, "PrintableString"},
657 {0, 1073745928, "0"},
658 {"ub-surname-length", 524298, "1"},
659 {"given-name", 1814061058, "PrintableString"},
660 {0, 1073745928, "1"},
661 {"ub-given-name-length", 524298, "1"},
662 {"initials", 1814061058, "PrintableString"},
663 {0, 1073745928, "2"},
664 {"ub-initials-length", 524298, "1"},
665 {"generation-qualifier", 740319234, "PrintableString"},
666 {0, 1073745928, "3"},
667 {"ub-generation-qualifier-length", 524298, "1"},
668 {"OrganizationalUnitNames", 1612709899, 0},
669 {"ub-organizational-units", 1074266122, "1"},
670 {0, 2, "OrganizationalUnitName"},
671 {"OrganizationalUnitName", 1612709890, "PrintableString"},
672 {"ub-organizational-unit-name-length", 524298, "1"},
673 {"BuiltInDomainDefinedAttributes", 1612709899, 0},
674 {"ub-domain-defined-attributes", 1074266122, "1"},
675 {0, 2, "BuiltInDomainDefinedAttribute"},
676 {"BuiltInDomainDefinedAttribute", 1610612741, 0},
677 {"type", 1612709890, "PrintableString"},
678 {"ub-domain-defined-attribute-type-length", 524298, "1"},
679 {"value", 538968066, "PrintableString"},
680 {"ub-domain-defined-attribute-value-length", 524298, "1"},
681 {"ExtensionAttributes", 1612709903, 0},
682 {"ub-extension-attributes", 1074266122, "1"},
683 {0, 2, "ExtensionAttribute"},
684 {"ExtensionAttribute", 1610612741, 0},
685 {"extension-attribute-type", 1611145219, 0},
686 {0, 1073743880, "0"},
687 {"0", 10, "ub-extension-attributes"},
688 {"extension-attribute-value", 541073421, 0},
689 {0, 1073743880, "1"},
690 {"extension-attribute-type", 1, 0},
691 {"common-name", 1342177283, "1"},
692 {"CommonName", 1612709890, "PrintableString"},
693 {"ub-common-name-length", 524298, "1"},
694 {"teletex-common-name", 1342177283, "2"},
695 {"TeletexCommonName", 1612709890, "TeletexString"},
696 {"ub-common-name-length", 524298, "1"},
697 {"teletex-organization-name", 1342177283, "3"},
698 {"TeletexOrganizationName", 1612709890, "TeletexString"},
699 {"ub-organization-name-length", 524298, "1"},
700 {"teletex-personal-name", 1342177283, "4"},
701 {"TeletexPersonalName", 1610612750, 0},
702 {"surname", 1814044674, "TeletexString"},
703 {0, 1073743880, "0"},
704 {"ub-surname-length", 524298, "1"},
705 {"given-name", 1814061058, "TeletexString"},
706 {0, 1073743880, "1"},
707 {"ub-given-name-length", 524298, "1"},
708 {"initials", 1814061058, "TeletexString"},
709 {0, 1073743880, "2"},
710 {"ub-initials-length", 524298, "1"},
711 {"generation-qualifier", 740319234, "TeletexString"},
712 {0, 1073743880, "3"},
713 {"ub-generation-qualifier-length", 524298, "1"},
714 {"teletex-organizational-unit-names", 1342177283, "5"},
715 {"TeletexOrganizationalUnitNames", 1612709899, 0},
716 {"ub-organizational-units", 1074266122, "1"},
717 {0, 2, "TeletexOrganizationalUnitName"},
718 {"TeletexOrganizationalUnitName", 1612709890, "TeletexString"},
719 {"ub-organizational-unit-name-length", 524298, "1"},
720 {"pds-name", 1342177283, "7"},
721 {"PDSName", 1612709890, "PrintableString"},
722 {"ub-pds-name-length", 524298, "1"},
723 {"physical-delivery-country-name", 1342177283, "8"},
724 {"PhysicalDeliveryCountryName", 1610612754, 0},
725 {"x121-dcc-code", 1612709890, "NumericString"},
726 {0, 1048586, "ub-country-name-numeric-length"},
727 {"iso-3166-alpha2-code", 538968066, "PrintableString"},
728 {0, 1048586, "ub-country-name-alpha-length"},
729 {"postal-code", 1342177283, "9"},
730 {"PostalCode", 1610612754, 0},
731 {"numeric-code", 1612709890, "NumericString"},
732 {"ub-postal-code-length", 524298, "1"},
733 {"printable-code", 538968066, "PrintableString"},
734 {"ub-postal-code-length", 524298, "1"},
735 {"physical-delivery-office-name", 1342177283, "10"},
736 {"PhysicalDeliveryOfficeName", 1073741826, "PDSParameter"},
737 {"physical-delivery-office-number", 1342177283, "11"},
738 {"PhysicalDeliveryOfficeNumber", 1073741826, "PDSParameter"},
739 {"extension-OR-address-components", 1342177283, "12"},
740 {"ExtensionORAddressComponents", 1073741826, "PDSParameter"},
741 {"physical-delivery-personal-name", 1342177283, "13"},
742 {"PhysicalDeliveryPersonalName", 1073741826, "PDSParameter"},
743 {"physical-delivery-organization-name", 1342177283, "14"},
744 {"PhysicalDeliveryOrganizationName", 1073741826, "PDSParameter"},
745 {"extension-physical-delivery-address-components", 1342177283, "15"},
746 {"ExtensionPhysicalDeliveryAddressComponents", 1073741826, "PDSParameter"},
747 {"unformatted-postal-address", 1342177283, "16"},
748 {"UnformattedPostalAddress", 1610612750, 0},
749 {"printable-address", 1814052875, 0},
750 {"ub-pds-physical-address-lines", 1074266122, "1"},
751 {0, 538968066, "PrintableString"},
752 {"ub-pds-parameter-length", 524298, "1"},
753 {"teletex-string", 740311042, "TeletexString"},
754 {"ub-unformatted-address-length", 524298, "1"},
755 {"street-address", 1342177283, "17"},
756 {"StreetAddress", 1073741826, "PDSParameter"},
757 {"post-office-box-address", 1342177283, "18"},
758 {"PostOfficeBoxAddress", 1073741826, "PDSParameter"},
759 {"poste-restante-address", 1342177283, "19"},
760 {"PosteRestanteAddress", 1073741826, "PDSParameter"},
761 {"unique-postal-name", 1342177283, "20"},
762 {"UniquePostalName", 1073741826, "PDSParameter"},
763 {"local-postal-attributes", 1342177283, "21"},
764 {"LocalPostalAttributes", 1073741826, "PDSParameter"},
765 {"PDSParameter", 1610612750, 0},
766 {"printable-string", 1814052866, "PrintableString"},
767 {"ub-pds-parameter-length", 524298, "1"},
768 {"teletex-string", 740311042, "TeletexString"},
769 {"ub-pds-parameter-length", 524298, "1"},
770 {"extended-network-address", 1342177283, "22"},
771 {"ExtendedNetworkAddress", 1610612754, 0},
772 {"e163-4-address", 1610612741, 0},
773 {"number", 1612718082, "NumericString"},
774 {0, 1073743880, "0"},
775 {"ub-e163-4-number-length", 524298, "1"},
776 {"sub-address", 538992642, "NumericString"},
777 {0, 1073743880, "1"},
778 {"ub-e163-4-sub-address-length", 524298, "1"},
779 {"psap-address", 536879106, "PresentationAddress"},
780 {0, 2056, "0"},
781 {"PresentationAddress", 1610612741, 0},
782 {"pSelector", 1610637319, 0},
783 {0, 2056, "0"},
784 {"sSelector", 1610637319, 0},
785 {0, 2056, "1"},
786 {"tSelector", 1610637319, 0},
787 {0, 2056, "2"},
788 {"nAddresses", 538976271, 0},
789 {0, 1073743880, "3"},
790 {"MAX", 1074266122, "1"},
791 {0, 7, 0},
792 {"terminal-type", 1342177283, "23"},
793 {"TerminalType", 1610874883, 0},
794 {"telex", 1073741825, "3"},
795 {"teletex", 1073741825, "4"},
796 {"g3-facsimile", 1073741825, "5"},
797 {"g4-facsimile", 1073741825, "6"},
798 {"ia5-terminal", 1073741825, "7"},
799 {"videotex", 1, "8"},
800 {"teletex-domain-defined-attributes", 1342177283, "6"},
801 {"TeletexDomainDefinedAttributes", 1612709899, 0},
802 {"ub-domain-defined-attributes", 1074266122, "1"},
803 {0, 2, "TeletexDomainDefinedAttribute"},
804 {"TeletexDomainDefinedAttribute", 1610612741, 0},
805 {"type", 1612709890, "TeletexString"},
806 {"ub-domain-defined-attribute-type-length", 524298, "1"},
807 {"value", 538968066, "TeletexString"},
808 {"ub-domain-defined-attribute-value-length", 524298, "1"},
809 {"ub-name", 1342177283, "32768"},
810 {"ub-common-name", 1342177283, "64"},
811 {"ub-locality-name", 1342177283, "128"},
812 {"ub-state-name", 1342177283, "128"},
813 {"ub-organization-name", 1342177283, "64"},
814 {"ub-organizational-unit-name", 1342177283, "64"},
815 {"ub-title", 1342177283, "64"},
816 {"ub-match", 1342177283, "128"},
817 {"ub-emailaddress-length", 1342177283, "128"},
818 {"ub-common-name-length", 1342177283, "64"},
819 {"ub-country-name-alpha-length", 1342177283, "2"},
820 {"ub-country-name-numeric-length", 1342177283, "3"},
821 {"ub-domain-defined-attributes", 1342177283, "4"},
822 {"ub-domain-defined-attribute-type-length", 1342177283, "8"},
823 {"ub-domain-defined-attribute-value-length", 1342177283, "128"},
824 {"ub-domain-name-length", 1342177283, "16"},
825 {"ub-extension-attributes", 1342177283, "256"},
826 {"ub-e163-4-number-length", 1342177283, "15"},
827 {"ub-e163-4-sub-address-length", 1342177283, "40"},
828 {"ub-generation-qualifier-length", 1342177283, "3"},
829 {"ub-given-name-length", 1342177283, "16"},
830 {"ub-initials-length", 1342177283, "5"},
831 {"ub-integer-options", 1342177283, "256"},
832 {"ub-numeric-user-id-length", 1342177283, "32"},
833 {"ub-organization-name-length", 1342177283, "64"},
834 {"ub-organizational-unit-name-length", 1342177283, "32"},
835 {"ub-organizational-units", 1342177283, "4"},
836 {"ub-pds-name-length", 1342177283, "16"},
837 {"ub-pds-parameter-length", 1342177283, "30"},
838 {"ub-pds-physical-address-lines", 1342177283, "6"},
839 {"ub-postal-code-length", 1342177283, "16"},
840 {"ub-surname-length", 1342177283, "40"},
841 {"ub-terminal-id-length", 1342177283, "24"},
842 {"ub-unformatted-address-length", 1342177283, "180"},
843 {"ub-x121-address-length", 1342177283, "16"},
844 {"pkcs-7-ContentInfo", 1610612741, 0},
845 {"contentType", 1073741826, "pkcs-7-ContentType"},
846 {"content", 541073421, 0},
847 {0, 1073743880, "0"},
848 {"contentType", 1, 0},
849 {"pkcs-7-DigestInfo", 1610612741, 0},
850 {"digestAlgorithm", 1073741826, "pkcs-7-DigestAlgorithmIdentifier"},
851 {"digest", 2, "pkcs-7-Digest"},
852 {"pkcs-7-Digest", 1073741831, 0},
853 {"pkcs-7-ContentType", 1073741836, 0},
854 {"pkcs-7-SignedData", 1610612741, 0},
855 {"version", 1073741826, "pkcs-7-CMSVersion"},
856 {"digestAlgorithms", 1073741826, "pkcs-7-DigestAlgorithmIdentifiers"},
857 {"encapContentInfo", 1073741826, "pkcs-7-EncapsulatedContentInfo"},
858 {"certificates", 1610637314, "pkcs-7-CertificateSet"},
859 {0, 4104, "0"},
860 {"crls", 1610637314, "pkcs-7-CertificateRevocationLists"},
861 {0, 4104, "1"},
862 {"signerInfos", 2, "pkcs-7-SignerInfos"},
863 {"pkcs-7-CMSVersion", 1610874883, 0},
864 {"v0", 1073741825, "0"},
865 {"v1", 1073741825, "1"},
866 {"v2", 1073741825, "2"},
867 {"v3", 1073741825, "3"},
868 {"v4", 1, "4"},
869 {"pkcs-7-DigestAlgorithmIdentifiers", 1610612751, 0},
870 {0, 2, "pkcs-7-DigestAlgorithmIdentifier"},
871 {"pkcs-7-DigestAlgorithmIdentifier", 1073741826, "AlgorithmIdentifier"},
872 {"pkcs-7-EncapsulatedContentInfo", 1610612741, 0},
873 {"eContentType", 1073741826, "pkcs-7-ContentType"},
874 {"eContent", 536895495, 0},
875 {0, 2056, "0"},
876 {"pkcs-7-CertificateRevocationLists", 1610612751, 0},
877 {0, 13, 0},
878 {"pkcs-7-CertificateChoices", 1610612754, 0},
879 {"certificate", 13, 0},
880 {"pkcs-7-CertificateSet", 1610612751, 0},
881 {0, 2, "pkcs-7-CertificateChoices"},
882 {"pkcs-7-SignerInfos", 1610612751, 0},
883 {0, 13, 0},
884 {"pkcs-10-CertificationRequestInfo", 1610612741, 0},
885 {"version", 1610874883, 0},
886 {"v1", 1, "0"},
887 {"subject", 1073741826, "Name"},
888 {"subjectPKInfo", 1073741826, "SubjectPublicKeyInfo"},
889 {"attributes", 536879106, "Attributes"},
890 {0, 4104, "0"},
891 {"Attributes", 1610612751, 0},
892 {0, 2, "Attribute"},
893 {"pkcs-10-CertificationRequest", 1610612741, 0},
894 {"certificationRequestInfo", 1073741826,
895 "pkcs-10-CertificationRequestInfo"},
896 {"signatureAlgorithm", 1073741826, "AlgorithmIdentifier"},
897 {"signature", 6, 0},
898 {"pkcs-9-ub-challengePassword", 1342177283, "255"},
899 {"pkcs-9-certTypes", 1879048204, 0},
900 {0, 1073741825, "pkcs-9"},
901 {0, 1, "22"},
902 {"pkcs-9-crlTypes", 1879048204, 0},
903 {0, 1073741825, "pkcs-9"},
904 {0, 1, "23"},
905 {"pkcs-9-at-challengePassword", 1879048204, 0},
906 {0, 1073741825, "pkcs-9"},
907 {0, 1, "7"},
908 {"pkcs-9-challengePassword", 1610612754, 0},
909 {"printableString", 1612709890, "PrintableString"},
910 {"pkcs-9-ub-challengePassword", 524298, "1"},
911 {"utf8String", 538968066, "UTF8String"},
912 {"pkcs-9-ub-challengePassword", 524298, "1"},
913 {"pkcs-9-at-localKeyId", 1879048204, 0},
914 {0, 1073741825, "pkcs-9"},
915 {0, 1, "21"},
916 {"pkcs-9-localKeyId", 1073741831, 0},
917 {"pkcs-9-at-friendlyName", 1879048204, 0},
918 {0, 1073741825, "pkcs-9"},
919 {0, 1, "20"},
920 {"pkcs-9-friendlyName", 1612709890, "BMPString"},
921 {"255", 524298, "1"},
922 {"pkcs-8-PrivateKeyInfo", 1610612741, 0},
923 {"version", 1073741826, "pkcs-8-Version"},
924 {"privateKeyAlgorithm", 1073741826, "AlgorithmIdentifier"},
925 {"privateKey", 1073741826, "pkcs-8-PrivateKey"},
926 {"attributes", 536895490, "Attributes"},
927 {0, 4104, "0"},
928 {"pkcs-8-Version", 1610874883, 0},
929 {"v1", 1, "0"},
930 {"pkcs-8-PrivateKey", 1073741831, 0},
931 {"pkcs-8-Attributes", 1610612751, 0},
932 {0, 2, "Attribute"},
933 {"pkcs-8-EncryptedPrivateKeyInfo", 1610612741, 0},
934 {"encryptionAlgorithm", 1073741826, "AlgorithmIdentifier"},
935 {"encryptedData", 2, "pkcs-8-EncryptedData"},
936 {"pkcs-8-EncryptedData", 1073741831, 0},
937 {"pkcs-5", 1879048204, 0},
938 {0, 1073741825, "pkcs"},
939 {0, 1, "5"},
940 {"pkcs-5-encryptionAlgorithm", 1879048204, 0},
941 {"iso", 1073741825, "1"},
942 {"member-body", 1073741825, "2"},
943 {"us", 1073741825, "840"},
944 {"rsadsi", 1073741825, "113549"},
945 {0, 1, "3"},
946 {"pkcs-5-des-EDE3-CBC", 1879048204, 0},
947 {0, 1073741825, "pkcs-5-encryptionAlgorithm"},
948 {0, 1, "7"},
949 {"pkcs-5-des-EDE3-CBC-params", 1612709895, 0},
950 {0, 1048586, "8"},
951 {"pkcs-5-id-PBES2", 1879048204, 0},
952 {0, 1073741825, "pkcs-5"},
953 {0, 1, "13"},
954 {"pkcs-5-PBES2-params", 1610612741, 0},
955 {"keyDerivationFunc", 1073741826, "AlgorithmIdentifier"},
956 {"encryptionScheme", 2, "AlgorithmIdentifier"},
957 {"pkcs-5-id-PBKDF2", 1879048204, 0},
958 {0, 1073741825, "pkcs-5"},
959 {0, 1, "12"},
960 {"pkcs-5-PBKDF2-params", 1610612741, 0},
961 {"salt", 1610612754, 0},
962 {"specified", 1073741831, 0},
963 {"otherSource", 2, "AlgorithmIdentifier"},
964 {"iterationCount", 1611137027, 0},
965 {"1", 10, "MAX"},
966 {"keyLength", 1611153411, 0},
967 {"1", 10, "MAX"},
968 {"prf", 16386, "AlgorithmIdentifier"},
969 {"pkcs-12", 1879048204, 0},
970 {0, 1073741825, "pkcs"},
971 {0, 1, "12"},
972 {"pkcs-12-PFX", 1610612741, 0},
973 {"version", 1610874883, 0},
974 {"v3", 1, "3"},
975 {"authSafe", 1073741826, "pkcs-7-ContentInfo"},
976 {"macData", 16386, "pkcs-12-MacData"},
977 {"pkcs-12-PbeParams", 1610612741, 0},
978 {"salt", 1073741831, 0},
979 {"iterations", 3, 0},
980 {"pkcs-12-MacData", 1610612741, 0},
981 {"mac", 1073741826, "pkcs-7-DigestInfo"},
982 {"macSalt", 1073741831, 0},
983 {"iterations", 536903683, 0},
984 {0, 9, "1"},
985 {"pkcs-12-AuthenticatedSafe", 1610612747, 0},
986 {0, 2, "pkcs-7-ContentInfo"},
987 {"pkcs-12-SafeContents", 1610612747, 0},
988 {0, 2, "pkcs-12-SafeBag"},
989 {"pkcs-12-SafeBag", 1610612741, 0},
990 {"bagId", 1073741836, 0},
991 {"bagValue", 1614815245, 0},
992 {0, 1073743880, "0"},
993 {"badId", 1, 0},
994 {"bagAttributes", 536887311, 0},
995 {0, 2, "pkcs-12-PKCS12Attribute"},
996 {"pkcs-12-bagtypes", 1879048204, 0},
997 {0, 1073741825, "pkcs-12"},
998 {0, 1073741825, "10"},
999 {0, 1, "1"},
1000 {"pkcs-12-keyBag", 1879048204, 0},
1001 {0, 1073741825, "pkcs-12-bagtypes"},
1002 {0, 1, "1"},
1003 {"pkcs-12-pkcs8ShroudedKeyBag", 1879048204, 0},
1004 {0, 1073741825, "pkcs-12-bagtypes"},
1005 {0, 1, "2"},
1006 {"pkcs-12-certBag", 1879048204, 0},
1007 {0, 1073741825, "pkcs-12-bagtypes"},
1008 {0, 1, "3"},
1009 {"pkcs-12-crlBag", 1879048204, 0},
1010 {0, 1073741825, "pkcs-12-bagtypes"},
1011 {0, 1, "4"},
1012 {"pkcs-12-KeyBag", 1073741826, "pkcs-8-PrivateKeyInfo"},
1013 {"pkcs-12-PKCS8ShroudedKeyBag", 1073741826,
1014 "pkcs-8-EncryptedPrivateKeyInfo"},
1015 {"pkcs-12-CertBag", 1610612741, 0},
1016 {"certId", 1073741836, 0},
1017 {"certValue", 541073421, 0},
1018 {0, 1073743880, "0"},
1019 {"certId", 1, 0},
1020 {"pkcs-12-CRLBag", 1610612741, 0},
1021 {"crlId", 1073741836, 0},
1022 {"crlValue", 541073421, 0},
1023 {0, 1073743880, "0"},
1024 {"crlId", 1, 0},
1025 {"pkcs-12-PKCS12Attribute", 1073741826, "Attribute"},
1026 {"pkcs-7-data", 1879048204, 0},
1027 {"iso", 1073741825, "1"},
1028 {"member-body", 1073741825, "2"},
1029 {"us", 1073741825, "840"},
1030 {"rsadsi", 1073741825, "113549"},
1031 {"pkcs", 1073741825, "1"},
1032 {"pkcs7", 1073741825, "7"},
1033 {0, 1, "1"},
1034 {"pkcs-7-encryptedData", 1879048204, 0},
1035 {"iso", 1073741825, "1"},
1036 {"member-body", 1073741825, "2"},
1037 {"us", 1073741825, "840"},
1038 {"rsadsi", 1073741825, "113549"},
1039 {"pkcs", 1073741825, "1"},
1040 {"pkcs7", 1073741825, "7"},
1041 {0, 1, "6"},
1042 {"pkcs-7-Data", 1073741831, 0},
1043 {"pkcs-7-EncryptedData", 1610612741, 0},
1044 {"version", 1073741826, "pkcs-7-CMSVersion"},
1045 {"encryptedContentInfo", 1073741826, "pkcs-7-EncryptedContentInfo"},
1046 {"unprotectedAttrs", 536895490, "pkcs-7-UnprotectedAttributes"},
1047 {0, 4104, "1"},
1048 {"pkcs-7-EncryptedContentInfo", 1610612741, 0},
1049 {"contentType", 1073741826, "pkcs-7-ContentType"},
1050 {"contentEncryptionAlgorithm", 1073741826,
1051 "pkcs-7-ContentEncryptionAlgorithmIdentifier"},
1052 {"encryptedContent", 536895490, "pkcs-7-EncryptedContent"},
1053 {0, 4104, "0"},
1054 {"pkcs-7-ContentEncryptionAlgorithmIdentifier", 1073741826,
1055 "AlgorithmIdentifier"},
1056 {"pkcs-7-EncryptedContent", 1073741831, 0},
1057 {"pkcs-7-UnprotectedAttributes", 1612709903, 0},
1058 {"MAX", 1074266122, "1"},
1059 {0, 2, "Attribute"},
1060 {"id-at-ldap-DC", 1880096780, "AttributeType"},
1061 {0, 1073741825, "0"},
1062 {0, 1073741825, "9"},
1063 {0, 1073741825, "2342"},
1064 {0, 1073741825, "19200300"},
1065 {0, 1073741825, "100"},
1066 {0, 1073741825, "1"},
1067 {0, 1, "25"},
1068 {"ldap-DC", 1073741826, "IA5String"},
1069 {"id-at-ldap-UID", 1880096780, "AttributeType"},
1070 {0, 1073741825, "0"},
1071 {0, 1073741825, "9"},
1072 {0, 1073741825, "2342"},
1073 {0, 1073741825, "19200300"},
1074 {0, 1073741825, "100"},
1075 {0, 1073741825, "1"},
1076 {0, 1, "1"},
1077 {"ldap-UID", 1073741826, "DirectoryString"},
1078 {"id-pda", 1879048204, 0},
1079 {0, 1073741825, "id-pkix"},
1080 {0, 1, "9"},
1081 {"id-pda-dateOfBirth", 1880096780, "AttributeType"},
1082 {0, 1073741825, "id-pda"},
1083 {0, 1, "1"},
1084 {"DateOfBirth", 1082130449, 0},
1085 {"id-pda-placeOfBirth", 1880096780, "AttributeType"},
1086 {0, 1073741825, "id-pda"},
1087 {0, 1, "2"},
1088 {"PlaceOfBirth", 1073741826, "DirectoryString"},
1089 {"id-pda-gender", 1880096780, "AttributeType"},
1090 {0, 1073741825, "id-pda"},
1091 {0, 1, "3"},
1092 {"Gender", 1612709890, "PrintableString"},
1093 {0, 1048586, "1"},
1094 {"id-pda-countryOfCitizenship", 1880096780, "AttributeType"},
1095 {0, 1073741825, "id-pda"},
1096 {0, 1, "4"},
1097 {"CountryOfCitizenship", 1612709890, "PrintableString"},
1098 {0, 1048586, "2"},
1099 {"id-pda-countryOfResidence", 1880096780, "AttributeType"},
1100 {0, 1073741825, "id-pda"},
1101 {0, 1, "5"},
1102 {"CountryOfResidence", 1612709890, "PrintableString"},
1103 {0, 1048586, "2"},
1104 {"id-pe-proxyCertInfo", 1879048204, 0},
1105 {0, 1073741825, "id-pe"},
1106 {0, 1, "14"},
1107 {"id-ppl-inheritAll", 1879048204, 0},
1108 {0, 1073741825, "id-pkix"},
1109 {0, 1073741825, "21"},
1110 {0, 1, "1"},
1111 {"id-ppl-independent", 1879048204, 0},
1112 {0, 1073741825, "id-pkix"},
1113 {0, 1073741825, "21"},
1114 {0, 1, "2"},
1115 {"ProxyCertInfo", 1610612741, 0},
1116 {"pCPathLenConstraint", 1611153411, 0},
1117 {"0", 10, "MAX"},
1118 {"proxyPolicy", 2, "ProxyPolicy"},
1119 {"ProxyPolicy", 1610612741, 0},
1120 {"policyLanguage", 1073741836, 0},
1121 {"policy", 16391, 0},
1122 {"id-on", 1879048204, 0},
1123 {0, 1073741825, "id-pkix"},
1124 {0, 1, "8"},
1125 {"id-on-xmppAddr", 1879048204, 0},
1126 {0, 1073741825, "id-on"},
1127 {0, 1, "5"},
1128 {"XmppAddr", 2, "UTF8String"},
1129 {0, 0, 0}
1130};
diff --git a/src/daemon/https/tls/x509_b64.c b/src/daemon/https/tls/x509_b64.c
new file mode 100644
index 00000000..50a9b475
--- /dev/null
+++ b/src/daemon/https/tls/x509_b64.c
@@ -0,0 +1,599 @@
1/*
2 * Copyright (C) 2000, 2001, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* Functions that relate to base64 encoding and decoding.
26 */
27
28#include "gnutls_int.h"
29#include "gnutls_errors.h"
30#include <gnutls_datum.h>
31#include <x509_b64.h>
32
33static const uint8_t b64table[] =
34 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
35
36static const uint8_t asciitable[128] = {
37 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
38 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
39 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
40 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
41 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
42 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
43 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
44 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
45 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
46 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff,
47 0xff, 0xf1, 0xff, 0xff, 0xff, 0x00, /* 0xf1 for '=' */
48 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
49 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
50 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
51 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
52 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
53 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
54 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
55 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
56 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
57 0x31, 0x32, 0x33, 0xff, 0xff, 0xff,
58 0xff, 0xff
59};
60
61inline static int
62encode (char *result, const uint8_t * data, int left)
63{
64
65 int data_len;
66
67 if (left > 3)
68 data_len = 3;
69 else
70 data_len = left;
71
72 switch (data_len)
73 {
74 case 3:
75 result[0] = b64table[(data[0] >> 2)];
76 result[1] =
77 b64table[(((((data[0] & 0x03) & 0xff) << 4) & 0xff) |
78 (data[1] >> 4))];
79 result[2] =
80 b64table[((((data[1] & 0x0f) << 2) & 0xff) | (data[2] >> 6))];
81 result[3] = b64table[(((data[2] << 2) & 0xff) >> 2)];
82 break;
83 case 2:
84 result[0] = b64table[(data[0] >> 2)];
85 result[1] =
86 b64table[(((((data[0] & 0x03) & 0xff) << 4) & 0xff) |
87 (data[1] >> 4))];
88 result[2] = b64table[(((data[1] << 4) & 0xff) >> 2)];
89 result[3] = '=';
90 break;
91 case 1:
92 result[0] = b64table[(data[0] >> 2)];
93 result[1] = b64table[(((((data[0] & 0x03) & 0xff) << 4) & 0xff))];
94 result[2] = '=';
95 result[3] = '=';
96 break;
97 default:
98 return -1;
99 }
100
101 return 4;
102
103}
104
105/* data must be 4 bytes
106 * result should be 3 bytes
107 */
108#define TOASCII(c) (c < 127 ? asciitable[c] : 0xff)
109inline static int
110decode (uint8_t * result, const opaque * data)
111{
112 uint8_t a1, a2;
113 int ret = 3;
114
115 a1 = TOASCII (data[0]);
116 a2 = TOASCII (data[1]);
117 if (a1 == 0xff || a2 == 0xff)
118 return -1;
119 result[0] = ((a1 << 2) & 0xff) | ((a2 >> 4) & 0xff);
120
121 a1 = a2;
122 a2 = TOASCII (data[2]);
123 if (a2 == 0xff)
124 return -1;
125 result[1] = ((a1 << 4) & 0xff) | ((a2 >> 2) & 0xff);
126
127 a1 = a2;
128 a2 = TOASCII (data[3]);
129 if (a2 == 0xff)
130 return -1;
131 result[2] = ((a1 << 6) & 0xff) | (a2 & 0xff);
132
133 if (data[2] == '=')
134 ret--;
135
136 if (data[3] == '=')
137 ret--;
138 return ret;
139}
140
141/* encodes data and puts the result into result (locally allocated)
142 * The result_size is the return value
143 */
144int
145_gnutls_base64_encode (const uint8_t * data, size_t data_size,
146 uint8_t ** result)
147{
148 unsigned int i, j;
149 int ret, tmp;
150 char tmpres[4];
151
152 ret = B64SIZE (data_size);
153
154 (*result) = gnutls_malloc (ret + 1);
155 if ((*result) == NULL)
156 return GNUTLS_E_MEMORY_ERROR;
157
158 for (i = j = 0; i < data_size; i += 3, j += 4)
159 {
160 tmp = encode (tmpres, &data[i], data_size - i);
161 if (tmp == -1)
162 {
163 gnutls_free ((*result));
164 return GNUTLS_E_MEMORY_ERROR;
165 }
166 memcpy (&(*result)[j], tmpres, tmp);
167 }
168 (*result)[ret] = 0; /* null terminated */
169
170 return ret;
171}
172
173#define INCR(what, size) \
174 do { \
175 what+=size; \
176 if (what > ret) { \
177 gnutls_assert(); \
178 gnutls_free( (*result)); *result = NULL; \
179 return GNUTLS_E_INTERNAL_ERROR; \
180 } \
181 } while(0)
182
183/* encodes data and puts the result into result (locally allocated)
184 * The result_size (including the null terminator) is the return value.
185 */
186int
187_gnutls_fbase64_encode (const char *msg, const uint8_t * data,
188 int data_size, uint8_t ** result)
189{
190 int i, ret, tmp, j;
191 char tmpres[4];
192 uint8_t *ptr;
193 uint8_t top[80];
194 uint8_t bottom[80];
195 int pos, bytes, top_len, bottom_len;
196 size_t msglen = strlen (msg);
197
198 if (msglen > 50)
199 {
200 gnutls_assert ();
201 return GNUTLS_E_BASE64_ENCODING_ERROR;
202 }
203
204 memset (bottom, 0, sizeof (bottom));
205 memset (top, 0, sizeof (top));
206
207 strcat (top, "-----BEGIN "); /* Flawfinder: ignore */
208 strcat (top, msg); /* Flawfinder: ignore */
209 strcat (top, "-----"); /* Flawfinder: ignore */
210
211 strcat (bottom, "\n-----END "); /* Flawfinder: ignore */
212 strcat (bottom, msg); /* Flawfinder: ignore */
213 strcat (bottom, "-----\n"); /* Flawfinder: ignore */
214
215 top_len = strlen (top);
216 bottom_len = strlen (bottom);
217
218 ret = B64FSIZE (msglen, data_size);
219
220 (*result) = gnutls_calloc (1, ret + 1);
221 if ((*result) == NULL)
222 {
223 gnutls_assert ();
224 return GNUTLS_E_MEMORY_ERROR;
225 }
226
227 bytes = pos = 0;
228 INCR (bytes, top_len);
229 pos = top_len;
230
231 strcpy (*result, top); /* Flawfinder: ignore */
232
233 for (i = j = 0; i < data_size; i += 3, j += 4)
234 {
235
236 tmp = encode (tmpres, &data[i], data_size - i);
237 if (tmp == -1)
238 {
239 gnutls_assert ();
240 gnutls_free ((*result));
241 *result = NULL;
242 return GNUTLS_E_BASE64_ENCODING_ERROR;
243 }
244
245 INCR (bytes, 4);
246 ptr = &(*result)[j + pos];
247
248 if ((j) % 64 == 0)
249 {
250 INCR (bytes, 1);
251 pos++;
252 *ptr++ = '\n';
253 }
254 *ptr++ = tmpres[0];
255
256 if ((j + 1) % 64 == 0)
257 {
258 INCR (bytes, 1);
259 pos++;
260 *ptr++ = '\n';
261 }
262 *ptr++ = tmpres[1];
263
264 if ((j + 2) % 64 == 0)
265 {
266 INCR (bytes, 1);
267 pos++;
268 *ptr++ = '\n';
269 }
270 *ptr++ = tmpres[2];
271
272 if ((j + 3) % 64 == 0)
273 {
274 INCR (bytes, 1);
275 pos++;
276 *ptr++ = '\n';
277 }
278 *ptr++ = tmpres[3];
279 }
280
281 INCR (bytes, bottom_len);
282
283 memcpy (&(*result)[bytes - bottom_len], bottom, bottom_len);
284 (*result)[bytes] = 0;
285
286 return ret + 1;
287}
288
289/**
290 * gnutls_pem_base64_encode - This function will convert raw data to Base64 encoded
291 * @msg: is a message to be put in the header
292 * @data: contain the raw data
293 * @result: the place where base64 data will be copied
294 * @result_size: holds the size of the result
295 *
296 * This function will convert the given data to printable data, using the base64
297 * encoding. This is the encoding used in PEM messages. If the provided
298 * buffer is not long enough GNUTLS_E_SHORT_MEMORY_BUFFER is returned.
299 *
300 * The output string will be null terminated, although the size will not include
301 * the terminating null.
302 *
303 **/
304int
305gnutls_pem_base64_encode (const char *msg, const gnutls_datum_t * data,
306 char *result, size_t * result_size)
307{
308 opaque *ret;
309 int size;
310
311 size = _gnutls_fbase64_encode (msg, data->data, data->size, &ret);
312 if (size < 0)
313 return size;
314
315 if (result == NULL || *result_size < (unsigned) size)
316 {
317 gnutls_free (ret);
318 *result_size = size;
319 return GNUTLS_E_SHORT_MEMORY_BUFFER;
320 }
321 else
322 {
323 memcpy (result, ret, size);
324 gnutls_free (ret);
325 *result_size = size - 1;
326 }
327
328 return 0;
329}
330
331/**
332 * gnutls_pem_base64_encode_alloc - This function will convert raw data to Base64 encoded
333 * @msg: is a message to be put in the encoded header
334 * @data: contains the raw data
335 * @result: will hold the newly allocated encoded data
336 *
337 * This function will convert the given data to printable data, using the base64
338 * encoding. This is the encoding used in PEM messages. This function will
339 * allocate the required memory to hold the encoded data.
340 *
341 * You should use gnutls_free() to free the returned data.
342 *
343 **/
344int
345gnutls_pem_base64_encode_alloc (const char *msg,
346 const gnutls_datum_t * data,
347 gnutls_datum_t * result)
348{
349 opaque *ret;
350 int size;
351
352 if (result == NULL)
353 return GNUTLS_E_INVALID_REQUEST;
354
355 size = _gnutls_fbase64_encode (msg, data->data, data->size, &ret);
356 if (size < 0)
357 return size;
358
359 result->data = ret;
360 result->size = size - 1;
361 return 0;
362}
363
364
365/* decodes data and puts the result into result (locally allocated)
366 * The result_size is the return value
367 */
368int
369_gnutls_base64_decode (const uint8_t * data, size_t data_size,
370 uint8_t ** result)
371{
372 unsigned int i, j;
373 int ret, tmp, est;
374 uint8_t tmpres[3];
375
376 est = ((data_size * 3) / 4) + 1;
377 (*result) = gnutls_malloc (est);
378 if ((*result) == NULL)
379 return GNUTLS_E_MEMORY_ERROR;
380
381 ret = 0;
382 for (i = j = 0; i < data_size; i += 4, j += 3)
383 {
384 tmp = decode (tmpres, &data[i]);
385 if (tmp < 0)
386 {
387 gnutls_free (*result);
388 *result = NULL;
389 return tmp;
390 }
391 memcpy (&(*result)[j], tmpres, tmp);
392 ret += tmp;
393 }
394 return ret;
395}
396
397/* copies data to result but removes newlines and <CR>
398 * returns the size of the data copied.
399 */
400inline static int
401cpydata (const uint8_t * data, int data_size, uint8_t ** result)
402{
403 int i, j;
404
405 (*result) = gnutls_malloc (data_size);
406 if (*result == NULL)
407 return GNUTLS_E_MEMORY_ERROR;
408
409 for (j = i = 0; i < data_size; i++)
410 {
411 if (data[i] == '\n' || data[i] == '\r')
412 continue;
413 (*result)[j] = data[i];
414 j++;
415 }
416 return j;
417}
418
419/* Searches the given string for ONE PEM encoded certificate, and
420 * stores it in the result.
421 *
422 * The result_size is the return value
423 */
424#define ENDSTR "-----\n"
425#define ENDSTR2 "-----\r"
426int
427_gnutls_fbase64_decode (const char *header, const opaque * data,
428 size_t data_size, uint8_t ** result)
429{
430 int ret;
431 static const char top[] = "-----BEGIN ";
432 static const char bottom[] = "\n-----END ";
433 uint8_t *rdata;
434 int rdata_size;
435 uint8_t *kdata;
436 int kdata_size;
437 char pem_header[128];
438
439 _gnutls_str_cpy (pem_header, sizeof (pem_header), top);
440 if (header != NULL)
441 _gnutls_str_cat (pem_header, sizeof (pem_header), header);
442
443 rdata = memmem (data, data_size, pem_header, strlen (pem_header));
444
445 if (rdata == NULL)
446 {
447 gnutls_assert ();
448 _gnutls_debug_log ("Could not find '%s'\n", pem_header);
449 return GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR;
450 }
451
452 data_size -= (unsigned long int) rdata - (unsigned long int) data;
453
454 if (data_size < 4 + strlen (bottom))
455 {
456 gnutls_assert ();
457 return GNUTLS_E_BASE64_DECODING_ERROR;
458 }
459
460 kdata = memmem (rdata, data_size, ENDSTR, sizeof (ENDSTR) - 1);
461 /* allow CR as well.
462 */
463 if (kdata == NULL)
464 kdata = memmem (rdata, data_size, ENDSTR2, sizeof (ENDSTR2) - 1);
465
466 if (kdata == NULL)
467 {
468 gnutls_assert ();
469 _gnutls_x509_log ("Could not find '%s'\n", ENDSTR);
470 return GNUTLS_E_BASE64_DECODING_ERROR;
471 }
472 data_size -= strlen (ENDSTR);
473 data_size -= (unsigned long int) kdata - (unsigned long int) rdata;
474
475 rdata = kdata + strlen (ENDSTR);
476
477 /* position is now after the ---BEGIN--- headers */
478
479 kdata = memmem (rdata, data_size, bottom, strlen (bottom));
480 if (kdata == NULL)
481 {
482 gnutls_assert ();
483 return GNUTLS_E_BASE64_DECODING_ERROR;
484 }
485
486 /* position of kdata is before the ----END--- footer
487 */
488 rdata_size = (unsigned long int) kdata - (unsigned long int) rdata;
489
490 if (rdata_size < 4)
491 {
492 gnutls_assert ();
493 return GNUTLS_E_BASE64_DECODING_ERROR;
494 }
495
496 kdata_size = cpydata (rdata, rdata_size, &kdata);
497
498 if (kdata_size < 0)
499 {
500 gnutls_assert ();
501 return kdata_size;
502 }
503
504 if (kdata_size < 4)
505 {
506 gnutls_assert ();
507 gnutls_free (kdata);
508 return GNUTLS_E_BASE64_DECODING_ERROR;
509 }
510
511 if ((ret = _gnutls_base64_decode (kdata, kdata_size, result)) < 0)
512 {
513 gnutls_free (kdata);
514 gnutls_assert ();
515 return GNUTLS_E_BASE64_DECODING_ERROR;
516 }
517 gnutls_free (kdata);
518
519 return ret;
520}
521
522/**
523 * gnutls_pem_base64_decode - This function will decode base64 encoded data
524 * @header: A null terminated string with the PEM header (eg. CERTIFICATE)
525 * @b64_data: contain the encoded data
526 * @result: the place where decoded data will be copied
527 * @result_size: holds the size of the result
528 *
529 * This function will decode the given encoded data. If the header given
530 * is non null this function will search for "-----BEGIN header" and decode
531 * only this part. Otherwise it will decode the first PEM packet found.
532 *
533 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the buffer given is not long enough,
534 * or 0 on success.
535 **/
536int
537gnutls_pem_base64_decode (const char *header,
538 const gnutls_datum_t * b64_data,
539 unsigned char *result, size_t * result_size)
540{
541 opaque *ret;
542 int size;
543
544 size =
545 _gnutls_fbase64_decode (header, b64_data->data, b64_data->size, &ret);
546 if (size < 0)
547 return size;
548
549 if (result == NULL || *result_size < (unsigned) size)
550 {
551 gnutls_free (ret);
552 *result_size = size;
553 return GNUTLS_E_SHORT_MEMORY_BUFFER;
554 }
555 else
556 {
557 memcpy (result, ret, size);
558 gnutls_free (ret);
559 *result_size = size;
560 }
561
562 return 0;
563}
564
565/**
566 * gnutls_pem_base64_decode_alloc - This function will decode base64 encoded data
567 * @header: The PEM header (eg. CERTIFICATE)
568 * @b64_data: contains the encoded data
569 * @result: the place where decoded data lie
570 *
571 * This function will decode the given encoded data. The decoded data
572 * will be allocated, and stored into result.
573 * If the header given is non null this function will search for
574 * "-----BEGIN header" and decode only this part. Otherwise it will decode the
575 * first PEM packet found.
576 *
577 * You should use gnutls_free() to free the returned data.
578 *
579 **/
580int
581gnutls_pem_base64_decode_alloc (const char *header,
582 const gnutls_datum_t * b64_data,
583 gnutls_datum_t * result)
584{
585 opaque *ret;
586 int size;
587
588 if (result == NULL)
589 return GNUTLS_E_INVALID_REQUEST;
590
591 size =
592 _gnutls_fbase64_decode (header, b64_data->data, b64_data->size, &ret);
593 if (size < 0)
594 return size;
595
596 result->data = ret;
597 result->size = size;
598 return 0;
599}
diff --git a/src/daemon/https/tls/x509_b64.h b/src/daemon/https/tls/x509_b64.h
new file mode 100644
index 00000000..539bec42
--- /dev/null
+++ b/src/daemon/https/tls/x509_b64.h
@@ -0,0 +1,45 @@
1/*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25int _gnutls_base64_encode (const uint8_t * data, size_t data_size,
26 uint8_t ** result);
27int _gnutls_fbase64_encode (const char *msg, const uint8_t * data,
28 int data_size, uint8_t ** result);
29int _gnutls_base64_decode (const uint8_t * data, size_t data_size,
30 uint8_t ** result);
31int _gnutls_fbase64_decode (const char *header, const uint8_t * data,
32 size_t data_size, uint8_t ** result);
33
34#define B64SIZE( data_size) ((data_size%3==0)?((data_size*4)/3):(4+((data_size/3)*4)))
35
36/* The size for B64 encoding + newlines plus header
37 */
38
39#define HEADSIZE( hsize) \
40 sizeof("-----BEGIN ")-1+sizeof("-----")-1+ \
41 sizeof("\n-----END ")-1+sizeof("-----\n")-1+hsize+hsize
42
43#define B64FSIZE( hsize, dsize) \
44 (B64SIZE(dsize) + HEADSIZE(hsize) + /*newlines*/ \
45 B64SIZE(dsize)/64 + (((B64SIZE(dsize) % 64) > 0) ? 1 : 0))
diff --git a/src/daemon/https/tls_test.c b/src/daemon/https/tls_test.c
new file mode 100644
index 00000000..492521e8
--- /dev/null
+++ b/src/daemon/https/tls_test.c
@@ -0,0 +1,348 @@
1/*
2 * Copyright (C) 2000,2001,2002,2003,2006,2007 Nikos Mavrogiannopoulos
3 * Copyright (C) 2004,2005 Free Software Foundation
4 *
5 * This file is part of GNUTLS.
6 *
7 * GNUTLS is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * GNUTLS is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <config.h>
22#include <stdio.h>
23#include <errno.h>
24#include <stdlib.h>
25#include <sys/types.h>
26#include <string.h>
27#include <gnutls.h>
28#include <extra.h>
29#include <sys/time.h>
30#include <tests.h>
31#include <common.h>
32#include <tls_test-gaa.h>
33
34#ifndef SHUT_WR
35# define SHUT_WR 1
36#endif
37
38#ifndef SHUT_RDWR
39# define SHUT_RDWR 2
40#endif
41
42#define SA struct sockaddr
43#define ERR(err,s) if (err==-1) {perror(s);return(1);}
44#define MAX_BUF 4096
45
46/* global stuff here */
47int resume;
48char *hostname = NULL;
49int port;
50int record_max_size;
51int fingerprint;
52static int debug;
53
54gnutls_srp_client_credentials_t srp_cred;
55gnutls_anon_client_credentials_t anon_cred;
56gnutls_certificate_credentials_t xcred;
57
58/* end of global stuff */
59
60
61int verbose = 0;
62
63extern int tls1_ok;
64extern int tls1_1_ok;
65extern int ssl3_ok;
66
67static void
68tls_log_func (int level, const char *str)
69{
70 fprintf (stderr, "|<%d>| %s", level, str);
71}
72
73typedef test_code_t (*TEST_FUNC) (gnutls_session_t);
74
75typedef struct
76{
77 char *test_name;
78 TEST_FUNC func;
79 char *suc_str;
80 char *fail_str;
81 char *unsure_str;
82} TLS_TEST;
83
84static const TLS_TEST tls_tests[] = {
85 {"for TLS 1.1 support", test_tls1_1, "yes", "no", "dunno"},
86 {"fallback from TLS 1.1 to", test_tls1_1_fallback, "TLS 1.0", "failed",
87 "SSL 3.0"},
88 {"for TLS 1.0 support", test_tls1, "yes", "no", "dunno"},
89 {"for SSL 3.0 support", test_ssl3, "yes", "no", "dunno"},
90 {"for HTTPS server name", test_server, "", "failed", "not checked"},
91 {"for version rollback bug in RSA PMS", test_rsa_pms, "no", "yes",
92 "dunno"},
93 {"for version rollback bug in Client Hello", test_version_rollback,
94 "no", "yes", "dunno"},
95
96 /* this test will disable TLS 1.0 if the server is
97 * buggy */
98 {"whether we need to disable TLS 1.0", test_tls_disable, "no", "yes",
99 "dunno"},
100
101 {"whether the server ignores the RSA PMS version",
102 test_rsa_pms_version_check, "yes", "no", "dunno"},
103 {"whether the server can accept Hello Extensions",
104 test_hello_extension, "yes", "no", "dunno"},
105 {"whether the server can accept cipher suites not in SSL 3.0 spec",
106 test_unknown_ciphersuites, "yes", "no", "dunno"},
107 {"whether the server can accept a bogus TLS record version in the client hello", test_version_oob, "yes", "no", "dunno"},
108 {"for certificate information", test_certificate, "", "", ""},
109 {"for trusted CAs", test_server_cas, "", "", ""},
110 {"whether the server understands TLS closure alerts", test_bye, "yes",
111 "no", "partially"},
112 /* the fact that is after the closure alert test does matter.
113 */
114 {"whether the server supports session resumption",
115 test_session_resume2, "yes", "no", "dunno"},
116 {"for export-grade ciphersuite support", test_export, "yes", "no",
117 "dunno"},
118 {"RSA-export ciphersuite info", test_export_info, "", "N/A", "N/A"},
119#ifdef ENABLE_ANON
120 {"for anonymous authentication support", test_anonymous, "yes", "no",
121 "dunno"},
122 {"anonymous Diffie Hellman group info", test_dhe_group, "", "N/A",
123 "N/A"},
124#endif
125 {"for ephemeral Diffie Hellman support", test_dhe, "yes", "no",
126 "dunno"},
127 {"ephemeral Diffie Hellman group info", test_dhe_group, "", "N/A",
128 "N/A"},
129 {"for AES cipher support (TLS extension)", test_aes, "yes", "no",
130 "dunno"},
131#ifdef ENABLE_CAMELLIA
132 {"for CAMELLIA cipher support (TLS extension)", test_camellia, "yes", "no",
133 "dunno"},
134#endif
135 {"for 3DES cipher support", test_3des, "yes", "no", "dunno"},
136 {"for ARCFOUR 128 cipher support", test_arcfour, "yes", "no", "dunno"},
137 {"for ARCFOUR 40 cipher support", test_arcfour_40, "yes", "no",
138 "dunno"},
139 {"for MD5 MAC support", test_md5, "yes", "no", "dunno"},
140 {"for SHA1 MAC support", test_sha, "yes", "no", "dunno"},
141#ifdef HAVE_LIBZ
142 {"for ZLIB compression support (TLS extension)", test_zlib, "yes",
143 "no", "dunno"},
144#endif
145 {"for LZO compression support (GnuTLS extension)", test_lzo, "yes",
146 "no", "dunno"},
147 {"for max record size (TLS extension)", test_max_record_size, "yes",
148 "no", "dunno"},
149#ifdef ENABLE_SRP
150 {"for SRP authentication support (TLS extension)", test_srp, "yes",
151 "no", "dunno"},
152#endif
153 {"for OpenPGP authentication support (TLS extension)", test_openpgp1,
154 "yes", "no", "dunno"},
155 {NULL, NULL, NULL, NULL, NULL}
156};
157
158static int tt = 0;
159const char *ip;
160
161static void gaa_parser (int argc, char **argv);
162
163int
164main (int argc, char **argv)
165{
166 int err, ret;
167 int sd, i;
168 gnutls_session_t state;
169 char buffer[MAX_BUF + 1];
170 char portname[6];
171 struct addrinfo hints, *res, *ptr;
172
173 gaa_parser (argc, argv);
174
175#ifndef _WIN32
176 signal (SIGPIPE, SIG_IGN);
177#endif
178
179 sockets_init ();
180
181 if (gnutls_global_init () < 0)
182 {
183 fprintf (stderr, "global state initialization error\n");
184 exit (1);
185 }
186
187 gnutls_global_set_log_function (tls_log_func);
188 gnutls_global_set_log_level (debug);
189
190 if (gnutls_global_init_extra () < 0)
191 {
192 fprintf (stderr, "global state initialization error\n");
193 exit (1);
194 }
195
196 printf ("Resolving '%s'...\n", hostname);
197 /* get server name */
198 memset (&hints, 0, sizeof (hints));
199 hints.ai_socktype = SOCK_STREAM;
200 hints.ai_flags = 0;
201 snprintf (portname, sizeof (portname), "%d", port);
202 if ((err = getaddrinfo (hostname, portname, &hints, &res)) != 0)
203 {
204 fprintf (stderr, "Cannot resolve %s: %s\n", hostname,
205 gai_strerror (err));
206 exit (1);
207 }
208
209 /* X509 stuff */
210 if (gnutls_certificate_allocate_credentials (&xcred) < 0)
211 { /* space for 2 certificates */
212 fprintf (stderr, "memory error\n");
213 exit (1);
214 }
215
216 /* SRP stuff */
217#ifdef ENABLE_SRP
218 if (gnutls_srp_allocate_client_credentials (&srp_cred) < 0)
219 {
220 fprintf (stderr, "memory error\n");
221 exit (1);
222 }
223#endif
224
225#ifdef ENABLE_ANON
226 /* ANON stuff */
227 if (gnutls_anon_allocate_client_credentials (&anon_cred) < 0)
228 {
229 fprintf (stderr, "memory error\n");
230 exit (1);
231 }
232#endif
233
234 i = 0;
235
236 do
237 {
238
239 if (tls_tests[i].test_name == NULL)
240 break; /* finished */
241
242 /* if neither of SSL3 and TLSv1 are supported, exit
243 */
244 if (i > 3 && tls1_1_ok == 0 && tls1_ok == 0 && ssl3_ok == 0)
245 {
246 fprintf (stderr,
247 "\nServer does not support any of SSL 3.0, TLS 1.0 and TLS 1.1\n");
248 break;
249 }
250
251 sd = -1;
252 for (ptr = res; ptr != NULL; ptr = ptr->ai_next)
253 {
254 sd = socket (ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
255 if (sd == -1)
256 {
257 continue;
258 }
259
260 getnameinfo (ptr->ai_addr, ptr->ai_addrlen, buffer, MAX_BUF,
261 NULL, 0, NI_NUMERICHOST);
262 if (tt++ == 0)
263 printf ("Connecting to '%s:%d'...\n", buffer, port);
264 if ((err = connect (sd, ptr->ai_addr, ptr->ai_addrlen)) != 0)
265 {
266 close (sd);
267 sd = -1;
268 continue;
269 }
270 }
271 ERR (err, "connect") gnutls_init (&state, GNUTLS_CLIENT);
272 gnutls_transport_set_ptr (state, (gnutls_transport_ptr_t) sd);
273
274 do
275 {
276 printf ("Checking %s...", tls_tests[i].test_name);
277
278 ret = tls_tests[i].func (state);
279
280 if (ret == TEST_SUCCEED)
281 printf (" %s\n", tls_tests[i].suc_str);
282 else if (ret == TEST_FAILED)
283 printf (" %s\n", tls_tests[i].fail_str);
284 else if (ret == TEST_UNSURE)
285 printf (" %s\n", tls_tests[i].unsure_str);
286 else if (ret == TEST_IGNORE)
287 {
288 printf (" N/A\n");
289 i++;
290 }
291 }
292 while (ret == TEST_IGNORE && tls_tests[i].test_name != NULL);
293
294 gnutls_deinit (state);
295
296 shutdown (sd, SHUT_RDWR); /* no more receptions */
297 close (sd);
298
299 i++;
300 }
301 while (1);
302
303 freeaddrinfo (res);
304
305#ifdef ENABLE_SRP
306 gnutls_srp_free_client_credentials (srp_cred);
307#endif
308 gnutls_certificate_free_credentials (xcred);
309#ifdef ENABLE_ANON
310 gnutls_anon_free_client_credentials (anon_cred);
311#endif
312 gnutls_global_deinit ();
313
314 return 0;
315}
316
317static gaainfo info;
318void
319gaa_parser (int argc, char **argv)
320{
321 if (gaa (argc, argv, &info) != -1)
322 {
323 fprintf (stderr,
324 "Error in the arguments. Use the -h or --help parameters to get more info.\n");
325 exit (1);
326 }
327
328 port = info.pp;
329 if (info.rest_args == NULL)
330 hostname = "localhost";
331 else
332 hostname = info.rest_args;
333
334 debug = info.debug;
335
336 verbose = info.more_info;
337
338}
339
340void
341tls_test_version (void)
342{
343 const char *v = gnutls_check_version (NULL);
344
345 printf ("gnutls-cli-debug (GnuTLS) %s\n", LIBGNUTLS_VERSION);
346 if (strcmp (v, LIBGNUTLS_VERSION) != 0)
347 printf ("libgnutls %s\n", v);
348}
diff --git a/src/daemon/https/x509/Makefile.am b/src/daemon/https/x509/Makefile.am
new file mode 100644
index 00000000..c3a30f03
--- /dev/null
+++ b/src/daemon/https/x509/Makefile.am
@@ -0,0 +1,36 @@
1
2AM_CPPFLAGS = -I./includes \
3-I$(top_srcdir)/src/daemon/https/includes \
4-I$(top_srcdir)/src/daemon/https/minitasn1 \
5-I$(top_srcdir)/src/daemon/https/lgl \
6-I$(top_srcdir)/src/daemon/https/x509 \
7-I$(top_srcdir)/src/daemon/https/tls
8
9noinst_LTLIBRARIES = libx509.la
10
11libx509_la_LDFLAGS = -lgcrypt
12# -l $(top_srcdir)/src/daemon/https/lgl/liblgl.la
13
14libx509_la_SOURCES = \
15common.c \
16crq.c \
17crl.c \
18crl_write.c \
19dn.c \
20dsa.c \
21extensions.c \
22mpi.c \
23pkcs12_bag.c \
24pkcs12.c \
25pkcs12_encr.c \
26pkcs7.c \
27x509_privkey.c \
28privkey_pkcs8.c \
29rfc2818_hostname.c \
30sign.c \
31x509_verify.c \
32x509.c \
33x509_write.c
34# output.c
35
36
diff --git a/src/daemon/https/x509/common.c b/src/daemon/https/x509/common.c
new file mode 100644
index 00000000..98a655c7
--- /dev/null
+++ b/src/daemon/https/x509/common.c
@@ -0,0 +1,1491 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26#include <libtasn1.h>
27#include <gnutls_datum.h>
28#include <gnutls_global.h>
29#include <gnutls_errors.h>
30#include <gnutls_str.h>
31#include <gnutls_x509.h>
32#include <gnutls_num.h>
33#include <x509_b64.h>
34#include <common.h>
35#include <mpi.h>
36#include <time.h>
37
38typedef struct _oid2string
39{
40 const char *oid;
41 const char *ldap_desc;
42 int choice; /* of type DirectoryString */
43 int printable;
44} oid2string;
45
46/* This list contains all the OIDs that may be
47 * contained in a rdnSequence and are printable.
48 */
49static const oid2string _oid2str[] = {
50 /* PKIX
51 */
52 {"1.3.6.1.5.5.7.9.1",
53 "dateOfBirth",
54 0,
55 1},
56 {"1.3.6.1.5.5.7.9.2",
57 "placeOfBirth",
58 0,
59 1},
60 {"1.3.6.1.5.5.7.9.3",
61 "gender",
62 0,
63 1},
64 {"1.3.6.1.5.5.7.9.4",
65 "countryOfCitizenship",
66 0,
67 1},
68 {"1.3.6.1.5.5.7.9.5",
69 "countryOfResidence",
70 0,
71 1},
72
73 {"2.5.4.6",
74 "C",
75 0,
76 1},
77 {"2.5.4.9",
78 "STREET",
79 1,
80 1},
81 {"2.5.4.12",
82 "T",
83 1,
84 1},
85 {"2.5.4.10",
86 "O",
87 1,
88 1},
89 {"2.5.4.11",
90 "OU",
91 1,
92 1},
93 {"2.5.4.3",
94 "CN",
95 1,
96 1},
97 {"2.5.4.7",
98 "L",
99 1,
100 1},
101 {"2.5.4.8",
102 "ST",
103 1,
104 1},
105
106 {"2.5.4.5",
107 "serialNumber",
108 0,
109 1},
110 {"2.5.4.20",
111 "telephoneNumber",
112 0,
113 1},
114 {"2.5.4.4",
115 "surName",
116 1,
117 1},
118 {"2.5.4.43",
119 "initials",
120 1,
121 1},
122 {"2.5.4.44",
123 "generationQualifier",
124 1,
125 1},
126 {"2.5.4.42",
127 "givenName",
128 1,
129 1},
130 {"2.5.4.65",
131 "pseudonym",
132 1,
133 1},
134 {"2.5.4.46",
135 "dnQualifier",
136 0,
137 1},
138
139 {"0.9.2342.19200300.100.1.25",
140 "DC",
141 0,
142 1},
143 {"0.9.2342.19200300.100.1.1",
144 "UID",
145 1,
146 1},
147
148 /* PKCS #9
149 */
150 {"1.2.840.113549.1.9.1",
151 "EMAIL",
152 0,
153 1},
154 {"1.2.840.113549.1.9.7",
155 NULL,
156 1,
157 1},
158
159 /* friendly name */
160 {"1.2.840.113549.1.9.20",
161 NULL,
162 0,
163 1},
164 {NULL,
165 NULL,
166 0,
167 0}
168};
169
170/* Returns 1 if the data defined by the OID are printable.
171 */
172int
173_gnutls_x509_oid_data_printable (const char *oid)
174{
175 int i = 0;
176
177 do
178 {
179 if (strcmp (_oid2str[i].oid, oid) == 0)
180 return _oid2str[i].printable;
181 i++;
182 }
183 while (_oid2str[i].oid != NULL);
184
185 return 0;
186}
187
188/**
189 * gnutls_x509_dn_oid_known - This function will return true if the given OID is known
190 * @oid: holds an Object Identifier in a null terminated string
191 *
192 * This function will inform about known DN OIDs. This is useful since functions
193 * like gnutls_x509_crt_set_dn_by_oid() use the information on known
194 * OIDs to properly encode their input. Object Identifiers that are not
195 * known are not encoded by these functions, and their input is stored directly
196 * into the ASN.1 structure. In that case of unknown OIDs, you have
197 * the responsibility of DER encoding your data.
198 *
199 * Returns 1 on known OIDs and 0 otherwise.
200 *
201 **/
202int
203gnutls_x509_dn_oid_known (const char *oid)
204{
205 int i = 0;
206
207 do
208 {
209 if (strcmp (_oid2str[i].oid, oid) == 0)
210 return 1;
211 i++;
212 }
213 while (_oid2str[i].oid != NULL);
214
215 return 0;
216}
217
218/* Returns 1 if the data defined by the OID are of a choice
219 * type.
220 */
221int
222_gnutls_x509_oid_data_choice (const char *oid)
223{
224 int i = 0;
225
226 do
227 {
228 if (strcmp (_oid2str[i].oid, oid) == 0)
229 return _oid2str[i].choice;
230 i++;
231 }
232 while (_oid2str[i].oid != NULL);
233
234 return 0;
235}
236
237const char *
238_gnutls_x509_oid2ldap_string (const char *oid)
239{
240 int i = 0;
241
242 do
243 {
244 if (strcmp (_oid2str[i].oid, oid) == 0)
245 return _oid2str[i].ldap_desc;
246 i++;
247 }
248 while (_oid2str[i].oid != NULL);
249
250 return NULL;
251}
252
253/* This function will convert an attribute value, specified by the OID,
254 * to a string. The result will be a null terminated string.
255 *
256 * res may be null. This will just return the res_size, needed to
257 * hold the string.
258 */
259int
260_gnutls_x509_oid_data2string (const char *oid,
261 void *value,
262 int value_size, char *res, size_t * res_size)
263{
264 char str[MAX_STRING_LEN], tmpname[128];
265 const char *ANAME = NULL;
266 int CHOICE = -1, len = -1, result;
267 ASN1_TYPE tmpasn = ASN1_TYPE_EMPTY;
268 char asn1_err[MAX_ERROR_DESCRIPTION_SIZE] = "";
269
270 if (value == NULL || value_size <= 0 || res_size == NULL)
271 {
272 gnutls_assert ();
273 return GNUTLS_E_INVALID_REQUEST;
274 }
275
276 if (_gnutls_x509_oid_data_printable (oid) == 0)
277 {
278 gnutls_assert ();
279 return GNUTLS_E_INTERNAL_ERROR;
280 }
281
282 ANAME = asn1_find_structure_from_oid (_gnutls_get_pkix (), oid);
283 CHOICE = _gnutls_x509_oid_data_choice (oid);
284
285 if (ANAME == NULL)
286 {
287 gnutls_assert ();
288 return GNUTLS_E_INTERNAL_ERROR;
289 }
290
291 _gnutls_str_cpy (str, sizeof (str), "PKIX1.");
292 _gnutls_str_cat (str, sizeof (str), ANAME);
293
294 if ((result = asn1_create_element (_gnutls_get_pkix (), str,
295 &tmpasn)) != ASN1_SUCCESS)
296 {
297 gnutls_assert ();
298 return _gnutls_asn2err (result);
299 }
300
301 if ((result = asn1_der_decoding (&tmpasn, value, value_size, asn1_err))
302 != ASN1_SUCCESS)
303 {
304 gnutls_assert ();
305 _gnutls_x509_log ("asn1_der_decoding: %s:%s\n", str, asn1_err);
306 asn1_delete_structure (&tmpasn);
307 return _gnutls_asn2err (result);
308 }
309
310 /* If this is a choice then we read the choice. Otherwise it
311 * is the value;
312 */
313 len = sizeof (str) - 1;
314 if ((result = asn1_read_value (tmpasn, "", str, &len)) != ASN1_SUCCESS)
315 { /* CHOICE */
316 gnutls_assert ();
317 asn1_delete_structure (&tmpasn);
318 return _gnutls_asn2err (result);
319 }
320
321 if (CHOICE == 0)
322 {
323 str[len] = 0;
324
325 if (res)
326 _gnutls_str_cpy (res, *res_size, str);
327 *res_size = len;
328
329 asn1_delete_structure (&tmpasn);
330 }
331 else
332 { /* CHOICE */
333 int non_printable = 0, teletex = 0;
334 str[len] = 0;
335
336 /* Note that we do not support strings other than
337 * UTF-8 (thus ASCII as well).
338 */
339 if (strcmp (str, "printableString") != 0
340 && strcmp (str, "ia5String") != 0
341 && strcmp (str, "utf8String") != 0)
342 {
343 non_printable = 1;
344 }
345 if (strcmp (str, "teletexString") == 0)
346 teletex = 1;
347
348 _gnutls_str_cpy (tmpname, sizeof (tmpname), str);
349
350 len = sizeof (str) - 1;
351 if ((result = asn1_read_value (tmpasn, tmpname, str, &len))
352 != ASN1_SUCCESS)
353 {
354 asn1_delete_structure (&tmpasn);
355 return _gnutls_asn2err (result);
356 }
357
358 asn1_delete_structure (&tmpasn);
359
360 if (teletex != 0)
361 {
362 int ascii = 0, i;
363 /* HACK: if the teletex string contains only ascii
364 * characters then treat it as printable.
365 */
366 for (i = 0; i < len; i++)
367 if (!isascii (str[i]))
368 ascii = 1;
369
370 if (ascii == 0)
371 non_printable = 0;
372 }
373
374 if (res)
375 {
376 if (non_printable == 0)
377 {
378 str[len] = 0;
379 _gnutls_str_cpy (res, *res_size, str);
380 *res_size = len;
381 }
382 else
383 {
384 result = _gnutls_x509_data2hex (str, len, res, res_size);
385 if (result < 0)
386 {
387 gnutls_assert ();
388 return result;
389 }
390 }
391 }
392
393 }
394
395 return 0;
396}
397
398/* Converts a data string to an LDAP rfc2253 hex string
399 * something like '#01020304'
400 */
401int
402_gnutls_x509_data2hex (const opaque * data,
403 size_t data_size, opaque * out, size_t * sizeof_out)
404{
405 char *res;
406 char escaped[MAX_STRING_LEN];
407
408 if (2 * data_size + 1 > MAX_STRING_LEN)
409 {
410 gnutls_assert ();
411 return GNUTLS_E_INTERNAL_ERROR;
412 }
413
414 res = _gnutls_bin2hex (data, data_size, escaped, sizeof (escaped));
415
416 if (res)
417 {
418 unsigned int size = strlen (res) + 1;
419 if (size + 1 > *sizeof_out)
420 {
421 *sizeof_out = size;
422 return GNUTLS_E_SHORT_MEMORY_BUFFER;
423 }
424 *sizeof_out = size; /* -1 for the null +1 for the '#' */
425
426 if (out)
427 {
428 strcpy (out, "#");
429 strcat (out, res);
430 }
431
432 return 0;
433 }
434 else
435 {
436 gnutls_assert ();
437 return GNUTLS_E_INTERNAL_ERROR;
438 }
439
440 return 0;
441}
442
443/* TIME functions
444 * Convertions between generalized or UTC time to time_t
445 *
446 */
447
448/* This is an emulations of the struct tm.
449 * Since we do not use libc's functions, we don't need to
450 * depend on the libc structure.
451 */
452typedef struct fake_tm
453{
454 int tm_mon;
455 int tm_year; /* FULL year - ie 1971 */
456 int tm_mday;
457 int tm_hour;
458 int tm_min;
459 int tm_sec;
460} fake_tm;
461
462/* The mktime_utc function is due to Russ Allbery (rra@stanford.edu),
463 * who placed it under public domain:
464 */
465
466/* The number of days in each month.
467 */
468static const int MONTHDAYS[] = { 31,
469 28,
470 31,
471 30,
472 31,
473 30,
474 31,
475 31,
476 30,
477 31,
478 30,
479 31
480};
481
482/* Whether a given year is a leap year. */
483#define ISLEAP(year) \
484 (((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0))
485
486/*
487 ** Given a struct tm representing a calendar time in UTC, convert it to
488 ** seconds since epoch. Returns (time_t) -1 if the time is not
489 ** convertable. Note that this function does not canonicalize the provided
490 ** struct tm, nor does it allow out of range values or years before 1970.
491 */
492static time_t
493mktime_utc (const struct fake_tm *tm)
494{
495 time_t result = 0;
496 int i;
497
498 /* We do allow some ill-formed dates, but we don't do anything special
499 * with them and our callers really shouldn't pass them to us. Do
500 * explicitly disallow the ones that would cause invalid array accesses
501 * or other algorithm problems.
502 */
503 if (tm->tm_mon < 0 || tm->tm_mon > 11 || tm->tm_year < 1970)
504 return (time_t) - 1;
505
506 /* Convert to a time_t.
507 */
508 for (i = 1970; i < tm->tm_year; i++)
509 result += 365 + ISLEAP (i);
510 for (i = 0; i < tm->tm_mon; i++)
511 result += MONTHDAYS[i];
512 if (tm->tm_mon > 1 && ISLEAP (tm->tm_year))
513 result++;
514 result = 24 * (result + tm->tm_mday - 1) + tm->tm_hour;
515 result = 60 * result + tm->tm_min;
516 result = 60 * result + tm->tm_sec;
517 return result;
518}
519
520/* this one will parse dates of the form:
521 * month|day|hour|minute|sec* (2 chars each)
522 * and year is given. Returns a time_t date.
523 */
524time_t
525_gnutls_x509_time2gtime (const char *ttime, int year)
526{
527 char xx[3];
528 struct fake_tm etime;
529 time_t ret;
530
531 if (strlen (ttime) < 8)
532 {
533 gnutls_assert ();
534 return (time_t) - 1;
535 }
536
537 etime.tm_year = year;
538
539 /* In order to work with 32 bit
540 * time_t.
541 */
542 if (sizeof (time_t) <= 4 && etime.tm_year >= 2038)
543 return (time_t) 2145914603; /* 2037-12-31 23:23:23 */
544
545 xx[2] = 0;
546
547 /* get the month
548 */
549 memcpy (xx, ttime, 2); /* month */
550 etime.tm_mon = atoi (xx) - 1;
551 ttime += 2;
552
553 /* get the day
554 */
555 memcpy (xx, ttime, 2); /* day */
556 etime.tm_mday = atoi (xx);
557 ttime += 2;
558
559 /* get the hour
560 */
561 memcpy (xx, ttime, 2); /* hour */
562 etime.tm_hour = atoi (xx);
563 ttime += 2;
564
565 /* get the minutes
566 */
567 memcpy (xx, ttime, 2); /* minutes */
568 etime.tm_min = atoi (xx);
569 ttime += 2;
570
571 if (strlen (ttime) >= 2)
572 {
573 memcpy (xx, ttime, 2);
574 etime.tm_sec = atoi (xx);
575 ttime += 2;
576 }
577 else
578 etime.tm_sec = 0;
579
580 ret = mktime_utc (&etime);
581
582 return ret;
583}
584
585/* returns a time_t value that contains the given time.
586 * The given time is expressed as:
587 * YEAR(2)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2)|SEC(2)*
588 *
589 * (seconds are optional)
590 */
591time_t
592_gnutls_x509_utcTime2gtime (const char *ttime)
593{
594 char xx[3];
595 int year;
596
597 if (strlen (ttime) < 10)
598 {
599 gnutls_assert ();
600 return (time_t) - 1;
601 }
602 xx[2] = 0;
603 /* get the year
604 */
605 memcpy (xx, ttime, 2); /* year */
606 year = atoi (xx);
607 ttime += 2;
608
609 if (year > 49)
610 year += 1900;
611 else
612 year += 2000;
613
614 return _gnutls_x509_time2gtime (ttime, year);
615}
616
617/* returns a time value that contains the given time.
618 * The given time is expressed as:
619 * YEAR(2)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2)|SEC(2)
620 */
621int
622_gnutls_x509_gtime2utcTime (time_t gtime, char *str_time, int str_time_size)
623{
624 size_t ret;
625
626#ifdef HAVE_GMTIME_R
627 struct tm _tm;
628
629 gmtime_r (&gtime, &_tm);
630
631 ret = strftime (str_time, str_time_size, "%y%m%d%H%M%SZ", &_tm);
632#else
633 struct tm *_tm;
634
635 _tm = gmtime (&gtime);
636
637 ret = strftime (str_time, str_time_size, "%y%m%d%H%M%SZ", _tm);
638#endif
639
640 if (!ret)
641 {
642 gnutls_assert ();
643 return GNUTLS_E_SHORT_MEMORY_BUFFER;
644 }
645
646 return 0;
647
648}
649
650/* returns a time_t value that contains the given time.
651 * The given time is expressed as:
652 * YEAR(4)|MONTH(2)|DAY(2)|HOUR(2)|MIN(2)|SEC(2)*
653 */
654time_t
655_gnutls_x509_generalTime2gtime (const char *ttime)
656{
657 char xx[5];
658 int year;
659
660 if (strlen (ttime) < 12)
661 {
662 gnutls_assert ();
663 return (time_t) - 1;
664 }
665
666 if (strchr (ttime, 'Z') == 0)
667 {
668 gnutls_assert ();
669 /* sorry we don't support it yet
670 */
671 return (time_t) - 1;
672 }
673 xx[4] = 0;
674
675 /* get the year
676 */
677 memcpy (xx, ttime, 4); /* year */
678 year = atoi (xx);
679 ttime += 4;
680
681 return _gnutls_x509_time2gtime (ttime, year);
682
683}
684
685/* Extracts the time in time_t from the ASN1_TYPE given. When should
686 * be something like "tbsCertList.thisUpdate".
687 */
688#define MAX_TIME 64
689time_t
690_gnutls_x509_get_time (ASN1_TYPE c2, const char *when)
691{
692 char ttime[MAX_TIME];
693 char name[128];
694 time_t c_time = (time_t) - 1;
695 int len, result;
696
697 _gnutls_str_cpy (name, sizeof (name), when);
698
699 len = sizeof (ttime) - 1;
700 if ((result = asn1_read_value (c2, name, ttime, &len)) < 0)
701 {
702 gnutls_assert ();
703 return (time_t) (-1);
704 }
705
706 /* CHOICE */
707 if (strcmp (ttime, "generalTime") == 0)
708 {
709
710 _gnutls_str_cat (name, sizeof (name), ".generalTime");
711 len = sizeof (ttime) - 1;
712 result = asn1_read_value (c2, name, ttime, &len);
713 if (result == ASN1_SUCCESS)
714 c_time = _gnutls_x509_generalTime2gtime (ttime);
715 }
716 else
717 { /* UTCTIME */
718
719 _gnutls_str_cat (name, sizeof (name), ".utcTime");
720 len = sizeof (ttime) - 1;
721 result = asn1_read_value (c2, name, ttime, &len);
722 if (result == ASN1_SUCCESS)
723 c_time = _gnutls_x509_utcTime2gtime (ttime);
724 }
725
726 /* We cannot handle dates after 2031 in 32 bit machines.
727 * a time_t of 64bits has to be used.
728 */
729
730 if (result != ASN1_SUCCESS)
731 {
732 gnutls_assert ();
733 return (time_t) (-1);
734 }
735 return c_time;
736}
737
738/* Sets the time in time_t in the ASN1_TYPE given. Where should
739 * be something like "tbsCertList.thisUpdate".
740 */
741int
742_gnutls_x509_set_time (ASN1_TYPE c2, const char *where, time_t tim)
743{
744 char str_time[MAX_TIME];
745 char name[128];
746 int result, len;
747
748 _gnutls_str_cpy (name, sizeof (name), where);
749
750 if ((result = asn1_write_value (c2, name, "utcTime", 1)) < 0)
751 {
752 gnutls_assert ();
753 return _gnutls_asn2err (result);
754 }
755
756 result = _gnutls_x509_gtime2utcTime (tim, str_time, sizeof (str_time));
757 if (result < 0)
758 {
759 gnutls_assert ();
760 return result;
761 }
762
763 _gnutls_str_cat (name, sizeof (name), ".utcTime");
764
765 len = strlen (str_time);
766 result = asn1_write_value (c2, name, str_time, len);
767 if (result != ASN1_SUCCESS)
768 {
769 gnutls_assert ();
770 return _gnutls_asn2err (result);
771 }
772
773 return 0;
774}
775
776gnutls_x509_subject_alt_name_t
777_gnutls_x509_san_find_type (char *str_type)
778{
779 if (strcmp (str_type, "dNSName") == 0)
780 return GNUTLS_SAN_DNSNAME;
781 if (strcmp (str_type, "rfc822Name") == 0)
782 return GNUTLS_SAN_RFC822NAME;
783 if (strcmp (str_type, "uniformResourceIdentifier") == 0)
784 return GNUTLS_SAN_URI;
785 if (strcmp (str_type, "iPAddress") == 0)
786 return GNUTLS_SAN_IPADDRESS;
787 if (strcmp (str_type, "otherName") == 0)
788 return GNUTLS_SAN_OTHERNAME;
789 if (strcmp (str_type, "directoryName") == 0)
790 return GNUTLS_SAN_DN;
791 return (gnutls_x509_subject_alt_name_t) - 1;
792}
793
794/* A generic export function. Will export the given ASN.1 encoded data
795 * to PEM or DER raw data.
796 */
797int
798_gnutls_x509_export_int (ASN1_TYPE asn1_data,
799 gnutls_x509_crt_fmt_t format,
800 char *pem_header,
801 unsigned char *output_data,
802 size_t * output_data_size)
803{
804 int result, len;
805
806 if (format == GNUTLS_X509_FMT_DER)
807 {
808
809 if (output_data == NULL)
810 *output_data_size = 0;
811
812 len = *output_data_size;
813
814 if ((result = asn1_der_coding (asn1_data, "", output_data, &len,
815 NULL)) != ASN1_SUCCESS)
816 {
817 *output_data_size = len;
818 if (result == ASN1_MEM_ERROR)
819 {
820 return GNUTLS_E_SHORT_MEMORY_BUFFER;
821 }
822 gnutls_assert ();
823 return _gnutls_asn2err (result);
824 }
825
826 *output_data_size = len;
827
828 }
829 else
830 { /* PEM */
831 opaque *out;
832 gnutls_datum_t tmp;
833
834 result = _gnutls_x509_der_encode (asn1_data, "", &tmp, 0);
835 if (result < 0)
836 {
837 gnutls_assert ();
838 return result;
839 }
840
841 result = _gnutls_fbase64_encode (pem_header, tmp.data, tmp.size, &out);
842
843 _gnutls_free_datum (&tmp);
844
845 if (result < 0)
846 {
847 gnutls_assert ();
848 return result;
849 }
850
851 if (result == 0)
852 { /* oooops */
853 gnutls_assert ();
854 return GNUTLS_E_INTERNAL_ERROR;
855 }
856
857 if ((unsigned) result > *output_data_size)
858 {
859 gnutls_assert ();
860 gnutls_free (out);
861 *output_data_size = result;
862 return GNUTLS_E_SHORT_MEMORY_BUFFER;
863 }
864
865 *output_data_size = result;
866
867 if (output_data)
868 {
869 memcpy (output_data, out, result);
870
871 /* do not include the null character into output size.
872 */
873 *output_data_size = result - 1;
874 }
875 gnutls_free (out);
876
877 }
878
879 return 0;
880}
881
882/* Decodes an octet string. Leave string_type null for a normal
883 * octet string. Otherwise put something like BMPString, PrintableString
884 * etc.
885 */
886int
887_gnutls_x509_decode_octet_string (const char *string_type,
888 const opaque * der,
889 size_t der_size,
890 opaque * output, size_t * output_size)
891{
892 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
893 int result, tmp_output_size;
894 char strname[64];
895
896 if (string_type == NULL)
897 _gnutls_str_cpy (strname, sizeof (strname), "PKIX1.pkcs-7-Data");
898 else
899 {
900 _gnutls_str_cpy (strname, sizeof (strname), "PKIX1.");
901 _gnutls_str_cat (strname, sizeof (strname), string_type);
902 }
903
904 if ((result =
905 asn1_create_element (_gnutls_get_pkix (), strname,
906 &c2)) != ASN1_SUCCESS)
907 {
908 gnutls_assert ();
909 result = _gnutls_asn2err (result);
910 goto cleanup;
911 }
912
913 result = asn1_der_decoding (&c2, der, der_size, NULL);
914 if (result != ASN1_SUCCESS)
915 {
916 gnutls_assert ();
917 result = _gnutls_asn2err (result);
918 goto cleanup;
919 }
920
921 tmp_output_size = *output_size;
922 result = asn1_read_value (c2, "", output, &tmp_output_size);
923 *output_size = tmp_output_size;
924
925 if (result != ASN1_SUCCESS)
926 {
927 gnutls_assert ();
928 result = _gnutls_asn2err (result);
929 goto cleanup;
930 }
931
932 return 0;
933
934cleanup:if (c2)
935 asn1_delete_structure (&c2);
936
937 return result;
938}
939
940/* Reads a value from an ASN1 tree, and puts the output
941 * in an allocated variable in the given datum.
942 * flags == 0 do nothing with the DER output
943 * flags == 1 parse the DER output as OCTET STRING
944 * flags == 2 the value is a BIT STRING
945 */
946int
947_gnutls_x509_read_value (ASN1_TYPE c,
948 const char *root, gnutls_datum_t * ret, int flags)
949{
950 int len = 0, result;
951 size_t slen;
952 opaque *tmp = NULL;
953
954 result = asn1_read_value (c, root, NULL, &len);
955 if (result != ASN1_MEM_ERROR)
956 {
957 gnutls_assert ();
958 result = _gnutls_asn2err (result);
959 return result;
960 }
961
962 if (flags == 2)
963 len /= 8;
964
965 tmp = gnutls_malloc (len);
966 if (tmp == NULL)
967 {
968 gnutls_assert ();
969 result = GNUTLS_E_MEMORY_ERROR;
970 goto cleanup;
971 }
972
973 result = asn1_read_value (c, root, tmp, &len);
974 if (result != ASN1_SUCCESS)
975 {
976 gnutls_assert ();
977 result = _gnutls_asn2err (result);
978 goto cleanup;
979 }
980
981 if (flags == 2)
982 len /= 8;
983
984 /* Extract the OCTET STRING.
985 */
986
987 if (flags == 1)
988 {
989 slen = len;
990 result = _gnutls_x509_decode_octet_string (NULL, tmp, slen, tmp, &slen);
991 if (result < 0)
992 {
993 gnutls_assert ();
994 goto cleanup;
995 }
996 len = slen;
997 }
998
999 ret->data = tmp;
1000 ret->size = len;
1001
1002 return 0;
1003
1004cleanup:gnutls_free (tmp);
1005 return result;
1006
1007}
1008
1009/* DER Encodes the src ASN1_TYPE and stores it to
1010 * the given datum. If str is non null then the data are encoded as
1011 * an OCTET STRING.
1012 */
1013int
1014_gnutls_x509_der_encode (ASN1_TYPE src,
1015 const char *src_name, gnutls_datum_t * res, int str)
1016{
1017 int size, result;
1018 int asize;
1019 opaque *data = NULL;
1020 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1021
1022 size = 0;
1023 result = asn1_der_coding (src, src_name, NULL, &size, NULL);
1024 if (result != ASN1_MEM_ERROR)
1025 {
1026 gnutls_assert ();
1027 result = _gnutls_asn2err (result);
1028 goto cleanup;
1029 }
1030
1031 /* allocate data for the der
1032 */
1033
1034 if (str)
1035 size += 16; /* for later to include the octet tags */
1036 asize = size;
1037
1038 data = gnutls_malloc (size);
1039 if (data == NULL)
1040 {
1041 gnutls_assert ();
1042 result = GNUTLS_E_MEMORY_ERROR;
1043 goto cleanup;
1044 }
1045
1046 result = asn1_der_coding (src, src_name, data, &size, NULL);
1047 if (result != ASN1_SUCCESS)
1048 {
1049 gnutls_assert ();
1050 result = _gnutls_asn2err (result);
1051 goto cleanup;
1052 }
1053
1054 if (str)
1055 {
1056 if ((result =
1057 asn1_create_element (_gnutls_get_pkix (), "PKIX1.pkcs-7-Data",
1058 &c2)) != ASN1_SUCCESS)
1059 {
1060 gnutls_assert ();
1061 result = _gnutls_asn2err (result);
1062 goto cleanup;
1063 }
1064
1065 result = asn1_write_value (c2, "", data, size);
1066 if (result != ASN1_SUCCESS)
1067 {
1068 gnutls_assert ();
1069 result = _gnutls_asn2err (result);
1070 goto cleanup;
1071 }
1072
1073 result = asn1_der_coding (c2, "", data, &asize, NULL);
1074 if (result != ASN1_SUCCESS)
1075 {
1076 gnutls_assert ();
1077 result = _gnutls_asn2err (result);
1078 goto cleanup;
1079 }
1080
1081 size = asize;
1082
1083 asn1_delete_structure (&c2);
1084 }
1085
1086 res->data = data;
1087 res->size = size;
1088 return 0;
1089
1090cleanup:gnutls_free (data);
1091 asn1_delete_structure (&c2);
1092 return result;
1093
1094}
1095
1096/* DER Encodes the src ASN1_TYPE and stores it to
1097 * dest in dest_name. Useful to encode something and store it
1098 * as OCTET. If str is non null then the data are encoded as
1099 * an OCTET STRING.
1100 */
1101int
1102_gnutls_x509_der_encode_and_copy (ASN1_TYPE src,
1103 const char *src_name,
1104 ASN1_TYPE dest,
1105 const char *dest_name, int str)
1106{
1107 int result;
1108 gnutls_datum_t encoded;
1109
1110 result = _gnutls_x509_der_encode (src, src_name, &encoded, str);
1111
1112 if (result < 0)
1113 {
1114 gnutls_assert ();
1115 return result;
1116 }
1117
1118 /* Write the data.
1119 */
1120 result = asn1_write_value (dest, dest_name, encoded.data, encoded.size);
1121
1122 _gnutls_free_datum (&encoded);
1123
1124 if (result != ASN1_SUCCESS)
1125 {
1126 gnutls_assert ();
1127 return _gnutls_asn2err (result);
1128 }
1129
1130 return 0;
1131}
1132
1133/* Writes the value of the datum in the given ASN1_TYPE. If str is non
1134 * zero it encodes it as OCTET STRING.
1135 */
1136int
1137_gnutls_x509_write_value (ASN1_TYPE c,
1138 const char *root,
1139 const gnutls_datum_t * data, int str)
1140{
1141 int result;
1142 int asize;
1143 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1144 gnutls_datum_t val;
1145
1146 asize = data->size + 16;
1147
1148 val.data = gnutls_malloc (asize);
1149 if (val.data == NULL)
1150 {
1151 gnutls_assert ();
1152 result = GNUTLS_E_MEMORY_ERROR;
1153 goto cleanup;
1154 }
1155
1156 if (str)
1157 {
1158 /* Convert it to OCTET STRING
1159 */
1160 if ((result =
1161 asn1_create_element (_gnutls_get_pkix (), "PKIX1.pkcs-7-Data",
1162 &c2)) != ASN1_SUCCESS)
1163 {
1164 gnutls_assert ();
1165 result = _gnutls_asn2err (result);
1166 goto cleanup;
1167 }
1168
1169 result = asn1_write_value (c2, "", data->data, data->size);
1170 if (result != ASN1_SUCCESS)
1171 {
1172 gnutls_assert ();
1173 result = _gnutls_asn2err (result);
1174 goto cleanup;
1175 }
1176
1177 result = _gnutls_x509_der_encode (c2, "", &val, 0);
1178 if (result < 0)
1179 {
1180 gnutls_assert ();
1181 goto cleanup;
1182 }
1183
1184 }
1185 else
1186 {
1187 val.data = data->data;
1188 val.size = data->size;
1189 }
1190
1191 /* Write the data.
1192 */
1193 result = asn1_write_value (c, root, val.data, val.size);
1194
1195 if (val.data != data->data)
1196 _gnutls_free_datum (&val);
1197
1198 if (result != ASN1_SUCCESS)
1199 {
1200 gnutls_assert ();
1201 return _gnutls_asn2err (result);
1202 }
1203
1204 return 0;
1205
1206cleanup:if (val.data != data->data)
1207 _gnutls_free_datum (&val);
1208 return result;
1209}
1210
1211/* Encodes and copies the private key parameters into a
1212 * subjectPublicKeyInfo structure.
1213 *
1214 */
1215int
1216_gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst,
1217 const char *dst_name,
1218 gnutls_pk_algorithm_t
1219 pk_algorithm,
1220 mpi_t * params, int params_size)
1221{
1222 const char *pk;
1223 gnutls_datum_t der = { NULL,
1224 0
1225 };
1226 int result;
1227 char name[128];
1228
1229 pk = _gnutls_x509_pk_to_oid (pk_algorithm);
1230 if (pk == NULL)
1231 {
1232 gnutls_assert ();
1233 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
1234 }
1235
1236 /* write the OID
1237 */
1238 _gnutls_str_cpy (name, sizeof (name), dst_name);
1239 _gnutls_str_cat (name, sizeof (name), ".algorithm.algorithm");
1240 result = asn1_write_value (dst, name, pk, 1);
1241 if (result != ASN1_SUCCESS)
1242 {
1243 gnutls_assert ();
1244 return _gnutls_asn2err (result);
1245 }
1246
1247 if (pk_algorithm == GNUTLS_PK_RSA)
1248 {
1249 /* disable parameters, which are not used in RSA.
1250 */
1251 _gnutls_str_cpy (name, sizeof (name), dst_name);
1252 _gnutls_str_cat (name, sizeof (name), ".algorithm.parameters");
1253 result = asn1_write_value (dst, name, NULL, 0);
1254 if (result != ASN1_SUCCESS)
1255 {
1256 gnutls_assert ();
1257 return _gnutls_asn2err (result);
1258 }
1259
1260 result = _gnutls_x509_write_rsa_params (params, params_size, &der);
1261 if (result < 0)
1262 {
1263 gnutls_assert ();
1264 return result;
1265 }
1266
1267 /* Write the DER parameters. (in bits)
1268 */
1269 _gnutls_str_cpy (name, sizeof (name), dst_name);
1270 _gnutls_str_cat (name, sizeof (name), ".subjectPublicKey");
1271 result = asn1_write_value (dst, name, der.data, der.size * 8);
1272
1273 _gnutls_free_datum (&der);
1274
1275 if (result != ASN1_SUCCESS)
1276 {
1277 gnutls_assert ();
1278 return _gnutls_asn2err (result);
1279 }
1280 }
1281 else
1282 return GNUTLS_E_UNIMPLEMENTED_FEATURE;
1283
1284 return 0;
1285}
1286
1287/* Reads and returns the PK algorithm of the given certificate-like
1288 * ASN.1 structure. src_name should be something like "tbsCertificate.subjectPublicKeyInfo".
1289 */
1290int
1291_gnutls_x509_get_pk_algorithm (ASN1_TYPE src,
1292 const char *src_name, unsigned int *bits)
1293{
1294 int result;
1295 opaque *str = NULL;
1296 int algo;
1297 char oid[64];
1298 int len;
1299 mpi_t params[MAX_PUBLIC_PARAMS_SIZE];
1300 char name[128];
1301
1302 _gnutls_str_cpy (name, sizeof (name), src_name);
1303 _gnutls_str_cat (name, sizeof (name), ".algorithm.algorithm");
1304
1305 len = sizeof (oid);
1306 result = asn1_read_value (src, name, oid, &len);
1307
1308 if (result != ASN1_SUCCESS)
1309 {
1310 gnutls_assert ();
1311 return _gnutls_asn2err (result);
1312 }
1313
1314 algo = _gnutls_x509_oid2pk_algorithm (oid);
1315
1316 if (bits == NULL)
1317 {
1318 gnutls_free (str);
1319 return algo;
1320 }
1321
1322 /* Now read the parameters' bits
1323 */
1324 _gnutls_str_cpy (name, sizeof (name), src_name);
1325 _gnutls_str_cat (name, sizeof (name), ".subjectPublicKey");
1326
1327 len = 0;
1328 result = asn1_read_value (src, name, NULL, &len);
1329 if (result != ASN1_MEM_ERROR)
1330 {
1331 gnutls_assert ();
1332 return _gnutls_asn2err (result);
1333 }
1334
1335 if (len % 8 != 0)
1336 {
1337 gnutls_assert ();
1338 return GNUTLS_E_CERTIFICATE_ERROR;
1339 }
1340
1341 len /= 8;
1342
1343 str = gnutls_malloc (len);
1344 if (str == NULL)
1345 {
1346 gnutls_assert ();
1347 return GNUTLS_E_MEMORY_ERROR;
1348 }
1349
1350 _gnutls_str_cpy (name, sizeof (name), src_name);
1351 _gnutls_str_cat (name, sizeof (name), ".subjectPublicKey");
1352
1353 result = asn1_read_value (src, name, str, &len);
1354
1355 if (result != ASN1_SUCCESS)
1356 {
1357 gnutls_assert ();
1358 gnutls_free (str);
1359 return _gnutls_asn2err (result);
1360 }
1361
1362 len /= 8;
1363
1364 switch (algo)
1365 {
1366 case GNUTLS_PK_RSA:
1367 {
1368 if ((result = _gnutls_x509_read_rsa_params (str, len, params)) < 0)
1369 {
1370 gnutls_assert ();
1371 return result;
1372 }
1373
1374 bits[0] = _gnutls_mpi_get_nbits (params[0]);
1375
1376 _gnutls_mpi_release (&params[0]);
1377 _gnutls_mpi_release (&params[1]);
1378 }
1379 break;
1380 default:
1381 _gnutls_x509_log
1382 ("_gnutls_x509_get_pk_algorithm: unhandled algorithm %d\n", algo);
1383 }
1384
1385 gnutls_free (str);
1386 return algo;
1387}
1388
1389/* Reads the DER signed data from the certificate and allocates space and
1390 * returns them into signed_data.
1391 */
1392int
1393_gnutls_x509_get_signed_data (ASN1_TYPE src,
1394 const char *src_name,
1395 gnutls_datum_t * signed_data)
1396{
1397 gnutls_datum_t der;
1398 int start, end, result;
1399
1400 result = _gnutls_x509_der_encode (src, "", &der, 0);
1401 if (result < 0)
1402 {
1403 gnutls_assert ();
1404 return result;
1405 }
1406
1407 /* Get the signed data
1408 */
1409 result = asn1_der_decoding_startEnd (src, der.data, der.size, src_name,
1410 &start, &end);
1411 if (result != ASN1_SUCCESS)
1412 {
1413 result = _gnutls_asn2err (result);
1414 gnutls_assert ();
1415 goto cleanup;
1416 }
1417
1418 result = _gnutls_set_datum (signed_data, &der.data[start], end - start + 1);
1419
1420 if (result < 0)
1421 {
1422 gnutls_assert ();
1423 goto cleanup;
1424 }
1425
1426 result = 0;
1427
1428cleanup:_gnutls_free_datum (&der);
1429
1430 return result;
1431}
1432
1433/* Reads the DER signature from the certificate and allocates space and
1434 * returns them into signed_data.
1435 */
1436int
1437_gnutls_x509_get_signature (ASN1_TYPE src,
1438 const char *src_name, gnutls_datum_t * signature)
1439{
1440 int bits, result, len;
1441
1442 signature->data = NULL;
1443 signature->size = 0;
1444
1445 /* Read the signature
1446 */
1447 bits = 0;
1448 result = asn1_read_value (src, src_name, NULL, &bits);
1449
1450 if (result != ASN1_MEM_ERROR)
1451 {
1452 result = _gnutls_asn2err (result);
1453 gnutls_assert ();
1454 goto cleanup;
1455 }
1456
1457 if (bits % 8 != 0)
1458 {
1459 gnutls_assert ();
1460 result = GNUTLS_E_CERTIFICATE_ERROR;
1461 goto cleanup;
1462 }
1463
1464 len = bits / 8;
1465
1466 signature->data = gnutls_malloc (len);
1467 if (signature->data == NULL)
1468 {
1469 gnutls_assert ();
1470 result = GNUTLS_E_MEMORY_ERROR;
1471 return result;
1472 }
1473
1474 /* read the bit string of the signature
1475 */
1476 bits = len;
1477 result = asn1_read_value (src, src_name, signature->data, &bits);
1478
1479 if (result != ASN1_SUCCESS)
1480 {
1481 result = _gnutls_asn2err (result);
1482 gnutls_assert ();
1483 goto cleanup;
1484 }
1485
1486 signature->size = len;
1487
1488 return 0;
1489
1490cleanup:return result;
1491}
diff --git a/src/daemon/https/x509/common.h b/src/daemon/https/x509/common.h
new file mode 100644
index 00000000..0b696810
--- /dev/null
+++ b/src/daemon/https/x509/common.h
@@ -0,0 +1,126 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#ifndef COMMON_H
26# define COMMON_H
27
28#include <gnutls.h>
29#include <gnutls_algorithms.h>
30
31#define MAX_STRING_LEN 512
32
33#define GNUTLS_XML_SHOW_ALL 1
34
35#define PEM_CRL "X509 CRL"
36#define PEM_X509_CERT "X509 CERTIFICATE"
37#define PEM_X509_CERT2 "CERTIFICATE"
38#define PEM_PKCS7 "PKCS7"
39#define PEM_PKCS12 "PKCS12"
40
41/* public key algorithm's OIDs
42 */
43#define PK_PKIX1_RSA_OID "1.2.840.113549.1.1.1"
44#define PK_DSA_OID "1.2.840.10040.4.1"
45#define PK_GOST_R3410_94_OID "1.2.643.2.2.20"
46#define PK_GOST_R3410_2001_OID "1.2.643.2.2.19"
47
48/* signature OIDs
49 */
50#define SIG_DSA_SHA1_OID "1.2.840.10040.4.3"
51#define SIG_RSA_MD5_OID "1.2.840.113549.1.1.4"
52#define SIG_RSA_MD2_OID "1.2.840.113549.1.1.2"
53#define SIG_RSA_SHA1_OID "1.2.840.113549.1.1.5"
54#define SIG_RSA_SHA256_OID "1.2.840.113549.1.1.11"
55#define SIG_RSA_SHA384_OID "1.2.840.113549.1.1.12"
56#define SIG_RSA_SHA512_OID "1.2.840.113549.1.1.13"
57#define SIG_RSA_RMD160_OID "1.3.36.3.3.1.2"
58#define SIG_GOST_R3410_94_OID "1.2.643.2.2.4"
59#define SIG_GOST_R3410_2001_OID "1.2.643.2.2.3"
60
61time_t _gnutls_x509_utcTime2gtime (const char *ttime);
62time_t _gnutls_x509_generalTime2gtime (const char *ttime);
63int _gnutls_x509_set_time (ASN1_TYPE c2, const char *where, time_t tim);
64
65int _gnutls_x509_decode_octet_string (const char *string_type,
66 const opaque * der, size_t der_size,
67 opaque * output, size_t * output_size);
68int _gnutls_x509_oid_data2string (const char *OID, void *value,
69 int value_size, char *res,
70 size_t * res_size);
71int _gnutls_x509_data2hex (const opaque * data, size_t data_size,
72 opaque * out, size_t * sizeof_out);
73
74const char *_gnutls_x509_oid2ldap_string (const char *OID);
75
76int _gnutls_x509_oid_data_choice (const char *OID);
77int _gnutls_x509_oid_data_printable (const char *OID);
78
79time_t _gnutls_x509_get_time (ASN1_TYPE c2, const char *when);
80
81gnutls_x509_subject_alt_name_t _gnutls_x509_san_find_type (char *str_type);
82
83int _gnutls_x509_der_encode_and_copy (ASN1_TYPE src, const char *src_name,
84 ASN1_TYPE dest, const char *dest_name,
85 int str);
86int _gnutls_x509_der_encode (ASN1_TYPE src, const char *src_name,
87 gnutls_datum_t * res, int str);
88
89int _gnutls_x509_export_int (ASN1_TYPE asn1_data,
90 gnutls_x509_crt_fmt_t format, char *pem_header,
91 unsigned char *output_data,
92 size_t * output_data_size);
93
94int _gnutls_x509_read_value (ASN1_TYPE c, const char *root,
95 gnutls_datum_t * ret, int str);
96int _gnutls_x509_write_value (ASN1_TYPE c, const char *root,
97 const gnutls_datum_t * data, int str);
98
99int _gnutls_x509_encode_and_write_attribute (const char *given_oid,
100 ASN1_TYPE asn1_struct,
101 const char *where,
102 const void *data,
103 int sizeof_data, int multi);
104int _gnutls_x509_decode_and_read_attribute (ASN1_TYPE asn1_struct,
105 const char *where, char *oid,
106 int oid_size,
107 gnutls_datum_t * value, int multi,
108 int octet);
109
110int _gnutls_x509_get_pk_algorithm (ASN1_TYPE src, const char *src_name,
111 unsigned int *bits);
112
113int _gnutls_x509_encode_and_copy_PKI_params (ASN1_TYPE dst,
114 const char *dst_name,
115 gnutls_pk_algorithm_t
116 pk_algorithm, mpi_t * params,
117 int params_size);
118int _gnutls_asn1_copy_node (ASN1_TYPE * dst, const char *dst_name,
119 ASN1_TYPE src, const char *src_name);
120
121int _gnutls_x509_get_signed_data (ASN1_TYPE src, const char *src_name,
122 gnutls_datum_t * signed_data);
123int _gnutls_x509_get_signature (ASN1_TYPE src, const char *src_name,
124 gnutls_datum_t * signature);
125
126#endif
diff --git a/src/daemon/https/x509/crl.c b/src/daemon/https/x509/crl.c
new file mode 100644
index 00000000..d3b5c954
--- /dev/null
+++ b/src/daemon/https/x509/crl.c
@@ -0,0 +1,705 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26#include <libtasn1.h>
27
28#ifdef ENABLE_PKI
29
30#include <gnutls_datum.h>
31#include <gnutls_global.h>
32#include <gnutls_errors.h>
33#include <common.h>
34#include <x509_b64.h>
35#include <x509.h>
36#include <dn.h>
37
38/**
39 * gnutls_x509_crl_init - This function initializes a gnutls_x509_crl_t structure
40 * @crl: The structure to be initialized
41 *
42 * This function will initialize a CRL structure. CRL stands for
43 * Certificate Revocation List. A revocation list usually contains
44 * lists of certificate serial numbers that have been revoked
45 * by an Authority. The revocation lists are always signed with
46 * the authority's private key.
47 *
48 * Returns 0 on success.
49 *
50 **/
51int
52gnutls_x509_crl_init (gnutls_x509_crl_t * crl)
53{
54 *crl = gnutls_calloc (1, sizeof (gnutls_x509_crl_int));
55
56 if (*crl)
57 {
58 int result = asn1_create_element (_gnutls_get_pkix (),
59 "PKIX1.CertificateList",
60 &(*crl)->crl);
61 if (result != ASN1_SUCCESS)
62 {
63 gnutls_assert ();
64 gnutls_free (*crl);
65 return _gnutls_asn2err (result);
66 }
67 return 0; /* success */
68 }
69 return GNUTLS_E_MEMORY_ERROR;
70}
71
72/**
73 * gnutls_x509_crl_deinit - This function deinitializes memory used by a gnutls_x509_crl_t structure
74 * @crl: The structure to be initialized
75 *
76 * This function will deinitialize a CRL structure.
77 *
78 **/
79void
80gnutls_x509_crl_deinit (gnutls_x509_crl_t crl)
81{
82 if (!crl)
83 return;
84
85 if (crl->crl)
86 asn1_delete_structure (&crl->crl);
87
88 gnutls_free (crl);
89}
90
91/**
92 * gnutls_x509_crl_import - This function will import a DER or PEM encoded CRL
93 * @crl: The structure to store the parsed CRL.
94 * @data: The DER or PEM encoded CRL.
95 * @format: One of DER or PEM
96 *
97 * This function will convert the given DER or PEM encoded CRL
98 * to the native gnutls_x509_crl_t format. The output will be stored in 'crl'.
99 *
100 * If the CRL is PEM encoded it should have a header of "X509 CRL".
101 *
102 * Returns 0 on success.
103 *
104 **/
105int
106gnutls_x509_crl_import (gnutls_x509_crl_t crl,
107 const gnutls_datum_t * data,
108 gnutls_x509_crt_fmt_t format)
109{
110 int result = 0, need_free = 0;
111 gnutls_datum_t _data;
112
113 _data.data = data->data;
114 _data.size = data->size;
115
116 if (crl == NULL)
117 {
118 gnutls_assert ();
119 return GNUTLS_E_INVALID_REQUEST;
120 }
121
122 /* If the CRL is in PEM format then decode it
123 */
124 if (format == GNUTLS_X509_FMT_PEM)
125 {
126 opaque *out;
127
128 result = _gnutls_fbase64_decode (PEM_CRL, data->data, data->size, &out);
129
130 if (result <= 0)
131 {
132 if (result == 0)
133 result = GNUTLS_E_INTERNAL_ERROR;
134 gnutls_assert ();
135 return result;
136 }
137
138 _data.data = out;
139 _data.size = result;
140
141 need_free = 1;
142 }
143
144
145 result = asn1_der_decoding (&crl->crl, _data.data, _data.size, NULL);
146 if (result != ASN1_SUCCESS)
147 {
148 result = _gnutls_asn2err (result);
149 gnutls_assert ();
150 goto cleanup;
151 }
152
153 if (need_free)
154 _gnutls_free_datum (&_data);
155
156 return 0;
157
158cleanup:
159 if (need_free)
160 _gnutls_free_datum (&_data);
161 return result;
162}
163
164
165/**
166 * gnutls_x509_crl_get_issuer_dn - This function returns the CRL's issuer distinguished name
167 * @crl: should contain a gnutls_x509_crl_t structure
168 * @buf: a pointer to a structure to hold the peer's name (may be null)
169 * @sizeof_buf: initially holds the size of @buf
170 *
171 * This function will copy the name of the CRL issuer in the provided buffer. The name
172 * will be in the form "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output
173 * string will be ASCII or UTF-8 encoded, depending on the certificate data.
174 *
175 * If buf is null then only the size will be filled.
176 *
177 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not long enough, and
178 * in that case the sizeof_buf will be updated with the required size, and
179 * 0 on success.
180 *
181 **/
182int
183gnutls_x509_crl_get_issuer_dn (const gnutls_x509_crl_t crl, char *buf,
184 size_t * sizeof_buf)
185{
186 if (crl == NULL)
187 {
188 gnutls_assert ();
189 return GNUTLS_E_INVALID_REQUEST;
190 }
191
192 return _gnutls_x509_parse_dn (crl->crl,
193 "tbsCertList.issuer.rdnSequence",
194 buf, sizeof_buf);
195}
196
197/**
198 * gnutls_x509_crl_get_issuer_dn_by_oid - This function returns the CRL's issuer distinguished name
199 * @crl: should contain a gnutls_x509_crl_t structure
200 * @oid: holds an Object Identified in null terminated string
201 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use zero to get the first one.
202 * @raw_flag: If non zero returns the raw DER data of the DN part.
203 * @buf: a pointer to a structure to hold the peer's name (may be null)
204 * @sizeof_buf: initially holds the size of @buf
205 *
206 * This function will extract the part of the name of the CRL issuer specified
207 * by the given OID. The output will be encoded as described in RFC2253. The output
208 * string will be ASCII or UTF-8 encoded, depending on the certificate data.
209 *
210 * Some helper macros with popular OIDs can be found in gnutls/x509.h
211 * If raw flag is zero, this function will only return known OIDs as text. Other OIDs
212 * will be DER encoded, as described in RFC2253 -- in hex format with a '\#' prefix.
213 * You can check about known OIDs using gnutls_x509_dn_oid_known().
214 *
215 * If buf is null then only the size will be filled.
216 *
217 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not long enough, and
218 * in that case the sizeof_buf will be updated with the required size,
219 * and 0 on success.
220 *
221 **/
222int
223gnutls_x509_crl_get_issuer_dn_by_oid (gnutls_x509_crl_t crl,
224 const char *oid, int indx,
225 unsigned int raw_flag, void *buf,
226 size_t * sizeof_buf)
227{
228 if (crl == NULL)
229 {
230 gnutls_assert ();
231 return GNUTLS_E_INVALID_REQUEST;
232 }
233
234 return _gnutls_x509_parse_dn_oid (crl->crl,
235 "tbsCertList.issuer.rdnSequence",
236 oid, indx, raw_flag, buf, sizeof_buf);
237}
238
239/**
240 * gnutls_x509_crl_get_dn_oid - This function returns the Certificate request issuer's distinguished name OIDs
241 * @crl: should contain a gnutls_x509_crl_t structure
242 * @indx: Specifies which DN OID to send. Use zero to get the first one.
243 * @oid: a pointer to a structure to hold the name (may be null)
244 * @sizeof_oid: initially holds the size of 'oid'
245 *
246 * This function will extract the requested OID of the name of the CRL issuer, specified
247 * by the given index.
248 *
249 * If oid is null then only the size will be filled.
250 *
251 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not long enough, and
252 * in that case the sizeof_oid will be updated with the required size.
253 * On success 0 is returned.
254 *
255 **/
256int
257gnutls_x509_crl_get_dn_oid (gnutls_x509_crl_t crl,
258 int indx, void *oid, size_t * sizeof_oid)
259{
260 if (crl == NULL)
261 {
262 gnutls_assert ();
263 return GNUTLS_E_INVALID_REQUEST;
264 }
265
266 return _gnutls_x509_get_dn_oid (crl->crl,
267 "tbsCertList.issuer.rdnSequence", indx,
268 oid, sizeof_oid);
269}
270
271
272/**
273 * gnutls_x509_crl_get_signature_algorithm - This function returns the CRL's signature algorithm
274 * @crl: should contain a gnutls_x509_crl_t structure
275 *
276 * This function will return a value of the gnutls_sign_algorithm_t enumeration that
277 * is the signature algorithm.
278 *
279 * Returns a negative value on error.
280 *
281 **/
282int
283gnutls_x509_crl_get_signature_algorithm (gnutls_x509_crl_t crl)
284{
285 int result;
286 gnutls_datum_t sa;
287
288 if (crl == NULL)
289 {
290 gnutls_assert ();
291 return GNUTLS_E_INVALID_REQUEST;
292 }
293
294 /* Read the signature algorithm. Note that parameters are not
295 * read. They will be read from the issuer's certificate if needed.
296 */
297
298 result =
299 _gnutls_x509_read_value (crl->crl, "signatureAlgorithm.algorithm",
300 &sa, 0);
301
302 if (result < 0)
303 {
304 gnutls_assert ();
305 return result;
306 }
307
308 result = _gnutls_x509_oid2sign_algorithm ((const char *) sa.data);
309
310 _gnutls_free_datum (&sa);
311
312 return result;
313}
314
315/**
316 * gnutls_x509_crl_get_signature - Returns the CRL's signature
317 * @crl: should contain a gnutls_x509_crl_t structure
318 * @sig: a pointer where the signature part will be copied (may be null).
319 * @sizeof_sig: initially holds the size of @sig
320 *
321 * This function will extract the signature field of a CRL.
322 *
323 * Returns 0 on success, and a negative value on error.
324 **/
325int
326gnutls_x509_crl_get_signature (gnutls_x509_crl_t crl,
327 char *sig, size_t * sizeof_sig)
328{
329 int result;
330 int bits, len;
331
332 if (crl == NULL)
333 {
334 gnutls_assert ();
335 return GNUTLS_E_INVALID_REQUEST;
336 }
337
338 bits = 0;
339 result = asn1_read_value (crl->crl, "signature", NULL, &bits);
340 if (result != ASN1_MEM_ERROR)
341 {
342 gnutls_assert ();
343 return _gnutls_asn2err (result);
344 }
345
346 if (bits % 8 != 0)
347 {
348 gnutls_assert ();
349 return GNUTLS_E_CERTIFICATE_ERROR;
350 }
351
352 len = bits / 8;
353
354 if (*sizeof_sig < len)
355 {
356 *sizeof_sig = bits / 8;
357 return GNUTLS_E_SHORT_MEMORY_BUFFER;
358 }
359
360 result = asn1_read_value (crl->crl, "signature", sig, &len);
361 if (result != ASN1_SUCCESS)
362 {
363 gnutls_assert ();
364 return _gnutls_asn2err (result);
365 }
366
367 return 0;
368}
369
370/**
371 * gnutls_x509_crl_get_version - This function returns the CRL's version number
372 * @crl: should contain a gnutls_x509_crl_t structure
373 *
374 * This function will return the version of the specified CRL.
375 *
376 * Returns a negative value on error.
377 *
378 **/
379int
380gnutls_x509_crl_get_version (gnutls_x509_crl_t crl)
381{
382 opaque version[5];
383 int len, result;
384
385 if (crl == NULL)
386 {
387 gnutls_assert ();
388 return GNUTLS_E_INVALID_REQUEST;
389 }
390
391 len = sizeof (version);
392 if ((result =
393 asn1_read_value (crl->crl, "tbsCertList.version", version,
394 &len)) != ASN1_SUCCESS)
395 {
396 gnutls_assert ();
397 return _gnutls_asn2err (result);
398 }
399
400 return (int) version[0] + 1;
401}
402
403/**
404 * gnutls_x509_crl_get_this_update - This function returns the CRL's thisUpdate time
405 * @crl: should contain a gnutls_x509_crl_t structure
406 *
407 * This function will return the time this CRL was issued.
408 *
409 * Returns (time_t)-1 on error.
410 *
411 **/
412time_t
413gnutls_x509_crl_get_this_update (gnutls_x509_crl_t crl)
414{
415 if (crl == NULL)
416 {
417 gnutls_assert ();
418 return (time_t) - 1;
419 }
420
421 return _gnutls_x509_get_time (crl->crl, "tbsCertList.thisUpdate");
422}
423
424/**
425 * gnutls_x509_crl_get_next_update - This function returns the CRL's nextUpdate time
426 * @crl: should contain a gnutls_x509_crl_t structure
427 *
428 * This function will return the time the next CRL will be issued.
429 * This field is optional in a CRL so it might be normal to get
430 * an error instead.
431 *
432 * Returns (time_t)-1 on error.
433 *
434 **/
435time_t
436gnutls_x509_crl_get_next_update (gnutls_x509_crl_t crl)
437{
438 if (crl == NULL)
439 {
440 gnutls_assert ();
441 return (time_t) - 1;
442 }
443
444 return _gnutls_x509_get_time (crl->crl, "tbsCertList.nextUpdate");
445}
446
447/**
448 * gnutls_x509_crl_get_crt_count - This function returns the number of revoked certificates in a CRL
449 * @crl: should contain a gnutls_x509_crl_t structure
450 *
451 * This function will return the number of revoked certificates in the
452 * given CRL.
453 *
454 * Returns a negative value on failure.
455 *
456 **/
457int
458gnutls_x509_crl_get_crt_count (gnutls_x509_crl_t crl)
459{
460
461 int count, result;
462
463 if (crl == NULL)
464 {
465 gnutls_assert ();
466 return GNUTLS_E_INVALID_REQUEST;
467 }
468
469 result =
470 asn1_number_of_elements (crl->crl,
471 "tbsCertList.revokedCertificates", &count);
472
473 if (result != ASN1_SUCCESS)
474 {
475 gnutls_assert ();
476 return 0; /* no certificates */
477 }
478
479 return count;
480}
481
482/**
483 * gnutls_x509_crl_get_crt_serial - This function returns the serial number of a revoked certificate
484 * @crl: should contain a gnutls_x509_crl_t structure
485 * @indx: the index of the certificate to extract (starting from 0)
486 * @serial: where the serial number will be copied
487 * @serial_size: initially holds the size of serial
488 * @t: if non null, will hold the time this certificate was revoked
489 *
490 * This function will return the serial number of the specified, by
491 * the index, revoked certificate.
492 *
493 * Returns a negative value on failure.
494 *
495 **/
496int
497gnutls_x509_crl_get_crt_serial (gnutls_x509_crl_t crl, int indx,
498 unsigned char *serial,
499 size_t * serial_size, time_t * t)
500{
501
502 int result, _serial_size;
503 char serial_name[MAX_NAME_SIZE];
504 char date_name[MAX_NAME_SIZE];
505
506 if (crl == NULL)
507 {
508 gnutls_assert ();
509 return GNUTLS_E_INVALID_REQUEST;
510 }
511
512 snprintf (serial_name, sizeof (serial_name),
513 "tbsCertList.revokedCertificates.?%u.userCertificate", indx + 1);
514 snprintf (date_name, sizeof (date_name),
515 "tbsCertList.revokedCertificates.?%u.revocationDate", indx + 1);
516
517 _serial_size = *serial_size;
518 result = asn1_read_value (crl->crl, serial_name, serial, &_serial_size);
519
520 *serial_size = _serial_size;
521 if (result != ASN1_SUCCESS)
522 {
523 gnutls_assert ();
524 if (result == ASN1_ELEMENT_NOT_FOUND)
525 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
526 return _gnutls_asn2err (result);
527 }
528
529 if (t)
530 {
531 *t = _gnutls_x509_get_time (crl->crl, date_name);
532 }
533
534 return 0;
535}
536
537/*-
538 * _gnutls_x509_crl_get_raw_issuer_dn - This function returns the issuer's DN DER encoded
539 * @crl: should contain a gnutls_x509_crl_t structure
540 * @dn: will hold the starting point of the DN
541 *
542 * This function will return a pointer to the DER encoded DN structure and
543 * the length.
544 *
545 * Returns a negative value on error, and zero on success.
546 *
547 -*/
548int
549_gnutls_x509_crl_get_raw_issuer_dn (gnutls_x509_crl_t crl,
550 gnutls_datum_t * dn)
551{
552 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
553 int result, len1;
554 int start1, end1;
555 gnutls_datum_t crl_signed_data;
556
557 if (crl == NULL)
558 {
559 gnutls_assert ();
560 return GNUTLS_E_INVALID_REQUEST;
561 }
562
563 /* get the issuer of 'crl'
564 */
565 if ((result =
566 asn1_create_element (_gnutls_get_pkix (), "PKIX1.TBSCertList",
567 &c2)) != ASN1_SUCCESS)
568 {
569 gnutls_assert ();
570 return _gnutls_asn2err (result);
571 }
572
573 result =
574 _gnutls_x509_get_signed_data (crl->crl, "tbsCertList", &crl_signed_data);
575 if (result < 0)
576 {
577 gnutls_assert ();
578 goto cleanup;
579 }
580
581 result =
582 asn1_der_decoding (&c2, crl_signed_data.data, crl_signed_data.size, NULL);
583 if (result != ASN1_SUCCESS)
584 {
585 /* couldn't decode DER */
586 gnutls_assert ();
587 asn1_delete_structure (&c2);
588 result = _gnutls_asn2err (result);
589 goto cleanup;
590 }
591
592 result =
593 asn1_der_decoding_startEnd (c2, crl_signed_data.data,
594 crl_signed_data.size, "issuer",
595 &start1, &end1);
596
597 if (result != ASN1_SUCCESS)
598 {
599 gnutls_assert ();
600 result = _gnutls_asn2err (result);
601 goto cleanup;
602 }
603
604 len1 = end1 - start1 + 1;
605
606 _gnutls_set_datum (dn, &crl_signed_data.data[start1], len1);
607
608 result = 0;
609
610cleanup:
611 asn1_delete_structure (&c2);
612 _gnutls_free_datum (&crl_signed_data);
613 return result;
614}
615
616/**
617 * gnutls_x509_crl_export - This function will export the CRL
618 * @crl: Holds the revocation list
619 * @format: the format of output params. One of PEM or DER.
620 * @output_data: will contain a private key PEM or DER encoded
621 * @output_data_size: holds the size of output_data (and will be replaced by the actual size of parameters)
622 *
623 * This function will export the revocation list to DER or PEM format.
624 *
625 * If the buffer provided is not long enough to hold the output, then
626 * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
627 *
628 * If the structure is PEM encoded, it will have a header
629 * of "BEGIN X509 CRL".
630 *
631 * Returns 0 on success, and a negative value on failure.
632 *
633 **/
634int
635gnutls_x509_crl_export (gnutls_x509_crl_t crl,
636 gnutls_x509_crt_fmt_t format, void *output_data,
637 size_t * output_data_size)
638{
639 if (crl == NULL)
640 {
641 gnutls_assert ();
642 return GNUTLS_E_INVALID_REQUEST;
643 }
644
645 return _gnutls_x509_export_int (crl->crl, format, PEM_CRL,
646 output_data, output_data_size);
647}
648
649/*-
650 * _gnutls_x509_crl_cpy - This function copies a gnutls_x509_crl_t structure
651 * @dest: The structure where to copy
652 * @src: The structure to be copied
653 *
654 * This function will copy an X.509 certificate structure.
655 *
656 * Returns 0 on success.
657 *
658 -*/
659int
660_gnutls_x509_crl_cpy (gnutls_x509_crl_t dest, gnutls_x509_crl_t src)
661{
662 int ret;
663 size_t der_size;
664 opaque *der;
665 gnutls_datum_t tmp;
666
667 ret = gnutls_x509_crl_export (src, GNUTLS_X509_FMT_DER, NULL, &der_size);
668 if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
669 {
670 gnutls_assert ();
671 return ret;
672 }
673
674 der = gnutls_alloca (der_size);
675 if (der == NULL)
676 {
677 gnutls_assert ();
678 return GNUTLS_E_MEMORY_ERROR;
679 }
680
681 ret = gnutls_x509_crl_export (src, GNUTLS_X509_FMT_DER, der, &der_size);
682 if (ret < 0)
683 {
684 gnutls_assert ();
685 gnutls_afree (der);
686 return ret;
687 }
688
689 tmp.data = der;
690 tmp.size = der_size;
691 ret = gnutls_x509_crl_import (dest, &tmp, GNUTLS_X509_FMT_DER);
692
693 gnutls_afree (der);
694
695 if (ret < 0)
696 {
697 gnutls_assert ();
698 return ret;
699 }
700
701 return 0;
702
703}
704
705#endif
diff --git a/src/daemon/https/x509/crl_write.c b/src/daemon/https/x509/crl_write.c
new file mode 100644
index 00000000..370a492c
--- /dev/null
+++ b/src/daemon/https/x509/crl_write.c
@@ -0,0 +1,316 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file contains functions to handle CRL generation.
26 */
27
28#include <gnutls_int.h>
29
30#ifdef ENABLE_PKI
31
32#include <gnutls_datum.h>
33#include <gnutls_global.h>
34#include <gnutls_errors.h>
35#include <common.h>
36#include <gnutls_x509.h>
37#include <x509_b64.h>
38#include <crq.h>
39#include <dn.h>
40#include <mpi.h>
41#include <sign.h>
42#include <extensions.h>
43#include <libtasn1.h>
44
45static void disable_optional_stuff (gnutls_x509_crl_t crl);
46
47/**
48 * gnutls_x509_crl_set_version - This function will set the CRL version
49 * @crl: should contain a gnutls_x509_crl_t structure
50 * @version: holds the version number. For CRLv1 crls must be 1.
51 *
52 * This function will set the version of the CRL. This
53 * must be one for CRL version 1, and so on. The CRLs generated
54 * by gnutls should have a version number of 2.
55 *
56 * Returns 0 on success.
57 *
58 **/
59int
60gnutls_x509_crl_set_version (gnutls_x509_crl_t crl, unsigned int version)
61{
62 int result;
63 char null = version;
64
65 if (crl == NULL)
66 {
67 gnutls_assert ();
68 return GNUTLS_E_INVALID_REQUEST;
69 }
70
71 null -= 1;
72 if (null < 0)
73 null = 0;
74
75 result = asn1_write_value (crl->crl, "tbsCertList.version", &null, 1);
76 if (result != ASN1_SUCCESS)
77 {
78 gnutls_assert ();
79 return _gnutls_asn2err (result);
80 }
81
82 return 0;
83}
84
85/**
86 * gnutls_x509_crl_sign2 - This function will sign a CRL with a key
87 * @crl: should contain a gnutls_x509_crl_t structure
88 * @issuer: is the certificate of the certificate issuer
89 * @issuer_key: holds the issuer's private key
90 * @dig: The message digest to use. GNUTLS_DIG_SHA1 is the safe choice unless you know what you're doing.
91 * @flags: must be 0
92 *
93 * This function will sign the CRL with the issuer's private key, and
94 * will copy the issuer's information into the CRL.
95 *
96 * This must be the last step in a certificate CRL since all
97 * the previously set parameters are now signed.
98 *
99 * Returns 0 on success.
100 *
101 **/
102int
103gnutls_x509_crl_sign2 (gnutls_x509_crl_t crl, gnutls_x509_crt_t issuer,
104 gnutls_x509_privkey_t issuer_key,
105 gnutls_digest_algorithm_t dig, unsigned int flags)
106{
107 int result;
108
109 if (crl == NULL || issuer == NULL)
110 {
111 gnutls_assert ();
112 return GNUTLS_E_INVALID_REQUEST;
113 }
114
115 /* disable all the unneeded OPTIONAL fields.
116 */
117 disable_optional_stuff (crl);
118
119 result = _gnutls_x509_pkix_sign (crl->crl, "tbsCertList",
120 dig, issuer, issuer_key);
121 if (result < 0)
122 {
123 gnutls_assert ();
124 return result;
125 }
126
127 return 0;
128}
129
130/**
131 * gnutls_x509_crl_sign - This function will sign a CRL with a key
132 * @crl: should contain a gnutls_x509_crl_t structure
133 * @issuer: is the certificate of the certificate issuer
134 * @issuer_key: holds the issuer's private key
135 *
136 * This function is the same a gnutls_x509_crl_sign2() with no flags, and
137 * SHA1 as the hash algorithm.
138 *
139 * Returns 0 on success.
140 *
141 **/
142int
143gnutls_x509_crl_sign (gnutls_x509_crl_t crl, gnutls_x509_crt_t issuer,
144 gnutls_x509_privkey_t issuer_key)
145{
146 return gnutls_x509_crl_sign2 (crl, issuer, issuer_key, GNUTLS_DIG_SHA1, 0);
147}
148
149/**
150 * gnutls_x509_crl_set_this_update - This function will set the CRL's issuing time
151 * @crl: should contain a gnutls_x509_crl_t structure
152 * @act_time: The actual time
153 *
154 * This function will set the time this CRL was issued.
155 *
156 * Returns 0 on success, or a negative value in case of an error.
157 *
158 **/
159int
160gnutls_x509_crl_set_this_update (gnutls_x509_crl_t crl, time_t act_time)
161{
162 if (crl == NULL)
163 {
164 gnutls_assert ();
165 return GNUTLS_E_INVALID_REQUEST;
166 }
167
168 return _gnutls_x509_set_time (crl->crl, "tbsCertList.thisUpdate", act_time);
169}
170
171/**
172 * gnutls_x509_crl_set_next_update - This function will set the CRL next update time
173 * @crl: should contain a gnutls_x509_crl_t structure
174 * @exp_time: The actual time
175 *
176 * This function will set the time this CRL will be updated.
177 *
178 * Returns 0 on success, or a negative value in case of an error.
179 *
180 **/
181int
182gnutls_x509_crl_set_next_update (gnutls_x509_crl_t crl, time_t exp_time)
183{
184 if (crl == NULL)
185 {
186 gnutls_assert ();
187 return GNUTLS_E_INVALID_REQUEST;
188 }
189 return _gnutls_x509_set_time (crl->crl, "tbsCertList.nextUpdate", exp_time);
190}
191
192/**
193 * gnutls_x509_crl_set_crt_serial - This function will set a revoked certificate's serial number
194 * @crl: should contain a gnutls_x509_crl_t structure
195 * @serial: The revoked certificate's serial number
196 * @serial_size: Holds the size of the serial field.
197 * @revocation_time: The time this certificate was revoked
198 *
199 * This function will set a revoked certificate's serial number to the CRL.
200 *
201 * Returns 0 on success, or a negative value in case of an error.
202 *
203 **/
204int
205gnutls_x509_crl_set_crt_serial (gnutls_x509_crl_t crl,
206 const void *serial, size_t serial_size,
207 time_t revocation_time)
208{
209 int ret;
210
211 if (crl == NULL)
212 {
213 gnutls_assert ();
214 return GNUTLS_E_INVALID_REQUEST;
215 }
216
217 ret =
218 asn1_write_value (crl->crl, "tbsCertList.revokedCertificates", "NEW", 1);
219 if (ret != ASN1_SUCCESS)
220 {
221 gnutls_assert ();
222 return _gnutls_asn2err (ret);
223 }
224
225 ret =
226 asn1_write_value (crl->crl,
227 "tbsCertList.revokedCertificates.?LAST.userCertificate",
228 serial, serial_size);
229 if (ret != ASN1_SUCCESS)
230 {
231 gnutls_assert ();
232 return _gnutls_asn2err (ret);
233 }
234
235 ret =
236 _gnutls_x509_set_time (crl->crl,
237 "tbsCertList.revokedCertificates.?LAST.revocationDate",
238 revocation_time);
239 if (ret < 0)
240 {
241 gnutls_assert ();
242 return ret;
243 }
244
245 ret =
246 asn1_write_value (crl->crl,
247 "tbsCertList.revokedCertificates.?LAST.crlEntryExtensions",
248 NULL, 0);
249 if (ret != ASN1_SUCCESS)
250 {
251 gnutls_assert ();
252 return _gnutls_asn2err (ret);
253 }
254
255 return 0;
256}
257
258/**
259 * gnutls_x509_crl_set_crt - This function will set a revoked certificate's serial number
260 * @crl: should contain a gnutls_x509_crl_t structure
261 * @crt: should contain a gnutls_x509_crt_t structure with the revoked certificate
262 * @revocation_time: The time this certificate was revoked
263 *
264 * This function will set a revoked certificate's serial number to the CRL.
265 *
266 * Returns 0 on success, or a negative value in case of an error.
267 *
268 **/
269int
270gnutls_x509_crl_set_crt (gnutls_x509_crl_t crl, gnutls_x509_crt_t crt,
271 time_t revocation_time)
272{
273 int ret;
274 opaque serial[128];
275 size_t serial_size;
276
277 if (crl == NULL || crt == NULL)
278 {
279 gnutls_assert ();
280 return GNUTLS_E_INVALID_REQUEST;
281 }
282
283 serial_size = sizeof (serial);
284 ret = gnutls_x509_crt_get_serial (crt, serial, &serial_size);
285 if (ret < 0)
286 {
287 gnutls_assert ();
288 return ret;
289 }
290
291 ret =
292 gnutls_x509_crl_set_crt_serial (crl, serial, serial_size,
293 revocation_time);
294 if (ret < 0)
295 {
296 gnutls_assert ();
297 return _gnutls_asn2err (ret);
298 }
299
300 return 0;
301}
302
303
304/* If OPTIONAL fields have not been initialized then
305 * disable them.
306 */
307static void
308disable_optional_stuff (gnutls_x509_crl_t crl)
309{
310
311 asn1_write_value (crl->crl, "tbsCertList.crlExtensions", NULL, 0);
312
313 return;
314}
315
316#endif /* ENABLE_PKI */
diff --git a/src/daemon/https/x509/crq.c b/src/daemon/https/x509/crq.c
new file mode 100644
index 00000000..8e663d51
--- /dev/null
+++ b/src/daemon/https/x509/crq.c
@@ -0,0 +1,887 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file contains functions to handle PKCS #10 certificate requests.
26 */
27
28#include <gnutls_int.h>
29
30#ifdef ENABLE_PKI
31
32#include <gnutls_datum.h>
33#include <gnutls_global.h>
34#include <gnutls_errors.h>
35#include <common.h>
36#include <gnutls_x509.h>
37#include <x509_b64.h>
38#include <crq.h>
39#include <dn.h>
40#include <mpi.h>
41#include <sign.h>
42#include <extensions.h>
43#include <libtasn1.h>
44
45/**
46 * gnutls_x509_crq_init - This function initializes a gnutls_x509_crq_t structure
47 * @crq: The structure to be initialized
48 *
49 * This function will initialize a PKCS10 certificate request structure.
50 *
51 * Returns 0 on success.
52 *
53 **/
54int
55gnutls_x509_crq_init (gnutls_x509_crq_t * crq)
56{
57 *crq = gnutls_calloc (1, sizeof (gnutls_x509_crq_int));
58
59 if (*crq)
60 {
61 int result = asn1_create_element (_gnutls_get_pkix (),
62 "PKIX1.pkcs-10-CertificationRequest",
63 &((*crq)->crq));
64 if (result != ASN1_SUCCESS)
65 {
66 gnutls_assert ();
67 gnutls_free (*crq);
68 return _gnutls_asn2err (result);
69 }
70 return 0; /* success */
71 }
72 return GNUTLS_E_MEMORY_ERROR;
73}
74
75/**
76 * gnutls_x509_crq_deinit - This function deinitializes memory used by a gnutls_x509_crq_t structure
77 * @crq: The structure to be initialized
78 *
79 * This function will deinitialize a CRL structure.
80 *
81 **/
82void
83gnutls_x509_crq_deinit (gnutls_x509_crq_t crq)
84{
85 if (!crq)
86 return;
87
88 if (crq->crq)
89 asn1_delete_structure (&crq->crq);
90
91 gnutls_free (crq);
92}
93
94#define PEM_CRQ "NEW CERTIFICATE REQUEST"
95#define PEM_CRQ2 "CERTIFICATE REQUEST"
96
97/**
98 * gnutls_x509_crq_import - This function will import a DER or PEM encoded Certificate request
99 * @crq: The structure to store the parsed certificate request.
100 * @data: The DER or PEM encoded certificate.
101 * @format: One of DER or PEM
102 *
103 * This function will convert the given DER or PEM encoded Certificate
104 * to the native gnutls_x509_crq_t format. The output will be stored in @cert.
105 *
106 * If the Certificate is PEM encoded it should have a header of "NEW CERTIFICATE REQUEST".
107 *
108 * Returns 0 on success.
109 *
110 **/
111int
112gnutls_x509_crq_import (gnutls_x509_crq_t crq,
113 const gnutls_datum_t * data,
114 gnutls_x509_crt_fmt_t format)
115{
116 int result = 0, need_free = 0;
117 gnutls_datum_t _data;
118
119 if (crq == NULL)
120 {
121 gnutls_assert ();
122 return GNUTLS_E_INVALID_REQUEST;
123 }
124
125 _data.data = data->data;
126 _data.size = data->size;
127
128 /* If the Certificate is in PEM format then decode it
129 */
130 if (format == GNUTLS_X509_FMT_PEM)
131 {
132 opaque *out;
133
134 /* Try the first header */
135 result = _gnutls_fbase64_decode (PEM_CRQ, data->data, data->size, &out);
136
137 if (result <= 0) /* Go for the second header */
138 result =
139 _gnutls_fbase64_decode (PEM_CRQ2, data->data, data->size, &out);
140
141 if (result <= 0)
142 {
143 if (result == 0)
144 result = GNUTLS_E_INTERNAL_ERROR;
145 gnutls_assert ();
146 return result;
147 }
148
149 _data.data = out;
150 _data.size = result;
151
152 need_free = 1;
153 }
154
155 result = asn1_der_decoding (&crq->crq, _data.data, _data.size, NULL);
156 if (result != ASN1_SUCCESS)
157 {
158 result = _gnutls_asn2err (result);
159 gnutls_assert ();
160 goto cleanup;
161 }
162
163 result = 0;
164
165cleanup:
166 if (need_free)
167 _gnutls_free_datum (&_data);
168 return result;
169}
170
171
172
173/**
174 * gnutls_x509_crq_get_dn - This function returns the Certificate request subject's distinguished name
175 * @crq: should contain a gnutls_x509_crq_t structure
176 * @buf: a pointer to a structure to hold the name (may be null)
177 * @sizeof_buf: initially holds the size of @buf
178 *
179 * This function will copy the name of the Certificate request
180 * subject in the provided buffer. The name will be in the form
181 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output string
182 * will be ASCII or UTF-8 encoded, depending on the certificate data.
183 *
184 * If @buf is null then only the size will be filled.
185 *
186 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
187 * long enough, and in that case the *sizeof_buf will be updated with
188 * the required size. On success 0 is returned.
189 *
190 **/
191int
192gnutls_x509_crq_get_dn (gnutls_x509_crq_t crq, char *buf, size_t * sizeof_buf)
193{
194 if (crq == NULL)
195 {
196 gnutls_assert ();
197 return GNUTLS_E_INVALID_REQUEST;
198 }
199
200 return _gnutls_x509_parse_dn (crq->crq,
201 "certificationRequestInfo.subject.rdnSequence",
202 buf, sizeof_buf);
203}
204
205/**
206 * gnutls_x509_crq_get_dn_by_oid - This function returns the Certificate request subject's distinguished name
207 * @crq: should contain a gnutls_x509_crq_t structure
208 * @oid: holds an Object Identified in null terminated string
209 * @indx: In case multiple same OIDs exist in the RDN, this specifies
210 * which to send. Use zero to get the first one.
211 * @raw_flag: If non zero returns the raw DER data of the DN part.
212 * @buf: a pointer to a structure to hold the name (may be null)
213 * @sizeof_buf: initially holds the size of @buf
214 *
215 * This function will extract the part of the name of the Certificate
216 * request subject, specified by the given OID. The output will be
217 * encoded as described in RFC2253. The output string will be ASCII
218 * or UTF-8 encoded, depending on the certificate data.
219 *
220 * Some helper macros with popular OIDs can be found in gnutls/x509.h
221 * If raw flag is zero, this function will only return known OIDs as
222 * text. Other OIDs will be DER encoded, as described in RFC2253 --
223 * in hex format with a '\#' prefix. You can check about known OIDs
224 * using gnutls_x509_dn_oid_known().
225 *
226 * If @buf is null then only the size will be filled.
227 *
228 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
229 * long enough, and in that case the *sizeof_buf will be updated with
230 * the required size. On success 0 is returned.
231 *
232 **/
233int
234gnutls_x509_crq_get_dn_by_oid (gnutls_x509_crq_t crq, const char *oid,
235 int indx, unsigned int raw_flag,
236 void *buf, size_t * sizeof_buf)
237{
238 if (crq == NULL)
239 {
240 gnutls_assert ();
241 return GNUTLS_E_INVALID_REQUEST;
242 }
243
244 return _gnutls_x509_parse_dn_oid (crq->crq,
245 "certificationRequestInfo.subject.rdnSequence",
246 oid, indx, raw_flag, buf, sizeof_buf);
247}
248
249/**
250 * gnutls_x509_crq_get_dn_oid - This function returns the Certificate request subject's distinguished name OIDs
251 * @crq: should contain a gnutls_x509_crq_t structure
252 * @indx: Specifies which DN OID to send. Use zero to get the first one.
253 * @oid: a pointer to a structure to hold the name (may be null)
254 * @sizeof_oid: initially holds the size of @oid
255 *
256 * This function will extract the requested OID of the name of the
257 * Certificate request subject, specified by the given index.
258 *
259 * If oid is null then only the size will be filled.
260 *
261 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
262 * long enough, and in that case the *sizeof_oid will be updated with
263 * the required size. On success 0 is returned.
264 *
265 **/
266int
267gnutls_x509_crq_get_dn_oid (gnutls_x509_crq_t crq,
268 int indx, void *oid, size_t * sizeof_oid)
269{
270 if (crq == NULL)
271 {
272 gnutls_assert ();
273 return GNUTLS_E_INVALID_REQUEST;
274 }
275
276 return _gnutls_x509_get_dn_oid (crq->crq,
277 "certificationRequestInfo.subject.rdnSequence",
278 indx, oid, sizeof_oid);
279}
280
281/* Parses an Attribute list in the asn1_struct, and searches for the
282 * given OID. The index indicates the attribute value to be returned.
283 *
284 * If raw==0 only printable data are returned, or GNUTLS_E_X509_UNSUPPORTED_ATTRIBUTE.
285 *
286 * asn1_attr_name must be a string in the form "certificationRequestInfo.attributes"
287 *
288 */
289static int
290parse_attribute (ASN1_TYPE asn1_struct,
291 const char *attr_name, const char *given_oid, int indx,
292 int raw, char *buf, size_t * sizeof_buf)
293{
294 int k1, result;
295 char tmpbuffer1[MAX_NAME_SIZE];
296 char tmpbuffer3[MAX_NAME_SIZE];
297 char value[200];
298 char oid[128];
299 int len, printable;
300
301 if (*sizeof_buf == 0)
302 {
303 gnutls_assert ();
304 return GNUTLS_E_INVALID_REQUEST;
305 }
306
307 buf[0] = 0;
308
309 k1 = 0;
310 do
311 {
312
313 k1++;
314 /* create a string like "attribute.?1"
315 */
316 if (attr_name[0] != 0)
317 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", attr_name, k1);
318 else
319 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
320
321 len = sizeof (value) - 1;
322 result = asn1_read_value (asn1_struct, tmpbuffer1, value, &len);
323
324 if (result == ASN1_ELEMENT_NOT_FOUND)
325 {
326 gnutls_assert ();
327 break;
328 }
329
330 if (result != ASN1_VALUE_NOT_FOUND)
331 {
332 gnutls_assert ();
333 result = _gnutls_asn2err (result);
334 goto cleanup;
335 }
336
337 /* Move to the attibute type and values
338 */
339 /* Read the OID
340 */
341 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer1);
342 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
343
344 len = sizeof (oid) - 1;
345 result = asn1_read_value (asn1_struct, tmpbuffer3, oid, &len);
346
347 if (result == ASN1_ELEMENT_NOT_FOUND)
348 break;
349 else if (result != ASN1_SUCCESS)
350 {
351 gnutls_assert ();
352 result = _gnutls_asn2err (result);
353 goto cleanup;
354 }
355
356 if (strcmp (oid, given_oid) == 0)
357 { /* Found the OID */
358
359 /* Read the Value
360 */
361 snprintf (tmpbuffer3, sizeof (tmpbuffer3), "%s.values.?%u",
362 tmpbuffer1, indx + 1);
363
364 len = sizeof (value) - 1;
365 result = asn1_read_value (asn1_struct, tmpbuffer3, value, &len);
366
367 if (result != ASN1_SUCCESS)
368 {
369 gnutls_assert ();
370 result = _gnutls_asn2err (result);
371 goto cleanup;
372 }
373
374 if (raw == 0)
375 {
376 printable = _gnutls_x509_oid_data_printable (oid);
377 if (printable == 1)
378 {
379 if ((result =
380 _gnutls_x509_oid_data2string
381 (oid, value, len, buf, sizeof_buf)) < 0)
382 {
383 gnutls_assert ();
384 goto cleanup;
385 }
386 return 0;
387 }
388 else
389 {
390 gnutls_assert ();
391 return GNUTLS_E_X509_UNSUPPORTED_ATTRIBUTE;
392 }
393 }
394 else
395 { /* raw!=0 */
396 if (*sizeof_buf > (size_t) len && buf != NULL)
397 {
398 *sizeof_buf = len;
399 memcpy (buf, value, len);
400
401 return 0;
402 }
403 else
404 {
405 *sizeof_buf = len;
406 gnutls_assert ();
407 return GNUTLS_E_SHORT_MEMORY_BUFFER;
408 }
409 }
410 }
411
412 }
413 while (1);
414
415 gnutls_assert ();
416
417 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
418
419cleanup:
420 return result;
421}
422
423/**
424 * gnutls_x509_crq_get_challenge_password - This function will get the challenge password
425 * @crq: should contain a gnutls_x509_crq_t structure
426 * @pass: will hold a null terminated password
427 * @sizeof_pass: Initially holds the size of @pass.
428 *
429 * This function will return the challenge password in the
430 * request.
431 *
432 * Returns 0 on success.
433 *
434 **/
435int
436gnutls_x509_crq_get_challenge_password (gnutls_x509_crq_t crq,
437 char *pass, size_t * sizeof_pass)
438{
439 if (crq == NULL)
440 {
441 gnutls_assert ();
442 return GNUTLS_E_INVALID_REQUEST;
443 }
444
445 return parse_attribute (crq->crq, "certificationRequestInfo.attributes",
446 "1.2.840.113549.1.9.7", 0, 0, pass, sizeof_pass);
447}
448
449/**
450 * gnutls_x509_crq_set_attribute_by_oid - This function will set an attribute in the request
451 * @crq: should contain a gnutls_x509_crq_t structure
452 * @oid: holds an Object Identified in null terminated string
453 * @buf: a pointer to a structure that holds the attribute data
454 * @sizeof_buf: holds the size of @buf
455 *
456 * This function will set the attribute in the certificate request specified
457 * by the given Object ID. The attribute must be be DER encoded.
458 *
459 * Returns 0 on success.
460 *
461 **/
462int
463gnutls_x509_crq_set_attribute_by_oid (gnutls_x509_crq_t crq,
464 const char *oid, void *buf,
465 size_t sizeof_buf)
466{
467 int result;
468
469 if (crq == NULL)
470 {
471 gnutls_assert ();
472 return GNUTLS_E_INVALID_REQUEST;
473 }
474
475 /* Add the attribute.
476 */
477 result =
478 asn1_write_value (crq->crq, "certificationRequestInfo.attributes",
479 "NEW", 1);
480 if (result != ASN1_SUCCESS)
481 {
482 gnutls_assert ();
483 return _gnutls_asn2err (result);
484 }
485
486 result =
487 _gnutls_x509_encode_and_write_attribute (oid,
488 crq->crq,
489 "certificationRequestInfo.attributes.?LAST",
490 buf, sizeof_buf, 1);
491
492 if (result < 0)
493 {
494 gnutls_assert ();
495 return result;
496 }
497
498 return 0;
499}
500
501/**
502 * gnutls_x509_crq_get_attribute_by_oid - This function will get an attribute of the request
503 * @crq: should contain a gnutls_x509_crq_t structure
504 * @oid: holds an Object Identified in null terminated string
505 * @indx: In case multiple same OIDs exist in the attribute list, this specifies
506 * which to send. Use zero to get the first one.
507 * @buf: a pointer to a structure to hold the attribute data (may be null)
508 * @sizeof_buf: initially holds the size of @buf
509 *
510 * This function will return the attribute in the certificate request specified
511 * by the given Object ID. The attribute will be DER encoded.
512 *
513 * Returns 0 on success.
514 *
515 **/
516int
517gnutls_x509_crq_get_attribute_by_oid (gnutls_x509_crq_t crq,
518 const char *oid, int indx, void *buf,
519 size_t * sizeof_buf)
520{
521 if (crq == NULL)
522 {
523 gnutls_assert ();
524 return GNUTLS_E_INVALID_REQUEST;
525 }
526
527 return parse_attribute (crq->crq, "certificationRequestInfo.attributes",
528 oid, indx, 1, buf, sizeof_buf);
529}
530
531/**
532 * gnutls_x509_crq_set_dn_by_oid - This function will set the Certificate request subject's distinguished name
533 * @crq: should contain a gnutls_x509_crq_t structure
534 * @oid: holds an Object Identifier in a null terminated string
535 * @raw_flag: must be 0, or 1 if the data are DER encoded
536 * @data: a pointer to the input data
537 * @sizeof_data: holds the size of @data
538 *
539 * This function will set the part of the name of the Certificate request subject, specified
540 * by the given OID. The input string should be ASCII or UTF-8 encoded.
541 *
542 * Some helper macros with popular OIDs can be found in gnutls/x509.h
543 * With this function you can only set the known OIDs. You can test
544 * for known OIDs using gnutls_x509_dn_oid_known(). For OIDs that are
545 * not known (by gnutls) you should properly DER encode your data, and
546 * call this function with raw_flag set.
547 *
548 * Returns 0 on success.
549 *
550 **/
551int
552gnutls_x509_crq_set_dn_by_oid (gnutls_x509_crq_t crq, const char *oid,
553 unsigned int raw_flag, const void *data,
554 unsigned int sizeof_data)
555{
556 if (sizeof_data == 0 || data == NULL || crq == NULL)
557 {
558 return GNUTLS_E_INVALID_REQUEST;
559 }
560
561 return _gnutls_x509_set_dn_oid (crq->crq,
562 "certificationRequestInfo.subject", oid,
563 raw_flag, data, sizeof_data);
564}
565
566/**
567 * gnutls_x509_crq_set_version - This function will set the Certificate request version
568 * @crq: should contain a gnutls_x509_crq_t structure
569 * @version: holds the version number. For v1 Requests must be 1.
570 *
571 * This function will set the version of the certificate request. For
572 * version 1 requests this must be one.
573 *
574 * Returns 0 on success.
575 *
576 **/
577int
578gnutls_x509_crq_set_version (gnutls_x509_crq_t crq, unsigned int version)
579{
580 int result;
581 unsigned char null = version;
582
583 if (crq == NULL)
584 {
585 gnutls_assert ();
586 return GNUTLS_E_INVALID_REQUEST;
587 }
588
589 if (null > 0)
590 null--;
591
592 result =
593 asn1_write_value (crq->crq, "certificationRequestInfo.version", &null, 1);
594 if (result != ASN1_SUCCESS)
595 {
596 gnutls_assert ();
597 return _gnutls_asn2err (result);
598 }
599
600 return 0;
601}
602
603/**
604 * gnutls_x509_crq_get_version - This function returns the Certificate request's version number
605 * @crq: should contain a gnutls_x509_crq_t structure
606 *
607 * This function will return the version of the specified Certificate request.
608 *
609 * Returns a negative value on error.
610 *
611 **/
612int
613gnutls_x509_crq_get_version (gnutls_x509_crq_t crq)
614{
615 opaque version[5];
616 int len, result;
617
618 if (crq == NULL)
619 {
620 gnutls_assert ();
621 return GNUTLS_E_INVALID_REQUEST;
622 }
623
624 len = sizeof (version);
625 if ((result =
626 asn1_read_value (crq->crq, "certificationRequestInfo.version",
627 version, &len)) != ASN1_SUCCESS)
628 {
629
630 if (result == ASN1_ELEMENT_NOT_FOUND)
631 return 1; /* the DEFAULT version */
632 gnutls_assert ();
633 return _gnutls_asn2err (result);
634 }
635
636 return (int) version[0] + 1;
637}
638
639/**
640 * gnutls_x509_crq_set_key - This function will associate the Certificate request with a key
641 * @crq: should contain a gnutls_x509_crq_t structure
642 * @key: holds a private key
643 *
644 * This function will set the public parameters from the given private key to the
645 * request. Only RSA keys are currently supported.
646 *
647 * Returns 0 on success.
648 *
649 **/
650int
651gnutls_x509_crq_set_key (gnutls_x509_crq_t crq, gnutls_x509_privkey_t key)
652{
653 int result;
654
655 if (crq == NULL)
656 {
657 gnutls_assert ();
658 return GNUTLS_E_INVALID_REQUEST;
659 }
660
661 result = _gnutls_x509_encode_and_copy_PKI_params (crq->crq,
662 "certificationRequestInfo.subjectPKInfo",
663 key->pk_algorithm,
664 key->params,
665 key->params_size);
666
667 if (result < 0)
668 {
669 gnutls_assert ();
670 return result;
671 }
672
673 return 0;
674}
675
676/**
677 * gnutls_x509_crq_set_challenge_password - This function will set a challenge password
678 * @crq: should contain a gnutls_x509_crq_t structure
679 * @pass: holds a null terminated password
680 *
681 * This function will set a challenge password to be used when revoking the request.
682 *
683 * Returns 0 on success.
684 *
685 **/
686int
687gnutls_x509_crq_set_challenge_password (gnutls_x509_crq_t crq,
688 const char *pass)
689{
690 int result;
691
692 if (crq == NULL)
693 {
694 gnutls_assert ();
695 return GNUTLS_E_INVALID_REQUEST;
696 }
697
698 /* Add the attribute.
699 */
700 result =
701 asn1_write_value (crq->crq, "certificationRequestInfo.attributes",
702 "NEW", 1);
703 if (result != ASN1_SUCCESS)
704 {
705 gnutls_assert ();
706 return _gnutls_asn2err (result);
707 }
708
709 result =
710 _gnutls_x509_encode_and_write_attribute ("1.2.840.113549.1.9.7",
711 crq->crq,
712 "certificationRequestInfo.attributes.?LAST",
713 pass, strlen (pass), 1);
714
715 if (result < 0)
716 {
717 gnutls_assert ();
718 return result;
719 }
720
721 return 0;
722}
723
724/**
725 * gnutls_x509_crq_sign2 - This function will sign a Certificate request with a key
726 * @crq: should contain a gnutls_x509_crq_t structure
727 * @key: holds a private key
728 * @dig: The message digest to use. GNUTLS_DIG_SHA1 is the safe choice unless you know what you're doing.
729 * @flags: must be 0
730 *
731 * This function will sign the certificate request with a private key.
732 * This must be the same key as the one used in gnutls_x509_crt_set_key() since a
733 * certificate request is self signed.
734 *
735 * This must be the last step in a certificate request generation since all
736 * the previously set parameters are now signed.
737 *
738 * Returns 0 on success.
739 *
740 **/
741int
742gnutls_x509_crq_sign2 (gnutls_x509_crq_t crq, gnutls_x509_privkey_t key,
743 gnutls_digest_algorithm_t dig, unsigned int flags)
744{
745 int result;
746 gnutls_datum_t signature;
747
748 if (crq == NULL)
749 {
750 gnutls_assert ();
751 return GNUTLS_E_INVALID_REQUEST;
752 }
753
754 /* Step 1. Self sign the request.
755 */
756 result =
757 _gnutls_x509_sign_tbs (crq->crq, "certificationRequestInfo",
758 dig, key, &signature);
759
760 if (result < 0)
761 {
762 gnutls_assert ();
763 return result;
764 }
765
766 /* Step 2. write the signature (bits)
767 */
768 result =
769 asn1_write_value (crq->crq, "signature", signature.data,
770 signature.size * 8);
771
772 _gnutls_free_datum (&signature);
773
774 if (result != ASN1_SUCCESS)
775 {
776 gnutls_assert ();
777 return _gnutls_asn2err (result);
778 }
779
780 /* Step 3. Write the signatureAlgorithm field.
781 */
782 result = _gnutls_x509_write_sig_params (crq->crq, "signatureAlgorithm",
783 key->pk_algorithm, dig, key->params,
784 key->params_size);
785 if (result < 0)
786 {
787 gnutls_assert ();
788 return result;
789 }
790
791 return 0;
792}
793
794/**
795 * gnutls_x509_crq_sign - This function will sign a Certificate request with a key
796 * @crq: should contain a gnutls_x509_crq_t structure
797 * @key: holds a private key
798 *
799 * This function is the same a gnutls_x509_crq_sign2() with no flags, and
800 * SHA1 as the hash algorithm.
801 *
802 * Returns 0 on success.
803 *
804 **/
805int
806gnutls_x509_crq_sign (gnutls_x509_crq_t crq, gnutls_x509_privkey_t key)
807{
808 return gnutls_x509_crq_sign2 (crq, key, GNUTLS_DIG_SHA1, 0);
809}
810
811/**
812 * gnutls_x509_crq_export - Export the generated certificate request
813 * @crq: Holds the request
814 * @format: the format of output params. One of PEM or DER.
815 * @output_data: will contain a certificate request PEM or DER encoded
816 * @output_data_size: holds the size of output_data (and will be
817 * replaced by the actual size of parameters)
818 *
819 * This function will export the certificate request to a PKCS10
820 *
821 * If the buffer provided is not long enough to hold the output, then
822 * GNUTLS_E_SHORT_MEMORY_BUFFER will be returned and
823 * *output_data_size will be updated.
824 *
825 * If the structure is PEM encoded, it will have a header of "BEGIN
826 * NEW CERTIFICATE REQUEST".
827 *
828 * Return value: In case of failure a negative value will be
829 * returned, and 0 on success.
830 *
831 **/
832int
833gnutls_x509_crq_export (gnutls_x509_crq_t crq,
834 gnutls_x509_crt_fmt_t format, void *output_data,
835 size_t * output_data_size)
836{
837 if (crq == NULL)
838 {
839 gnutls_assert ();
840 return GNUTLS_E_INVALID_REQUEST;
841 }
842
843 return _gnutls_x509_export_int (crq->crq, format, PEM_CRQ,
844 output_data, output_data_size);
845}
846
847/**
848 * gnutls_x509_crq_get_pk_algorithm - This function returns the certificate request's PublicKey algorithm
849 * @crq: should contain a gnutls_x509_crq_t structure
850 * @bits: if bits is non null it will hold the size of the parameters' in bits
851 *
852 * This function will return the public key algorithm of a PKCS \#10
853 * certificate request.
854 *
855 * If bits is non null, it should have enough size to hold the parameters
856 * size in bits. For RSA the bits returned is the modulus.
857 * For DSA the bits returned are of the public
858 * exponent.
859 *
860 * Returns a member of the gnutls_pk_algorithm_t enumeration on success,
861 * or a negative value on error.
862 *
863 **/
864int
865gnutls_x509_crq_get_pk_algorithm (gnutls_x509_crq_t crq, unsigned int *bits)
866{
867 int result;
868
869 if (crq == NULL)
870 {
871 gnutls_assert ();
872 return GNUTLS_E_INVALID_REQUEST;
873 }
874
875 result =
876 _gnutls_x509_get_pk_algorithm (crq->crq,
877 "certificationRequestInfo.subjectPKInfo",
878 bits);
879 if (result < 0)
880 {
881 gnutls_assert ();
882 }
883
884 return result;
885}
886
887#endif /* ENABLE_PKI */
diff --git a/src/daemon/https/x509/crq.h b/src/daemon/https/x509/crq.h
new file mode 100644
index 00000000..80e600b5
--- /dev/null
+++ b/src/daemon/https/x509/crq.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <x509.h>
26
27typedef struct gnutls_x509_crq_int
28{
29 ASN1_TYPE crq;
30} gnutls_x509_crq_int;
diff --git a/src/daemon/https/x509/dn.c b/src/daemon/https/x509/dn.c
new file mode 100644
index 00000000..c356aac1
--- /dev/null
+++ b/src/daemon/https/x509/dn.c
@@ -0,0 +1,1140 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26#include <libtasn1.h>
27#include <gnutls_datum.h>
28#include <gnutls_global.h>
29#include <gnutls_errors.h>
30#include <gnutls_str.h>
31#include <common.h>
32#include <gnutls_num.h>
33#include <dn.h>
34
35/* This file includes all the required to parse an X.509 Distriguished
36 * Name (you need a parser just to read a name in the X.509 protoocols!!!)
37 */
38
39/* Converts the given OID to an ldap acceptable string or
40 * a dotted OID.
41 */
42static const char *
43oid2ldap_string (const char *oid)
44{
45 const char *ret;
46
47 ret = _gnutls_x509_oid2ldap_string (oid);
48 if (ret)
49 return ret;
50
51 /* else return the OID in dotted format */
52 return oid;
53}
54
55/* Escapes a string following the rules from RFC2253.
56 */
57static char *
58str_escape (char *str, char *buffer, unsigned int buffer_size)
59{
60 int str_length, j, i;
61
62 if (str == NULL || buffer == NULL)
63 return NULL;
64
65 str_length = MIN (strlen (str), buffer_size - 1);
66
67 for (i = j = 0; i < str_length; i++)
68 {
69 if (str[i] == ',' || str[i] == '+' || str[i] == '"'
70 || str[i] == '\\' || str[i] == '<' || str[i] == '>'
71 || str[i] == ';')
72 buffer[j++] = '\\';
73
74 buffer[j++] = str[i];
75 }
76
77 /* null terminate the string */
78 buffer[j] = 0;
79
80 return buffer;
81}
82
83/* Parses an X509 DN in the asn1_struct, and puts the output into
84 * the string buf. The output is an LDAP encoded DN.
85 *
86 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
87 * That is to point in the rndSequence.
88 */
89int
90_gnutls_x509_parse_dn (ASN1_TYPE asn1_struct,
91 const char *asn1_rdn_name, char *buf,
92 size_t * sizeof_buf)
93{
94 gnutls_string out_str;
95 int k2, k1, result;
96 char tmpbuffer1[MAX_NAME_SIZE];
97 char tmpbuffer2[MAX_NAME_SIZE];
98 char tmpbuffer3[MAX_NAME_SIZE];
99 opaque value[MAX_STRING_LEN], *value2 = NULL;
100 char *escaped = NULL;
101 const char *ldap_desc;
102 char oid[128];
103 int len, printable;
104 char *string = NULL;
105 size_t sizeof_string, sizeof_escaped;
106
107 if (sizeof_buf == NULL)
108 {
109 gnutls_assert ();
110 return GNUTLS_E_INVALID_REQUEST;
111 }
112
113 if (*sizeof_buf > 0 && buf)
114 buf[0] = 0;
115 else
116 *sizeof_buf = 0;
117
118 _gnutls_string_init (&out_str, gnutls_malloc, gnutls_realloc, gnutls_free);
119
120 k1 = 0;
121 do
122 {
123
124 k1++;
125 /* create a string like "tbsCertList.issuer.rdnSequence.?1"
126 */
127 if (asn1_rdn_name[0] != 0)
128 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", asn1_rdn_name,
129 k1);
130 else
131 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
132
133 len = sizeof (value) - 1;
134 result = asn1_read_value (asn1_struct, tmpbuffer1, value, &len);
135
136 if (result == ASN1_ELEMENT_NOT_FOUND)
137 {
138 break;
139 }
140
141 if (result != ASN1_VALUE_NOT_FOUND)
142 {
143 gnutls_assert ();
144 result = _gnutls_asn2err (result);
145 goto cleanup;
146 }
147
148 k2 = 0;
149
150 do
151 { /* Move to the attibute type and values
152 */
153 k2++;
154
155 if (tmpbuffer1[0] != 0)
156 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "%s.?%u", tmpbuffer1,
157 k2);
158 else
159 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "?%u", k2);
160
161 /* Try to read the RelativeDistinguishedName attributes.
162 */
163
164 len = sizeof (value) - 1;
165 result = asn1_read_value (asn1_struct, tmpbuffer2, value, &len);
166
167 if (result == ASN1_ELEMENT_NOT_FOUND)
168 break;
169 if (result != ASN1_VALUE_NOT_FOUND)
170 {
171 gnutls_assert ();
172 result = _gnutls_asn2err (result);
173 goto cleanup;
174 }
175
176 /* Read the OID
177 */
178 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
179 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
180
181 len = sizeof (oid) - 1;
182 result = asn1_read_value (asn1_struct, tmpbuffer3, oid, &len);
183
184 if (result == ASN1_ELEMENT_NOT_FOUND)
185 break;
186 else if (result != ASN1_SUCCESS)
187 {
188 gnutls_assert ();
189 result = _gnutls_asn2err (result);
190 goto cleanup;
191 }
192
193 /* Read the Value
194 */
195 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
196 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".value");
197
198 len = 0;
199 result = asn1_read_value (asn1_struct, tmpbuffer3, NULL, &len);
200
201 value2 = gnutls_malloc (len);
202 if (value2 == NULL)
203 {
204 gnutls_assert ();
205 result = GNUTLS_E_MEMORY_ERROR;
206 goto cleanup;
207 }
208
209 result = asn1_read_value (asn1_struct, tmpbuffer3, value2, &len);
210
211 if (result != ASN1_SUCCESS)
212 {
213 gnutls_assert ();
214 result = _gnutls_asn2err (result);
215 goto cleanup;
216 }
217#define STR_APPEND(y) if ((result=_gnutls_string_append_str( &out_str, y)) < 0) { \
218 gnutls_assert(); \
219 goto cleanup; \
220}
221 /* The encodings of adjoining RelativeDistinguishedNames are separated
222 * by a comma character (',' ASCII 44).
223 */
224
225 /* Where there is a multi-valued RDN, the outputs from adjoining
226 * AttributeTypeAndValues are separated by a plus ('+' ASCII 43)
227 * character.
228 */
229 if (k1 != 1)
230 { /* the first time do not append a comma */
231 if (k2 != 1)
232 { /* adjoining multi-value RDN */
233 STR_APPEND ("+");
234 }
235 else
236 {
237 STR_APPEND (",");
238 }
239 }
240
241 ldap_desc = oid2ldap_string (oid);
242 printable = _gnutls_x509_oid_data_printable (oid);
243
244 sizeof_escaped = 2 * len + 1;
245
246 escaped = gnutls_malloc (sizeof_escaped);
247 if (escaped == NULL)
248 {
249 gnutls_assert ();
250 result = GNUTLS_E_MEMORY_ERROR;
251 goto cleanup;
252 }
253
254 sizeof_string = 2 * len + 2; /* in case it is not printable */
255
256 string = gnutls_malloc (sizeof_string);
257 if (string == NULL)
258 {
259 gnutls_assert ();
260 result = GNUTLS_E_MEMORY_ERROR;
261 goto cleanup;
262 }
263
264 STR_APPEND (ldap_desc);
265 STR_APPEND ("=");
266 result = 0;
267
268 if (printable)
269 result =
270 _gnutls_x509_oid_data2string (oid,
271 value2, len,
272 string, &sizeof_string);
273
274 if (!printable || result < 0)
275 result =
276 _gnutls_x509_data2hex (value2, len, string, &sizeof_string);
277
278 if (result < 0)
279 {
280 gnutls_assert ();
281 _gnutls_x509_log
282 ("Found OID: '%s' with value '%s'\n",
283 oid, _gnutls_bin2hex (value2, len, escaped, sizeof_escaped));
284 goto cleanup;
285 }
286 STR_APPEND (str_escape (string, escaped, sizeof_escaped));
287 gnutls_free (string);
288 string = NULL;
289
290 gnutls_free (escaped);
291 escaped = NULL;
292 gnutls_free (value2);
293 value2 = NULL;
294
295 }
296 while (1);
297
298 }
299 while (1);
300
301 if (out_str.length >= (unsigned int) *sizeof_buf)
302 {
303 gnutls_assert ();
304 *sizeof_buf = out_str.length + 1;
305 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
306 goto cleanup;
307 }
308
309 if (buf)
310 {
311 memcpy (buf, out_str.data, out_str.length);
312 buf[out_str.length] = 0;
313 }
314 *sizeof_buf = out_str.length;
315
316 result = 0;
317
318cleanup:
319 gnutls_free (value2);
320 gnutls_free (string);
321 gnutls_free (escaped);
322 _gnutls_string_clear (&out_str);
323 return result;
324}
325
326/* Parses an X509 DN in the asn1_struct, and searches for the
327 * given OID in the DN.
328 *
329 * If raw_flag == 0, the output will be encoded in the LDAP way. (#hex for non printable)
330 * Otherwise the raw DER data are returned.
331 *
332 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
333 * That is to point in the rndSequence.
334 *
335 * indx specifies which OID to return. Ie 0 means return the first specified
336 * OID found, 1 the second etc.
337 */
338int
339_gnutls_x509_parse_dn_oid (ASN1_TYPE asn1_struct,
340 const char *asn1_rdn_name,
341 const char *given_oid, int indx,
342 unsigned int raw_flag,
343 void *buf, size_t * sizeof_buf)
344{
345 int k2, k1, result;
346 char tmpbuffer1[MAX_NAME_SIZE];
347 char tmpbuffer2[MAX_NAME_SIZE];
348 char tmpbuffer3[MAX_NAME_SIZE];
349 opaque value[256];
350 char oid[128];
351 int len, printable;
352 int i = 0;
353 char *cbuf = buf;
354
355 if (cbuf == NULL)
356 *sizeof_buf = 0;
357 else
358 cbuf[0] = 0;
359
360 k1 = 0;
361 do
362 {
363
364 k1++;
365 /* create a string like "tbsCertList.issuer.rdnSequence.?1"
366 */
367 if (asn1_rdn_name[0] != 0)
368 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", asn1_rdn_name,
369 k1);
370 else
371 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
372
373 len = sizeof (value) - 1;
374 result = asn1_read_value (asn1_struct, tmpbuffer1, value, &len);
375
376 if (result == ASN1_ELEMENT_NOT_FOUND)
377 {
378 gnutls_assert ();
379 break;
380 }
381
382 if (result != ASN1_VALUE_NOT_FOUND)
383 {
384 gnutls_assert ();
385 result = _gnutls_asn2err (result);
386 goto cleanup;
387 }
388
389 k2 = 0;
390
391 do
392 { /* Move to the attibute type and values
393 */
394 k2++;
395
396 if (tmpbuffer1[0] != 0)
397 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "%s.?%u", tmpbuffer1,
398 k2);
399 else
400 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "?%u", k2);
401
402 /* Try to read the RelativeDistinguishedName attributes.
403 */
404
405 len = sizeof (value) - 1;
406 result = asn1_read_value (asn1_struct, tmpbuffer2, value, &len);
407
408 if (result == ASN1_ELEMENT_NOT_FOUND)
409 {
410 break;
411 }
412 if (result != ASN1_VALUE_NOT_FOUND)
413 {
414 gnutls_assert ();
415 result = _gnutls_asn2err (result);
416 goto cleanup;
417 }
418
419 /* Read the OID
420 */
421 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
422 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
423
424 len = sizeof (oid) - 1;
425 result = asn1_read_value (asn1_struct, tmpbuffer3, oid, &len);
426
427 if (result == ASN1_ELEMENT_NOT_FOUND)
428 break;
429 else if (result != ASN1_SUCCESS)
430 {
431 gnutls_assert ();
432 result = _gnutls_asn2err (result);
433 goto cleanup;
434 }
435
436 if (strcmp (oid, given_oid) == 0 && indx == i++)
437 { /* Found the OID */
438
439 /* Read the Value
440 */
441 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
442 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".value");
443
444 len = *sizeof_buf;
445 result = asn1_read_value (asn1_struct, tmpbuffer3, buf, &len);
446
447 if (result != ASN1_SUCCESS)
448 {
449 gnutls_assert ();
450 if (result == ASN1_MEM_ERROR)
451 *sizeof_buf = len;
452 result = _gnutls_asn2err (result);
453 goto cleanup;
454 }
455
456 if (raw_flag != 0)
457 {
458 if ((unsigned) len > *sizeof_buf)
459 {
460 *sizeof_buf = len;
461 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
462 goto cleanup;
463 }
464 *sizeof_buf = len;
465
466 return 0;
467
468 }
469 else
470 { /* parse data. raw_flag == 0 */
471 printable = _gnutls_x509_oid_data_printable (oid);
472
473 if (printable == 1)
474 result =
475 _gnutls_x509_oid_data2string (oid, buf, len,
476 cbuf, sizeof_buf);
477 else
478 result =
479 _gnutls_x509_data2hex (buf, len, cbuf, sizeof_buf);
480
481 if (result < 0)
482 {
483 gnutls_assert ();
484 goto cleanup;
485 }
486
487 return 0;
488
489 } /* raw_flag == 0 */
490 }
491 }
492 while (1);
493
494 }
495 while (1);
496
497 gnutls_assert ();
498
499 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
500
501cleanup:
502 return result;
503}
504
505
506/* Parses an X509 DN in the asn1_struct, and returns the requested
507 * DN OID.
508 *
509 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer.rdnSequence".
510 * That is to point in the rndSequence.
511 *
512 * indx specifies which OID to return. Ie 0 means return the first specified
513 * OID found, 1 the second etc.
514 */
515int
516_gnutls_x509_get_dn_oid (ASN1_TYPE asn1_struct,
517 const char *asn1_rdn_name,
518 int indx, void *_oid, size_t * sizeof_oid)
519{
520 int k2, k1, result;
521 char tmpbuffer1[MAX_NAME_SIZE];
522 char tmpbuffer2[MAX_NAME_SIZE];
523 char tmpbuffer3[MAX_NAME_SIZE];
524 char value[256];
525 char oid[128];
526 int len;
527 int i = 0;
528
529 k1 = 0;
530 do
531 {
532
533 k1++;
534 /* create a string like "tbsCertList.issuer.rdnSequence.?1"
535 */
536 if (asn1_rdn_name[0] != 0)
537 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "%s.?%u", asn1_rdn_name,
538 k1);
539 else
540 snprintf (tmpbuffer1, sizeof (tmpbuffer1), "?%u", k1);
541
542 len = sizeof (value) - 1;
543 result = asn1_read_value (asn1_struct, tmpbuffer1, value, &len);
544
545 if (result == ASN1_ELEMENT_NOT_FOUND)
546 {
547 gnutls_assert ();
548 break;
549 }
550
551 if (result != ASN1_VALUE_NOT_FOUND)
552 {
553 gnutls_assert ();
554 result = _gnutls_asn2err (result);
555 goto cleanup;
556 }
557
558 k2 = 0;
559
560 do
561 { /* Move to the attibute type and values
562 */
563 k2++;
564
565 if (tmpbuffer1[0] != 0)
566 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "%s.?%u", tmpbuffer1,
567 k2);
568 else
569 snprintf (tmpbuffer2, sizeof (tmpbuffer2), "?%u", k2);
570
571 /* Try to read the RelativeDistinguishedName attributes.
572 */
573
574 len = sizeof (value) - 1;
575 result = asn1_read_value (asn1_struct, tmpbuffer2, value, &len);
576
577 if (result == ASN1_ELEMENT_NOT_FOUND)
578 {
579 break;
580 }
581 if (result != ASN1_VALUE_NOT_FOUND)
582 {
583 gnutls_assert ();
584 result = _gnutls_asn2err (result);
585 goto cleanup;
586 }
587
588 /* Read the OID
589 */
590 _gnutls_str_cpy (tmpbuffer3, sizeof (tmpbuffer3), tmpbuffer2);
591 _gnutls_str_cat (tmpbuffer3, sizeof (tmpbuffer3), ".type");
592
593 len = sizeof (oid) - 1;
594 result = asn1_read_value (asn1_struct, tmpbuffer3, oid, &len);
595
596 if (result == ASN1_ELEMENT_NOT_FOUND)
597 break;
598 else if (result != ASN1_SUCCESS)
599 {
600 gnutls_assert ();
601 result = _gnutls_asn2err (result);
602 goto cleanup;
603 }
604
605 if (indx == i++)
606 { /* Found the OID */
607
608 len = strlen (oid) + 1;
609
610 if (*sizeof_oid < (unsigned) len)
611 {
612 *sizeof_oid = len;
613 gnutls_assert ();
614 return GNUTLS_E_SHORT_MEMORY_BUFFER;
615 }
616
617 memcpy (_oid, oid, len);
618 *sizeof_oid = len - 1;
619
620 return 0;
621 }
622 }
623 while (1);
624
625 }
626 while (1);
627
628 gnutls_assert ();
629
630 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
631
632cleanup:
633 return result;
634}
635
636/* This will encode and write the AttributeTypeAndValue field.
637 * 'multi' must be zero if writing an AttributeTypeAndValue, and 1 if Attribute.
638 * In all cases only one value is written.
639 */
640int
641_gnutls_x509_encode_and_write_attribute (const char *given_oid,
642 ASN1_TYPE asn1_struct,
643 const char *where,
644 const void *_data,
645 int sizeof_data, int multi)
646{
647 const char *val_name;
648 const opaque *data = _data;
649 char tmp[128];
650 ASN1_TYPE c2;
651 int result;
652
653
654 /* Find how to encode the data.
655 */
656 val_name = asn1_find_structure_from_oid (_gnutls_get_pkix (), given_oid);
657 if (val_name == NULL)
658 {
659 gnutls_assert ();
660 return GNUTLS_E_X509_UNSUPPORTED_OID;
661 }
662
663 _gnutls_str_cpy (tmp, sizeof (tmp), "PKIX1.");
664 _gnutls_str_cat (tmp, sizeof (tmp), val_name);
665
666 result = asn1_create_element (_gnutls_get_pkix (), tmp, &c2);
667 if (result != ASN1_SUCCESS)
668 {
669 gnutls_assert ();
670 return _gnutls_asn2err (result);
671 }
672
673 tmp[0] = 0;
674
675 if ((result = _gnutls_x509_oid_data_choice (given_oid)) > 0)
676 {
677 char *string_type;
678 int i;
679
680 string_type = "printableString";
681
682 /* Check if the data is plain ascii, and use
683 * the UTF8 string type if not.
684 */
685 for (i = 0; i < sizeof_data; i++)
686 {
687 if (!isascii (data[i]))
688 {
689 string_type = "utf8String";
690 break;
691 }
692 }
693
694 /* if the type is a CHOICE then write the
695 * type we'll use.
696 */
697 result = asn1_write_value (c2, "", string_type, 1);
698 if (result != ASN1_SUCCESS)
699 {
700 gnutls_assert ();
701 asn1_delete_structure (&c2);
702 return _gnutls_asn2err (result);
703 }
704
705 _gnutls_str_cpy (tmp, sizeof (tmp), string_type);
706 }
707
708 result = asn1_write_value (c2, tmp, data, sizeof_data);
709 if (result != ASN1_SUCCESS)
710 {
711 gnutls_assert ();
712 asn1_delete_structure (&c2);
713 return _gnutls_asn2err (result);
714 }
715
716
717 /* write the data (value)
718 */
719
720 _gnutls_str_cpy (tmp, sizeof (tmp), where);
721 _gnutls_str_cat (tmp, sizeof (tmp), ".value");
722
723 if (multi != 0)
724 { /* if not writing an AttributeTypeAndValue, but an Attribute */
725 _gnutls_str_cat (tmp, sizeof (tmp), "s"); /* values */
726
727 result = asn1_write_value (asn1_struct, tmp, "NEW", 1);
728 if (result != ASN1_SUCCESS)
729 {
730 gnutls_assert ();
731 return _gnutls_asn2err (result);
732 }
733
734 _gnutls_str_cat (tmp, sizeof (tmp), ".?LAST");
735
736 }
737
738 result = _gnutls_x509_der_encode_and_copy (c2, "", asn1_struct, tmp, 0);
739 if (result < 0)
740 {
741 gnutls_assert ();
742 return result;
743 }
744
745 /* write the type
746 */
747 _gnutls_str_cpy (tmp, sizeof (tmp), where);
748 _gnutls_str_cat (tmp, sizeof (tmp), ".type");
749
750 result = asn1_write_value (asn1_struct, tmp, given_oid, 1);
751 if (result != ASN1_SUCCESS)
752 {
753 gnutls_assert ();
754 return _gnutls_asn2err (result);
755 }
756
757 return 0;
758}
759
760/* This will write the AttributeTypeAndValue field. The data must be already DER encoded.
761 * 'multi' must be zero if writing an AttributeTypeAndValue, and 1 if Attribute.
762 * In all cases only one value is written.
763 */
764int
765_gnutls_x509_write_attribute (const char *given_oid,
766 ASN1_TYPE asn1_struct, const char *where,
767 const void *_data, int sizeof_data, int multi)
768{
769 char tmp[128];
770 int result;
771
772 /* write the data (value)
773 */
774
775 _gnutls_str_cpy (tmp, sizeof (tmp), where);
776 _gnutls_str_cat (tmp, sizeof (tmp), ".value");
777
778 if (multi != 0)
779 { /* if not writing an AttributeTypeAndValue, but an Attribute */
780 _gnutls_str_cat (tmp, sizeof (tmp), "s"); /* values */
781
782 result = asn1_write_value (asn1_struct, tmp, "NEW", 1);
783 if (result != ASN1_SUCCESS)
784 {
785 gnutls_assert ();
786 return _gnutls_asn2err (result);
787 }
788
789 _gnutls_str_cat (tmp, sizeof (tmp), ".?LAST");
790
791 }
792
793 result = asn1_write_value (asn1_struct, tmp, _data, sizeof_data);
794 if (result < 0)
795 {
796 gnutls_assert ();
797 return _gnutls_asn2err (result);
798 }
799
800 /* write the type
801 */
802 _gnutls_str_cpy (tmp, sizeof (tmp), where);
803 _gnutls_str_cat (tmp, sizeof (tmp), ".type");
804
805 result = asn1_write_value (asn1_struct, tmp, given_oid, 1);
806 if (result != ASN1_SUCCESS)
807 {
808 gnutls_assert ();
809 return _gnutls_asn2err (result);
810 }
811
812 return 0;
813}
814
815
816/* Decodes an X.509 Attribute (if multi==1) or an AttributeTypeAndValue
817 * otherwise.
818 *
819 * octet_string should be non zero if we are to decode octet strings after
820 * decoding.
821 *
822 * The output is allocated and stored in value.
823 */
824int
825_gnutls_x509_decode_and_read_attribute (ASN1_TYPE asn1_struct,
826 const char *where, char *oid,
827 int oid_size, gnutls_datum_t * value,
828 int multi, int octet_string)
829{
830 char tmpbuffer[128];
831 int len, result;
832
833 /* Read the OID
834 */
835 _gnutls_str_cpy (tmpbuffer, sizeof (tmpbuffer), where);
836 _gnutls_str_cat (tmpbuffer, sizeof (tmpbuffer), ".type");
837
838 len = oid_size - 1;
839 result = asn1_read_value (asn1_struct, tmpbuffer, oid, &len);
840
841 if (result != ASN1_SUCCESS)
842 {
843 gnutls_assert ();
844 result = _gnutls_asn2err (result);
845 return result;
846 }
847
848 /* Read the Value
849 */
850
851 _gnutls_str_cpy (tmpbuffer, sizeof (tmpbuffer), where);
852 _gnutls_str_cat (tmpbuffer, sizeof (tmpbuffer), ".value");
853
854 if (multi)
855 _gnutls_str_cat (tmpbuffer, sizeof (tmpbuffer), "s.?1"); /* .values.?1 */
856
857 result =
858 _gnutls_x509_read_value (asn1_struct, tmpbuffer, value, octet_string);
859 if (result < 0)
860 {
861 gnutls_assert ();
862 return result;
863 }
864
865 return 0;
866
867}
868
869/* Sets an X509 DN in the asn1_struct, and puts the given OID in the DN.
870 * The input is assumed to be raw data.
871 *
872 * asn1_rdn_name must be a string in the form "tbsCertificate.issuer".
873 * That is to point before the rndSequence.
874 *
875 */
876int
877_gnutls_x509_set_dn_oid (ASN1_TYPE asn1_struct,
878 const char *asn1_name, const char *given_oid,
879 int raw_flag, const char *name, int sizeof_name)
880{
881 int result;
882 char tmp[MAX_NAME_SIZE], asn1_rdn_name[MAX_NAME_SIZE];
883
884 if (sizeof_name == 0 || name == NULL)
885 {
886 gnutls_assert ();
887 return GNUTLS_E_INVALID_REQUEST;
888 }
889
890 /* create the rdnSequence
891 */
892 result = asn1_write_value (asn1_struct, asn1_name, "rdnSequence", 1);
893 if (result != ASN1_SUCCESS)
894 {
895 gnutls_assert ();
896 return _gnutls_asn2err (result);
897 }
898
899 _gnutls_str_cpy (asn1_rdn_name, sizeof (asn1_rdn_name), asn1_name);
900 _gnutls_str_cat (asn1_rdn_name, sizeof (asn1_rdn_name), ".rdnSequence");
901
902 /* create a new element
903 */
904 result = asn1_write_value (asn1_struct, asn1_rdn_name, "NEW", 1);
905 if (result != ASN1_SUCCESS)
906 {
907 gnutls_assert ();
908 return _gnutls_asn2err (result);
909 }
910
911 _gnutls_str_cpy (tmp, sizeof (tmp), asn1_rdn_name);
912 _gnutls_str_cat (tmp, sizeof (tmp), ".?LAST");
913
914 /* create the set with only one element
915 */
916 result = asn1_write_value (asn1_struct, tmp, "NEW", 1);
917 if (result != ASN1_SUCCESS)
918 {
919 gnutls_assert ();
920 return _gnutls_asn2err (result);
921 }
922
923
924 /* Encode and write the data
925 */
926 _gnutls_str_cpy (tmp, sizeof (tmp), asn1_rdn_name);
927 _gnutls_str_cat (tmp, sizeof (tmp), ".?LAST.?LAST");
928
929 if (!raw_flag)
930 {
931 result =
932 _gnutls_x509_encode_and_write_attribute (given_oid,
933 asn1_struct,
934 tmp, name, sizeof_name, 0);
935 }
936 else
937 {
938 result =
939 _gnutls_x509_write_attribute (given_oid, asn1_struct,
940 tmp, name, sizeof_name, 0);
941 }
942
943 if (result < 0)
944 {
945 gnutls_assert ();
946 return result;
947 }
948
949 return 0;
950}
951
952
953/**
954 * gnutls_x509_rdn_get - This function parses an RDN sequence and returns a string
955 * @idn: should contain a DER encoded RDN sequence
956 * @buf: a pointer to a structure to hold the peer's name
957 * @sizeof_buf: holds the size of @buf
958 *
959 * This function will return the name of the given RDN sequence. The
960 * name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as described in
961 * RFC2253.
962 *
963 * If the provided buffer is not long enough, returns
964 * GNUTLS_E_SHORT_MEMORY_BUFFER and *sizeof_buf will be updated. On
965 * success 0 is returned.
966 *
967 **/
968int
969gnutls_x509_rdn_get (const gnutls_datum_t * idn,
970 char *buf, size_t * sizeof_buf)
971{
972 int result;
973 ASN1_TYPE dn = ASN1_TYPE_EMPTY;
974
975 if (sizeof_buf == 0)
976 {
977 gnutls_assert ();
978 return GNUTLS_E_INVALID_REQUEST;
979 }
980
981 if (buf)
982 buf[0] = 0;
983
984
985 if ((result =
986 asn1_create_element (_gnutls_get_pkix (),
987 "PKIX1.Name", &dn)) != ASN1_SUCCESS)
988 {
989 gnutls_assert ();
990 return _gnutls_asn2err (result);
991 }
992
993 result = asn1_der_decoding (&dn, idn->data, idn->size, NULL);
994 if (result != ASN1_SUCCESS)
995 {
996 /* couldn't decode DER */
997 gnutls_assert ();
998 asn1_delete_structure (&dn);
999 return _gnutls_asn2err (result);
1000 }
1001
1002 result = _gnutls_x509_parse_dn (dn, "rdnSequence", buf, sizeof_buf);
1003
1004 asn1_delete_structure (&dn);
1005 return result;
1006
1007}
1008
1009/**
1010 * gnutls_x509_rdn_get_by_oid - This function parses an RDN sequence and returns a string
1011 * @idn: should contain a DER encoded RDN sequence
1012 * @oid: an Object Identifier
1013 * @indx: In case multiple same OIDs exist in the RDN indicates which
1014 * to send. Use 0 for the first one.
1015 * @raw_flag: If non zero then the raw DER data are returned.
1016 * @buf: a pointer to a structure to hold the peer's name
1017 * @sizeof_buf: holds the size of @buf
1018 *
1019 * This function will return the name of the given Object identifier,
1020 * of the RDN sequence. The name will be encoded using the rules
1021 * from RFC2253.
1022 *
1023 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER and updates *sizeof_buf if
1024 * the provided buffer is not long enough, and 0 on success.
1025 *
1026 **/
1027int
1028gnutls_x509_rdn_get_by_oid (const gnutls_datum_t * idn, const char *oid,
1029 int indx, unsigned int raw_flag,
1030 void *buf, size_t * sizeof_buf)
1031{
1032 int result;
1033 ASN1_TYPE dn = ASN1_TYPE_EMPTY;
1034
1035 if (sizeof_buf == 0)
1036 {
1037 return GNUTLS_E_INVALID_REQUEST;
1038 }
1039
1040 if ((result =
1041 asn1_create_element (_gnutls_get_pkix (),
1042 "PKIX1.Name", &dn)) != ASN1_SUCCESS)
1043 {
1044 gnutls_assert ();
1045 return _gnutls_asn2err (result);
1046 }
1047
1048 result = asn1_der_decoding (&dn, idn->data, idn->size, NULL);
1049 if (result != ASN1_SUCCESS)
1050 {
1051 /* couldn't decode DER */
1052 gnutls_assert ();
1053 asn1_delete_structure (&dn);
1054 return _gnutls_asn2err (result);
1055 }
1056
1057 result =
1058 _gnutls_x509_parse_dn_oid (dn, "rdnSequence", oid, indx,
1059 raw_flag, buf, sizeof_buf);
1060
1061 asn1_delete_structure (&dn);
1062 return result;
1063
1064}
1065
1066/**
1067 * gnutls_x509_rdn_get_oid - This function parses an RDN sequence and returns an OID.
1068 * @idn: should contain a DER encoded RDN sequence
1069 * @indx: Indicates which OID to return. Use 0 for the first one.
1070 * @oid: a pointer to a structure to hold the peer's name OID
1071 * @sizeof_oid: holds the size of @oid
1072 *
1073 * This function will return the specified Object identifier, of the
1074 * RDN sequence.
1075 *
1076 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER and updates *sizeof_buf if
1077 * the provided buffer is not long enough, and 0 on success.
1078 *
1079 **/
1080int
1081gnutls_x509_rdn_get_oid (const gnutls_datum_t * idn,
1082 int indx, void *buf, size_t * sizeof_buf)
1083{
1084 int result;
1085 ASN1_TYPE dn = ASN1_TYPE_EMPTY;
1086
1087 if (sizeof_buf == 0)
1088 {
1089 return GNUTLS_E_INVALID_REQUEST;
1090 }
1091
1092 if ((result =
1093 asn1_create_element (_gnutls_get_pkix (),
1094 "PKIX1.Name", &dn)) != ASN1_SUCCESS)
1095 {
1096 gnutls_assert ();
1097 return _gnutls_asn2err (result);
1098 }
1099
1100 result = asn1_der_decoding (&dn, idn->data, idn->size, NULL);
1101 if (result != ASN1_SUCCESS)
1102 {
1103 /* couldn't decode DER */
1104 gnutls_assert ();
1105 asn1_delete_structure (&dn);
1106 return _gnutls_asn2err (result);
1107 }
1108
1109 result = _gnutls_x509_get_dn_oid (dn, "rdnSequence", indx, buf, sizeof_buf);
1110
1111 asn1_delete_structure (&dn);
1112 return result;
1113
1114}
1115
1116/*
1117 * Compares the DER encoded part of a DN.
1118 *
1119 * FIXME: use a real DN comparison algorithm.
1120 *
1121 * Returns 1 if the DN's match and zero if they don't match. Otherwise
1122 * a negative value is returned to indicate error.
1123 */
1124int
1125_gnutls_x509_compare_raw_dn (const gnutls_datum_t * dn1,
1126 const gnutls_datum_t * dn2)
1127{
1128
1129 if (dn1->size != dn2->size)
1130 {
1131 gnutls_assert ();
1132 return 0;
1133 }
1134 if (memcmp (dn1->data, dn2->data, dn2->size) != 0)
1135 {
1136 gnutls_assert ();
1137 return 0;
1138 }
1139 return 1; /* they match */
1140}
diff --git a/src/daemon/https/x509/dn.h b/src/daemon/https/x509/dn.h
new file mode 100644
index 00000000..93a9262c
--- /dev/null
+++ b/src/daemon/https/x509/dn.h
@@ -0,0 +1,58 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#ifndef DN_H
26# define DN_H
27
28/* Some OIDs usually found in Distinguished names
29 */
30#define OID_X520_COUNTRY_NAME "2.5.4.6"
31#define OID_X520_ORGANIZATION_NAME "2.5.4.10"
32#define OID_X520_ORGANIZATIONAL_UNIT_NAME "2.5.4.11"
33#define OID_X520_COMMON_NAME "2.5.4.3"
34#define OID_X520_LOCALITY_NAME "2.5.4.7"
35#define OID_X520_STATE_OR_PROVINCE_NAME "2.5.4.8"
36#define OID_LDAP_DC "0.9.2342.19200300.100.1.25"
37#define OID_LDAP_UID "0.9.2342.19200300.100.1.1"
38#define OID_PKCS9_EMAIL "1.2.840.113549.1.9.1"
39
40int _gnutls_x509_parse_dn (ASN1_TYPE asn1_struct,
41 const char *asn1_rdn_name, char *buf,
42 size_t * sizeof_buf);
43
44int _gnutls_x509_parse_dn_oid (ASN1_TYPE asn1_struct,
45 const char *asn1_rdn_name, const char *oid,
46 int indx, unsigned int raw_flag, void *buf,
47 size_t * sizeof_buf);
48
49int _gnutls_x509_set_dn_oid (ASN1_TYPE asn1_struct,
50 const char *asn1_rdn_name, const char *oid,
51 int raw_flag, const char *name, int sizeof_name);
52
53int _gnutls_x509_get_dn_oid (ASN1_TYPE asn1_struct,
54 const char *asn1_rdn_name,
55 int indx, void *_oid, size_t * sizeof_oid);
56
57
58#endif
diff --git a/src/daemon/https/x509/dsa.c b/src/daemon/https/x509/dsa.c
new file mode 100644
index 00000000..af403911
--- /dev/null
+++ b/src/daemon/https/x509/dsa.c
@@ -0,0 +1,142 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file contains code for DSA keys.
26 */
27
28#include <gnutls_int.h>
29#include <gnutls_errors.h>
30#include <gnutls_datum.h>
31#include <debug.h>
32
33/* resarr will contain: p(0), q(1), g(2), y(3), x(4).
34 */
35int
36_gnutls_dsa_generate_params (mpi_t * resarr, int *resarr_len, int bits)
37{
38
39 int ret;
40 gcry_sexp_t parms, key, list;
41
42 /* FIXME: Remove me once we depend on 1.3.1 */
43 if (bits > 1024 && gcry_check_version ("1.3.1") == NULL)
44 {
45 gnutls_assert ();
46 return GNUTLS_E_INVALID_REQUEST;
47 }
48
49 if (bits < 512)
50 {
51 gnutls_assert ();
52 return GNUTLS_E_INVALID_REQUEST;
53 }
54
55 ret = gcry_sexp_build (&parms, NULL, "(genkey(dsa(nbits %d)))", bits);
56 if (ret != 0)
57 {
58 gnutls_assert ();
59 return GNUTLS_E_INTERNAL_ERROR;
60 }
61
62 /* generate the DSA key
63 */
64 ret = gcry_pk_genkey (&key, parms);
65 gcry_sexp_release (parms);
66
67 if (ret != 0)
68 {
69 gnutls_assert ();
70 return GNUTLS_E_INTERNAL_ERROR;
71 }
72
73 list = gcry_sexp_find_token (key, "p", 0);
74 if (list == NULL)
75 {
76 gnutls_assert ();
77 gcry_sexp_release (key);
78 return GNUTLS_E_INTERNAL_ERROR;
79 }
80
81 resarr[0] = gcry_sexp_nth_mpi (list, 1, 0);
82 gcry_sexp_release (list);
83
84 list = gcry_sexp_find_token (key, "q", 0);
85 if (list == NULL)
86 {
87 gnutls_assert ();
88 gcry_sexp_release (key);
89 return GNUTLS_E_INTERNAL_ERROR;
90 }
91
92 resarr[1] = gcry_sexp_nth_mpi (list, 1, 0);
93 gcry_sexp_release (list);
94
95 list = gcry_sexp_find_token (key, "g", 0);
96 if (list == NULL)
97 {
98 gnutls_assert ();
99 gcry_sexp_release (key);
100 return GNUTLS_E_INTERNAL_ERROR;
101 }
102
103 resarr[2] = gcry_sexp_nth_mpi (list, 1, 0);
104 gcry_sexp_release (list);
105
106 list = gcry_sexp_find_token (key, "y", 0);
107 if (list == NULL)
108 {
109 gnutls_assert ();
110 gcry_sexp_release (key);
111 return GNUTLS_E_INTERNAL_ERROR;
112 }
113
114 resarr[3] = gcry_sexp_nth_mpi (list, 1, 0);
115 gcry_sexp_release (list);
116
117
118 list = gcry_sexp_find_token (key, "x", 0);
119 if (list == NULL)
120 {
121 gnutls_assert ();
122 gcry_sexp_release (key);
123 return GNUTLS_E_INTERNAL_ERROR;
124 }
125
126 resarr[4] = gcry_sexp_nth_mpi (list, 1, 0);
127 gcry_sexp_release (list);
128
129
130 gcry_sexp_release (key);
131
132 _gnutls_dump_mpi ("p: ", resarr[0]);
133 _gnutls_dump_mpi ("q: ", resarr[1]);
134 _gnutls_dump_mpi ("g: ", resarr[2]);
135 _gnutls_dump_mpi ("y: ", resarr[3]);
136 _gnutls_dump_mpi ("x: ", resarr[4]);
137
138 *resarr_len = 5;
139
140 return 0;
141
142}
diff --git a/src/daemon/https/x509/dsa.h b/src/daemon/https/x509/dsa.h
new file mode 100644
index 00000000..5489ffa3
--- /dev/null
+++ b/src/daemon/https/x509/dsa.h
@@ -0,0 +1,25 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25int _gnutls_dsa_generate_params (mpi_t * resarr, int *resarr_len, int bits);
diff --git a/src/daemon/https/x509/extensions.c b/src/daemon/https/x509/extensions.c
new file mode 100644
index 00000000..98379add
--- /dev/null
+++ b/src/daemon/https/x509/extensions.c
@@ -0,0 +1,1095 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* Functions that relate to the X.509 extension parsing.
26 */
27
28#include <gnutls_int.h>
29#include <gnutls_errors.h>
30#include <gnutls_global.h>
31#include <mpi.h>
32#include <libtasn1.h>
33#include <common.h>
34#include <x509.h>
35#include <extensions.h>
36#include <gnutls_datum.h>
37
38/* This function will attempt to return the requested extension found in
39 * the given X509v3 certificate. The return value is allocated and stored into
40 * ret.
41 *
42 * Critical will be either 0 or 1.
43 *
44 * If the extension does not exist, GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
45 * be returned.
46 */
47int
48_gnutls_x509_crt_get_extension (gnutls_x509_crt_t cert,
49 const char *extension_id, int indx,
50 gnutls_datum_t * ret, unsigned int *_critical)
51{
52 int k, result, len;
53 char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
54 char str[1024];
55 char str_critical[10];
56 int critical = 0;
57 char extnID[128];
58 gnutls_datum_t value;
59 int indx_counter = 0;
60
61 ret->data = NULL;
62 ret->size = 0;
63
64 k = 0;
65 do
66 {
67 k++;
68
69 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u", k);
70
71 len = sizeof (str) - 1;
72 result = asn1_read_value (cert->cert, name, str, &len);
73
74 /* move to next
75 */
76
77 if (result == ASN1_ELEMENT_NOT_FOUND)
78 {
79 break;
80 }
81
82 do
83 {
84
85 _gnutls_str_cpy (name2, sizeof (name2), name);
86 _gnutls_str_cat (name2, sizeof (name2), ".extnID");
87
88 len = sizeof (extnID) - 1;
89 result = asn1_read_value (cert->cert, name2, extnID, &len);
90
91 if (result == ASN1_ELEMENT_NOT_FOUND)
92 {
93 gnutls_assert ();
94 break;
95 }
96 else if (result != ASN1_SUCCESS)
97 {
98 gnutls_assert ();
99 return _gnutls_asn2err (result);
100 }
101
102 /* Handle Extension
103 */
104 if (strcmp (extnID, extension_id) == 0 && indx == indx_counter++)
105 {
106 /* extension was found
107 */
108
109 /* read the critical status.
110 */
111 _gnutls_str_cpy (name2, sizeof (name2), name);
112 _gnutls_str_cat (name2, sizeof (name2), ".critical");
113
114 len = sizeof (str_critical);
115 result =
116 asn1_read_value (cert->cert, name2, str_critical, &len);
117
118 if (result == ASN1_ELEMENT_NOT_FOUND)
119 {
120 gnutls_assert ();
121 break;
122 }
123 else if (result != ASN1_SUCCESS)
124 {
125 gnutls_assert ();
126 return _gnutls_asn2err (result);
127 }
128
129 if (str_critical[0] == 'T')
130 critical = 1;
131 else
132 critical = 0;
133
134 /* read the value.
135 */
136 _gnutls_str_cpy (name2, sizeof (name2), name);
137 _gnutls_str_cat (name2, sizeof (name2), ".extnValue");
138
139 result = _gnutls_x509_read_value (cert->cert, name2, &value, 0);
140 if (result < 0)
141 {
142 gnutls_assert ();
143 return result;
144 }
145
146 ret->data = value.data;
147 ret->size = value.size;
148
149 if (_critical)
150 *_critical = critical;
151
152 return 0;
153 }
154
155
156 }
157 while (0);
158 }
159 while (1);
160
161 if (result == ASN1_ELEMENT_NOT_FOUND)
162 {
163 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
164 }
165 else
166 {
167 gnutls_assert ();
168 return _gnutls_asn2err (result);
169 }
170}
171
172/* This function will attempt to return the requested extension OID found in
173 * the given X509v3 certificate.
174 *
175 * If you have passed the last extension, GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will
176 * be returned.
177 */
178int
179_gnutls_x509_crt_get_extension_oid (gnutls_x509_crt_t cert,
180 int indx, void *oid, size_t * sizeof_oid)
181{
182 int k, result, len;
183 char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
184 char str[1024];
185 char extnID[128];
186 int indx_counter = 0;
187
188 k = 0;
189 do
190 {
191 k++;
192
193 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u", k);
194
195 len = sizeof (str) - 1;
196 result = asn1_read_value (cert->cert, name, str, &len);
197
198 /* move to next
199 */
200
201 if (result == ASN1_ELEMENT_NOT_FOUND)
202 {
203 break;
204 }
205
206 do
207 {
208
209 _gnutls_str_cpy (name2, sizeof (name2), name);
210 _gnutls_str_cat (name2, sizeof (name2), ".extnID");
211
212 len = sizeof (extnID) - 1;
213 result = asn1_read_value (cert->cert, name2, extnID, &len);
214
215 if (result == ASN1_ELEMENT_NOT_FOUND)
216 {
217 gnutls_assert ();
218 break;
219 }
220 else if (result != ASN1_SUCCESS)
221 {
222 gnutls_assert ();
223 return _gnutls_asn2err (result);
224 }
225
226 /* Handle Extension
227 */
228 if (indx == indx_counter++)
229 {
230 len = strlen (extnID) + 1;
231
232 if (*sizeof_oid < (unsigned) len)
233 {
234 *sizeof_oid = len;
235 gnutls_assert ();
236 return GNUTLS_E_SHORT_MEMORY_BUFFER;
237 }
238
239 memcpy (oid, extnID, len);
240 *sizeof_oid = len - 1;
241
242 return 0;
243 }
244
245
246 }
247 while (0);
248 }
249 while (1);
250
251 if (result == ASN1_ELEMENT_NOT_FOUND)
252 {
253 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
254 }
255 else
256 {
257 gnutls_assert ();
258 return _gnutls_asn2err (result);
259 }
260}
261
262/* This function will attempt to set the requested extension in
263 * the given X509v3 certificate.
264 *
265 * Critical will be either 0 or 1.
266 */
267static int
268set_extension (ASN1_TYPE asn, const char *extension_id,
269 const gnutls_datum_t * ext_data, unsigned int critical)
270{
271 int result;
272 const char *str;
273
274 /* Add a new extension in the list.
275 */
276 result = asn1_write_value (asn, "tbsCertificate.extensions", "NEW", 1);
277 if (result != ASN1_SUCCESS)
278 {
279 gnutls_assert ();
280 return _gnutls_asn2err (result);
281 }
282
283 result =
284 asn1_write_value (asn, "tbsCertificate.extensions.?LAST.extnID",
285 extension_id, 1);
286 if (result != ASN1_SUCCESS)
287 {
288 gnutls_assert ();
289 return _gnutls_asn2err (result);
290 }
291
292 if (critical == 0)
293 str = "FALSE";
294 else
295 str = "TRUE";
296
297
298 result =
299 asn1_write_value (asn, "tbsCertificate.extensions.?LAST.critical",
300 str, 1);
301 if (result != ASN1_SUCCESS)
302 {
303 gnutls_assert ();
304 return _gnutls_asn2err (result);
305 }
306
307 result =
308 _gnutls_x509_write_value (asn,
309 "tbsCertificate.extensions.?LAST.extnValue",
310 ext_data, 0);
311 if (result < 0)
312 {
313 gnutls_assert ();
314 return result;
315 }
316
317 return 0;
318}
319
320/* Overwrite the given extension (using the index)
321 * index here starts from one.
322 */
323static int
324overwrite_extension (ASN1_TYPE asn, unsigned int indx,
325 const gnutls_datum_t * ext_data, unsigned int critical)
326{
327 char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
328 const char *str;
329 int result;
330
331 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u", indx);
332
333 if (critical == 0)
334 str = "FALSE";
335 else
336 str = "TRUE";
337
338 _gnutls_str_cpy (name2, sizeof (name2), name);
339 _gnutls_str_cat (name2, sizeof (name2), ".critical");
340
341 result = asn1_write_value (asn, name2, str, 1);
342 if (result != ASN1_SUCCESS)
343 {
344 gnutls_assert ();
345 return _gnutls_asn2err (result);
346 }
347
348 _gnutls_str_cpy (name2, sizeof (name2), name);
349 _gnutls_str_cat (name2, sizeof (name2), ".extnValue");
350
351 result = _gnutls_x509_write_value (asn, name2, ext_data, 0);
352 if (result < 0)
353 {
354 gnutls_assert ();
355 return result;
356 }
357
358 return 0;
359}
360
361/* This function will attempt to overwrite the requested extension with
362 * the given one.
363 *
364 * Critical will be either 0 or 1.
365 */
366int
367_gnutls_x509_crt_set_extension (gnutls_x509_crt_t cert,
368 const char *ext_id,
369 const gnutls_datum_t * ext_data,
370 unsigned int critical)
371{
372 int result;
373 int k, len;
374 char name[MAX_NAME_SIZE], name2[MAX_NAME_SIZE];
375 char extnID[128];
376
377 /* Find the index of the given extension.
378 */
379 k = 0;
380 do
381 {
382 k++;
383
384 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u", k);
385
386 len = sizeof (extnID) - 1;
387 result = asn1_read_value (cert->cert, name, extnID, &len);
388
389 /* move to next
390 */
391
392 if (result == ASN1_ELEMENT_NOT_FOUND)
393 {
394 break;
395 }
396
397 do
398 {
399
400 _gnutls_str_cpy (name2, sizeof (name2), name);
401 _gnutls_str_cat (name2, sizeof (name2), ".extnID");
402
403 len = sizeof (extnID) - 1;
404 result = asn1_read_value (cert->cert, name2, extnID, &len);
405
406 if (result == ASN1_ELEMENT_NOT_FOUND)
407 {
408 gnutls_assert ();
409 break;
410 }
411 else if (result != ASN1_SUCCESS)
412 {
413 gnutls_assert ();
414 return _gnutls_asn2err (result);
415 }
416
417 /* Handle Extension
418 */
419 if (strcmp (extnID, ext_id) == 0)
420 {
421 /* extension was found
422 */
423 return overwrite_extension (cert->cert, k, ext_data, critical);
424 }
425
426
427 }
428 while (0);
429 }
430 while (1);
431
432 if (result == ASN1_ELEMENT_NOT_FOUND)
433 {
434 return set_extension (cert->cert, ext_id, ext_data, critical);
435 }
436 else
437 {
438 gnutls_assert ();
439 return _gnutls_asn2err (result);
440 }
441
442
443 return 0;
444}
445
446
447/* Here we only extract the KeyUsage field, from the DER encoded
448 * extension.
449 */
450int
451_gnutls_x509_ext_extract_keyUsage (uint16_t * keyUsage,
452 opaque * extnValue, int extnValueLen)
453{
454 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
455 int len, result;
456 uint8_t str[2];
457
458 str[0] = str[1] = 0;
459 *keyUsage = 0;
460
461 if ((result = asn1_create_element
462 (_gnutls_get_pkix (), "PKIX1.KeyUsage", &ext)) != ASN1_SUCCESS)
463 {
464 gnutls_assert ();
465 return _gnutls_asn2err (result);
466 }
467
468 result = asn1_der_decoding (&ext, extnValue, extnValueLen, NULL);
469
470 if (result != ASN1_SUCCESS)
471 {
472 gnutls_assert ();
473 asn1_delete_structure (&ext);
474 return _gnutls_asn2err (result);
475 }
476
477 len = sizeof (str);
478 result = asn1_read_value (ext, "", str, &len);
479 if (result != ASN1_SUCCESS)
480 {
481 gnutls_assert ();
482 asn1_delete_structure (&ext);
483 return 0;
484 }
485
486 *keyUsage = str[0] | (str[1] << 8);
487
488 asn1_delete_structure (&ext);
489
490 return 0;
491}
492
493/* extract the basicConstraints from the DER encoded extension
494 */
495int
496_gnutls_x509_ext_extract_basicConstraints (int *CA,
497 int *pathLenConstraint,
498 opaque * extnValue,
499 int extnValueLen)
500{
501 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
502 char str[128];
503 int len, result;
504
505 if ((result = asn1_create_element
506 (_gnutls_get_pkix (), "PKIX1.BasicConstraints", &ext)) != ASN1_SUCCESS)
507 {
508 gnutls_assert ();
509 return _gnutls_asn2err (result);
510 }
511
512 result = asn1_der_decoding (&ext, extnValue, extnValueLen, NULL);
513 if (result != ASN1_SUCCESS)
514 {
515 gnutls_assert ();
516 asn1_delete_structure (&ext);
517 return _gnutls_asn2err (result);
518 }
519
520 if (pathLenConstraint)
521 {
522 result = _gnutls_x509_read_uint (ext, "pathLenConstraint",
523 pathLenConstraint);
524 if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
525 *pathLenConstraint = -1;
526 else if (result != GNUTLS_E_SUCCESS)
527 {
528 gnutls_assert ();
529 asn1_delete_structure (&ext);
530 return _gnutls_asn2err (result);
531 }
532 }
533
534 /* the default value of cA is false.
535 */
536 len = sizeof (str) - 1;
537 result = asn1_read_value (ext, "cA", str, &len);
538 if (result == ASN1_SUCCESS && strcmp (str, "TRUE") == 0)
539 *CA = 1;
540 else
541 *CA = 0;
542
543 asn1_delete_structure (&ext);
544
545 return 0;
546}
547
548/* generate the basicConstraints in a DER encoded extension
549 * Use 0 or 1 (TRUE) for CA.
550 * Use negative values for pathLenConstraint to indicate that the field
551 * should not be present, >= 0 to indicate set values.
552 */
553int
554_gnutls_x509_ext_gen_basicConstraints (int CA,
555 int pathLenConstraint,
556 gnutls_datum_t * der_ext)
557{
558 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
559 const char *str;
560 int result;
561
562 if (CA == 0)
563 str = "FALSE";
564 else
565 str = "TRUE";
566
567 result =
568 asn1_create_element (_gnutls_get_pkix (), "PKIX1.BasicConstraints", &ext);
569 if (result != ASN1_SUCCESS)
570 {
571 gnutls_assert ();
572 return _gnutls_asn2err (result);
573 }
574
575 result = asn1_write_value (ext, "cA", str, 1);
576 if (result != ASN1_SUCCESS)
577 {
578 gnutls_assert ();
579 asn1_delete_structure (&ext);
580 return _gnutls_asn2err (result);
581 }
582
583 if (pathLenConstraint < 0)
584 {
585 result = asn1_write_value (ext, "pathLenConstraint", NULL, 0);
586 if (result < 0)
587 result = _gnutls_asn2err (result);
588 }
589 else
590 result = _gnutls_x509_write_uint32 (ext, "pathLenConstraint",
591 pathLenConstraint);
592 if (result < 0)
593 {
594 gnutls_assert ();
595 asn1_delete_structure (&ext);
596 return result;
597 }
598
599 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
600
601 asn1_delete_structure (&ext);
602
603 if (result < 0)
604 {
605 gnutls_assert ();
606 return result;
607 }
608
609 return 0;
610}
611
612/* generate the keyUsage in a DER encoded extension
613 * Use an ORed SEQUENCE of GNUTLS_KEY_* for usage.
614 */
615int
616_gnutls_x509_ext_gen_keyUsage (uint16_t usage, gnutls_datum_t * der_ext)
617{
618 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
619 int result;
620 uint8_t str[2];
621
622 result = asn1_create_element (_gnutls_get_pkix (), "PKIX1.KeyUsage", &ext);
623 if (result != ASN1_SUCCESS)
624 {
625 gnutls_assert ();
626 return _gnutls_asn2err (result);
627 }
628
629 str[0] = usage & 0xff;
630 str[1] = usage >> 8;
631
632 result = asn1_write_value (ext, "", str, 9);
633 if (result != ASN1_SUCCESS)
634 {
635 gnutls_assert ();
636 asn1_delete_structure (&ext);
637 return _gnutls_asn2err (result);
638 }
639
640 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
641
642 asn1_delete_structure (&ext);
643
644 if (result < 0)
645 {
646 gnutls_assert ();
647 return result;
648 }
649
650 return 0;
651}
652
653static int
654write_new_general_name (ASN1_TYPE ext, const char *ext_name,
655 gnutls_x509_subject_alt_name_t type,
656 const char *data_string)
657{
658 const char *str;
659 int result;
660 char name[128];
661
662 result = asn1_write_value (ext, ext_name, "NEW", 1);
663 if (result != ASN1_SUCCESS)
664 {
665 gnutls_assert ();
666 return _gnutls_asn2err (result);
667 }
668
669 switch (type)
670 {
671 case GNUTLS_SAN_DNSNAME:
672 str = "dNSName";
673 break;
674 case GNUTLS_SAN_RFC822NAME:
675 str = "rfc822Name";
676 break;
677 case GNUTLS_SAN_URI:
678 str = "uniformResourceIdentifier";
679 break;
680 case GNUTLS_SAN_IPADDRESS:
681 str = "iPAddress";
682 break;
683 default:
684 gnutls_assert ();
685 return GNUTLS_E_INTERNAL_ERROR;
686 }
687
688 if (ext_name[0] == 0)
689 { /* no dot */
690 _gnutls_str_cpy (name, sizeof (name), "?LAST");
691 }
692 else
693 {
694 _gnutls_str_cpy (name, sizeof (name), ext_name);
695 _gnutls_str_cat (name, sizeof (name), ".?LAST");
696 }
697
698 result = asn1_write_value (ext, name, str, 1);
699 if (result != ASN1_SUCCESS)
700 {
701 gnutls_assert ();
702 return _gnutls_asn2err (result);
703 }
704
705 _gnutls_str_cat (name, sizeof (name), ".");
706 _gnutls_str_cat (name, sizeof (name), str);
707
708 result = asn1_write_value (ext, name, data_string, strlen (data_string));
709 if (result != ASN1_SUCCESS)
710 {
711 gnutls_assert ();
712 asn1_delete_structure (&ext);
713 return _gnutls_asn2err (result);
714 }
715
716 return 0;
717}
718
719/* Convert the given name to GeneralNames in a DER encoded extension.
720 * This is the same as subject alternative name.
721 */
722int
723_gnutls_x509_ext_gen_subject_alt_name (gnutls_x509_subject_alt_name_t
724 type, const char *data_string,
725 gnutls_datum_t * der_ext)
726{
727 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
728 int result;
729
730 result =
731 asn1_create_element (_gnutls_get_pkix (), "PKIX1.GeneralNames", &ext);
732 if (result != ASN1_SUCCESS)
733 {
734 gnutls_assert ();
735 return _gnutls_asn2err (result);
736 }
737
738 result = write_new_general_name (ext, "", type, data_string);
739 if (result < 0)
740 {
741 gnutls_assert ();
742 asn1_delete_structure (&ext);
743 return result;
744 }
745
746 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
747
748 asn1_delete_structure (&ext);
749
750 if (result < 0)
751 {
752 gnutls_assert ();
753 return result;
754 }
755
756 return 0;
757}
758
759/* generate the SubjectKeyID in a DER encoded extension
760 */
761int
762_gnutls_x509_ext_gen_key_id (const void *id, size_t id_size,
763 gnutls_datum_t * der_ext)
764{
765 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
766 int result;
767
768 result =
769 asn1_create_element (_gnutls_get_pkix (),
770 "PKIX1.SubjectKeyIdentifier", &ext);
771 if (result != ASN1_SUCCESS)
772 {
773 gnutls_assert ();
774 return _gnutls_asn2err (result);
775 }
776
777 result = asn1_write_value (ext, "", id, id_size);
778 if (result != ASN1_SUCCESS)
779 {
780 gnutls_assert ();
781 asn1_delete_structure (&ext);
782 return _gnutls_asn2err (result);
783 }
784
785 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
786
787 asn1_delete_structure (&ext);
788
789 if (result < 0)
790 {
791 gnutls_assert ();
792 return result;
793 }
794
795 return 0;
796}
797
798/* generate the AuthorityKeyID in a DER encoded extension
799 */
800int
801_gnutls_x509_ext_gen_auth_key_id (const void *id, size_t id_size,
802 gnutls_datum_t * der_ext)
803{
804 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
805 int result;
806
807 result =
808 asn1_create_element (_gnutls_get_pkix (),
809 "PKIX1.AuthorityKeyIdentifier", &ext);
810 if (result != ASN1_SUCCESS)
811 {
812 gnutls_assert ();
813 return _gnutls_asn2err (result);
814 }
815
816 result = asn1_write_value (ext, "keyIdentifier", id, id_size);
817 if (result != ASN1_SUCCESS)
818 {
819 gnutls_assert ();
820 asn1_delete_structure (&ext);
821 return _gnutls_asn2err (result);
822 }
823
824 asn1_write_value (ext, "authorityCertIssuer", NULL, 0);
825 asn1_write_value (ext, "authorityCertSerialNumber", NULL, 0);
826
827 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
828
829 asn1_delete_structure (&ext);
830
831 if (result < 0)
832 {
833 gnutls_assert ();
834 return result;
835 }
836
837 return 0;
838}
839
840
841/* Creates and encodes the CRL Distribution points. data_string should be a name
842 * and type holds the type of the name.
843 * reason_flags should be an or'ed sequence of GNUTLS_CRL_REASON_*.
844 *
845 */
846int
847_gnutls_x509_ext_gen_crl_dist_points (gnutls_x509_subject_alt_name_t
848 type, const void *data_string,
849 unsigned int reason_flags,
850 gnutls_datum_t * der_ext)
851{
852 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
853 gnutls_datum_t gnames = { NULL, 0 };
854 int result;
855 uint8_t reasons[2];
856
857 reasons[0] = reason_flags & 0xff;
858 reasons[1] = reason_flags >> 8;
859
860 result =
861 asn1_create_element (_gnutls_get_pkix (),
862 "PKIX1.CRLDistributionPoints", &ext);
863 if (result != ASN1_SUCCESS)
864 {
865 gnutls_assert ();
866 result = _gnutls_asn2err (result);
867 goto cleanup;
868 }
869
870 result = asn1_write_value (ext, "", "NEW", 1);
871 if (result != ASN1_SUCCESS)
872 {
873 gnutls_assert ();
874 result = _gnutls_asn2err (result);
875 goto cleanup;
876 }
877
878 if (reason_flags)
879 {
880 result = asn1_write_value (ext, "?LAST.reasons", reasons, 9);
881 if (result != ASN1_SUCCESS)
882 {
883 gnutls_assert ();
884 result = _gnutls_asn2err (result);
885 goto cleanup;
886 }
887 }
888 else
889 {
890 result = asn1_write_value (ext, "?LAST.reasons", NULL, 0);
891 if (result != ASN1_SUCCESS)
892 {
893 gnutls_assert ();
894 result = _gnutls_asn2err (result);
895 goto cleanup;
896 }
897 }
898
899 result = asn1_write_value (ext, "?LAST.cRLIssuer", NULL, 0);
900 if (result != ASN1_SUCCESS)
901 {
902 gnutls_assert ();
903 result = _gnutls_asn2err (result);
904 goto cleanup;
905 }
906
907 /* When used as type CHOICE.
908 */
909 result = asn1_write_value (ext, "?LAST.distributionPoint", "fullName", 1);
910 if (result != ASN1_SUCCESS)
911 {
912 gnutls_assert ();
913 result = _gnutls_asn2err (result);
914 goto cleanup;
915 }
916
917#if 0
918 /* only needed in old code (where defined as SEQUENCE OF) */
919 asn1_write_value (ext,
920 "?LAST.distributionPoint.nameRelativeToCRLIssuer",
921 NULL, 0);
922#endif
923
924 result =
925 write_new_general_name (ext, "?LAST.distributionPoint.fullName",
926 type, data_string);
927 if (result < 0)
928 {
929 gnutls_assert ();
930 goto cleanup;
931 }
932
933 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
934
935 if (result < 0)
936 {
937 gnutls_assert ();
938 goto cleanup;
939 }
940
941 result = 0;
942
943cleanup:
944 _gnutls_free_datum (&gnames);
945 asn1_delete_structure (&ext);
946
947 return result;
948}
949
950/* extract the proxyCertInfo from the DER encoded extension
951 */
952int
953_gnutls_x509_ext_extract_proxyCertInfo (int *pathLenConstraint,
954 char **policyLanguage,
955 char **policy,
956 size_t * sizeof_policy,
957 opaque * extnValue, int extnValueLen)
958{
959 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
960 int result;
961 gnutls_datum_t value;
962
963 if ((result = asn1_create_element
964 (_gnutls_get_pkix (), "PKIX1.ProxyCertInfo", &ext)) != ASN1_SUCCESS)
965 {
966 gnutls_assert ();
967 return _gnutls_asn2err (result);
968 }
969
970 result = asn1_der_decoding (&ext, extnValue, extnValueLen, NULL);
971 if (result != ASN1_SUCCESS)
972 {
973 gnutls_assert ();
974 asn1_delete_structure (&ext);
975 return _gnutls_asn2err (result);
976 }
977
978 if (pathLenConstraint)
979 {
980 result = _gnutls_x509_read_uint (ext, "pCPathLenConstraint",
981 pathLenConstraint);
982 if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
983 *pathLenConstraint = -1;
984 else if (result != GNUTLS_E_SUCCESS)
985 {
986 asn1_delete_structure (&ext);
987 return _gnutls_asn2err (result);
988 }
989 }
990
991 result = _gnutls_x509_read_value (ext, "proxyPolicy.policyLanguage",
992 &value, 0);
993 if (result < 0)
994 {
995 gnutls_assert ();
996 asn1_delete_structure (&ext);
997 return result;
998 }
999
1000 if (policyLanguage)
1001 *policyLanguage = gnutls_strdup (value.data);
1002
1003 result = _gnutls_x509_read_value (ext, "proxyPolicy.policy", &value, 0);
1004 if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1005 {
1006 if (policy)
1007 *policy = NULL;
1008 if (sizeof_policy)
1009 *sizeof_policy = 0;
1010 }
1011 else if (result < 0)
1012 {
1013 gnutls_assert ();
1014 asn1_delete_structure (&ext);
1015 return result;
1016 }
1017 else
1018 {
1019 if (policy)
1020 *policy = value.data;
1021 if (sizeof_policy)
1022 *sizeof_policy = value.size;
1023 }
1024
1025 asn1_delete_structure (&ext);
1026
1027 return 0;
1028}
1029
1030/* generate the proxyCertInfo in a DER encoded extension
1031 */
1032int
1033_gnutls_x509_ext_gen_proxyCertInfo (int pathLenConstraint,
1034 const char *policyLanguage,
1035 const char *policy,
1036 size_t sizeof_policy,
1037 gnutls_datum_t * der_ext)
1038{
1039 ASN1_TYPE ext = ASN1_TYPE_EMPTY;
1040 int result;
1041
1042 result = asn1_create_element (_gnutls_get_pkix (),
1043 "PKIX1.ProxyCertInfo", &ext);
1044 if (result != ASN1_SUCCESS)
1045 {
1046 gnutls_assert ();
1047 return _gnutls_asn2err (result);
1048 }
1049
1050 if (pathLenConstraint < 0)
1051 {
1052 result = asn1_write_value (ext, "pCPathLenConstraint", NULL, 0);
1053 if (result < 0)
1054 result = _gnutls_asn2err (result);
1055 }
1056 else
1057 result = _gnutls_x509_write_uint32 (ext, "pCPathLenConstraint",
1058 pathLenConstraint);
1059 if (result < 0)
1060 {
1061 gnutls_assert ();
1062 asn1_delete_structure (&ext);
1063 return result;
1064 }
1065
1066 result = asn1_write_value (ext, "proxyPolicy.policyLanguage",
1067 policyLanguage, 1);
1068 if (result < 0)
1069 {
1070 gnutls_assert ();
1071 asn1_delete_structure (&ext);
1072 return _gnutls_asn2err (result);
1073 }
1074
1075 result = asn1_write_value (ext, "proxyPolicy.policy",
1076 policy, sizeof_policy);
1077 if (result < 0)
1078 {
1079 gnutls_assert ();
1080 asn1_delete_structure (&ext);
1081 return _gnutls_asn2err (result);
1082 }
1083
1084 result = _gnutls_x509_der_encode (ext, "", der_ext, 0);
1085
1086 asn1_delete_structure (&ext);
1087
1088 if (result < 0)
1089 {
1090 gnutls_assert ();
1091 return result;
1092 }
1093
1094 return 0;
1095}
diff --git a/src/daemon/https/x509/extensions.h b/src/daemon/https/x509/extensions.h
new file mode 100644
index 00000000..fb758c90
--- /dev/null
+++ b/src/daemon/https/x509/extensions.h
@@ -0,0 +1,68 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25int _gnutls_x509_crt_get_extension (gnutls_x509_crt_t cert,
26 const char *extension_id, int indx,
27 gnutls_datum_t * ret,
28 unsigned int *critical);
29
30int _gnutls_x509_crt_get_extension_oid (gnutls_x509_crt_t cert,
31 int indx, void *ret,
32 size_t * ret_size);
33int _gnutls_x509_ext_extract_keyUsage (uint16_t * keyUsage,
34 opaque * extnValue, int extnValueLen);
35int _gnutls_x509_ext_extract_basicConstraints (int *CA,
36 int *pathLenConstraint,
37 opaque * extnValue,
38 int extnValueLen);
39int _gnutls_x509_crt_set_extension (gnutls_x509_crt_t cert,
40 const char *extension_id,
41 const gnutls_datum_t * ext_data,
42 unsigned int critical);
43int _gnutls_x509_ext_gen_basicConstraints (int CA, int pathLenConstraint,
44 gnutls_datum_t * der_ext);
45int _gnutls_x509_ext_gen_keyUsage (uint16_t usage, gnutls_datum_t * der_ext);
46int _gnutls_x509_ext_gen_subject_alt_name (gnutls_x509_subject_alt_name_t
47 type, const char *data_string,
48 gnutls_datum_t * der_ext);
49int _gnutls_x509_ext_gen_crl_dist_points (gnutls_x509_subject_alt_name_t
50 type, const void *data_string,
51 unsigned int reason_flags,
52 gnutls_datum_t * der_ext);
53int _gnutls_x509_ext_gen_key_id (const void *id, size_t id_size,
54 gnutls_datum_t * der_data);
55int _gnutls_x509_ext_gen_auth_key_id (const void *id, size_t id_size,
56 gnutls_datum_t * der_data);
57
58int _gnutls_x509_ext_extract_proxyCertInfo (int *pathLenConstraint,
59 char **policyLanguage,
60 char **policy,
61 size_t *sizeof_policy,
62 opaque * extnValue,
63 int extnValueLen);
64int _gnutls_x509_ext_gen_proxyCertInfo (int pathLenConstraint,
65 const char *policyLanguage,
66 const char *policy,
67 size_t sizeof_policy,
68 gnutls_datum_t * der_ext);
diff --git a/src/daemon/https/x509/mpi.c b/src/daemon/https/x509/mpi.c
new file mode 100644
index 00000000..8cc43855
--- /dev/null
+++ b/src/daemon/https/x509/mpi.c
@@ -0,0 +1,576 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_errors.h>
27#include <gnutls_global.h>
28#include <libtasn1.h>
29#include <gnutls_datum.h>
30#include "common.h"
31#include "x509.h"
32#include <gnutls_num.h>
33#include "mpi.h"
34
35/*
36 * some x509 certificate parsing functions that relate to MPI parameter
37 * extraction. This reads the BIT STRING subjectPublicKey.
38 * Returns 2 parameters (m,e).
39 */
40int
41_gnutls_x509_read_rsa_params (opaque * der, int dersize, mpi_t * params)
42{
43 int result;
44 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
45
46 if ((result =
47 asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPublicKey",
48 &spk)) != ASN1_SUCCESS)
49 {
50 gnutls_assert ();
51 return _gnutls_asn2err (result);
52 }
53
54 result = asn1_der_decoding (&spk, der, dersize, NULL);
55
56 if (result != ASN1_SUCCESS)
57 {
58 gnutls_assert ();
59 asn1_delete_structure (&spk);
60 return _gnutls_asn2err (result);
61 }
62
63 if ((result = _gnutls_x509_read_int (spk, "modulus", &params[0])) < 0)
64 {
65 gnutls_assert ();
66 asn1_delete_structure (&spk);
67 return GNUTLS_E_ASN1_GENERIC_ERROR;
68 }
69
70 if ((result =
71 _gnutls_x509_read_int (spk, "publicExponent", &params[1])) < 0)
72 {
73 gnutls_assert ();
74 _gnutls_mpi_release (&params[0]);
75 asn1_delete_structure (&spk);
76 return GNUTLS_E_ASN1_GENERIC_ERROR;
77 }
78
79 asn1_delete_structure (&spk);
80
81 return 0;
82
83}
84
85/* reads p,q and g
86 * from the certificate (subjectPublicKey BIT STRING).
87 * params[0-2]
88 */
89int
90_gnutls_x509_read_dsa_params (opaque * der, int dersize, mpi_t * params)
91{
92 int result;
93 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
94
95 if ((result =
96 asn1_create_element (_gnutls_get_pkix (), "PKIX1.Dss-Parms",
97 &spk)) != ASN1_SUCCESS)
98 {
99 gnutls_assert ();
100 return _gnutls_asn2err (result);
101 }
102
103 result = asn1_der_decoding (&spk, der, dersize, NULL);
104
105 if (result != ASN1_SUCCESS)
106 {
107 gnutls_assert ();
108 asn1_delete_structure (&spk);
109 return _gnutls_asn2err (result);
110 }
111
112 /* FIXME: If the parameters are not included in the certificate
113 * then the issuer's parameters should be used. This is not
114 * done yet.
115 */
116
117 /* Read p */
118
119 if ((result = _gnutls_x509_read_int (spk, "p", &params[0])) < 0)
120 {
121 gnutls_assert ();
122 asn1_delete_structure (&spk);
123 return GNUTLS_E_ASN1_GENERIC_ERROR;
124 }
125
126 /* Read q */
127
128 if ((result = _gnutls_x509_read_int (spk, "q", &params[1])) < 0)
129 {
130 gnutls_assert ();
131 asn1_delete_structure (&spk);
132 _gnutls_mpi_release (&params[0]);
133 return GNUTLS_E_ASN1_GENERIC_ERROR;
134 }
135
136 /* Read g */
137
138 if ((result = _gnutls_x509_read_int (spk, "g", &params[2])) < 0)
139 {
140 gnutls_assert ();
141 asn1_delete_structure (&spk);
142 _gnutls_mpi_release (&params[0]);
143 _gnutls_mpi_release (&params[1]);
144 return GNUTLS_E_ASN1_GENERIC_ERROR;
145 }
146
147 asn1_delete_structure (&spk);
148
149 return 0;
150
151}
152
153/* Reads an Integer from the DER encoded data
154 */
155
156int
157_gnutls_x509_read_der_int (opaque * der, int dersize, mpi_t * out)
158{
159 int result;
160 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
161
162 /* == INTEGER */
163 if ((result =
164 asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPublicKey",
165 &spk)) != ASN1_SUCCESS)
166 {
167 gnutls_assert ();
168 return _gnutls_asn2err (result);
169 }
170
171 result = asn1_der_decoding (&spk, der, dersize, NULL);
172
173 if (result != ASN1_SUCCESS)
174 {
175 gnutls_assert ();
176 asn1_delete_structure (&spk);
177 return _gnutls_asn2err (result);
178 }
179
180 /* Read Y */
181
182 if ((result = _gnutls_x509_read_int (spk, "", out)) < 0)
183 {
184 gnutls_assert ();
185 asn1_delete_structure (&spk);
186 return _gnutls_asn2err (result);
187 }
188
189 asn1_delete_structure (&spk);
190
191 return 0;
192
193}
194
195/* reads DSA's Y
196 * from the certificate
197 * only sets params[3]
198 */
199int
200_gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, mpi_t * params)
201{
202 return _gnutls_x509_read_der_int (der, dersize, &params[3]);
203}
204
205/* Extracts DSA and RSA parameters from a certificate.
206 */
207int
208_gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert,
209 mpi_t * params, int *params_size)
210{
211 int result;
212 int pk_algorithm;
213 gnutls_datum tmp = { NULL, 0 };
214
215 /* Read the algorithm's OID
216 */
217 pk_algorithm = gnutls_x509_crt_get_pk_algorithm (cert, NULL);
218
219 /* Read the algorithm's parameters
220 */
221 result
222 = _gnutls_x509_read_value (cert->cert,
223 "tbsCertificate.subjectPublicKeyInfo.subjectPublicKey",
224 &tmp, 2);
225
226 if (result < 0)
227 {
228 gnutls_assert ();
229 return result;
230 }
231
232 switch (pk_algorithm)
233 {
234 case GNUTLS_PK_RSA:
235 /* params[0] is the modulus,
236 * params[1] is the exponent
237 */
238 if (*params_size < RSA_PUBLIC_PARAMS)
239 {
240 gnutls_assert ();
241 /* internal error. Increase the mpi_ts in params */
242 result = GNUTLS_E_INTERNAL_ERROR;
243 goto error;
244 }
245
246 if ((result =
247 _gnutls_x509_read_rsa_params (tmp.data, tmp.size, params)) < 0)
248 {
249 gnutls_assert ();
250 goto error;
251 }
252 *params_size = RSA_PUBLIC_PARAMS;
253
254 break;
255 default:
256 /* other types like DH
257 * currently not supported
258 */
259 gnutls_assert ();
260 result = GNUTLS_E_X509_CERTIFICATE_ERROR;
261 goto error;
262 }
263
264 result = 0;
265
266error:_gnutls_free_datum (&tmp);
267 return result;
268}
269
270/*
271 * some x509 certificate functions that relate to MPI parameter
272 * setting. This writes the BIT STRING subjectPublicKey.
273 * Needs 2 parameters (m,e).
274 *
275 * Allocates the space used to store the DER data.
276 */
277int
278_gnutls_x509_write_rsa_params (mpi_t * params,
279 int params_size, gnutls_datum_t * der)
280{
281 int result;
282 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
283
284 der->data = NULL;
285 der->size = 0;
286
287 if (params_size < 2)
288 {
289 gnutls_assert ();
290 result = GNUTLS_E_INVALID_REQUEST;
291 goto cleanup;
292 }
293
294 if ((result =
295 asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPublicKey",
296 &spk)) != ASN1_SUCCESS)
297 {
298 gnutls_assert ();
299 return _gnutls_asn2err (result);
300 }
301
302 result = _gnutls_x509_write_int (spk, "modulus", params[0], 0);
303 if (result < 0)
304 {
305 gnutls_assert ();
306 goto cleanup;
307 }
308
309 result = _gnutls_x509_write_int (spk, "publicExponent", params[1], 0);
310 if (result < 0)
311 {
312 gnutls_assert ();
313 goto cleanup;
314 }
315
316 result = _gnutls_x509_der_encode (spk, "", der, 0);
317 if (result < 0)
318 {
319 gnutls_assert ();
320 goto cleanup;
321 }
322
323 asn1_delete_structure (&spk);
324 return 0;
325
326cleanup:asn1_delete_structure (&spk);
327
328 return result;
329}
330
331/*
332 * This function writes and encodes the parameters for DSS or RSA keys.
333 * This is the "signatureAlgorithm" fields.
334 */
335int
336_gnutls_x509_write_sig_params (ASN1_TYPE dst,
337 const char *dst_name,
338 gnutls_pk_algorithm_t pk_algorithm,
339 gnutls_digest_algorithm_t dig,
340 mpi_t * params, int params_size)
341{
342 gnutls_datum_t der;
343 int result;
344 char name[128];
345 const char *pk;
346
347 _gnutls_str_cpy (name, sizeof (name), dst_name);
348 _gnutls_str_cat (name, sizeof (name), ".algorithm");
349
350 pk = _gnutls_x509_sign_to_oid (pk_algorithm, HASH2MAC (dig));
351 if (pk == NULL)
352 {
353 gnutls_assert ();
354 return GNUTLS_E_INVALID_REQUEST;
355 }
356
357 /* write the OID.
358 */
359 result = asn1_write_value (dst, name, pk, 1);
360 if (result != ASN1_SUCCESS)
361 {
362 gnutls_assert ();
363 return _gnutls_asn2err (result);
364 }
365
366 _gnutls_str_cpy (name, sizeof (name), dst_name);
367 _gnutls_str_cat (name, sizeof (name), ".parameters");
368
369 if (pk_algorithm == GNUTLS_PK_RSA)
370 { /* RSA */
371 result = asn1_write_value (dst, name, NULL, 0);
372
373 if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND)
374 {
375 /* Here we ignore the element not found error, since this
376 * may have been disabled before.
377 */
378 gnutls_assert ();
379 return _gnutls_asn2err (result);
380 }
381 }
382
383 return 0;
384}
385
386/*
387 * This function writes the parameters for DSS keys.
388 * Needs 3 parameters (p,q,g).
389 *
390 * Allocates the space used to store the DER data.
391 */
392int
393_gnutls_x509_write_dsa_params (mpi_t * params,
394 int params_size, gnutls_datum_t * der)
395{
396 int result;
397 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
398
399 der->data = NULL;
400 der->size = 0;
401
402 if (params_size < 3)
403 {
404 gnutls_assert ();
405 result = GNUTLS_E_INVALID_REQUEST;
406 goto cleanup;
407 }
408
409 if ((result =
410 asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DSAParameters",
411 &spk)) != ASN1_SUCCESS)
412 {
413 gnutls_assert ();
414 return _gnutls_asn2err (result);
415 }
416
417 result = _gnutls_x509_write_int (spk, "p", params[0], 0);
418 if (result < 0)
419 {
420 gnutls_assert ();
421 goto cleanup;
422 }
423
424 result = _gnutls_x509_write_int (spk, "q", params[1], 0);
425 if (result < 0)
426 {
427 gnutls_assert ();
428 goto cleanup;
429 }
430
431 result = _gnutls_x509_write_int (spk, "g", params[2], 0);
432 if (result < 0)
433 {
434 gnutls_assert ();
435 goto cleanup;
436 }
437
438 result = _gnutls_x509_der_encode (spk, "", der, 0);
439 if (result < 0)
440 {
441 gnutls_assert ();
442 goto cleanup;
443 }
444
445 result = 0;
446
447cleanup:asn1_delete_structure (&spk);
448 return result;
449}
450
451/*
452 * This function writes the public parameters for DSS keys.
453 * Needs 1 parameter (y).
454 *
455 * Allocates the space used to store the DER data.
456 */
457int
458_gnutls_x509_write_dsa_public_key (mpi_t * params,
459 int params_size, gnutls_datum_t * der)
460{
461 int result;
462 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
463
464 der->data = NULL;
465 der->size = 0;
466
467 if (params_size < 3)
468 {
469 gnutls_assert ();
470 result = GNUTLS_E_INVALID_REQUEST;
471 goto cleanup;
472 }
473
474 if ((result =
475 asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPublicKey",
476 &spk)) != ASN1_SUCCESS)
477 {
478 gnutls_assert ();
479 return _gnutls_asn2err (result);
480 }
481
482 result = _gnutls_x509_write_int (spk, "", params[3], 0);
483 if (result < 0)
484 {
485 gnutls_assert ();
486 goto cleanup;
487 }
488
489 result = _gnutls_x509_der_encode (spk, "", der, 0);
490 if (result < 0)
491 {
492 gnutls_assert ();
493 goto cleanup;
494 }
495
496 asn1_delete_structure (&spk);
497 return 0;
498
499cleanup:asn1_delete_structure (&spk);
500 return result;
501}
502
503/* this function reads a (small) unsigned integer
504 * from asn1 structs. Combines the read and the convertion
505 * steps.
506 */
507int
508_gnutls_x509_read_uint (ASN1_TYPE node, const char *value, unsigned int *ret)
509{
510 int len, result;
511 opaque *tmpstr;
512
513 len = 0;
514 result = asn1_read_value (node, value, NULL, &len);
515 if (result != ASN1_MEM_ERROR)
516 {
517 gnutls_assert ();
518 return _gnutls_asn2err (result);
519 }
520
521 tmpstr = gnutls_alloca (len);
522 if (tmpstr == NULL)
523 {
524 gnutls_assert ();
525 return GNUTLS_E_MEMORY_ERROR;
526 }
527
528 result = asn1_read_value (node, value, tmpstr, &len);
529
530 if (result != ASN1_SUCCESS)
531 {
532 gnutls_assert ();
533 gnutls_afree (tmpstr);
534 return _gnutls_asn2err (result);
535 }
536
537 if (len == 1)
538 *ret = tmpstr[0];
539 else if (len == 2)
540 *ret = _gnutls_read_uint16 (tmpstr);
541 else if (len == 3)
542 *ret = _gnutls_read_uint24 (tmpstr);
543 else if (len == 4)
544 *ret = _gnutls_read_uint32 (tmpstr);
545 else
546 {
547 gnutls_assert ();
548 gnutls_afree (tmpstr);
549 return GNUTLS_E_INTERNAL_ERROR;
550 }
551
552 gnutls_afree (tmpstr);
553
554 return 0;
555}
556
557/* Writes the specified integer into the specified node.
558 */
559int
560_gnutls_x509_write_uint32 (ASN1_TYPE node, const char *value, uint32_t num)
561{
562 opaque tmpstr[4];
563 int result;
564
565 _gnutls_write_uint32 (num, tmpstr);
566
567 result = asn1_write_value (node, value, tmpstr, 4);
568
569 if (result != ASN1_SUCCESS)
570 {
571 gnutls_assert ();
572 return _gnutls_asn2err (result);
573 }
574
575 return 0;
576}
diff --git a/src/daemon/https/x509/mpi.h b/src/daemon/https/x509/mpi.h
new file mode 100644
index 00000000..785d7e02
--- /dev/null
+++ b/src/daemon/https/x509/mpi.h
@@ -0,0 +1,57 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26#include "x509.h"
27
28int _gnutls_x509_crt_get_mpis (gnutls_x509_crt_t cert,
29 mpi_t * params, int *params_size);
30int _gnutls_x509_read_rsa_params (opaque * der, int dersize, mpi_t * params);
31int _gnutls_x509_read_dsa_pubkey (opaque * der, int dersize, mpi_t * params);
32int _gnutls_x509_read_dsa_params (opaque * der, int dersize, mpi_t * params);
33
34int _gnutls_x509_write_rsa_params (mpi_t * params, int params_size,
35 gnutls_datum_t * der);
36int _gnutls_x509_write_dsa_params (mpi_t * params, int params_size,
37 gnutls_datum_t * der);
38int _gnutls_x509_write_dsa_public_key (mpi_t * params, int params_size,
39 gnutls_datum_t * der);
40
41int _gnutls_x509_read_uint (ASN1_TYPE node, const char *value,
42 unsigned int *ret);
43
44int
45_gnutls_x509_read_der_int (opaque * der, int dersize, mpi_t* out);
46
47int _gnutls_x509_read_int (ASN1_TYPE node, const char *value,
48 mpi_t * ret_mpi);
49int _gnutls_x509_write_int (ASN1_TYPE node, const char *value, mpi_t mpi,
50 int lz);
51int _gnutls_x509_write_uint32 (ASN1_TYPE node, const char *value,
52 uint32_t num);
53
54int _gnutls_x509_write_sig_params (ASN1_TYPE dst, const char *dst_name,
55 gnutls_pk_algorithm_t pk_algorithm,
56 gnutls_digest_algorithm_t, mpi_t * params,
57 int params_size);
diff --git a/src/daemon/https/x509/output.c b/src/daemon/https/x509/output.c
new file mode 100644
index 00000000..dcc87ab1
--- /dev/null
+++ b/src/daemon/https/x509/output.c
@@ -0,0 +1,1360 @@
1/*
2 * Copyright (C) 2007 Free Software Foundation
3 *
4 * Author: Simon Josefsson
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA
22 *
23 */
24
25/* Functions for printing X.509 Certificate structures
26 */
27
28#include <gnutls_int.h>
29#include <common.h>
30#include <gnutls_x509.h>
31#include <x509.h>
32#include <gnutls_errors.h>
33
34/* I18n of error codes. */
35#include "gettext.h"
36#define _(String) dgettext (PACKAGE, String)
37#define N_(String) gettext_noop (String)
38
39#define addf _gnutls_string_append_printf
40#define adds _gnutls_string_append_str
41
42static void
43hexdump (gnutls_string * str, const char *data, size_t len, const char *spc)
44{
45 size_t j;
46
47 if (spc)
48 adds (str, spc);
49 for (j = 0; j < len; j++)
50 {
51 if (((j + 1) % 16) == 0)
52 {
53 addf (str, "%.2x\n", (unsigned char) data[j]);
54 if (spc && j != (len - 1))
55 adds (str, spc);
56 }
57 else if (j == (len - 1))
58 addf (str, "%.2x", (unsigned char) data[j]);
59 else
60 addf (str, "%.2x:", (unsigned char) data[j]);
61 }
62 if ((j % 16) != 0)
63 adds (str, "\n");
64}
65
66static void
67hexprint (gnutls_string * str, const char *data, size_t len)
68{
69 size_t j;
70
71 if (len == 0)
72 adds (str, "00");
73 else
74 {
75 for (j = 0; j < len; j++)
76 addf (str, "%.2x", (unsigned char) data[j]);
77 }
78}
79
80
81static void
82asciiprint (gnutls_string * str, const char *data, size_t len)
83{
84 size_t j;
85
86 for (j = 0; j < len; j++)
87 if (isprint (data[j]))
88 addf (str, "%c", (unsigned char) data[j]);
89 else
90 addf (str, ".");
91}
92
93static void
94print_proxy (gnutls_string * str, gnutls_x509_crt_t cert)
95{
96 int pathlen;
97 char *policyLanguage;
98 char *policy;
99 size_t npolicy;
100 int err;
101
102 err = gnutls_x509_crt_get_proxy (cert, NULL,
103 &pathlen, &policyLanguage,
104 &policy, &npolicy);
105 if (err < 0)
106 {
107 addf (str, "error: get_proxy: %s\n", gnutls_strerror (err));
108 return;
109 }
110
111 if (pathlen >= 0)
112 addf (str, _("\t\t\tPath Length Constraint: %d\n"), pathlen);
113 addf (str, _("\t\t\tPolicy Language: %s"), policyLanguage);
114 if (strcmp (policyLanguage, "1.3.6.1.5.5.7.21.1") == 0)
115 adds (str, " (id-ppl-inheritALL)\n");
116 else if (strcmp (policyLanguage, "1.3.6.1.5.5.7.21.2") == 0)
117 adds (str, " (id-ppl-independent)\n");
118 else
119 adds (str, "\n");
120 if (npolicy)
121 {
122 adds (str, _("\t\t\tPolicy:\n\t\t\t\tASCII: "));
123 asciiprint (str, policy, npolicy);
124 adds (str, _("\n\t\t\t\tHexdump: "));
125 hexprint (str, policy, npolicy);
126 adds (str, "\n");
127 }
128}
129
130static void
131print_ski (gnutls_string * str, gnutls_x509_crt_t cert)
132{
133 char *buffer = NULL;
134 size_t size = 0;
135 int err;
136
137 err = gnutls_x509_crt_get_subject_key_id (cert, buffer, &size, NULL);
138 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
139 {
140 addf (str, "error: get_subject_key_id: %s\n", gnutls_strerror (err));
141 return;
142 }
143
144 buffer = gnutls_malloc (size);
145 if (!buffer)
146 {
147 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
148 return;
149 }
150
151 err = gnutls_x509_crt_get_subject_key_id (cert, buffer, &size, NULL);
152 if (err < 0)
153 {
154 gnutls_free (buffer);
155 addf (str, "error: get_subject_key_id2: %s\n", gnutls_strerror (err));
156 return;
157 }
158
159 adds (str, "\t\t\t");
160 hexprint (str, buffer, size);
161 adds (str, "\n");
162
163 gnutls_free (buffer);
164}
165
166static void
167print_aki (gnutls_string * str, gnutls_x509_crt_t cert)
168{
169 char *buffer = NULL;
170 size_t size = 0;
171 int err;
172
173 err = gnutls_x509_crt_get_authority_key_id (cert, buffer, &size, NULL);
174 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
175 {
176 addf (str, "error: get_authority_key_id: %s\n", gnutls_strerror (err));
177 return;
178 }
179
180 buffer = gnutls_malloc (size);
181 if (!buffer)
182 {
183 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
184 return;
185 }
186
187 err = gnutls_x509_crt_get_authority_key_id (cert, buffer, &size, NULL);
188 if (err < 0)
189 {
190 gnutls_free (buffer);
191 addf (str, "error: get_authority_key_id2: %s\n", gnutls_strerror (err));
192 return;
193 }
194
195 adds (str, "\t\t\t");
196 hexprint (str, buffer, size);
197 adds (str, "\n");
198
199 gnutls_free (buffer);
200}
201
202static void
203print_key_usage (gnutls_string * str, gnutls_x509_crt_t cert)
204{
205 unsigned int key_usage;
206 int err;
207
208 err = gnutls_x509_crt_get_key_usage (cert, &key_usage, NULL);
209 if (err < 0)
210 {
211 addf (str, "error: get_key_usage: %s\n", gnutls_strerror (err));
212 return;
213 }
214
215 if (key_usage & GNUTLS_KEY_DIGITAL_SIGNATURE)
216 addf (str, _("\t\t\tDigital signature.\n"));
217 if (key_usage & GNUTLS_KEY_NON_REPUDIATION)
218 addf (str, _("\t\t\tNon repudiation.\n"));
219 if (key_usage & GNUTLS_KEY_KEY_ENCIPHERMENT)
220 addf (str, _("\t\t\tKey encipherment.\n"));
221 if (key_usage & GNUTLS_KEY_DATA_ENCIPHERMENT)
222 addf (str, _("\t\t\tData encipherment.\n"));
223 if (key_usage & GNUTLS_KEY_KEY_AGREEMENT)
224 addf (str, _("\t\t\tKey agreement.\n"));
225 if (key_usage & GNUTLS_KEY_KEY_CERT_SIGN)
226 addf (str, _("\t\t\tCertificate signing.\n"));
227 if (key_usage & GNUTLS_KEY_CRL_SIGN)
228 addf (str, _("\t\t\tCRL signing.\n"));
229 if (key_usage & GNUTLS_KEY_ENCIPHER_ONLY)
230 addf (str, _("\t\t\tKey encipher only.\n"));
231 if (key_usage & GNUTLS_KEY_DECIPHER_ONLY)
232 addf (str, _("\t\t\tKey decipher only.\n"));
233}
234
235static void
236print_crldist (gnutls_string * str, gnutls_x509_crt_t cert)
237{
238 char *buffer = NULL;
239 size_t size;
240 int err;
241 int indx;
242
243 for (indx = 0;; indx++)
244 {
245 size = 0;
246 err = gnutls_x509_crt_get_crl_dist_points (cert, indx, buffer, &size,
247 NULL, NULL);
248 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
249 return;
250 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
251 {
252 addf (str, "error: get_crl_dist_points: %s\n",
253 gnutls_strerror (err));
254 return;
255 }
256
257 buffer = gnutls_malloc (size);
258 if (!buffer)
259 {
260 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
261 return;
262 }
263
264 err = gnutls_x509_crt_get_crl_dist_points (cert, indx, buffer, &size,
265 NULL, NULL);
266 if (err < 0)
267 {
268 gnutls_free (buffer);
269 addf (str, "error: get_crl_dist_points2: %s\n",
270 gnutls_strerror (err));
271 return;
272 }
273
274 switch (err)
275 {
276 case GNUTLS_SAN_DNSNAME:
277 addf (str, "\t\t\tDNSname: %.*s\n", size, buffer);
278 break;
279
280 case GNUTLS_SAN_RFC822NAME:
281 addf (str, "\t\t\tRFC822name: %.*s\n", size, buffer);
282 break;
283
284 case GNUTLS_SAN_URI:
285 addf (str, "\t\t\tURI: %.*s\n", size, buffer);
286 break;
287
288 case GNUTLS_SAN_IPADDRESS:
289 addf (str, "\t\t\tIPAddress: %.*s\n", size, buffer);
290 break;
291
292 case GNUTLS_SAN_DN:
293 addf (str, "\t\t\tdirectoryName: %.*s\n", size, buffer);
294 break;
295
296 default:
297 addf (str, "error: unknown SAN\n");
298 break;
299 }
300 gnutls_free (buffer);
301 }
302}
303
304static void
305print_key_purpose (gnutls_string * str, gnutls_x509_crt_t cert)
306{
307 int indx;
308 char *buffer = NULL;
309 size_t size;
310 int err;
311
312 for (indx = 0;; indx++)
313 {
314 size = 0;
315 err = gnutls_x509_crt_get_key_purpose_oid (cert, indx, buffer,
316 &size, NULL);
317 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
318 return;
319 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
320 {
321 addf (str, "error: get_key_purpose_oid: %s\n",
322 gnutls_strerror (err));
323 return;
324 }
325
326 buffer = gnutls_malloc (size);
327 if (!buffer)
328 {
329 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
330 return;
331 }
332
333 err = gnutls_x509_crt_get_key_purpose_oid (cert, indx, buffer,
334 &size, NULL);
335 if (err < 0)
336 {
337 gnutls_free (buffer);
338 addf (str, "error: get_key_purpose_oid2: %s\n",
339 gnutls_strerror (err));
340 return;
341 }
342
343 if (strcmp (buffer, GNUTLS_KP_TLS_WWW_SERVER) == 0)
344 addf (str, _("\t\t\tTLS WWW Server.\n"));
345 else if (strcmp (buffer, GNUTLS_KP_TLS_WWW_CLIENT) == 0)
346 addf (str, _("\t\t\tTLS WWW Client.\n"));
347 else if (strcmp (buffer, GNUTLS_KP_CODE_SIGNING) == 0)
348 addf (str, _("\t\t\tCode signing.\n"));
349 else if (strcmp (buffer, GNUTLS_KP_EMAIL_PROTECTION) == 0)
350 addf (str, _("\t\t\tEmail protection.\n"));
351 else if (strcmp (buffer, GNUTLS_KP_TIME_STAMPING) == 0)
352 addf (str, _("\t\t\tTime stamping.\n"));
353 else if (strcmp (buffer, GNUTLS_KP_OCSP_SIGNING) == 0)
354 addf (str, _("\t\t\tOCSP signing.\n"));
355 else if (strcmp (buffer, GNUTLS_KP_ANY) == 0)
356 addf (str, _("\t\t\tAny purpose.\n"));
357 else
358 addf (str, "\t\t\t%s\n", buffer);
359
360 gnutls_free (buffer);
361 }
362}
363
364static void
365print_basic (gnutls_string * str, gnutls_x509_crt_t cert)
366{
367 int pathlen;
368 int err;
369
370 err = gnutls_x509_crt_get_basic_constraints (cert, NULL, NULL, &pathlen);
371 if (err < 0)
372 {
373 addf (str, "error: get_basic_constraints: %s\n", gnutls_strerror (err));
374 return;
375 }
376
377 if (err == 0)
378 addf (str, _("\t\t\tCertificate Authority (CA): FALSE\n"));
379 else
380 addf (str, _("\t\t\tCertificate Authority (CA): TRUE\n"));
381
382 if (pathlen >= 0)
383 addf (str, _("\t\t\tPath Length Constraint: %d\n"), pathlen);
384}
385
386static void
387print_san (gnutls_string * str, gnutls_x509_crt_t cert)
388{
389 unsigned int san_idx;
390
391 for (san_idx = 0;; san_idx++)
392 {
393 char *buffer = NULL;
394 size_t size = 0;
395 int err;
396
397 err =
398 gnutls_x509_crt_get_subject_alt_name (cert, san_idx, buffer, &size,
399 NULL);
400 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
401 break;
402 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
403 {
404 addf (str, "error: get_subject_alt_name: %s\n",
405 gnutls_strerror (err));
406 return;
407 }
408
409 buffer = gnutls_malloc (size);
410 if (!buffer)
411 {
412 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
413 return;
414 }
415
416 err = gnutls_x509_crt_get_subject_alt_name (cert, san_idx,
417 buffer, &size, NULL);
418 if (err < 0)
419 {
420 gnutls_free (buffer);
421 addf (str, "error: get_subject_alt_name2: %s\n",
422 gnutls_strerror (err));
423 return;
424 }
425
426 switch (err)
427 {
428 case GNUTLS_SAN_DNSNAME:
429 addf (str, "\t\t\tDNSname: %.*s\n", size, buffer);
430 break;
431
432 case GNUTLS_SAN_RFC822NAME:
433 addf (str, "\t\t\tRFC822name: %.*s\n", size, buffer);
434 break;
435
436 case GNUTLS_SAN_URI:
437 addf (str, "\t\t\tURI: %.*s\n", size, buffer);
438 break;
439
440 case GNUTLS_SAN_IPADDRESS:
441 addf (str, "\t\t\tIPAddress: %.*s\n", size, buffer);
442 break;
443
444 case GNUTLS_SAN_DN:
445 addf (str, "\t\t\tdirectoryName: %.*s\n", size, buffer);
446 break;
447
448 case GNUTLS_SAN_OTHERNAME:
449 {
450 char *oid = NULL;
451 size_t oidsize;
452
453 oidsize = 0;
454 err = gnutls_x509_crt_get_subject_alt_othername_oid
455 (cert, san_idx, oid, &oidsize);
456 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
457 {
458 gnutls_free (buffer);
459 addf (str, "error: get_subject_alt_othername_oid: %s\n",
460 gnutls_strerror (err));
461 return;
462 }
463
464 oid = gnutls_malloc (oidsize);
465 if (!oid)
466 {
467 gnutls_free (buffer);
468 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
469 return;
470 }
471
472 err = gnutls_x509_crt_get_subject_alt_othername_oid
473 (cert, san_idx, oid, &oidsize);
474 if (err < 0)
475 {
476 gnutls_free (buffer);
477 gnutls_free (oid);
478 addf (str, "error: get_subject_alt_othername_oid2: %s\n",
479 gnutls_strerror (err));
480 return;
481 }
482
483 if (err == GNUTLS_SAN_OTHERNAME_XMPP)
484 addf (str, _("\t\t\tXMPP Address: %.*s\n"), size, buffer);
485 else
486 {
487 addf (str, _("\t\t\totherName OID: %.*s\n"), oidsize, oid);
488 addf (str, _("\t\t\totherName DER: "));
489 hexprint (str, buffer, size);
490 addf (str, _("\n\t\t\totherName ASCII: "));
491 asciiprint (str, buffer, size);
492 addf (str, "\n");
493 }
494 gnutls_free (oid);
495 }
496 break;
497
498 default:
499 addf (str, "error: unknown SAN\n");
500 break;
501 }
502
503 gnutls_free (buffer);
504 }
505}
506
507static void
508print_cert (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned)
509{
510 /* Version. */
511 {
512 int version = gnutls_x509_crt_get_version (cert);
513 if (version < 0)
514 addf (str, "error: get_version: %s\n", gnutls_strerror (version));
515 else
516 addf (str, _("\tVersion: %d\n"), version);
517 }
518
519 /* Serial. */
520 {
521 char serial[128];
522 size_t serial_size = sizeof (serial);
523 int err;
524
525 err = gnutls_x509_crt_get_serial (cert, serial, &serial_size);
526 if (err < 0)
527 addf (str, "error: get_serial: %s\n", gnutls_strerror (err));
528 else
529 {
530 addf (str, _("\tSerial Number (hex): "));
531 hexprint (str, serial, serial_size);
532 addf (str, "\n");
533 }
534 }
535
536 /* Issuer. */
537 if (!notsigned)
538 {
539 char dn[1024];
540 size_t dn_size = sizeof (dn);
541 int err;
542
543 err = gnutls_x509_crt_get_issuer_dn (cert, dn, &dn_size);
544 if (err < 0)
545 addf (str, "error: get_issuer_dn: %s\n", gnutls_strerror (err));
546 else
547 addf (str, _("\tIssuer: %s\n"), dn);
548 }
549
550 /* Validity. */
551 {
552 time_t tim;
553
554 addf (str, _("\tValidity:\n"));
555
556 tim = gnutls_x509_crt_get_activation_time (cert);
557 {
558 char s[42];
559 size_t max = sizeof (s);
560 struct tm t;
561
562 if (gmtime_r (&tim, &t) == NULL)
563 addf (str, "error: gmtime_r (%d)\n", t);
564 else if (strftime (s, max, "%a %b %e %H:%M:%S UTC %Y", &t) == 0)
565 addf (str, "error: strftime (%d)\n", t);
566 else
567 addf (str, _("\t\tNot Before: %s\n"), s);
568 }
569
570 tim = gnutls_x509_crt_get_expiration_time (cert);
571 {
572 char s[42];
573 size_t max = sizeof (s);
574 struct tm t;
575
576 if (gmtime_r (&tim, &t) == NULL)
577 addf (str, "error: gmtime_r (%d)\n", t);
578 else if (strftime (s, max, "%a %b %e %H:%M:%S UTC %Y", &t) == 0)
579 addf (str, "error: strftime (%d)\n", t);
580 else
581 addf (str, _("\t\tNot After: %s\n"), s);
582 }
583 }
584
585 /* Subject. */
586 {
587 char dn[1024];
588 size_t dn_size = sizeof (dn);
589 int err;
590
591 err = gnutls_x509_crt_get_dn (cert, dn, &dn_size);
592 if (err < 0)
593 addf (str, "error: get_dn: %s\n", gnutls_strerror (err));
594 else
595 addf (str, _("\tSubject: %s\n"), dn);
596 }
597
598 /* SubjectPublicKeyInfo. */
599 {
600 int err;
601 unsigned int bits;
602
603 err = gnutls_x509_crt_get_pk_algorithm (cert, &bits);
604 if (err < 0)
605 addf (str, "error: get_pk_algorithm: %s\n", gnutls_strerror (err));
606 else
607 {
608 const char *name = gnutls_pk_algorithm_get_name (err);
609 if (name == NULL)
610 name = "Unknown";
611
612 addf (str, _("\tSubject Public Key Algorithm: %s\n"), name);
613 switch (err)
614 {
615 case GNUTLS_PK_RSA:
616 {
617 gnutls_datum_t m, e;
618
619 err = gnutls_x509_crt_get_pk_rsa_raw (cert, &m, &e);
620 if (err < 0)
621 addf (str, "error: get_pk_rsa_raw: %s\n",
622 gnutls_strerror (err));
623 else
624 {
625 addf (str, _("\t\tModulus (bits %d):\n"), bits);
626 hexdump (str, m.data, m.size, "\t\t\t");
627 addf (str, _("\t\tExponent:\n"));
628 hexdump (str, e.data, e.size, "\t\t\t");
629 }
630
631 gnutls_free (m.data);
632 gnutls_free (e.data);
633 }
634 break;
635
636 case GNUTLS_PK_DSA:
637 {
638 gnutls_datum_t p, q, g, y;
639
640 err = gnutls_x509_crt_get_pk_dsa_raw (cert, &p, &q, &g, &y);
641 if (err < 0)
642 addf (str, "error: get_pk_dsa_raw: %s\n",
643 gnutls_strerror (err));
644 else
645 {
646 addf (str, _("\t\tPublic key (bits %d):\n"), bits);
647 hexdump (str, y.data, y.size, "\t\t\t");
648 addf (str, _("\t\tP:\n"));
649 hexdump (str, p.data, p.size, "\t\t\t");
650 addf (str, _("\t\tQ:\n"));
651 hexdump (str, q.data, q.size, "\t\t\t");
652 addf (str, _("\t\tG:\n"));
653 hexdump (str, g.data, g.size, "\t\t\t");
654 }
655 }
656 break;
657
658 default:
659 break;
660 }
661 }
662 }
663
664 /* Extensions. */
665 if (gnutls_x509_crt_get_version (cert) >= 3)
666 {
667 size_t i;
668 int err = 0;
669
670 for (i = 0;; i++)
671 {
672 char oid[128] = "";
673 size_t sizeof_oid = sizeof (oid);
674 int critical;
675 size_t san_idx = 0;
676 size_t proxy_idx = 0;
677 size_t basic_idx = 0;
678 size_t keyusage_idx = 0;
679 size_t keypurpose_idx = 0;
680 size_t ski_idx = 0;
681 size_t aki_idx = 0;
682 size_t crldist_idx = 0;
683
684 err = gnutls_x509_crt_get_extension_info (cert, i,
685 oid, &sizeof_oid,
686 &critical);
687 if (err < 0)
688 {
689 if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
690 break;
691 addf (str, "error: get_extension_info: %s\n",
692 gnutls_strerror (err));
693 continue;
694 }
695
696 if (i == 0)
697 addf (str, _("\tExtensions:\n"));
698
699 if (strcmp (oid, "2.5.29.19") == 0)
700 {
701 if (basic_idx)
702 {
703 addf (str, "error: more than one basic constraint\n");
704 continue;
705 }
706
707 addf (str, _("\t\tBasic Constraints (%s):\n"),
708 critical ? _("critical") : _("not critical"));
709
710 print_basic (str, cert);
711
712 basic_idx++;
713 }
714 else if (strcmp (oid, "2.5.29.14") == 0)
715 {
716 if (ski_idx)
717 {
718 addf (str, "error: more than one SKI extension\n");
719 continue;
720 }
721
722 addf (str, _("\t\tSubject Key Identifier (%s):\n"),
723 critical ? _("critical") : _("not critical"));
724
725 print_ski (str, cert);
726
727 ski_idx++;
728 }
729 else if (strcmp (oid, "2.5.29.35") == 0)
730 {
731 if (aki_idx)
732 {
733 addf (str, "error: more than one AKI extension\n");
734 continue;
735 }
736
737 addf (str, _("\t\tAuthority Key Identifier (%s):\n"),
738 critical ? _("critical") : _("not critical"));
739
740 print_aki (str, cert);
741
742 aki_idx++;
743 }
744 else if (strcmp (oid, "2.5.29.15") == 0)
745 {
746 if (keyusage_idx)
747 {
748 addf (str, "error: more than one key usage extension\n");
749 continue;
750 }
751
752 addf (str, _("\t\tKey Usage (%s):\n"),
753 critical ? _("critical") : _("not critical"));
754
755 print_key_usage (str, cert);
756
757 keyusage_idx++;
758 }
759 else if (strcmp (oid, "2.5.29.37") == 0)
760 {
761 if (keypurpose_idx)
762 {
763 addf (str, "error: more than one key purpose extension\n");
764 continue;
765 }
766
767 addf (str, _("\t\tKey Purpose (%s):\n"),
768 critical ? _("critical") : _("not critical"));
769
770 print_key_purpose (str, cert);
771
772 keypurpose_idx++;
773 }
774 else if (strcmp (oid, "2.5.29.17") == 0)
775 {
776 if (san_idx)
777 {
778 addf (str, "error: more than one SKI extension\n");
779 continue;
780 }
781
782 addf (str, _("\t\tSubject Alternative Name (%s):\n"),
783 critical ? _("critical") : _("not critical"));
784
785 print_san (str, cert);
786
787 san_idx++;
788 }
789 else if (strcmp (oid, "2.5.29.31") == 0)
790 {
791 if (crldist_idx)
792 {
793 addf (str, "error: more than one CRL distribution point\n");
794 continue;
795 }
796
797 addf (str, _("\t\tCRL Distribution points (%s):\n"),
798 critical ? _("critical") : _("not critical"));
799
800 print_crldist (str, cert);
801
802 crldist_idx++;
803 }
804 else if (strcmp (oid, "1.3.6.1.5.5.7.1.14") == 0)
805 {
806 if (proxy_idx)
807 {
808 addf (str, "error: more than one proxy extension\n");
809 continue;
810 }
811
812 addf (str, _("\t\tProxy Certificate Information (%s):\n"),
813 critical ? _("critical") : _("not critical"));
814
815 print_proxy (str, cert);
816
817 proxy_idx++;
818 }
819 else
820 {
821 char *buffer;
822 size_t extlen = 0;
823
824 addf (str, _("\t\tUnknown extension %s (%s):\n"), oid,
825 critical ? _("critical") : _("not critical"));
826
827 err = gnutls_x509_crt_get_extension_data (cert, i,
828 NULL, &extlen);
829 if (err < 0)
830 {
831 addf (str, "error: get_extension_data: %s\n",
832 gnutls_strerror (err));
833 continue;
834 }
835
836 buffer = gnutls_malloc (extlen);
837 if (!buffer)
838 {
839 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
840 continue;
841 }
842
843 err = gnutls_x509_crt_get_extension_data (cert, i,
844 buffer, &extlen);
845 if (err < 0)
846 {
847 gnutls_free (buffer);
848 addf (str, "error: get_extension_data2: %s\n",
849 gnutls_strerror (err));
850 continue;
851 }
852
853 addf (str, _("\t\t\tASCII: "));
854 asciiprint (str, buffer, extlen);
855 addf (str, "\n");
856
857 addf (str, _("\t\t\tHexdump: "));
858 hexprint (str, buffer, extlen);
859 adds (str, "\n");
860
861 gnutls_free (buffer);
862 }
863 }
864 }
865
866 /* Signature. */
867 if (!notsigned)
868 {
869 int err;
870 size_t size = 0;
871 char *buffer = NULL;
872
873 err = gnutls_x509_crt_get_signature_algorithm (cert);
874 if (err < 0)
875 addf (str, "error: get_signature_algorithm: %s\n",
876 gnutls_strerror (err));
877 else
878 {
879 const char *name = gnutls_sign_algorithm_get_name (err);
880 if (name == NULL)
881 name = "Unknown";
882 addf (str, _("\tSignature Algorithm: %s\n"), name);
883 }
884 if (err == GNUTLS_SIGN_RSA_MD5 || err == GNUTLS_SIGN_RSA_MD2)
885 {
886 addf (str,
887 _
888 ("warning: signed using a broken signature algorithm that can be forged.\n"));
889 }
890
891 err = gnutls_x509_crt_get_signature (cert, buffer, &size);
892 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
893 {
894 addf (str, "error: get_signature: %s\n", gnutls_strerror (err));
895 return;
896 }
897
898 buffer = gnutls_malloc (size);
899 if (!buffer)
900 {
901 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
902 return;
903 }
904
905 err = gnutls_x509_crt_get_signature (cert, buffer, &size);
906 if (err < 0)
907 {
908 gnutls_free (buffer);
909 addf (str, "error: get_signature2: %s\n", gnutls_strerror (err));
910 return;
911 }
912
913 addf (str, _("\tSignature:\n"));
914 hexdump (str, buffer, size, "\t\t");
915
916 gnutls_free (buffer);
917 }
918}
919
920static void
921print_fingerprint (gnutls_string * str, gnutls_x509_crt_t cert,
922 gnutls_digest_algorithm_t algo)
923{
924 int err;
925 char buffer[MAX_HASH_SIZE];
926 size_t size = sizeof (buffer);
927
928 err = gnutls_x509_crt_get_fingerprint (cert, algo, buffer, &size);
929 if (err < 0)
930 {
931 addf (str, "error: get_fingerprint: %s\n", gnutls_strerror (err));
932 return;
933 }
934
935 if (algo == GNUTLS_DIG_MD5)
936 addf (str, _("\tMD5 fingerprint:\n\t\t"));
937 else
938 addf (str, _("\tSHA-1 fingerprint:\n\t\t"));
939 hexprint (str, buffer, size);
940 adds (str, "\n");
941}
942
943static void
944print_keyid (gnutls_string * str, gnutls_x509_crt_t cert)
945{
946 int err;
947 size_t size = 0;
948 char *buffer = NULL;
949
950 err = gnutls_x509_crt_get_key_id (cert, 0, buffer, &size);
951 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
952 {
953 addf (str, "error: get_key_id: %s\n", gnutls_strerror (err));
954 return;
955 }
956
957 buffer = gnutls_malloc (size);
958 if (!buffer)
959 {
960 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
961 return;
962 }
963
964 err = gnutls_x509_crt_get_key_id (cert, 0, buffer, &size);
965 if (err < 0)
966 {
967 gnutls_free (buffer);
968 addf (str, "error: get_key_id2: %s\n", gnutls_strerror (err));
969 return;
970 }
971
972 addf (str, _("\tPublic Key Id:\n\t\t"));
973 hexprint (str, buffer, size);
974 adds (str, "\n");
975
976 gnutls_free (buffer);
977}
978
979static void
980print_other (gnutls_string * str, gnutls_x509_crt_t cert, int notsigned)
981{
982 if (!notsigned)
983 {
984 print_fingerprint (str, cert, GNUTLS_DIG_MD5);
985 print_fingerprint (str, cert, GNUTLS_DIG_SHA1);
986 }
987 print_keyid (str, cert);
988}
989
990static void
991print_oneline (gnutls_string * str, gnutls_x509_crt_t cert)
992{
993
994 /* Subject. */
995 {
996 char dn[1024];
997 size_t dn_size = sizeof (dn);
998 int err;
999
1000 err = gnutls_x509_crt_get_dn (cert, dn, &dn_size);
1001 if (err < 0)
1002 addf (str, "unknown subject (%s), ", gnutls_strerror (err));
1003 else
1004 addf (str, "subject `%s', ", dn);
1005 }
1006
1007 /* Issuer. */
1008 {
1009 char dn[1024];
1010 size_t dn_size = sizeof (dn);
1011 int err;
1012
1013 err = gnutls_x509_crt_get_issuer_dn (cert, dn, &dn_size);
1014 if (err < 0)
1015 addf (str, "unknown issuer (%s), ", gnutls_strerror (err));
1016 else
1017 addf (str, "issuer `%s', ", dn);
1018 }
1019
1020 {
1021 int bits;
1022 const char *name = gnutls_pk_algorithm_get_name
1023 (gnutls_x509_crt_get_pk_algorithm (cert, &bits));
1024 if (name == NULL)
1025 name = "Unknown";
1026 addf (str, "%s key %d bits, ", name, bits);
1027 }
1028
1029 /* Validity. */
1030 {
1031 time_t tim;
1032
1033 tim = gnutls_x509_crt_get_activation_time (cert);
1034 {
1035 char s[42];
1036 size_t max = sizeof (s);
1037 struct tm t;
1038
1039 if (gmtime_r (&tim, &t) == NULL)
1040 addf (str, "unknown activation (%d), ", t);
1041 else if (strftime (s, max, "%Y-%m-%d %H:%M:%S UTC", &t) == 0)
1042 addf (str, "failed activation (%d), ", t);
1043 else
1044 addf (str, "activated `%s', ", s);
1045 }
1046
1047 tim = gnutls_x509_crt_get_expiration_time (cert);
1048 {
1049 char s[42];
1050 size_t max = sizeof (s);
1051 struct tm t;
1052
1053 if (gmtime_r (&tim, &t) == NULL)
1054 addf (str, "unknown expiry (%d), ", t);
1055 else if (strftime (s, max, "%Y-%m-%d %H:%M:%S UTC", &t) == 0)
1056 addf (str, "failed expiry (%d), ", t);
1057 else
1058 addf (str, "expires `%s', ", s);
1059 }
1060 }
1061
1062 {
1063 int pathlen;
1064 char *policyLanguage;
1065 int err;
1066
1067 err = gnutls_x509_crt_get_proxy (cert, NULL,
1068 &pathlen, &policyLanguage, NULL, NULL);
1069 if (err == 0)
1070 {
1071 addf (str, "proxy certificate (policy=");
1072 if (strcmp (policyLanguage, "1.3.6.1.5.5.7.21.1") == 0)
1073 addf (str, "id-ppl-inheritALL");
1074 else if (strcmp (policyLanguage, "1.3.6.1.5.5.7.21.2") == 0)
1075 addf (str, "id-ppl-independent");
1076 else
1077 addf (str, "%s", policyLanguage);
1078 if (pathlen >= 0)
1079 addf (str, ", pathlen=%d), ", pathlen);
1080 else
1081 addf (str, "), ");
1082 gnutls_free (policyLanguage);
1083 }
1084 }
1085
1086 {
1087 char buffer[20];
1088 size_t size = sizeof (buffer);
1089 int err;
1090
1091 err = gnutls_x509_crt_get_fingerprint (cert, GNUTLS_DIG_SHA1,
1092 buffer, &size);
1093 if (err < 0)
1094 {
1095 addf (str, "unknown fingerprint (%s)", gnutls_strerror (err));
1096 }
1097 else
1098 {
1099 addf (str, "SHA-1 fingerprint `");
1100 hexprint (str, buffer, size);
1101 adds (str, "'");
1102 }
1103 }
1104
1105}
1106
1107/**
1108 * gnutls_x509_crt_print - Pretty print X.509 certificates
1109 * @cert: The structure to be printed
1110 * @format: Indicate the format to use
1111 * @out: Newly allocated datum with zero terminated string.
1112 *
1113 * This function will pretty print a X.509 certificate, suitable for
1114 * display to a human.
1115 *
1116 * If the format is %GNUTLS_X509_CRT_FULL then all fields of the
1117 * certificate will be output, on multiple lines. The
1118 * %GNUTLS_X509_CRT_ONELINE format will generate one line with some
1119 * selected fields, which is useful for logging purposes.
1120 *
1121 * The output @out needs to be deallocate using gnutls_free().
1122 *
1123 * Returns 0 on success.
1124 **/
1125int
1126gnutls_x509_crt_print (gnutls_x509_crt_t cert,
1127 gnutls_certificate_print_formats_t format,
1128 gnutls_datum_t * out)
1129{
1130 gnutls_string str;
1131
1132 if (format == GNUTLS_X509_CRT_FULL
1133 || format == GNUTLS_X509_CRT_UNSIGNED_FULL)
1134 {
1135 _gnutls_string_init (&str, gnutls_malloc, gnutls_realloc, gnutls_free);
1136
1137 _gnutls_string_append_str (&str, _("X.509 Certificate Information:\n"));
1138
1139 print_cert (&str, cert, format == GNUTLS_X509_CRT_UNSIGNED_FULL);
1140
1141 _gnutls_string_append_str (&str, _("Other Information:\n"));
1142
1143 print_other (&str, cert, format == GNUTLS_X509_CRT_UNSIGNED_FULL);
1144
1145 _gnutls_string_append_data (&str, "\0", 1);
1146 out->data = str.data;
1147 out->size = strlen (str.data);
1148 }
1149 else if (format == GNUTLS_X509_CRT_ONELINE)
1150 {
1151 _gnutls_string_init (&str, gnutls_malloc, gnutls_realloc, gnutls_free);
1152
1153 print_oneline (&str, cert);
1154
1155 _gnutls_string_append_data (&str, "\0", 1);
1156 out->data = str.data;
1157 out->size = strlen (str.data);
1158 }
1159 else
1160 {
1161 gnutls_assert ();
1162 return GNUTLS_E_INVALID_REQUEST;
1163 }
1164
1165 return 0;
1166}
1167
1168static void
1169print_crl (gnutls_string * str, gnutls_x509_crl_t crl, int notsigned)
1170{
1171 /* Version. */
1172 {
1173 int version = gnutls_x509_crl_get_version (crl);
1174 if (version == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND)
1175 addf (str, _("\tVersion: 1 (default)\n"));
1176 else if (version < 0)
1177 addf (str, "error: get_version: %s\n", gnutls_strerror (version));
1178 else
1179 addf (str, _("\tVersion: %d\n"), version);
1180 }
1181
1182 /* Issuer. */
1183 if (!notsigned)
1184 {
1185 char dn[1024];
1186 size_t dn_size = sizeof (dn);
1187 int err;
1188
1189 err = gnutls_x509_crl_get_issuer_dn (crl, dn, &dn_size);
1190 if (err < 0)
1191 addf (str, "error: get_issuer_dn: %s\n", gnutls_strerror (err));
1192 else
1193 addf (str, _("\tIssuer: %s\n"), dn);
1194 }
1195
1196 /* Validity. */
1197 {
1198 time_t tim;
1199
1200 addf (str, _("\tUpdate dates:\n"));
1201
1202 tim = gnutls_x509_crl_get_this_update (crl);
1203 {
1204 char s[42];
1205 size_t max = sizeof (s);
1206 struct tm t;
1207
1208 if (gmtime_r (&tim, &t) == NULL)
1209 addf (str, "error: gmtime_r (%d)\n", t);
1210 else if (strftime (s, max, "%a %b %e %H:%M:%S UTC %Y", &t) == 0)
1211 addf (str, "error: strftime (%d)\n", t);
1212 else
1213 addf (str, _("\t\tIssued: %s\n"), s);
1214 }
1215
1216 tim = gnutls_x509_crl_get_next_update (crl);
1217 {
1218 char s[42];
1219 size_t max = sizeof (s);
1220 struct tm t;
1221
1222 if (tim == -1)
1223 addf (str, "\t\tNo next update time.\n");
1224 else if (gmtime_r (&tim, &t) == NULL)
1225 addf (str, "error: gmtime_r (%d)\n", t);
1226 else if (strftime (s, max, "%a %b %e %H:%M:%S UTC %Y", &t) == 0)
1227 addf (str, "error: strftime (%d)\n", t);
1228 else
1229 addf (str, _("\t\tNext at: %s\n"), s);
1230 }
1231 }
1232
1233 /* Revoked certificates. */
1234 {
1235 int num = gnutls_x509_crl_get_crt_count (crl);
1236 int j;
1237
1238 if (num)
1239 addf (str, _("\tRevoked certificates (%d):\n"), num);
1240 else
1241 addf (str, _("\tNo revoked certificates.\n"));
1242
1243 for (j = 0; j < num; j++)
1244 {
1245 char serial[128];
1246 size_t serial_size = sizeof (serial);
1247 int err;
1248 time_t tim;
1249
1250 err = gnutls_x509_crl_get_crt_serial (crl, j, serial,
1251 &serial_size, &tim);
1252 if (err < 0)
1253 addf (str, "error: get_crt_serial: %s\n", gnutls_strerror (err));
1254 else
1255 {
1256 char s[42];
1257 size_t max = sizeof (s);
1258 struct tm t;
1259
1260 addf (str, _("\t\tSerial Number (hex): "));
1261 hexprint (str, serial, serial_size);
1262 adds (str, "\n");
1263
1264 if (gmtime_r (&tim, &t) == NULL)
1265 addf (str, "error: gmtime_r (%d)\n", t);
1266 else if (strftime (s, max, "%a %b %e %H:%M:%S UTC %Y", &t) == 0)
1267 addf (str, "error: strftime (%d)\n", t);
1268 else
1269 addf (str, _("\t\tRevoked at: %s\n"), s);
1270 }
1271 }
1272 }
1273
1274 /* Signature. */
1275 if (!notsigned)
1276 {
1277 int err;
1278 size_t size = 0;
1279 char *buffer = NULL;
1280
1281 err = gnutls_x509_crl_get_signature_algorithm (crl);
1282 if (err < 0)
1283 addf (str, "error: get_signature_algorithm: %s\n",
1284 gnutls_strerror (err));
1285 else
1286 {
1287 const char *name = gnutls_sign_algorithm_get_name (err);
1288 if (name == NULL)
1289 name = "Unknown";
1290 addf (str, _("\tSignature Algorithm: %s\n"), name);
1291 }
1292 if (err == GNUTLS_SIGN_RSA_MD5 || err == GNUTLS_SIGN_RSA_MD2)
1293 {
1294 addf (str,
1295 _
1296 ("warning: signed using a broken signature algorithm that can be forged.\n"));
1297 }
1298
1299 err = gnutls_x509_crl_get_signature (crl, buffer, &size);
1300 if (err != GNUTLS_E_SHORT_MEMORY_BUFFER)
1301 {
1302 addf (str, "error: get_signature: %s\n", gnutls_strerror (err));
1303 return;
1304 }
1305
1306 buffer = gnutls_malloc (size);
1307 if (!buffer)
1308 {
1309 addf (str, "error: malloc: %s\n", gnutls_strerror (err));
1310 return;
1311 }
1312
1313 err = gnutls_x509_crl_get_signature (crl, buffer, &size);
1314 if (err < 0)
1315 {
1316 gnutls_free (buffer);
1317 addf (str, "error: get_signature2: %s\n", gnutls_strerror (err));
1318 return;
1319 }
1320
1321 addf (str, _("\tSignature:\n"));
1322 hexdump (str, buffer, size, "\t\t");
1323
1324 gnutls_free (buffer);
1325 }
1326}
1327
1328/**
1329 * gnutls_x509_crl_print - Pretty print X.509 certificate revocation list
1330 * @crl: The structure to be printed
1331 * @format: Indicate the format to use
1332 * @out: Newly allocated datum with zero terminated string.
1333 *
1334 * This function will pretty print a X.509 certificate revocation
1335 * list, suitable for display to a human.
1336 *
1337 * The output @out needs to be deallocate using gnutls_free().
1338 *
1339 * Returns 0 on success.
1340 **/
1341int
1342gnutls_x509_crl_print (gnutls_x509_crl_t crl,
1343 gnutls_certificate_print_formats_t format,
1344 gnutls_datum_t * out)
1345{
1346 gnutls_string str;
1347
1348 _gnutls_string_init (&str, gnutls_malloc, gnutls_realloc, gnutls_free);
1349
1350 _gnutls_string_append_str
1351 (&str, _("X.509 Certificate Revocation List Information:\n"));
1352
1353 print_crl (&str, crl, format == GNUTLS_X509_CRT_UNSIGNED_FULL);
1354
1355 _gnutls_string_append_data (&str, "\0", 1);
1356 out->data = str.data;
1357 out->size = strlen (str.data);
1358
1359 return 0;
1360}
diff --git a/src/daemon/https/x509/pkcs12.c b/src/daemon/https/x509/pkcs12.c
new file mode 100644
index 00000000..40f7a243
--- /dev/null
+++ b/src/daemon/https/x509/pkcs12.c
@@ -0,0 +1,1325 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* Functions that relate on PKCS12 packet parsing.
26 */
27
28#include <gnutls_int.h>
29#include <libtasn1.h>
30
31#ifdef ENABLE_PKI
32
33#include <gnutls_datum.h>
34#include <gnutls_global.h>
35#include <gnutls_errors.h>
36#include <gnutls_num.h>
37#include <common.h>
38#include <x509_b64.h>
39#include <pkcs12.h>
40#include <dn.h>
41#include <mpi.h>
42#include <gc.h>
43
44
45/* Decodes the PKCS #12 auth_safe, and returns the allocated raw data,
46 * which holds them. Returns an ASN1_TYPE of authenticatedSafe.
47 */
48static int
49_decode_pkcs12_auth_safe (ASN1_TYPE pkcs12, ASN1_TYPE * authen_safe,
50 gnutls_datum_t * raw)
51{
52 char oid[128];
53 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
54 gnutls_datum_t auth_safe = { NULL, 0 };
55 int tmp_size, len, result;
56
57 len = sizeof (oid) - 1;
58 result = asn1_read_value (pkcs12, "authSafe.contentType", oid, &len);
59 if (result != ASN1_SUCCESS)
60 {
61 gnutls_assert ();
62 return _gnutls_asn2err (result);
63 }
64
65 if (strcmp (oid, DATA_OID) != 0)
66 {
67 gnutls_assert ();
68 _gnutls_x509_log ("Unknown PKCS12 Content OID '%s'\n", oid);
69 return GNUTLS_E_UNKNOWN_PKCS_CONTENT_TYPE;
70 }
71
72 /* Step 1. Read the content data
73 */
74
75 tmp_size = 0;
76 result =
77 _gnutls_x509_read_value (pkcs12, "authSafe.content", &auth_safe, 1);
78 if (result < 0)
79 {
80 gnutls_assert ();
81 goto cleanup;
82 }
83
84 /* Step 2. Extract the authenticatedSafe.
85 */
86
87 if ((result = asn1_create_element
88 (_gnutls_get_pkix (), "PKIX1.pkcs-12-AuthenticatedSafe",
89 &c2)) != ASN1_SUCCESS)
90 {
91 gnutls_assert ();
92 result = _gnutls_asn2err (result);
93 goto cleanup;
94 }
95
96 result = asn1_der_decoding (&c2, auth_safe.data, auth_safe.size, NULL);
97 if (result != ASN1_SUCCESS)
98 {
99 gnutls_assert ();
100 result = _gnutls_asn2err (result);
101 goto cleanup;
102 }
103
104 if (raw == NULL)
105 {
106 _gnutls_free_datum (&auth_safe);
107 }
108 else
109 {
110 raw->data = auth_safe.data;
111 raw->size = auth_safe.size;
112 }
113
114 if (authen_safe)
115 *authen_safe = c2;
116 else
117 asn1_delete_structure (&c2);
118
119 return 0;
120
121cleanup:
122 if (c2)
123 asn1_delete_structure (&c2);
124 _gnutls_free_datum (&auth_safe);
125 return result;
126}
127
128/**
129 * gnutls_pkcs12_init - This function initializes a gnutls_pkcs12_t structure
130 * @pkcs12: The structure to be initialized
131 *
132 * This function will initialize a PKCS12 structure. PKCS12 structures
133 * usually contain lists of X.509 Certificates and X.509 Certificate
134 * revocation lists.
135 *
136 * Returns 0 on success.
137 *
138 **/
139int
140gnutls_pkcs12_init (gnutls_pkcs12_t * pkcs12)
141{
142 *pkcs12 = gnutls_calloc (1, sizeof (gnutls_pkcs12_int));
143
144 if (*pkcs12)
145 {
146 int result = asn1_create_element (_gnutls_get_pkix (),
147 "PKIX1.pkcs-12-PFX",
148 &(*pkcs12)->pkcs12);
149 if (result != ASN1_SUCCESS)
150 {
151 gnutls_assert ();
152 gnutls_free (*pkcs12);
153 return _gnutls_asn2err (result);
154 }
155 return 0; /* success */
156 }
157 return GNUTLS_E_MEMORY_ERROR;
158}
159
160/**
161 * gnutls_pkcs12_deinit - This function deinitializes memory used by a gnutls_pkcs12_t structure
162 * @pkcs12: The structure to be initialized
163 *
164 * This function will deinitialize a PKCS12 structure.
165 *
166 **/
167void
168gnutls_pkcs12_deinit (gnutls_pkcs12_t pkcs12)
169{
170 if (!pkcs12)
171 return;
172
173 if (pkcs12->pkcs12)
174 asn1_delete_structure (&pkcs12->pkcs12);
175
176 gnutls_free (pkcs12);
177}
178
179/**
180 * gnutls_pkcs12_import - This function will import a DER or PEM encoded PKCS12 structure
181 * @pkcs12: The structure to store the parsed PKCS12.
182 * @data: The DER or PEM encoded PKCS12.
183 * @format: One of DER or PEM
184 * @flags: an ORed sequence of gnutls_privkey_pkcs8_flags
185 *
186 * This function will convert the given DER or PEM encoded PKCS12
187 * to the native gnutls_pkcs12_t format. The output will be stored in 'pkcs12'.
188 *
189 * If the PKCS12 is PEM encoded it should have a header of "PKCS12".
190 *
191 * Returns 0 on success.
192 *
193 **/
194int
195gnutls_pkcs12_import (gnutls_pkcs12_t pkcs12,
196 const gnutls_datum_t * data,
197 gnutls_x509_crt_fmt_t format, unsigned int flags)
198{
199 int result = 0, need_free = 0;
200 gnutls_datum_t _data;
201
202 _data.data = data->data;
203 _data.size = data->size;
204
205 if (pkcs12 == NULL)
206 {
207 gnutls_assert ();
208 return GNUTLS_E_INVALID_REQUEST;
209 }
210
211 /* If the PKCS12 is in PEM format then decode it
212 */
213 if (format == GNUTLS_X509_FMT_PEM)
214 {
215 opaque *out;
216
217 result = _gnutls_fbase64_decode (PEM_PKCS12, data->data, data->size,
218 &out);
219
220 if (result <= 0)
221 {
222 if (result == 0)
223 result = GNUTLS_E_INTERNAL_ERROR;
224 gnutls_assert ();
225 return result;
226 }
227
228 _data.data = out;
229 _data.size = result;
230
231 need_free = 1;
232 }
233
234 result = asn1_der_decoding (&pkcs12->pkcs12, _data.data, _data.size, NULL);
235 if (result != ASN1_SUCCESS)
236 {
237 result = _gnutls_asn2err (result);
238 gnutls_assert ();
239 goto cleanup;
240 }
241
242 if (need_free)
243 _gnutls_free_datum (&_data);
244
245 return 0;
246
247cleanup:
248 if (need_free)
249 _gnutls_free_datum (&_data);
250 return result;
251}
252
253
254/**
255 * gnutls_pkcs12_export - This function will export the pkcs12 structure
256 * @pkcs12: Holds the pkcs12 structure
257 * @format: the format of output params. One of PEM or DER.
258 * @output_data: will contain a structure PEM or DER encoded
259 * @output_data_size: holds the size of output_data (and will be
260 * replaced by the actual size of parameters)
261 *
262 * This function will export the pkcs12 structure to DER or PEM format.
263 *
264 * If the buffer provided is not long enough to hold the output, then
265 * *output_data_size will be updated and GNUTLS_E_SHORT_MEMORY_BUFFER
266 * will be returned.
267 *
268 * If the structure is PEM encoded, it will have a header
269 * of "BEGIN PKCS12".
270 *
271 * Return value: In case of failure a negative value will be
272 * returned, and 0 on success.
273 *
274 **/
275int
276gnutls_pkcs12_export (gnutls_pkcs12_t pkcs12,
277 gnutls_x509_crt_fmt_t format, void *output_data,
278 size_t * output_data_size)
279{
280 if (pkcs12 == NULL)
281 {
282 gnutls_assert ();
283 return GNUTLS_E_INVALID_REQUEST;
284 }
285
286 return _gnutls_x509_export_int (pkcs12->pkcs12, format, PEM_PKCS12,
287 output_data, output_data_size);
288}
289
290static int
291oid2bag (const char *oid)
292{
293 if (strcmp (oid, BAG_PKCS8_KEY) == 0)
294 return GNUTLS_BAG_PKCS8_KEY;
295 if (strcmp (oid, BAG_PKCS8_ENCRYPTED_KEY) == 0)
296 return GNUTLS_BAG_PKCS8_ENCRYPTED_KEY;
297 if (strcmp (oid, BAG_CERTIFICATE) == 0)
298 return GNUTLS_BAG_CERTIFICATE;
299 if (strcmp (oid, BAG_CRL) == 0)
300 return GNUTLS_BAG_CRL;
301
302 return GNUTLS_BAG_UNKNOWN;
303}
304
305static const char *
306bag_to_oid (int bag)
307{
308 switch (bag)
309 {
310 case GNUTLS_BAG_PKCS8_KEY:
311 return BAG_PKCS8_KEY;
312 case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY:
313 return BAG_PKCS8_ENCRYPTED_KEY;
314 case GNUTLS_BAG_CERTIFICATE:
315 return BAG_CERTIFICATE;
316 case GNUTLS_BAG_CRL:
317 return BAG_CRL;
318 }
319 return NULL;
320}
321
322static inline char *
323ucs2_to_ascii (char *data, int size)
324{
325 int i, j;
326
327 for (i = 0; i < size / 2; i++)
328 {
329 j = 2 * i + 1;
330 if (isascii (data[j]))
331 data[i] = data[i * 2 + 1];
332 else
333 data[i] = '?';
334 }
335 data[i] = 0;
336
337 return data;
338}
339
340/* Decodes the SafeContents, and puts the output in
341 * the given bag.
342 */
343int
344_pkcs12_decode_safe_contents (const gnutls_datum_t * content,
345 gnutls_pkcs12_bag_t bag)
346{
347 char oid[128], root[MAX_NAME_SIZE];
348 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
349 int len, result;
350 int bag_type;
351 gnutls_datum_t attr_val;
352 int count = 0, i, attributes, j;
353 size_t size;
354
355 /* Step 1. Extract the SEQUENCE.
356 */
357
358 if ((result = asn1_create_element
359 (_gnutls_get_pkix (), "PKIX1.pkcs-12-SafeContents",
360 &c2)) != ASN1_SUCCESS)
361 {
362 gnutls_assert ();
363 result = _gnutls_asn2err (result);
364 goto cleanup;
365 }
366
367 result = asn1_der_decoding (&c2, content->data, content->size, NULL);
368 if (result != ASN1_SUCCESS)
369 {
370 gnutls_assert ();
371 result = _gnutls_asn2err (result);
372 goto cleanup;
373 }
374
375 /* Count the number of bags
376 */
377 result = asn1_number_of_elements (c2, "", &count);
378 if (result != ASN1_SUCCESS)
379 {
380 gnutls_assert ();
381 result = _gnutls_asn2err (result);
382 goto cleanup;
383 }
384
385 bag->bag_elements = MIN (MAX_BAG_ELEMENTS, count);
386
387 for (i = 0; i < bag->bag_elements; i++)
388 {
389
390 snprintf (root, sizeof (root), "?%u.bagId", i + 1);
391
392 len = sizeof (oid);
393 result = asn1_read_value (c2, root, oid, &len);
394 if (result != ASN1_SUCCESS)
395 {
396 gnutls_assert ();
397 result = _gnutls_asn2err (result);
398 goto cleanup;
399 }
400
401 /* Read the Bag type
402 */
403 bag_type = oid2bag (oid);
404
405 if (bag_type < 0)
406 {
407 gnutls_assert ();
408 goto cleanup;
409 }
410
411 /* Read the Bag Value
412 */
413
414 snprintf (root, sizeof (root), "?%u.bagValue", i + 1);
415
416 result = _gnutls_x509_read_value (c2, root, &bag->element[i].data, 0);
417 if (result < 0)
418 {
419 gnutls_assert ();
420 goto cleanup;
421 }
422
423 if (bag_type == GNUTLS_BAG_CERTIFICATE || bag_type == GNUTLS_BAG_CRL)
424 {
425 gnutls_datum_t tmp = bag->element[i].data;
426
427 result =
428 _pkcs12_decode_crt_bag (bag_type, &tmp, &bag->element[i].data);
429 if (result < 0)
430 {
431 gnutls_assert ();
432 goto cleanup;
433 }
434
435 _gnutls_free_datum (&tmp);
436 }
437
438 /* read the bag attributes
439 */
440 snprintf (root, sizeof (root), "?%u.bagAttributes", i + 1);
441
442 result = asn1_number_of_elements (c2, root, &attributes);
443 if (result != ASN1_SUCCESS && result != ASN1_ELEMENT_NOT_FOUND)
444 {
445 gnutls_assert ();
446 result = _gnutls_asn2err (result);
447 goto cleanup;
448 }
449
450 if (attributes < 0)
451 attributes = 1;
452
453 if (result != ASN1_ELEMENT_NOT_FOUND)
454 for (j = 0; j < attributes; j++)
455 {
456
457 snprintf (root, sizeof (root), "?%u.bagAttributes.?%u", i + 1,
458 j + 1);
459
460 result =
461 _gnutls_x509_decode_and_read_attribute (c2, root, oid,
462 sizeof (oid), &attr_val,
463 1, 0);
464
465 if (result < 0)
466 {
467 gnutls_assert ();
468 continue; /* continue in case we find some known attributes */
469 }
470
471 if (strcmp (oid, KEY_ID_OID) == 0)
472 {
473 size = attr_val.size;
474
475 result =
476 _gnutls_x509_decode_octet_string (NULL, attr_val.data, size,
477 attr_val.data, &size);
478 attr_val.size = size;
479 if (result < 0)
480 {
481 _gnutls_free_datum (&attr_val);
482 gnutls_assert ();
483 _gnutls_x509_log
484 ("Error decoding PKCS12 Bag Attribute OID '%s'\n", oid);
485 continue;
486 }
487 bag->element[i].local_key_id = attr_val;
488 }
489 else if (strcmp (oid, FRIENDLY_NAME_OID) == 0)
490 {
491 size = attr_val.size;
492 result =
493 _gnutls_x509_decode_octet_string ("BMPString",
494 attr_val.data, size,
495 attr_val.data, &size);
496 attr_val.size = size;
497 if (result < 0)
498 {
499 _gnutls_free_datum (&attr_val);
500 gnutls_assert ();
501 _gnutls_x509_log
502 ("Error decoding PKCS12 Bag Attribute OID '%s'\n", oid);
503 continue;
504 }
505 bag->element[i].friendly_name =
506 ucs2_to_ascii (attr_val.data, attr_val.size);
507 }
508 else
509 {
510 _gnutls_free_datum (&attr_val);
511 _gnutls_x509_log
512 ("Unknown PKCS12 Bag Attribute OID '%s'\n", oid);
513 }
514 }
515
516
517 bag->element[i].type = bag_type;
518
519 }
520
521 asn1_delete_structure (&c2);
522
523
524 return 0;
525
526cleanup:
527 if (c2)
528 asn1_delete_structure (&c2);
529 return result;
530
531}
532
533
534static int
535_parse_safe_contents (ASN1_TYPE sc, const char *sc_name,
536 gnutls_pkcs12_bag_t bag)
537{
538 gnutls_datum_t content = { NULL, 0 };
539 int result;
540
541 /* Step 1. Extract the content.
542 */
543
544 result = _gnutls_x509_read_value (sc, sc_name, &content, 1);
545 if (result < 0)
546 {
547 gnutls_assert ();
548 goto cleanup;
549 }
550
551 result = _pkcs12_decode_safe_contents (&content, bag);
552 if (result < 0)
553 {
554 gnutls_assert ();
555 goto cleanup;
556 }
557
558 _gnutls_free_datum (&content);
559
560 return 0;
561
562cleanup:
563 _gnutls_free_datum (&content);
564 return result;
565}
566
567
568/**
569 * gnutls_pkcs12_get_bag - This function returns a Bag from a PKCS12 structure
570 * @pkcs12: should contain a gnutls_pkcs12_t structure
571 * @indx: contains the index of the bag to extract
572 * @bag: An initialized bag, where the contents of the bag will be copied
573 *
574 * This function will return a Bag from the PKCS12 structure.
575 * Returns 0 on success.
576 *
577 * After the last Bag has been read GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
578 * will be returned.
579 *
580 **/
581int
582gnutls_pkcs12_get_bag (gnutls_pkcs12_t pkcs12,
583 int indx, gnutls_pkcs12_bag_t bag)
584{
585 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
586 int result, len;
587 char root2[MAX_NAME_SIZE];
588 char oid[128];
589
590 if (pkcs12 == NULL)
591 {
592 gnutls_assert ();
593 return GNUTLS_E_INVALID_REQUEST;
594 }
595
596 /* Step 1. decode the data.
597 */
598 result = _decode_pkcs12_auth_safe (pkcs12->pkcs12, &c2, NULL);
599 if (result < 0)
600 {
601 gnutls_assert ();
602 return result;
603 }
604
605 /* Step 2. Parse the AuthenticatedSafe
606 */
607
608 snprintf (root2, sizeof (root2), "?%u.contentType", indx + 1);
609
610 len = sizeof (oid) - 1;
611 result = asn1_read_value (c2, root2, oid, &len);
612
613 if (result == ASN1_ELEMENT_NOT_FOUND)
614 {
615 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
616 goto cleanup;
617 }
618
619 if (result != ASN1_SUCCESS)
620 {
621 gnutls_assert ();
622 result = _gnutls_asn2err (result);
623 goto cleanup;
624 }
625
626 /* Not encrypted Bag
627 */
628
629 snprintf (root2, sizeof (root2), "?%u.content", indx + 1);
630
631 if (strcmp (oid, DATA_OID) == 0)
632 {
633 result = _parse_safe_contents (c2, root2, bag);
634 goto cleanup;
635 }
636
637 /* ENC_DATA_OID needs decryption */
638
639 bag->element[0].type = GNUTLS_BAG_ENCRYPTED;
640 bag->bag_elements = 1;
641
642 result = _gnutls_x509_read_value (c2, root2, &bag->element[0].data, 0);
643 if (result < 0)
644 {
645 gnutls_assert ();
646 goto cleanup;
647 }
648
649 result = 0;
650
651cleanup:
652 if (c2)
653 asn1_delete_structure (&c2);
654 return result;
655}
656
657/* Creates an empty PFX structure for the PKCS12 structure.
658 */
659static int
660create_empty_pfx (ASN1_TYPE pkcs12)
661{
662 uint8_t three = 3;
663 int result;
664 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
665
666 /* Use version 3
667 */
668 result = asn1_write_value (pkcs12, "version", &three, 1);
669 if (result != ASN1_SUCCESS)
670 {
671 gnutls_assert ();
672 result = _gnutls_asn2err (result);
673 goto cleanup;
674 }
675
676 /* Write the content type of the data
677 */
678 result = asn1_write_value (pkcs12, "authSafe.contentType", DATA_OID, 1);
679 if (result != ASN1_SUCCESS)
680 {
681 gnutls_assert ();
682 result = _gnutls_asn2err (result);
683 goto cleanup;
684 }
685
686 /* Check if the authenticatedSafe content is empty, and encode a
687 * null one in that case.
688 */
689
690 if ((result = asn1_create_element
691 (_gnutls_get_pkix (), "PKIX1.pkcs-12-AuthenticatedSafe",
692 &c2)) != ASN1_SUCCESS)
693 {
694 gnutls_assert ();
695 result = _gnutls_asn2err (result);
696 goto cleanup;
697 }
698
699 result =
700 _gnutls_x509_der_encode_and_copy (c2, "", pkcs12, "authSafe.content", 1);
701 if (result < 0)
702 {
703 gnutls_assert ();
704 goto cleanup;
705 }
706 asn1_delete_structure (&c2);
707
708 return 0;
709
710cleanup:
711 asn1_delete_structure (&c2);
712 return result;
713
714}
715
716/**
717 * gnutls_pkcs12_set_bag - This function inserts a Bag into a PKCS12 structure
718 * @pkcs12: should contain a gnutls_pkcs12_t structure
719 * @bag: An initialized bag
720 *
721 * This function will insert a Bag into the PKCS12 structure.
722 * Returns 0 on success.
723 *
724 **/
725int
726gnutls_pkcs12_set_bag (gnutls_pkcs12_t pkcs12, gnutls_pkcs12_bag_t bag)
727{
728 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
729 ASN1_TYPE safe_cont = ASN1_TYPE_EMPTY;
730 int result;
731 int enc = 0, dum = 1;
732 char null;
733
734 if (pkcs12 == NULL)
735 {
736 gnutls_assert ();
737 return GNUTLS_E_INVALID_REQUEST;
738 }
739
740 /* Step 1. Check if the pkcs12 structure is empty. In that
741 * case generate an empty PFX.
742 */
743 result = asn1_read_value (pkcs12->pkcs12, "authSafe.content", &null, &dum);
744 if (result == ASN1_VALUE_NOT_FOUND)
745 {
746 result = create_empty_pfx (pkcs12->pkcs12);
747 if (result < 0)
748 {
749 gnutls_assert ();
750 return result;
751 }
752 }
753
754 /* Step 2. decode the authenticatedSafe.
755 */
756 result = _decode_pkcs12_auth_safe (pkcs12->pkcs12, &c2, NULL);
757 if (result < 0)
758 {
759 gnutls_assert ();
760 return result;
761 }
762
763 /* Step 3. Encode the bag elements into a SafeContents
764 * structure.
765 */
766 result = _pkcs12_encode_safe_contents (bag, &safe_cont, &enc);
767 if (result < 0)
768 {
769 gnutls_assert ();
770 return result;
771 }
772
773 /* Step 4. Insert the encoded SafeContents into the AuthenticatedSafe
774 * structure.
775 */
776 result = asn1_write_value (c2, "", "NEW", 1);
777 if (result != ASN1_SUCCESS)
778 {
779 gnutls_assert ();
780 result = _gnutls_asn2err (result);
781 goto cleanup;
782 }
783
784 if (enc)
785 result = asn1_write_value (c2, "?LAST.contentType", ENC_DATA_OID, 1);
786 else
787 result = asn1_write_value (c2, "?LAST.contentType", DATA_OID, 1);
788 if (result != ASN1_SUCCESS)
789 {
790 gnutls_assert ();
791 result = _gnutls_asn2err (result);
792 goto cleanup;
793 }
794
795 if (enc)
796 {
797 /* Encrypted packets are written directly.
798 */
799 result =
800 asn1_write_value (c2, "?LAST.content",
801 bag->element[0].data.data,
802 bag->element[0].data.size);
803 if (result != ASN1_SUCCESS)
804 {
805 gnutls_assert ();
806 result = _gnutls_asn2err (result);
807 goto cleanup;
808 }
809 }
810 else
811 {
812 result =
813 _gnutls_x509_der_encode_and_copy (safe_cont, "", c2,
814 "?LAST.content", 1);
815 if (result < 0)
816 {
817 gnutls_assert ();
818 goto cleanup;
819 }
820 }
821
822 asn1_delete_structure (&safe_cont);
823
824
825 /* Step 5. Reencode and copy the AuthenticatedSafe into the pkcs12
826 * structure.
827 */
828 result =
829 _gnutls_x509_der_encode_and_copy (c2, "", pkcs12->pkcs12,
830 "authSafe.content", 1);
831 if (result < 0)
832 {
833 gnutls_assert ();
834 goto cleanup;
835 }
836
837 asn1_delete_structure (&c2);
838
839 return 0;
840
841cleanup:
842 asn1_delete_structure (&c2);
843 asn1_delete_structure (&safe_cont);
844 return result;
845}
846
847/**
848 * gnutls_pkcs12_generate_mac - This function generates the MAC of the PKCS12 structure
849 * @pkcs12: should contain a gnutls_pkcs12_t structure
850 * @pass: The password for the MAC
851 *
852 * This function will generate a MAC for the PKCS12 structure.
853 * Returns 0 on success.
854 *
855 **/
856int
857gnutls_pkcs12_generate_mac (gnutls_pkcs12_t pkcs12, const char *pass)
858{
859 opaque salt[8], key[20];
860 int result;
861 const int iter = 1;
862 mac_hd_t td1 = NULL;
863 gnutls_datum_t tmp = { NULL, 0 };
864 opaque sha_mac[20];
865
866 if (pkcs12 == NULL)
867 {
868 gnutls_assert ();
869 return GNUTLS_E_INVALID_REQUEST;
870 }
871
872 /* Generate the salt.
873 */
874 if (gc_nonce (salt, sizeof (salt)) != GC_OK)
875 {
876 gnutls_assert ();
877 return GNUTLS_E_RANDOM_FAILED;
878 }
879
880 /* Write the salt into the structure.
881 */
882 result =
883 asn1_write_value (pkcs12->pkcs12, "macData.macSalt", salt, sizeof (salt));
884 if (result != ASN1_SUCCESS)
885 {
886 gnutls_assert ();
887 result = _gnutls_asn2err (result);
888 goto cleanup;
889 }
890
891 /* write the iterations
892 */
893
894 if (iter > 1)
895 {
896 result =
897 _gnutls_x509_write_uint32 (pkcs12->pkcs12, "macData.iterations",
898 iter);
899 if (result < 0)
900 {
901 gnutls_assert ();
902 goto cleanup;
903 }
904 }
905
906 /* Generate the key.
907 */
908 result = _pkcs12_string_to_key (3 /*MAC*/, salt, sizeof (salt),
909 iter, pass, sizeof (key), key);
910 if (result < 0)
911 {
912 gnutls_assert ();
913 goto cleanup;
914 }
915
916 /* Get the data to be MACed
917 */
918 result = _decode_pkcs12_auth_safe (pkcs12->pkcs12, NULL, &tmp);
919 if (result < 0)
920 {
921 gnutls_assert ();
922 goto cleanup;
923 }
924
925 /* MAC the data
926 */
927 td1 = _gnutls_hmac_init (GNUTLS_MAC_SHA1, key, sizeof (key));
928 if (td1 == GNUTLS_MAC_FAILED)
929 {
930 gnutls_assert ();
931 result = GNUTLS_E_INTERNAL_ERROR;
932 goto cleanup;
933 }
934
935 _gnutls_hmac (td1, tmp.data, tmp.size);
936 _gnutls_free_datum (&tmp);
937
938 _gnutls_hmac_deinit (td1, sha_mac);
939
940
941 result =
942 asn1_write_value (pkcs12->pkcs12, "macData.mac.digest", sha_mac,
943 sizeof (sha_mac));
944 if (result != ASN1_SUCCESS)
945 {
946 gnutls_assert ();
947 result = _gnutls_asn2err (result);
948 goto cleanup;
949 }
950
951 result =
952 asn1_write_value (pkcs12->pkcs12,
953 "macData.mac.digestAlgorithm.parameters", NULL, 0);
954 if (result != ASN1_SUCCESS)
955 {
956 gnutls_assert ();
957 result = _gnutls_asn2err (result);
958 goto cleanup;
959 }
960
961 result =
962 asn1_write_value (pkcs12->pkcs12,
963 "macData.mac.digestAlgorithm.algorithm", HASH_OID_SHA1,
964 1);
965 if (result != ASN1_SUCCESS)
966 {
967 gnutls_assert ();
968 result = _gnutls_asn2err (result);
969 goto cleanup;
970 }
971
972 return 0;
973
974cleanup:
975 _gnutls_free_datum (&tmp);
976 return result;
977}
978
979/**
980 * gnutls_pkcs12_verify_mac - This function verifies the MAC of the PKCS12 structure
981 * @pkcs12: should contain a gnutls_pkcs12_t structure
982 * @pass: The password for the MAC
983 *
984 * This function will verify the MAC for the PKCS12 structure.
985 * Returns 0 on success.
986 *
987 **/
988int
989gnutls_pkcs12_verify_mac (gnutls_pkcs12_t pkcs12, const char *pass)
990{
991 opaque key[20];
992 int result;
993 unsigned int iter;
994 int len;
995 mac_hd_t td1 = NULL;
996 gnutls_datum_t tmp = { NULL, 0 }, salt =
997 {
998 NULL, 0};
999 opaque sha_mac[20];
1000 opaque sha_mac_orig[20];
1001
1002 if (pkcs12 == NULL)
1003 {
1004 gnutls_assert ();
1005 return GNUTLS_E_INVALID_REQUEST;
1006 }
1007
1008 /* read the iterations
1009 */
1010
1011 result =
1012 _gnutls_x509_read_uint (pkcs12->pkcs12, "macData.iterations", &iter);
1013 if (result < 0)
1014 {
1015 iter = 1; /* the default */
1016 }
1017
1018
1019 /* Read the salt from the structure.
1020 */
1021 result =
1022 _gnutls_x509_read_value (pkcs12->pkcs12, "macData.macSalt", &salt, 0);
1023 if (result != ASN1_SUCCESS)
1024 {
1025 gnutls_assert ();
1026 result = _gnutls_asn2err (result);
1027 goto cleanup;
1028 }
1029
1030 /* Generate the key.
1031 */
1032 result = _pkcs12_string_to_key (3 /*MAC*/, salt.data, salt.size,
1033 iter, pass, sizeof (key), key);
1034 if (result < 0)
1035 {
1036 gnutls_assert ();
1037 goto cleanup;
1038 }
1039
1040 _gnutls_free_datum (&salt);
1041
1042 /* Get the data to be MACed
1043 */
1044 result = _decode_pkcs12_auth_safe (pkcs12->pkcs12, NULL, &tmp);
1045 if (result < 0)
1046 {
1047 gnutls_assert ();
1048 goto cleanup;
1049 }
1050
1051 /* MAC the data
1052 */
1053 td1 = _gnutls_hmac_init (GNUTLS_MAC_SHA1, key, sizeof (key));
1054 if (td1 == GNUTLS_MAC_FAILED)
1055 {
1056 gnutls_assert ();
1057 result = GNUTLS_E_INTERNAL_ERROR;
1058 goto cleanup;
1059 }
1060
1061 _gnutls_hmac (td1, tmp.data, tmp.size);
1062 _gnutls_free_datum (&tmp);
1063
1064 _gnutls_hmac_deinit (td1, sha_mac);
1065
1066 len = sizeof (sha_mac_orig);
1067 result =
1068 asn1_read_value (pkcs12->pkcs12, "macData.mac.digest", sha_mac_orig,
1069 &len);
1070 if (result != ASN1_SUCCESS)
1071 {
1072 gnutls_assert ();
1073 result = _gnutls_asn2err (result);
1074 goto cleanup;
1075 }
1076
1077 if (memcmp (sha_mac_orig, sha_mac, sizeof (sha_mac)) != 0)
1078 {
1079 gnutls_assert ();
1080 return GNUTLS_E_MAC_VERIFY_FAILED;
1081 }
1082
1083 return 0;
1084
1085cleanup:
1086 _gnutls_free_datum (&tmp);
1087 _gnutls_free_datum (&salt);
1088 return result;
1089}
1090
1091
1092static int
1093write_attributes (gnutls_pkcs12_bag_t bag, int elem,
1094 ASN1_TYPE c2, const char *where)
1095{
1096 int result;
1097 char root[128];
1098
1099 /* If the bag attributes are empty, then write
1100 * nothing to the attribute field.
1101 */
1102 if (bag->element[elem].friendly_name == NULL &&
1103 bag->element[elem].local_key_id.data == NULL)
1104 {
1105 /* no attributes
1106 */
1107 result = asn1_write_value (c2, where, NULL, 0);
1108 if (result != ASN1_SUCCESS)
1109 {
1110 gnutls_assert ();
1111 return _gnutls_asn2err (result);
1112 }
1113
1114 return 0;
1115 }
1116
1117 if (bag->element[elem].local_key_id.data != NULL)
1118 {
1119
1120 /* Add a new Attribute
1121 */
1122 result = asn1_write_value (c2, where, "NEW", 1);
1123 if (result != ASN1_SUCCESS)
1124 {
1125 gnutls_assert ();
1126 return _gnutls_asn2err (result);
1127 }
1128
1129 _gnutls_str_cpy (root, sizeof (root), where);
1130 _gnutls_str_cat (root, sizeof (root), ".?LAST");
1131
1132 result =
1133 _gnutls_x509_encode_and_write_attribute (KEY_ID_OID, c2, root,
1134 bag->element[elem].
1135 local_key_id.data,
1136 bag->element[elem].
1137 local_key_id.size, 1);
1138 if (result < 0)
1139 {
1140 gnutls_assert ();
1141 return result;
1142 }
1143 }
1144
1145 if (bag->element[elem].friendly_name != NULL)
1146 {
1147 opaque *name;
1148 int size, i;
1149 const char *p;
1150
1151 /* Add a new Attribute
1152 */
1153 result = asn1_write_value (c2, where, "NEW", 1);
1154 if (result != ASN1_SUCCESS)
1155 {
1156 gnutls_assert ();
1157 return _gnutls_asn2err (result);
1158 }
1159
1160 /* convert name to BMPString
1161 */
1162 size = strlen (bag->element[elem].friendly_name) * 2;
1163 name = gnutls_malloc (size);
1164
1165 if (name == NULL)
1166 {
1167 gnutls_assert ();
1168 return GNUTLS_E_MEMORY_ERROR;
1169 }
1170
1171 p = bag->element[elem].friendly_name;
1172 for (i = 0; i < size; i += 2)
1173 {
1174 name[i] = 0;
1175 name[i + 1] = *p;
1176 p++;
1177 }
1178
1179 _gnutls_str_cpy (root, sizeof (root), where);
1180 _gnutls_str_cat (root, sizeof (root), ".?LAST");
1181
1182 result =
1183 _gnutls_x509_encode_and_write_attribute (FRIENDLY_NAME_OID, c2,
1184 root, name, size, 1);
1185
1186 gnutls_free (name);
1187
1188 if (result < 0)
1189 {
1190 gnutls_assert ();
1191 return result;
1192 }
1193 }
1194
1195 return 0;
1196}
1197
1198
1199/* Encodes the bag into a SafeContents structure, and puts the output in
1200 * the given datum. Enc is set to non zero if the data are encrypted;
1201 */
1202int
1203_pkcs12_encode_safe_contents (gnutls_pkcs12_bag_t bag, ASN1_TYPE * contents,
1204 int *enc)
1205{
1206 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1207 int result;
1208 int i;
1209 const char *oid;
1210
1211 if (bag->element[0].type == GNUTLS_BAG_ENCRYPTED && enc)
1212 {
1213 *enc = 1;
1214 return 0; /* ENCRYPTED BAG, do nothing. */
1215 }
1216 else if (enc)
1217 *enc = 0;
1218
1219 /* Step 1. Create the SEQUENCE.
1220 */
1221
1222 if ((result = asn1_create_element
1223 (_gnutls_get_pkix (), "PKIX1.pkcs-12-SafeContents",
1224 &c2)) != ASN1_SUCCESS)
1225 {
1226 gnutls_assert ();
1227 result = _gnutls_asn2err (result);
1228 goto cleanup;
1229 }
1230
1231 for (i = 0; i < bag->bag_elements; i++)
1232 {
1233
1234 oid = bag_to_oid (bag->element[i].type);
1235 if (oid == NULL)
1236 {
1237 gnutls_assert ();
1238 continue;
1239 }
1240
1241 result = asn1_write_value (c2, "", "NEW", 1);
1242 if (result != ASN1_SUCCESS)
1243 {
1244 gnutls_assert ();
1245 result = _gnutls_asn2err (result);
1246 goto cleanup;
1247 }
1248
1249 /* Copy the bag type.
1250 */
1251 result = asn1_write_value (c2, "?LAST.bagId", oid, 1);
1252 if (result != ASN1_SUCCESS)
1253 {
1254 gnutls_assert ();
1255 result = _gnutls_asn2err (result);
1256 goto cleanup;
1257 }
1258
1259 /* Set empty attributes
1260 */
1261 result = write_attributes (bag, i, c2, "?LAST.bagAttributes");
1262 if (result < 0)
1263 {
1264 gnutls_assert ();
1265 goto cleanup;
1266 }
1267
1268
1269 /* Copy the Bag Value
1270 */
1271
1272 if (bag->element[i].type == GNUTLS_BAG_CERTIFICATE ||
1273 bag->element[i].type == GNUTLS_BAG_CRL)
1274 {
1275 gnutls_datum_t tmp;
1276
1277 /* in that case encode it to a CertBag or
1278 * a CrlBag.
1279 */
1280
1281 result =
1282 _pkcs12_encode_crt_bag (bag->element[i].type,
1283 &bag->element[i].data, &tmp);
1284
1285 if (result < 0)
1286 {
1287 gnutls_assert ();
1288 goto cleanup;
1289 }
1290
1291 result = _gnutls_x509_write_value (c2, "?LAST.bagValue", &tmp, 0);
1292
1293 _gnutls_free_datum (&tmp);
1294
1295 }
1296 else
1297 {
1298
1299 result = _gnutls_x509_write_value (c2, "?LAST.bagValue",
1300 &bag->element[i].data, 0);
1301 }
1302
1303 if (result < 0)
1304 {
1305 gnutls_assert ();
1306 goto cleanup;
1307 }
1308
1309 }
1310
1311 /* Encode the data and copy them into the datum
1312 */
1313 *contents = c2;
1314
1315 return 0;
1316
1317cleanup:
1318 if (c2)
1319 asn1_delete_structure (&c2);
1320 return result;
1321
1322}
1323
1324
1325#endif /* ENABLE_PKI */
diff --git a/src/daemon/https/x509/pkcs12.h b/src/daemon/https/x509/pkcs12.h
new file mode 100644
index 00000000..566058fb
--- /dev/null
+++ b/src/daemon/https/x509/pkcs12.h
@@ -0,0 +1,208 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25// TODO clean
26
27#ifndef GNUTLS_PKCS12_H
28# define GNUTLS_PKCS12_H
29
30#ifdef __cplusplus
31extern "C"
32 {
33#endif
34
35#include <x509.h>
36
37#define MAX_BAG_ELEMENTS 32
38
39/* PKCS12 structures handling
40 */
41struct gnutls_pkcs12_int;
42
43struct gnutls_pkcs12_bag_int;
44typedef struct gnutls_pkcs12_int
45 {
46 ASN1_TYPE pkcs12;
47 } gnutls_pkcs12_int;
48
49typedef enum gnutls_pkcs12_bag_type_t
50 {
51 GNUTLS_BAG_EMPTY = 0,
52
53 GNUTLS_BAG_PKCS8_ENCRYPTED_KEY = 1,
54 GNUTLS_BAG_PKCS8_KEY,
55 GNUTLS_BAG_CERTIFICATE,
56 GNUTLS_BAG_CRL,
57 GNUTLS_BAG_ENCRYPTED = 10,
58 GNUTLS_BAG_UNKNOWN = 20
59 } gnutls_pkcs12_bag_type_t;
60
61struct bag_element
62 {
63 gnutls_datum_t data;
64 gnutls_pkcs12_bag_type_t type;
65 gnutls_datum_t local_key_id;
66 char *friendly_name;
67 };
68
69typedef struct gnutls_pkcs12_bag_int
70 {
71 struct bag_element element[MAX_BAG_ELEMENTS];
72 int bag_elements;
73 } gnutls_pkcs12_bag_int;
74
75/* Bag attributes */
76#define FRIENDLY_NAME_OID "1.2.840.113549.1.9.20"
77#define KEY_ID_OID "1.2.840.113549.1.9.21"
78
79typedef struct gnutls_pkcs12_int *gnutls_pkcs12_t;
80typedef struct gnutls_pkcs12_bag_int *gnutls_pkcs12_bag_t;
81
82int gnutls_pkcs12_init(gnutls_pkcs12_t * pkcs12);
83void gnutls_pkcs12_deinit(gnutls_pkcs12_t pkcs12);
84int gnutls_pkcs12_import(gnutls_pkcs12_t pkcs12,
85 const gnutls_datum_t * data,
86 gnutls_x509_crt_fmt_t format,
87 unsigned int flags);
88int gnutls_pkcs12_export(gnutls_pkcs12_t pkcs12,
89 gnutls_x509_crt_fmt_t format,
90 void *output_data,
91 size_t * output_data_size);
92
93int gnutls_pkcs12_get_bag(gnutls_pkcs12_t pkcs12,
94 int indx,
95 gnutls_pkcs12_bag_t bag);
96int gnutls_pkcs12_set_bag(gnutls_pkcs12_t pkcs12,
97 gnutls_pkcs12_bag_t bag);
98
99int gnutls_pkcs12_generate_mac(gnutls_pkcs12_t pkcs12,
100 const char *pass);
101int gnutls_pkcs12_verify_mac(gnutls_pkcs12_t pkcs12,
102 const char *pass);
103
104int gnutls_pkcs12_bag_decrypt(gnutls_pkcs12_bag_t bag,
105 const char *pass);
106int gnutls_pkcs12_bag_encrypt(gnutls_pkcs12_bag_t bag,
107 const char *pass,
108 unsigned int flags);
109
110gnutls_pkcs12_bag_type_t gnutls_pkcs12_bag_get_type(gnutls_pkcs12_bag_t
111 bag,
112 int indx);
113int gnutls_pkcs12_bag_get_data(gnutls_pkcs12_bag_t bag,
114 int indx,
115 gnutls_datum_t * data);
116int gnutls_pkcs12_bag_set_data(gnutls_pkcs12_bag_t bag,
117 gnutls_pkcs12_bag_type_t type,
118 const gnutls_datum_t * data);
119int gnutls_pkcs12_bag_set_crl(gnutls_pkcs12_bag_t bag,
120 gnutls_x509_crl_t crl);
121int gnutls_pkcs12_bag_set_crt(gnutls_pkcs12_bag_t bag,
122 gnutls_x509_crt_t crt);
123
124int gnutls_pkcs12_bag_init(gnutls_pkcs12_bag_t * bag);
125void gnutls_pkcs12_bag_deinit(gnutls_pkcs12_bag_t bag);
126int gnutls_pkcs12_bag_get_count(gnutls_pkcs12_bag_t bag);
127
128int gnutls_pkcs12_bag_get_key_id(gnutls_pkcs12_bag_t bag,
129 int indx,
130 gnutls_datum_t * id);
131int gnutls_pkcs12_bag_set_key_id(gnutls_pkcs12_bag_t bag,
132 int indx,
133 const gnutls_datum_t * id);
134
135int gnutls_pkcs12_bag_get_friendly_name(gnutls_pkcs12_bag_t bag,
136 int indx,
137 char **name);
138int gnutls_pkcs12_bag_set_friendly_name(gnutls_pkcs12_bag_t bag,
139 int indx,
140 const char *name);
141
142#ifdef __cplusplus
143}
144#endif
145
146#define BAG_PKCS8_KEY "1.2.840.113549.1.12.10.1.1"
147#define BAG_PKCS8_ENCRYPTED_KEY "1.2.840.113549.1.12.10.1.2"
148#define BAG_CERTIFICATE "1.2.840.113549.1.12.10.1.3"
149#define BAG_CRL "1.2.840.113549.1.12.10.1.4"
150
151/* PKCS #7
152 */
153#define DATA_OID "1.2.840.113549.1.7.1"
154#define ENC_DATA_OID "1.2.840.113549.1.7.6"
155
156int gnutls_pkcs12_init(gnutls_pkcs12_t * pkcs12);
157void gnutls_pkcs12_deinit(gnutls_pkcs12_t pkcs12);
158int gnutls_pkcs12_import(gnutls_pkcs12_t pkcs12,
159 const gnutls_datum_t * data,
160 gnutls_x509_crt_fmt_t format,
161 unsigned int flags);
162
163int gnutls_pkcs12_get_bag(gnutls_pkcs12_t pkcs12,
164 int indx,
165 gnutls_pkcs12_bag_t bag);
166
167int gnutls_pkcs12_bag_init(gnutls_pkcs12_bag_t * bag);
168void gnutls_pkcs12_bag_deinit(gnutls_pkcs12_bag_t bag);
169
170int _pkcs12_string_to_key(unsigned int id,
171 const opaque * salt,
172 unsigned int salt_size,
173 unsigned int iter,
174 const char *pw,
175 unsigned int req_keylen,
176 opaque * keybuf);
177
178int _gnutls_pkcs7_decrypt_data(const gnutls_datum_t * data,
179 const char *password,
180 gnutls_datum_t * dec);
181
182typedef enum schema_id
183 {
184 PBES2, /* the stuff in PKCS #5 */
185 PKCS12_3DES_SHA1, /* the fucking stuff in PKCS #12 */
186 PKCS12_ARCFOUR_SHA1,
187 PKCS12_RC2_40_SHA1
188 } schema_id;
189
190int _gnutls_pkcs7_encrypt_data(schema_id schema,
191 const gnutls_datum_t * data,
192 const char *password,
193 gnutls_datum_t * enc);
194int _pkcs12_decode_safe_contents(const gnutls_datum_t * content,
195 gnutls_pkcs12_bag_t bag);
196
197int _pkcs12_encode_safe_contents(gnutls_pkcs12_bag_t bag,
198 ASN1_TYPE * content,
199 int *enc);
200
201int _pkcs12_decode_crt_bag(gnutls_pkcs12_bag_type_t type,
202 const gnutls_datum_t * in,
203 gnutls_datum_t * out);
204int _pkcs12_encode_crt_bag(gnutls_pkcs12_bag_type_t type,
205 const gnutls_datum_t * raw,
206 gnutls_datum_t * out);
207
208#endif /* GNUTLS_PKCS12_H */
diff --git a/src/daemon/https/x509/pkcs12_bag.c b/src/daemon/https/x509/pkcs12_bag.c
new file mode 100644
index 00000000..c34ec757
--- /dev/null
+++ b/src/daemon/https/x509/pkcs12_bag.c
@@ -0,0 +1,770 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* Functions that relate on PKCS12 Bag packet parsing.
26 */
27
28#include <gnutls_int.h>
29
30#ifdef ENABLE_PKI
31
32#include <gnutls_datum.h>
33#include <gnutls_global.h>
34#include <gnutls_errors.h>
35#include <common.h>
36#include <pkcs12.h>
37#include <privkey.h>
38
39/**
40 * gnutls_pkcs12_bag_init - This function initializes a gnutls_pkcs12_bag_t structure
41 * @bag: The structure to be initialized
42 *
43 * This function will initialize a PKCS12 bag structure. PKCS12 Bags
44 * usually contain private keys, lists of X.509 Certificates and X.509 Certificate
45 * revocation lists.
46 *
47 * Returns 0 on success.
48 *
49 **/
50int
51gnutls_pkcs12_bag_init (gnutls_pkcs12_bag_t * bag)
52{
53 *bag = gnutls_calloc (1, sizeof (gnutls_pkcs12_bag_int));
54
55 if (*bag)
56 {
57 return 0; /* success */
58 }
59 return GNUTLS_E_MEMORY_ERROR;
60}
61
62static inline void
63_pkcs12_bag_free_data (gnutls_pkcs12_bag_t bag)
64{
65 int i;
66
67 for (i = 0; i < bag->bag_elements; i++)
68 {
69 _gnutls_free_datum (&bag->element[i].data);
70 _gnutls_free_datum (&bag->element[i].local_key_id);
71 gnutls_free (bag->element[i].friendly_name);
72 bag->element[i].friendly_name = NULL;
73 bag->element[i].type = 0;
74 }
75
76}
77
78
79/**
80 * gnutls_pkcs12_bag_deinit - This function deinitializes memory used by a gnutls_pkcs12_t structure
81 * @bag: The structure to be initialized
82 *
83 * This function will deinitialize a PKCS12 Bag structure.
84 *
85 **/
86void
87gnutls_pkcs12_bag_deinit (gnutls_pkcs12_bag_t bag)
88{
89 if (!bag)
90 return;
91
92 _pkcs12_bag_free_data (bag);
93
94 gnutls_free (bag);
95}
96
97/**
98 * gnutls_pkcs12_bag_get_type - This function returns the bag's type
99 * @bag: The bag
100 * @indx: The element of the bag to get the type
101 *
102 * This function will return the bag's type. One of the gnutls_pkcs12_bag_type_t
103 * enumerations.
104 *
105 **/
106gnutls_pkcs12_bag_type_t
107gnutls_pkcs12_bag_get_type (gnutls_pkcs12_bag_t bag, int indx)
108{
109 if (bag == NULL)
110 {
111 gnutls_assert ();
112 return GNUTLS_E_INVALID_REQUEST;
113 }
114
115 if (indx >= bag->bag_elements)
116 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
117 return bag->element[indx].type;
118}
119
120/**
121 * gnutls_pkcs12_bag_get_count - This function returns the bag's elements count
122 * @bag: The bag
123 *
124 * This function will return the number of the elements withing the bag.
125 *
126 **/
127int
128gnutls_pkcs12_bag_get_count (gnutls_pkcs12_bag_t bag)
129{
130 if (bag == NULL)
131 {
132 gnutls_assert ();
133 return GNUTLS_E_INVALID_REQUEST;
134 }
135
136 return bag->bag_elements;
137}
138
139/**
140 * gnutls_pkcs12_bag_get_data - This function returns the bag's data
141 * @bag: The bag
142 * @indx: The element of the bag to get the data from
143 * @data: where the bag's data will be. Should be treated as constant.
144 *
145 * This function will return the bag's data. The data is a constant
146 * that is stored into the bag. Should not be accessed after the bag
147 * is deleted.
148 *
149 * Returns 0 on success and a negative error code on error.
150 *
151 **/
152int
153gnutls_pkcs12_bag_get_data (gnutls_pkcs12_bag_t bag, int indx,
154 gnutls_datum_t * data)
155{
156 if (bag == NULL)
157 {
158 gnutls_assert ();
159 return GNUTLS_E_INVALID_REQUEST;
160 }
161
162 if (indx >= bag->bag_elements)
163 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
164
165 data->data = bag->element[indx].data.data;
166 data->size = bag->element[indx].data.size;
167
168 return 0;
169}
170
171#define X509_CERT_OID "1.2.840.113549.1.9.22.1"
172#define X509_CRL_OID "1.2.840.113549.1.9.23.1"
173
174int
175_pkcs12_decode_crt_bag (gnutls_pkcs12_bag_type_t type,
176 const gnutls_datum_t * in, gnutls_datum_t * out)
177{
178 int ret;
179 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
180
181 if (type == GNUTLS_BAG_CERTIFICATE)
182 {
183 if ((ret = asn1_create_element (_gnutls_get_pkix (),
184 "PKIX1.pkcs-12-CertBag",
185 &c2)) != ASN1_SUCCESS)
186 {
187 gnutls_assert ();
188 ret = _gnutls_asn2err (ret);
189 goto cleanup;
190 }
191
192 ret = asn1_der_decoding (&c2, in->data, in->size, NULL);
193 if (ret != ASN1_SUCCESS)
194 {
195 gnutls_assert ();
196 ret = _gnutls_asn2err (ret);
197 goto cleanup;
198 }
199
200 ret = _gnutls_x509_read_value (c2, "certValue", out, 1);
201 if (ret < 0)
202 {
203 gnutls_assert ();
204 goto cleanup;
205 }
206
207 }
208 else
209 { /* CRL */
210 if ((ret = asn1_create_element (_gnutls_get_pkix (),
211 "PKIX1.pkcs-12-CRLBag",
212 &c2)) != ASN1_SUCCESS)
213 {
214 gnutls_assert ();
215 ret = _gnutls_asn2err (ret);
216 goto cleanup;
217 }
218
219 ret = asn1_der_decoding (&c2, in->data, in->size, NULL);
220 if (ret != ASN1_SUCCESS)
221 {
222 gnutls_assert ();
223 ret = _gnutls_asn2err (ret);
224 goto cleanup;
225 }
226
227 ret = _gnutls_x509_read_value (c2, "crlValue", out, 1);
228 if (ret < 0)
229 {
230 gnutls_assert ();
231 goto cleanup;
232 }
233 }
234
235 asn1_delete_structure (&c2);
236
237 return 0;
238
239
240cleanup:
241
242 asn1_delete_structure (&c2);
243 return ret;
244}
245
246
247int
248_pkcs12_encode_crt_bag (gnutls_pkcs12_bag_type_t type,
249 const gnutls_datum_t * raw, gnutls_datum_t * out)
250{
251 int ret;
252 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
253
254 if (type == GNUTLS_BAG_CERTIFICATE)
255 {
256 if ((ret = asn1_create_element (_gnutls_get_pkix (),
257 "PKIX1.pkcs-12-CertBag",
258 &c2)) != ASN1_SUCCESS)
259 {
260 gnutls_assert ();
261 ret = _gnutls_asn2err (ret);
262 goto cleanup;
263 }
264
265 ret = asn1_write_value (c2, "certId", X509_CERT_OID, 1);
266 if (ret != ASN1_SUCCESS)
267 {
268 gnutls_assert ();
269 ret = _gnutls_asn2err (ret);
270 goto cleanup;
271 }
272
273 ret = _gnutls_x509_write_value (c2, "certValue", raw, 1);
274 if (ret < 0)
275 {
276 gnutls_assert ();
277 goto cleanup;
278 }
279
280 }
281 else
282 { /* CRL */
283 if ((ret = asn1_create_element (_gnutls_get_pkix (),
284 "PKIX1.pkcs-12-CRLBag",
285 &c2)) != ASN1_SUCCESS)
286 {
287 gnutls_assert ();
288 ret = _gnutls_asn2err (ret);
289 goto cleanup;
290 }
291
292 ret = asn1_write_value (c2, "crlId", X509_CRL_OID, 1);
293 if (ret != ASN1_SUCCESS)
294 {
295 gnutls_assert ();
296 ret = _gnutls_asn2err (ret);
297 goto cleanup;
298 }
299
300 ret = _gnutls_x509_write_value (c2, "crlValue", raw, 1);
301 if (ret < 0)
302 {
303 gnutls_assert ();
304 goto cleanup;
305 }
306 }
307
308 ret = _gnutls_x509_der_encode (c2, "", out, 0);
309
310 if (ret < 0)
311 {
312 gnutls_assert ();
313 goto cleanup;
314 }
315
316 asn1_delete_structure (&c2);
317
318 return 0;
319
320
321cleanup:
322
323 asn1_delete_structure (&c2);
324 return ret;
325}
326
327
328/**
329 * gnutls_pkcs12_bag_set_data - This function inserts data into the bag
330 * @bag: The bag
331 * @type: The data's type
332 * @data: the data to be copied.
333 *
334 * This function will insert the given data of the given type into the
335 * bag.
336 *
337 * Returns the index of the added bag on success, or a negative
338 * value on error.
339 *
340 **/
341int
342gnutls_pkcs12_bag_set_data (gnutls_pkcs12_bag_t bag,
343 gnutls_pkcs12_bag_type_t type,
344 const gnutls_datum_t * data)
345{
346 int ret;
347 if (bag == NULL)
348 {
349 gnutls_assert ();
350 return GNUTLS_E_INVALID_REQUEST;
351 }
352
353 if (bag->bag_elements == MAX_BAG_ELEMENTS - 1)
354 {
355 gnutls_assert ();
356 /* bag is full */
357 return GNUTLS_E_MEMORY_ERROR;
358 }
359
360 if (bag->bag_elements == 1)
361 {
362 /* A bag with a key or an encrypted bag, must have
363 * only one element.
364 */
365
366 if (bag->element[0].type == GNUTLS_BAG_PKCS8_KEY ||
367 bag->element[0].type == GNUTLS_BAG_PKCS8_ENCRYPTED_KEY ||
368 bag->element[0].type == GNUTLS_BAG_ENCRYPTED)
369 {
370 gnutls_assert ();
371 return GNUTLS_E_INVALID_REQUEST;
372 }
373 }
374
375 ret =
376 _gnutls_set_datum (&bag->element[bag->bag_elements].data,
377 data->data, data->size);
378
379 if (ret < 0)
380 {
381 gnutls_assert ();
382 return ret;
383 }
384
385 bag->element[bag->bag_elements].type = type;
386
387 bag->bag_elements++;
388
389 return bag->bag_elements - 1;
390}
391
392/**
393 * gnutls_pkcs12_bag_set_crt - This function inserts a certificate into the bag
394 * @bag: The bag
395 * @crt: the certificate to be copied.
396 *
397 * This function will insert the given certificate into the
398 * bag. This is just a wrapper over gnutls_pkcs12_bag_set_data().
399 *
400 * Returns the index of the added bag on success, or a negative
401 * value on failure.
402 *
403 **/
404int
405gnutls_pkcs12_bag_set_crt (gnutls_pkcs12_bag_t bag, gnutls_x509_crt_t crt)
406{
407 int ret;
408 gnutls_datum_t data;
409
410 if (bag == NULL)
411 {
412 gnutls_assert ();
413 return GNUTLS_E_INVALID_REQUEST;
414 }
415
416 ret = _gnutls_x509_der_encode (crt->cert, "", &data, 0);
417 if (ret < 0)
418 {
419 gnutls_assert ();
420 return ret;
421 }
422
423 ret = gnutls_pkcs12_bag_set_data (bag, GNUTLS_BAG_CERTIFICATE, &data);
424
425 _gnutls_free_datum (&data);
426
427 return ret;
428}
429
430/**
431 * gnutls_pkcs12_bag_set_crl - This function inserts the CRL into the bag
432 * @bag: The bag
433 * @crl: the CRL to be copied.
434 *
435 * This function will insert the given CRL into the
436 * bag. This is just a wrapper over gnutls_pkcs12_bag_set_data().
437 *
438 * Returns the index of the added bag on success, or a negative
439 * value on failure.
440 *
441 **/
442int
443gnutls_pkcs12_bag_set_crl (gnutls_pkcs12_bag_t bag, gnutls_x509_crl_t crl)
444{
445 int ret;
446 gnutls_datum_t data;
447
448
449 if (bag == NULL)
450 {
451 gnutls_assert ();
452 return GNUTLS_E_INVALID_REQUEST;
453 }
454
455 ret = _gnutls_x509_der_encode (crl->crl, "", &data, 0);
456 if (ret < 0)
457 {
458 gnutls_assert ();
459 return ret;
460 }
461
462 ret = gnutls_pkcs12_bag_set_data (bag, GNUTLS_BAG_CRL, &data);
463
464 _gnutls_free_datum (&data);
465
466 return ret;
467}
468
469/**
470 * gnutls_pkcs12_bag_set_key_id - This function sets a key ID into the bag element
471 * @bag: The bag
472 * @indx: The bag's element to add the id
473 * @id: the ID
474 *
475 * This function will add the given key ID, to the specified, by the index, bag
476 * element. The key ID will be encoded as a 'Local key identifier' bag attribute,
477 * which is usually used to distinguish the local private key and the certificate pair.
478 *
479 * Returns 0 on success, or a negative value on error.
480 *
481 **/
482int
483gnutls_pkcs12_bag_set_key_id (gnutls_pkcs12_bag_t bag, int indx,
484 const gnutls_datum_t * id)
485{
486 int ret;
487
488
489 if (bag == NULL)
490 {
491 gnutls_assert ();
492 return GNUTLS_E_INVALID_REQUEST;
493 }
494
495 if (indx > bag->bag_elements - 1)
496 {
497 gnutls_assert ();
498 return GNUTLS_E_INVALID_REQUEST;
499 }
500
501 ret = _gnutls_set_datum (&bag->element[indx].local_key_id,
502 id->data, id->size);
503
504 if (ret < 0)
505 {
506 gnutls_assert ();
507 return ret;
508 }
509
510 return 0;
511}
512
513/**
514 * gnutls_pkcs12_bag_get_key_id - This function gets the key ID from the bag element
515 * @bag: The bag
516 * @indx: The bag's element to add the id
517 * @id: where the ID will be copied (to be treated as const)
518 *
519 * This function will return the key ID, of the specified bag element.
520 * The key ID is usually used to distinguish the local private key and the certificate pair.
521 *
522 * Returns 0 on success, or a negative value on error.
523 *
524 **/
525int
526gnutls_pkcs12_bag_get_key_id (gnutls_pkcs12_bag_t bag, int indx,
527 gnutls_datum_t * id)
528{
529 if (bag == NULL)
530 {
531 gnutls_assert ();
532 return GNUTLS_E_INVALID_REQUEST;
533 }
534
535 if (indx > bag->bag_elements - 1)
536 {
537 gnutls_assert ();
538 return GNUTLS_E_INVALID_REQUEST;
539 }
540
541 id->data = bag->element[indx].local_key_id.data;
542 id->size = bag->element[indx].local_key_id.size;
543
544 return 0;
545}
546
547/**
548 * gnutls_pkcs12_bag_get_friendly_name - This function returns the friendly name of the bag element
549 * @bag: The bag
550 * @indx: The bag's element to add the id
551 * @name: will hold a pointer to the name (to be treated as const)
552 *
553 * This function will return the friendly name, of the specified bag element.
554 * The key ID is usually used to distinguish the local private key and the certificate pair.
555 *
556 * Returns 0 on success, or a negative value on error.
557 *
558 **/
559int
560gnutls_pkcs12_bag_get_friendly_name (gnutls_pkcs12_bag_t bag, int indx,
561 char **name)
562{
563 if (bag == NULL)
564 {
565 gnutls_assert ();
566 return GNUTLS_E_INVALID_REQUEST;
567 }
568
569 if (indx > bag->bag_elements - 1)
570 {
571 gnutls_assert ();
572 return GNUTLS_E_INVALID_REQUEST;
573 }
574
575 *name = bag->element[indx].friendly_name;
576
577 return 0;
578}
579
580
581/**
582 * gnutls_pkcs12_bag_set_friendly_name - This function sets a friendly name into the bag element
583 * @bag: The bag
584 * @indx: The bag's element to add the id
585 * @name: the name
586 *
587 * This function will add the given key friendly name, to the specified, by the index, bag
588 * element. The name will be encoded as a 'Friendly name' bag attribute,
589 * which is usually used to set a user name to the local private key and the certificate pair.
590 *
591 * Returns 0 on success, or a negative value on error.
592 *
593 **/
594int
595gnutls_pkcs12_bag_set_friendly_name (gnutls_pkcs12_bag_t bag, int indx,
596 const char *name)
597{
598 if (bag == NULL)
599 {
600 gnutls_assert ();
601 return GNUTLS_E_INVALID_REQUEST;
602 }
603
604 if (indx > bag->bag_elements - 1)
605 {
606 gnutls_assert ();
607 return GNUTLS_E_INVALID_REQUEST;
608 }
609
610 bag->element[indx].friendly_name = gnutls_strdup (name);
611
612 if (name == NULL)
613 {
614 gnutls_assert ();
615 return GNUTLS_E_MEMORY_ERROR;
616 }
617
618 return 0;
619}
620
621
622/**
623 * gnutls_pkcs12_bag_decrypt - This function will decrypt an encrypted bag
624 * @bag: The bag
625 * @pass: The password used for encryption. This can only be ASCII.
626 *
627 * This function will decrypt the given encrypted bag and return 0 on success.
628 *
629 **/
630int
631gnutls_pkcs12_bag_decrypt (gnutls_pkcs12_bag_t bag, const char *pass)
632{
633 int ret;
634 gnutls_datum_t dec;
635
636 if (bag == NULL)
637 {
638 gnutls_assert ();
639 return GNUTLS_E_INVALID_REQUEST;
640 }
641
642 if (bag->element[0].type != GNUTLS_BAG_ENCRYPTED)
643 {
644 gnutls_assert ();
645 return GNUTLS_E_INVALID_REQUEST;
646 }
647
648 ret = _gnutls_pkcs7_decrypt_data (&bag->element[0].data, pass, &dec);
649
650 if (ret < 0)
651 {
652 gnutls_assert ();
653 return ret;
654 }
655
656 /* decryption succeeded. Now decode the SafeContents
657 * stuff, and parse it.
658 */
659
660 _gnutls_free_datum (&bag->element[0].data);
661
662 ret = _pkcs12_decode_safe_contents (&dec, bag);
663
664 _gnutls_free_datum (&dec);
665
666 if (ret < 0)
667 {
668 gnutls_assert ();
669 return ret;
670 }
671
672 return 0;
673}
674
675/**
676 * gnutls_pkcs12_bag_encrypt - This function will encrypt a bag
677 * @bag: The bag
678 * @pass: The password used for encryption. This can only be ASCII.
679 * @flags: should be one of gnutls_pkcs_encrypt_flags_t elements bitwise or'd
680 *
681 * This function will encrypt the given bag and return 0 on success.
682 *
683 **/
684int
685gnutls_pkcs12_bag_encrypt (gnutls_pkcs12_bag_t bag, const char *pass,
686 unsigned int flags)
687{
688 int ret;
689 ASN1_TYPE safe_cont = ASN1_TYPE_EMPTY;
690 gnutls_datum_t der = { NULL, 0 };
691 gnutls_datum_t enc = { NULL, 0 };
692 schema_id id;
693
694 if (bag == NULL)
695 {
696 gnutls_assert ();
697 return GNUTLS_E_INVALID_REQUEST;
698 }
699
700 if (bag->element[0].type == GNUTLS_BAG_ENCRYPTED)
701 {
702 gnutls_assert ();
703 return GNUTLS_E_INVALID_REQUEST;
704 }
705
706 /* Encode the whole bag to a safe contents
707 * structure.
708 */
709 ret = _pkcs12_encode_safe_contents (bag, &safe_cont, NULL);
710 if (ret < 0)
711 {
712 gnutls_assert ();
713 return ret;
714 }
715
716 /* DER encode the SafeContents.
717 */
718 ret = _gnutls_x509_der_encode (safe_cont, "", &der, 0);
719
720 asn1_delete_structure (&safe_cont);
721
722 if (ret < 0)
723 {
724 gnutls_assert ();
725 return ret;
726 }
727
728 if (flags & GNUTLS_PKCS_PLAIN)
729 {
730 gnutls_assert ();
731 return GNUTLS_E_INVALID_REQUEST;
732 }
733
734 if (flags & GNUTLS_PKCS_USE_PKCS12_ARCFOUR)
735 id = PKCS12_ARCFOUR_SHA1;
736 else if (flags & GNUTLS_PKCS_USE_PKCS12_RC2_40)
737 id = PKCS12_RC2_40_SHA1;
738 else if (flags & GNUTLS_PKCS_USE_PBES2_3DES)
739 id = PBES2;
740 else
741 id = PKCS12_3DES_SHA1;
742
743 /* Now encrypt them.
744 */
745 ret = _gnutls_pkcs7_encrypt_data (id, &der, pass, &enc);
746
747 _gnutls_free_datum (&der);
748
749 if (ret < 0)
750 {
751 gnutls_assert ();
752 return ret;
753 }
754
755 /* encryption succeeded.
756 */
757
758 _pkcs12_bag_free_data (bag);
759
760 bag->element[0].type = GNUTLS_BAG_ENCRYPTED;
761 bag->element[0].data = enc;
762
763 bag->bag_elements = 1;
764
765
766 return 0;
767}
768
769
770#endif /* ENABLE_PKI */
diff --git a/src/daemon/https/x509/pkcs12_encr.c b/src/daemon/https/x509/pkcs12_encr.c
new file mode 100644
index 00000000..c80d23a3
--- /dev/null
+++ b/src/daemon/https/x509/pkcs12_encr.c
@@ -0,0 +1,169 @@
1/* minip12.c - A mini pkcs-12 implementation (modified for gnutls)
2 *
3 * Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
4 *
5 * This file is part of GNUTLS.
6 *
7 * The GNUTLS library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 * USA
21 *
22 */
23
24#include <gnutls_int.h>
25
26#ifdef ENABLE_PKI
27
28#include <gcrypt.h>
29#include <gc.h>
30#include <gnutls_errors.h>
31
32/* Returns 0 if the password is ok, or a negative error
33 * code instead.
34 */
35static int
36_pkcs12_check_pass (const char *pass, size_t plen)
37{
38 const unsigned char *p = pass;
39 unsigned int i;
40
41 for (i = 0; i < plen; i++)
42 {
43 if (isascii (p[i]))
44 continue;
45 return GNUTLS_E_INVALID_PASSWORD;
46 }
47
48 return 0;
49}
50
51/* ID should be:
52 * 3 for MAC
53 * 2 for IV
54 * 1 for encryption key
55 */
56int
57_pkcs12_string_to_key (unsigned int id, const opaque * salt,
58 unsigned int salt_size, unsigned int iter,
59 const char *pw, unsigned int req_keylen,
60 opaque * keybuf)
61{
62 int rc;
63 unsigned int i, j;
64 gc_hash_handle md;
65 mpi_t num_b1 = NULL;
66 unsigned int pwlen;
67 opaque hash[20], buf_b[64], buf_i[128], *p;
68 size_t cur_keylen;
69 size_t n;
70
71 cur_keylen = 0;
72
73 if (pw == NULL)
74 pwlen = 0;
75 else
76 pwlen = strlen (pw);
77
78 if (pwlen > 63 / 2)
79 {
80 gnutls_assert ();
81 return GNUTLS_E_INVALID_REQUEST;
82 }
83
84 if ((rc = _pkcs12_check_pass (pw, pwlen)) < 0)
85 {
86 gnutls_assert ();
87 return rc;
88 }
89
90 /* Store salt and password in BUF_I */
91 p = buf_i;
92 for (i = 0; i < 64; i++)
93 *p++ = salt[i % salt_size];
94 if (pw)
95 {
96 for (i = j = 0; i < 64; i += 2)
97 {
98 *p++ = 0;
99 *p++ = pw[j];
100 if (++j > pwlen) /* Note, that we include the trailing zero */
101 j = 0;
102 }
103 }
104 else
105 memset (p, 0, 64);
106
107 for (;;)
108 {
109 rc = gc_hash_open (GC_SHA1, 0, &md);
110 if (rc)
111 {
112 gnutls_assert ();
113 return GNUTLS_E_DECRYPTION_FAILED;
114 }
115 for (i = 0; i < 64; i++)
116 {
117 unsigned char lid = id & 0xFF;
118 gc_hash_write (md, 1, &lid);
119 }
120 gc_hash_write (md, pw ? 128 : 64, buf_i);
121 memcpy (hash, gc_hash_read (md), 20);
122 gc_hash_close (md);
123 for (i = 1; i < iter; i++)
124 gc_hash_buffer (GC_SHA1, hash, 20, hash);
125 for (i = 0; i < 20 && cur_keylen < req_keylen; i++)
126 keybuf[cur_keylen++] = hash[i];
127 if (cur_keylen == req_keylen)
128 {
129 gcry_mpi_release (num_b1);
130 return 0; /* ready */
131 }
132
133 /* need more bytes. */
134 for (i = 0; i < 64; i++)
135 buf_b[i] = hash[i % 20];
136 n = 64;
137 rc = _gnutls_mpi_scan (&num_b1, buf_b, &n);
138 if (rc < 0)
139 {
140 gnutls_assert ();
141 return rc;
142 }
143 gcry_mpi_add_ui (num_b1, num_b1, 1);
144 for (i = 0; i < 128; i += 64)
145 {
146 mpi_t num_ij;
147
148 n = 64;
149 rc = _gnutls_mpi_scan (&num_ij, buf_i + i, &n);
150 if (rc < 0)
151 {
152 gnutls_assert ();
153 return rc;
154 }
155 gcry_mpi_add (num_ij, num_ij, num_b1);
156 gcry_mpi_clear_highbit (num_ij, 64 * 8);
157 n = 64;
158 rc = _gnutls_mpi_print (buf_i + i, &n, num_ij);
159 if (rc < 0)
160 {
161 gnutls_assert ();
162 return rc;
163 }
164 gcry_mpi_release (num_ij);
165 }
166 }
167}
168
169#endif /* ENABLE_PKI */
diff --git a/src/daemon/https/x509/pkcs7.c b/src/daemon/https/x509/pkcs7.c
new file mode 100644
index 00000000..35f21b12
--- /dev/null
+++ b/src/daemon/https/x509/pkcs7.c
@@ -0,0 +1,1023 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* Functions that relate on PKCS7 certificate lists parsing.
26 */
27
28#include <gnutls_int.h>
29#include <libtasn1.h>
30
31#ifdef ENABLE_PKI
32
33#include <gnutls_datum.h>
34#include <gnutls_global.h>
35#include <gnutls_errors.h>
36#include <common.h>
37#include <x509_b64.h>
38#include <pkcs7.h>
39#include <dn.h>
40
41#define SIGNED_DATA_OID "1.2.840.113549.1.7.2"
42
43/* Decodes the PKCS #7 signed data, and returns an ASN1_TYPE,
44 * which holds them. If raw is non null then the raw decoded
45 * data are copied (they are locally allocated) there.
46 */
47static int
48_decode_pkcs7_signed_data (ASN1_TYPE pkcs7, ASN1_TYPE * sdata,
49 gnutls_datum_t * raw)
50{
51 char oid[128];
52 ASN1_TYPE c2;
53 opaque *tmp = NULL;
54 int tmp_size, len, result;
55
56 len = sizeof (oid) - 1;
57 result = asn1_read_value (pkcs7, "contentType", oid, &len);
58 if (result != ASN1_SUCCESS)
59 {
60 gnutls_assert ();
61 return _gnutls_asn2err (result);
62 }
63
64 if (strcmp (oid, SIGNED_DATA_OID) != 0)
65 {
66 gnutls_assert ();
67 _gnutls_x509_log ("Unknown PKCS7 Content OID '%s'\n", oid);
68 return GNUTLS_E_UNKNOWN_PKCS_CONTENT_TYPE;
69 }
70
71 if ((result = asn1_create_element
72 (_gnutls_get_pkix (), "PKIX1.pkcs-7-SignedData", &c2)) != ASN1_SUCCESS)
73 {
74 gnutls_assert ();
75 return _gnutls_asn2err (result);
76 }
77
78 /* the Signed-data has been created, so
79 * decode them.
80 */
81 tmp_size = 0;
82 result = asn1_read_value (pkcs7, "content", NULL, &tmp_size);
83 if (result != ASN1_MEM_ERROR)
84 {
85 gnutls_assert ();
86 result = _gnutls_asn2err (result);
87 goto cleanup;
88 }
89
90 tmp = gnutls_malloc (tmp_size);
91 if (tmp == NULL)
92 {
93 gnutls_assert ();
94 result = GNUTLS_E_MEMORY_ERROR;
95 goto cleanup;
96 }
97
98 result = asn1_read_value (pkcs7, "content", tmp, &tmp_size);
99 if (result != ASN1_SUCCESS)
100 {
101 gnutls_assert ();
102 result = _gnutls_asn2err (result);
103 goto cleanup;
104 }
105
106 /* tmp, tmp_size hold the data and the size of the CertificateSet structure
107 * actually the ANY stuff.
108 */
109
110 /* Step 1. In case of a signed structure extract certificate set.
111 */
112
113 result = asn1_der_decoding (&c2, tmp, tmp_size, NULL);
114 if (result != ASN1_SUCCESS)
115 {
116 gnutls_assert ();
117 result = _gnutls_asn2err (result);
118 goto cleanup;
119 }
120
121 if (raw == NULL)
122 {
123 gnutls_free (tmp);
124 }
125 else
126 {
127 raw->data = tmp;
128 raw->size = tmp_size;
129 }
130
131 *sdata = c2;
132
133 return 0;
134
135cleanup:
136 if (c2)
137 asn1_delete_structure (&c2);
138 gnutls_free (tmp);
139 return result;
140}
141
142/**
143 * gnutls_pkcs7_init - This function initializes a gnutls_pkcs7_t structure
144 * @pkcs7: The structure to be initialized
145 *
146 * This function will initialize a PKCS7 structure. PKCS7 structures
147 * usually contain lists of X.509 Certificates and X.509 Certificate
148 * revocation lists.
149 *
150 * Returns 0 on success.
151 *
152 **/
153int
154gnutls_pkcs7_init (gnutls_pkcs7_t * pkcs7)
155{
156 *pkcs7 = gnutls_calloc (1, sizeof (gnutls_pkcs7_int));
157
158 if (*pkcs7)
159 {
160 int result = asn1_create_element (_gnutls_get_pkix (),
161 "PKIX1.pkcs-7-ContentInfo",
162 &(*pkcs7)->pkcs7);
163 if (result != ASN1_SUCCESS)
164 {
165 gnutls_assert ();
166 gnutls_free (*pkcs7);
167 return _gnutls_asn2err (result);
168 }
169 return 0; /* success */
170 }
171 return GNUTLS_E_MEMORY_ERROR;
172}
173
174/**
175 * gnutls_pkcs7_deinit - This function deinitializes memory used by a gnutls_pkcs7_t structure
176 * @pkcs7: The structure to be initialized
177 *
178 * This function will deinitialize a PKCS7 structure.
179 *
180 **/
181void
182gnutls_pkcs7_deinit (gnutls_pkcs7_t pkcs7)
183{
184 if (!pkcs7)
185 return;
186
187 if (pkcs7->pkcs7)
188 asn1_delete_structure (&pkcs7->pkcs7);
189
190 gnutls_free (pkcs7);
191}
192
193/**
194 * gnutls_pkcs7_import - This function will import a DER or PEM encoded PKCS7
195 * @pkcs7: The structure to store the parsed PKCS7.
196 * @data: The DER or PEM encoded PKCS7.
197 * @format: One of DER or PEM
198 *
199 * This function will convert the given DER or PEM encoded PKCS7
200 * to the native gnutls_pkcs7_t format. The output will be stored in 'pkcs7'.
201 *
202 * If the PKCS7 is PEM encoded it should have a header of "PKCS7".
203 *
204 * Returns 0 on success.
205 *
206 **/
207int
208gnutls_pkcs7_import (gnutls_pkcs7_t pkcs7, const gnutls_datum_t * data,
209 gnutls_x509_crt_fmt_t format)
210{
211 int result = 0, need_free = 0;
212 gnutls_datum_t _data;
213
214 if (pkcs7 == NULL)
215 return GNUTLS_E_INVALID_REQUEST;
216
217 _data.data = data->data;
218 _data.size = data->size;
219
220 /* If the PKCS7 is in PEM format then decode it
221 */
222 if (format == GNUTLS_X509_FMT_PEM)
223 {
224 opaque *out;
225
226 result = _gnutls_fbase64_decode (PEM_PKCS7, data->data, data->size,
227 &out);
228
229 if (result <= 0)
230 {
231 if (result == 0)
232 result = GNUTLS_E_INTERNAL_ERROR;
233 gnutls_assert ();
234 return result;
235 }
236
237 _data.data = out;
238 _data.size = result;
239
240 need_free = 1;
241 }
242
243
244 result = asn1_der_decoding (&pkcs7->pkcs7, _data.data, _data.size, NULL);
245 if (result != ASN1_SUCCESS)
246 {
247 result = _gnutls_asn2err (result);
248 gnutls_assert ();
249 goto cleanup;
250 }
251
252 if (need_free)
253 _gnutls_free_datum (&_data);
254
255 return 0;
256
257cleanup:
258 if (need_free)
259 _gnutls_free_datum (&_data);
260 return result;
261}
262
263/**
264 * gnutls_pkcs7_get_crt_raw - This function returns a certificate in a PKCS7 certificate set
265 * @pkcs7_struct: should contain a gnutls_pkcs7_t structure
266 * @indx: contains the index of the certificate to extract
267 * @certificate: the contents of the certificate will be copied there (may be null)
268 * @certificate_size: should hold the size of the certificate
269 *
270 * This function will return a certificate of the PKCS7 or RFC2630 certificate set.
271 * Returns 0 on success. If the provided buffer is not long enough,
272 * then @certificate_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER is returned.
273 *
274 * After the last certificate has been read GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
275 * will be returned.
276 *
277 **/
278int
279gnutls_pkcs7_get_crt_raw (gnutls_pkcs7_t pkcs7,
280 int indx, void *certificate,
281 size_t * certificate_size)
282{
283 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
284 int result, len;
285 char root2[MAX_NAME_SIZE];
286 char oid[128];
287 gnutls_datum_t tmp = { NULL, 0 };
288
289 if (certificate_size == NULL || pkcs7 == NULL)
290 return GNUTLS_E_INVALID_REQUEST;
291
292 /* Step 1. decode the signed data.
293 */
294 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, &tmp);
295 if (result < 0)
296 {
297 gnutls_assert ();
298 return result;
299 }
300
301 /* Step 2. Parse the CertificateSet
302 */
303
304 snprintf (root2, sizeof (root2), "certificates.?%u", indx + 1);
305
306 len = sizeof (oid) - 1;
307
308 result = asn1_read_value (c2, root2, oid, &len);
309
310 if (result == ASN1_VALUE_NOT_FOUND)
311 {
312 result = GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
313 goto cleanup;
314 }
315
316 if (result != ASN1_SUCCESS)
317 {
318 gnutls_assert ();
319 result = _gnutls_asn2err (result);
320 goto cleanup;
321 }
322
323 /* if 'Certificate' is the choice found:
324 */
325 if (strcmp (oid, "certificate") == 0)
326 {
327 int start, end;
328
329 result = asn1_der_decoding_startEnd (c2, tmp.data, tmp.size,
330 root2, &start, &end);
331
332 if (result != ASN1_SUCCESS)
333 {
334 gnutls_assert ();
335 result = _gnutls_asn2err (result);
336 goto cleanup;
337 }
338
339 end = end - start + 1;
340
341 if ((unsigned) end > *certificate_size)
342 {
343 *certificate_size = end;
344 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
345 goto cleanup;
346 }
347
348 if (certificate)
349 memcpy (certificate, &tmp.data[start], end);
350
351 *certificate_size = end;
352
353 result = 0;
354
355 }
356 else
357 {
358 result = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE;
359 }
360
361cleanup:
362 _gnutls_free_datum (&tmp);
363 if (c2)
364 asn1_delete_structure (&c2);
365 return result;
366}
367
368/**
369 * gnutls_pkcs7_get_crt_count - This function returns the number of certificates in a PKCS7 certificate set
370 * @pkcs7_struct: should contain a gnutls_pkcs7_t structure
371 *
372 * This function will return the number of certifcates in the PKCS7 or
373 * RFC2630 certificate set.
374 *
375 * Returns a negative value on failure.
376 *
377 **/
378int
379gnutls_pkcs7_get_crt_count (gnutls_pkcs7_t pkcs7)
380{
381 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
382 int result, count;
383
384 if (pkcs7 == NULL)
385 return GNUTLS_E_INVALID_REQUEST;
386
387 /* Step 1. decode the signed data.
388 */
389 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, NULL);
390 if (result < 0)
391 {
392 gnutls_assert ();
393 return result;
394 }
395
396 /* Step 2. Count the CertificateSet */
397
398 result = asn1_number_of_elements (c2, "certificates", &count);
399
400 asn1_delete_structure (&c2);
401
402 if (result != ASN1_SUCCESS)
403 {
404 gnutls_assert ();
405 return 0; /* no certificates */
406 }
407
408 return count;
409
410}
411
412/**
413 * gnutls_pkcs7_export - This function will export the pkcs7 structure
414 * @pkcs7: Holds the pkcs7 structure
415 * @format: the format of output params. One of PEM or DER.
416 * @output_data: will contain a structure PEM or DER encoded
417 * @output_data_size: holds the size of output_data (and will be
418 * replaced by the actual size of parameters)
419 *
420 * This function will export the pkcs7 structure to DER or PEM format.
421 *
422 * If the buffer provided is not long enough to hold the output, then
423 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
424 * be returned.
425 *
426 * If the structure is PEM encoded, it will have a header
427 * of "BEGIN PKCS7".
428 *
429 * Return value: In case of failure a negative value will be
430 * returned, and 0 on success.
431 *
432 **/
433int
434gnutls_pkcs7_export (gnutls_pkcs7_t pkcs7,
435 gnutls_x509_crt_fmt_t format, void *output_data,
436 size_t * output_data_size)
437{
438 if (pkcs7 == NULL)
439 return GNUTLS_E_INVALID_REQUEST;
440
441 return _gnutls_x509_export_int (pkcs7->pkcs7, format, PEM_PKCS7,
442 output_data, output_data_size);
443}
444
445/* Creates an empty signed data structure in the pkcs7
446 * structure and returns a handle to the signed data.
447 */
448static int
449create_empty_signed_data (ASN1_TYPE pkcs7, ASN1_TYPE * sdata)
450{
451 uint8_t one = 1;
452 int result;
453
454 *sdata = ASN1_TYPE_EMPTY;
455
456 if ((result = asn1_create_element
457 (_gnutls_get_pkix (), "PKIX1.pkcs-7-SignedData",
458 sdata)) != ASN1_SUCCESS)
459 {
460 gnutls_assert ();
461 result = _gnutls_asn2err (result);
462 goto cleanup;
463 }
464
465 /* Use version 1
466 */
467 result = asn1_write_value (*sdata, "version", &one, 1);
468 if (result != ASN1_SUCCESS)
469 {
470 gnutls_assert ();
471 result = _gnutls_asn2err (result);
472 goto cleanup;
473 }
474
475 /* Use no digest algorithms
476 */
477
478 /* id-data */
479 result =
480 asn1_write_value (*sdata, "encapContentInfo.eContentType",
481 "1.2.840.113549.1.7.5", 1);
482 if (result != ASN1_SUCCESS)
483 {
484 gnutls_assert ();
485 result = _gnutls_asn2err (result);
486 goto cleanup;
487 }
488
489 result = asn1_write_value (*sdata, "encapContentInfo.eContent", NULL, 0);
490 if (result != ASN1_SUCCESS)
491 {
492 gnutls_assert ();
493 result = _gnutls_asn2err (result);
494 goto cleanup;
495 }
496
497 /* Add no certificates.
498 */
499
500 /* Add no crls.
501 */
502
503 /* Add no signerInfos.
504 */
505
506 /* Write the content type of the signed data
507 */
508 result = asn1_write_value (pkcs7, "contentType", SIGNED_DATA_OID, 1);
509 if (result != ASN1_SUCCESS)
510 {
511 gnutls_assert ();
512 result = _gnutls_asn2err (result);
513 goto cleanup;
514 }
515
516 return 0;
517
518cleanup:
519 asn1_delete_structure (sdata);
520 return result;
521
522}
523
524/**
525 * gnutls_pkcs7_set_crt_raw - This function adds a certificate in a PKCS7 certificate set
526 * @pkcs7_struct: should contain a gnutls_pkcs7_t structure
527 * @crt: the DER encoded certificate to be added
528 *
529 * This function will add a certificate to the PKCS7 or RFC2630 certificate set.
530 * Returns 0 on success.
531 *
532 **/
533int
534gnutls_pkcs7_set_crt_raw (gnutls_pkcs7_t pkcs7, const gnutls_datum_t * crt)
535{
536 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
537 int result;
538
539 if (pkcs7 == NULL)
540 return GNUTLS_E_INVALID_REQUEST;
541
542 /* Step 1. decode the signed data.
543 */
544 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, NULL);
545 if (result < 0 && result != GNUTLS_E_ASN1_VALUE_NOT_FOUND)
546 {
547 gnutls_assert ();
548 return result;
549 }
550
551 /* If the signed data are uninitialized
552 * then create them.
553 */
554 if (result == GNUTLS_E_ASN1_VALUE_NOT_FOUND)
555 {
556 /* The pkcs7 structure is new, so create the
557 * signedData.
558 */
559 result = create_empty_signed_data (pkcs7->pkcs7, &c2);
560 if (result < 0)
561 {
562 gnutls_assert ();
563 return result;
564 }
565 }
566
567 /* Step 2. Append the new certificate.
568 */
569
570 result = asn1_write_value (c2, "certificates", "NEW", 1);
571 if (result != ASN1_SUCCESS)
572 {
573 gnutls_assert ();
574 result = _gnutls_asn2err (result);
575 goto cleanup;
576 }
577
578 result = asn1_write_value (c2, "certificates.?LAST", "certificate", 1);
579 if (result != ASN1_SUCCESS)
580 {
581 gnutls_assert ();
582 result = _gnutls_asn2err (result);
583 goto cleanup;
584 }
585
586 result =
587 asn1_write_value (c2, "certificates.?LAST.certificate", crt->data,
588 crt->size);
589 if (result != ASN1_SUCCESS)
590 {
591 gnutls_assert ();
592 result = _gnutls_asn2err (result);
593 goto cleanup;
594 }
595
596 /* Step 3. Replace the old content with the new
597 */
598 result =
599 _gnutls_x509_der_encode_and_copy (c2, "", pkcs7->pkcs7, "content", 0);
600 if (result < 0)
601 {
602 gnutls_assert ();
603 goto cleanup;
604 }
605
606 asn1_delete_structure (&c2);
607
608 return 0;
609
610cleanup:
611 if (c2)
612 asn1_delete_structure (&c2);
613 return result;
614}
615
616/**
617 * gnutls_pkcs7_set_crt - This function adds a parsed certificate in a PKCS7 certificate set
618 * @pkcs7_struct: should contain a gnutls_pkcs7_t structure
619 * @crt: the certificate to be copied.
620 *
621 * This function will add a parsed certificate to the PKCS7 or RFC2630 certificate set.
622 * This is a wrapper function over gnutls_pkcs7_set_crt_raw() .
623 *
624 * Returns 0 on success.
625 *
626 **/
627int
628gnutls_pkcs7_set_crt (gnutls_pkcs7_t pkcs7, gnutls_x509_crt_t crt)
629{
630 int ret;
631 gnutls_datum_t data;
632
633 if (pkcs7 == NULL)
634 return GNUTLS_E_INVALID_REQUEST;
635
636 ret = _gnutls_x509_der_encode (crt->cert, "", &data, 0);
637 if (ret < 0)
638 {
639 gnutls_assert ();
640 return ret;
641 }
642
643 ret = gnutls_pkcs7_set_crt_raw (pkcs7, &data);
644
645 _gnutls_free_datum (&data);
646
647 if (ret < 0)
648 {
649 gnutls_assert ();
650 return ret;
651 }
652
653 return 0;
654}
655
656
657/**
658 * gnutls_pkcs7_delete_crt - This function deletes a certificate from a PKCS7 certificate set
659 * @pkcs7_struct: should contain a gnutls_pkcs7_t structure
660 * @indx: the index of the certificate to delete
661 *
662 * This function will delete a certificate from a PKCS7 or RFC2630 certificate set.
663 * Index starts from 0. Returns 0 on success.
664 *
665 **/
666int
667gnutls_pkcs7_delete_crt (gnutls_pkcs7_t pkcs7, int indx)
668{
669 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
670 int result;
671 char root2[MAX_NAME_SIZE];
672
673 if (pkcs7 == NULL)
674 return GNUTLS_E_INVALID_REQUEST;
675
676 /* Step 1. Decode the signed data.
677 */
678 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, NULL);
679 if (result < 0)
680 {
681 gnutls_assert ();
682 return result;
683 }
684
685 /* Step 2. Delete the certificate.
686 */
687
688 snprintf (root2, sizeof (root2), "certificates.?%u", indx + 1);
689
690 result = asn1_write_value (c2, root2, NULL, 0);
691 if (result != ASN1_SUCCESS)
692 {
693 gnutls_assert ();
694 result = _gnutls_asn2err (result);
695 goto cleanup;
696 }
697
698 /* Step 3. Replace the old content with the new
699 */
700 result =
701 _gnutls_x509_der_encode_and_copy (c2, "", pkcs7->pkcs7, "content", 0);
702 if (result < 0)
703 {
704 gnutls_assert ();
705 goto cleanup;
706 }
707
708 asn1_delete_structure (&c2);
709
710 return 0;
711
712cleanup:
713 if (c2)
714 asn1_delete_structure (&c2);
715 return result;
716}
717
718/* Read and write CRLs
719 */
720
721/**
722 * gnutls_pkcs7_get_crl_raw - This function returns a crl in a PKCS7 crl set
723 * @pkcs7_struct: should contain a gnutls_pkcs7_t structure
724 * @indx: contains the index of the crl to extract
725 * @crl: the contents of the crl will be copied there (may be null)
726 * @crl_size: should hold the size of the crl
727 *
728 * This function will return a crl of the PKCS7 or RFC2630 crl set.
729 * Returns 0 on success. If the provided buffer is not long enough,
730 * then @crl_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER is returned.
731 *
732 * After the last crl has been read GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
733 * will be returned.
734 *
735 **/
736int
737gnutls_pkcs7_get_crl_raw (gnutls_pkcs7_t pkcs7,
738 int indx, void *crl, size_t * crl_size)
739{
740 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
741 int result;
742 char root2[MAX_NAME_SIZE];
743 gnutls_datum_t tmp = { NULL, 0 };
744 int start, end;
745
746 if (pkcs7 == NULL || crl_size == NULL)
747 return GNUTLS_E_INVALID_REQUEST;
748
749 /* Step 1. decode the signed data.
750 */
751 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, &tmp);
752 if (result < 0)
753 {
754 gnutls_assert ();
755 return result;
756 }
757
758 /* Step 2. Parse the CertificateSet
759 */
760
761 snprintf (root2, sizeof (root2), "crls.?%u", indx + 1);
762
763 /* Get the raw CRL
764 */
765 result = asn1_der_decoding_startEnd (c2, tmp.data, tmp.size,
766 root2, &start, &end);
767
768 if (result != ASN1_SUCCESS)
769 {
770 gnutls_assert ();
771 result = _gnutls_asn2err (result);
772 goto cleanup;
773 }
774
775 end = end - start + 1;
776
777 if ((unsigned) end > *crl_size)
778 {
779 *crl_size = end;
780 result = GNUTLS_E_SHORT_MEMORY_BUFFER;
781 goto cleanup;
782 }
783
784 if (crl)
785 memcpy (crl, &tmp.data[start], end);
786
787 *crl_size = end;
788
789 result = 0;
790
791cleanup:
792 _gnutls_free_datum (&tmp);
793 if (c2)
794 asn1_delete_structure (&c2);
795 return result;
796}
797
798/**
799 * gnutls_pkcs7_get_crl_count - This function returns the number of crls in a PKCS7 crl set
800 * @pkcs7_struct: should contain a gnutls_pkcs7_t structure
801 *
802 * This function will return the number of certifcates in the PKCS7 or
803 * RFC2630 crl set.
804 *
805 * Returns a negative value on failure.
806 *
807 **/
808int
809gnutls_pkcs7_get_crl_count (gnutls_pkcs7_t pkcs7)
810{
811 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
812 int result, count;
813
814 if (pkcs7 == NULL)
815 return GNUTLS_E_INVALID_REQUEST;
816
817 /* Step 1. decode the signed data.
818 */
819 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, NULL);
820 if (result < 0)
821 {
822 gnutls_assert ();
823 return result;
824 }
825
826 /* Step 2. Count the CertificateSet */
827
828 result = asn1_number_of_elements (c2, "crls", &count);
829
830 asn1_delete_structure (&c2);
831
832 if (result != ASN1_SUCCESS)
833 {
834 gnutls_assert ();
835 return 0; /* no crls */
836 }
837
838 return count;
839
840}
841
842/**
843 * gnutls_pkcs7_set_crl_raw - This function adds a crl in a PKCS7 crl set
844 * @pkcs7_struct: should contain a gnutls_pkcs7_t structure
845 * @crl: the DER encoded crl to be added
846 *
847 * This function will add a crl to the PKCS7 or RFC2630 crl set.
848 * Returns 0 on success.
849 *
850 **/
851int
852gnutls_pkcs7_set_crl_raw (gnutls_pkcs7_t pkcs7, const gnutls_datum_t * crl)
853{
854 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
855 int result;
856
857 if (pkcs7 == NULL)
858 return GNUTLS_E_INVALID_REQUEST;
859
860 /* Step 1. decode the signed data.
861 */
862 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, NULL);
863 if (result < 0 && result != GNUTLS_E_ASN1_VALUE_NOT_FOUND)
864 {
865 gnutls_assert ();
866 return result;
867 }
868
869 /* If the signed data are uninitialized
870 * then create them.
871 */
872 if (result == GNUTLS_E_ASN1_VALUE_NOT_FOUND)
873 {
874 /* The pkcs7 structure is new, so create the
875 * signedData.
876 */
877 result = create_empty_signed_data (pkcs7->pkcs7, &c2);
878 if (result < 0)
879 {
880 gnutls_assert ();
881 return result;
882 }
883 }
884
885 /* Step 2. Append the new crl.
886 */
887
888 result = asn1_write_value (c2, "crls", "NEW", 1);
889 if (result != ASN1_SUCCESS)
890 {
891 gnutls_assert ();
892 result = _gnutls_asn2err (result);
893 goto cleanup;
894 }
895
896 result = asn1_write_value (c2, "crls.?LAST", crl->data, crl->size);
897 if (result != ASN1_SUCCESS)
898 {
899 gnutls_assert ();
900 result = _gnutls_asn2err (result);
901 goto cleanup;
902 }
903
904 /* Step 3. Replace the old content with the new
905 */
906 result =
907 _gnutls_x509_der_encode_and_copy (c2, "", pkcs7->pkcs7, "content", 0);
908 if (result < 0)
909 {
910 gnutls_assert ();
911 goto cleanup;
912 }
913
914 asn1_delete_structure (&c2);
915
916 return 0;
917
918cleanup:
919 if (c2)
920 asn1_delete_structure (&c2);
921 return result;
922}
923
924/**
925 * gnutls_pkcs7_set_crl - This function adds a parsed crl in a PKCS7 crl set
926 * @pkcs7_struct: should contain a gnutls_pkcs7_t structure
927 * @crl: the DER encoded crl to be added
928 *
929 * This function will add a parsed crl to the PKCS7 or RFC2630 crl set.
930 * Returns 0 on success.
931 *
932 **/
933int
934gnutls_pkcs7_set_crl (gnutls_pkcs7_t pkcs7, gnutls_x509_crl_t crl)
935{
936 int ret;
937 gnutls_datum_t data;
938
939 if (pkcs7 == NULL)
940 return GNUTLS_E_INVALID_REQUEST;
941
942 ret = _gnutls_x509_der_encode (crl->crl, "", &data, 0);
943 if (ret < 0)
944 {
945 gnutls_assert ();
946 return ret;
947 }
948
949 ret = gnutls_pkcs7_set_crl_raw (pkcs7, &data);
950
951 _gnutls_free_datum (&data);
952
953 if (ret < 0)
954 {
955 gnutls_assert ();
956 return ret;
957 }
958
959 return 0;
960}
961
962/**
963 * gnutls_pkcs7_delete_crl - This function deletes a crl from a PKCS7 crl set
964 * @pkcs7_struct: should contain a gnutls_pkcs7_t structure
965 * @indx: the index of the crl to delete
966 *
967 * This function will delete a crl from a PKCS7 or RFC2630 crl set.
968 * Index starts from 0. Returns 0 on success.
969 *
970 **/
971int
972gnutls_pkcs7_delete_crl (gnutls_pkcs7_t pkcs7, int indx)
973{
974 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
975 int result;
976 char root2[MAX_NAME_SIZE];
977
978 if (pkcs7 == NULL)
979 return GNUTLS_E_INVALID_REQUEST;
980
981 /* Step 1. Decode the signed data.
982 */
983 result = _decode_pkcs7_signed_data (pkcs7->pkcs7, &c2, NULL);
984 if (result < 0)
985 {
986 gnutls_assert ();
987 return result;
988 }
989
990 /* Step 2. Delete the crl.
991 */
992
993 snprintf (root2, sizeof (root2), "crls.?%u", indx + 1);
994
995 result = asn1_write_value (c2, root2, NULL, 0);
996 if (result != ASN1_SUCCESS)
997 {
998 gnutls_assert ();
999 result = _gnutls_asn2err (result);
1000 goto cleanup;
1001 }
1002
1003 /* Step 3. Replace the old content with the new
1004 */
1005 result =
1006 _gnutls_x509_der_encode_and_copy (c2, "", pkcs7->pkcs7, "content", 0);
1007 if (result < 0)
1008 {
1009 gnutls_assert ();
1010 goto cleanup;
1011 }
1012
1013 asn1_delete_structure (&c2);
1014
1015 return 0;
1016
1017cleanup:
1018 if (c2)
1019 asn1_delete_structure (&c2);
1020 return result;
1021}
1022
1023#endif /* ENABLE_PKI */
diff --git a/src/daemon/https/x509/pkcs7.h b/src/daemon/https/x509/pkcs7.h
new file mode 100644
index 00000000..ee1990c3
--- /dev/null
+++ b/src/daemon/https/x509/pkcs7.h
@@ -0,0 +1,30 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include "x509.h"
26
27typedef struct gnutls_pkcs7_int
28{
29 ASN1_TYPE pkcs7;
30} gnutls_pkcs7_int;
diff --git a/src/daemon/https/x509/privkey.h b/src/daemon/https/x509/privkey.h
new file mode 100644
index 00000000..6e645b9d
--- /dev/null
+++ b/src/daemon/https/x509/privkey.h
@@ -0,0 +1,31 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include "x509.h"
26
27ASN1_TYPE _gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t *
28 raw_key,
29 gnutls_x509_privkey_t pkey);
30
31int _gnutls_asn1_encode_dsa (ASN1_TYPE * c2, mpi_t * params);
diff --git a/src/daemon/https/x509/privkey_pkcs8.c b/src/daemon/https/x509/privkey_pkcs8.c
new file mode 100644
index 00000000..2f1921bb
--- /dev/null
+++ b/src/daemon/https/x509/privkey_pkcs8.c
@@ -0,0 +1,2219 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26
27#ifdef ENABLE_PKI
28
29#include <gnutls_datum.h>
30#include <gnutls_global.h>
31#include <gnutls_errors.h>
32#include <gnutls_rsa_export.h>
33#include <common.h>
34#include <gnutls_x509.h>
35#include <x509_b64.h>
36#include <x509.h>
37#include <dn.h>
38#include <pkcs12.h>
39#include <privkey.h>
40#include <extensions.h>
41#include <mpi.h>
42#include <gnutls_algorithms.h>
43#include <gnutls_num.h>
44#include "gc.h"
45
46#define PBES2_OID "1.2.840.113549.1.5.13"
47#define PBKDF2_OID "1.2.840.113549.1.5.12"
48#define DES_EDE3_CBC_OID "1.2.840.113549.3.7"
49#define DES_CBC_OID "1.3.14.3.2.7"
50
51/* oid_pbeWithSHAAnd3_KeyTripleDES_CBC */
52#define PKCS12_PBE_3DES_SHA1_OID "1.2.840.113549.1.12.1.3"
53#define PKCS12_PBE_ARCFOUR_SHA1_OID "1.2.840.113549.1.12.1.1"
54#define PKCS12_PBE_RC2_40_SHA1_OID "1.2.840.113549.1.12.1.6"
55
56struct pbkdf2_params
57 {
58 opaque salt[32];
59 int salt_size;
60 unsigned int iter_count;
61 unsigned int key_size;
62 };
63
64struct pbe_enc_params
65 {
66 gnutls_cipher_algorithm_t cipher;
67 opaque iv[8];
68 int iv_size;
69 };
70
71static int generate_key (schema_id schema, const char *password,
72 struct pbkdf2_params *kdf_params,
73 struct pbe_enc_params *enc_params,
74 gnutls_datum_t * key);
75static int read_pbkdf2_params (ASN1_TYPE pbes2_asn,
76 const gnutls_datum_t * der,
77 struct pbkdf2_params *params);
78static int read_pbe_enc_params (ASN1_TYPE pbes2_asn,
79 const gnutls_datum_t * der,
80 struct pbe_enc_params *params);
81static int decrypt_data (schema_id, ASN1_TYPE pkcs8_asn, const char *root,
82 const char *password,
83 const struct pbkdf2_params *kdf_params,
84 const struct pbe_enc_params *enc_params,
85 gnutls_datum_t * decrypted_data);
86static int decode_private_key_info (const gnutls_datum_t * der,
87 gnutls_x509_privkey_t pkey);
88static int write_schema_params (schema_id schema, ASN1_TYPE pkcs8_asn,
89 const char *where,
90 const struct pbkdf2_params *kdf_params,
91 const struct pbe_enc_params *enc_params);
92static int encrypt_data (const gnutls_datum_t * plain,
93 const struct pbe_enc_params *enc_params,
94 gnutls_datum_t * key, gnutls_datum_t * encrypted);
95
96static int read_pkcs12_kdf_params (ASN1_TYPE pbes2_asn,
97 struct pbkdf2_params *params);
98static int write_pkcs12_kdf_params (ASN1_TYPE pbes2_asn,
99 const struct pbkdf2_params *params);
100
101#define PEM_PKCS8 "ENCRYPTED PRIVATE KEY"
102#define PEM_UNENCRYPTED_PKCS8 "PRIVATE KEY"
103
104/* Returns a negative error code if the encryption schema in
105 * the OID is not supported. The schema ID is returned.
106 */
107inline static int
108check_schema (const char *oid)
109 {
110
111 if (strcmp (oid, PBES2_OID) == 0)
112 return PBES2;
113
114 if (strcmp (oid, PKCS12_PBE_3DES_SHA1_OID) == 0)
115 return PKCS12_3DES_SHA1;
116
117 if (strcmp (oid, PKCS12_PBE_ARCFOUR_SHA1_OID) == 0)
118 return PKCS12_ARCFOUR_SHA1;
119
120 if (strcmp (oid, PKCS12_PBE_RC2_40_SHA1_OID) == 0)
121 return PKCS12_RC2_40_SHA1;
122
123 _gnutls_x509_log ("PKCS encryption schema OID '%s' is unsupported.\n", oid);
124
125 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
126 }
127
128/* Encodes a private key to the raw format PKCS #8 needs.
129 * For RSA it is a PKCS #1 DER private key and for DSA it is
130 * an ASN.1 INTEGER of the x value.
131 */
132inline static int
133_encode_privkey (gnutls_x509_privkey pkey, gnutls_datum * raw)
134 {
135 size_t size = 0;
136 opaque *data = NULL;
137 int ret;
138 ASN1_TYPE spk = ASN1_TYPE_EMPTY;
139
140 switch (pkey->pk_algorithm)
141 {
142 case GNUTLS_PK_RSA:
143 ret =
144 gnutls_x509_privkey_export (pkey, GNUTLS_X509_FMT_DER, NULL, &size);
145 if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
146 {
147 gnutls_assert ();
148 goto error;
149 }
150
151 data = gnutls_malloc (size);
152 if (data == NULL)
153 {
154 gnutls_assert ();
155 ret = GNUTLS_E_MEMORY_ERROR;
156 goto error;
157 }
158
159 ret =
160 gnutls_x509_privkey_export (pkey, GNUTLS_X509_FMT_DER, data, &size);
161 if (ret < 0)
162 {
163 gnutls_assert ();
164 goto error;
165 }
166
167 raw->data = data;
168 raw->size = size;
169 break;
170 default:
171 gnutls_assert ();
172 return GNUTLS_E_INVALID_REQUEST;
173 }
174
175 return 0;
176
177 error:
178 gnutls_free (data);
179 asn1_delete_structure (&spk);
180 return ret;
181
182 }
183
184/*
185 * Encodes a PKCS #1 private key to a PKCS #8 private key
186 * info. The output will be allocated and stored into der. Also
187 * the ASN1_TYPE of private key info will be returned.
188 */
189static int
190encode_to_private_key_info (gnutls_x509_privkey_t pkey,
191 gnutls_datum_t * der, ASN1_TYPE * pkey_info)
192 {
193 int result, len;
194 opaque null = 0;
195 const char *oid;
196 gnutls_datum algo_params =
197 { NULL, 0};
198 gnutls_datum algo_privkey =
199 { NULL, 0};
200
201 if (pkey->pk_algorithm == GNUTLS_PK_RSA)
202 {
203 oid = PK_PKIX1_RSA_OID;
204 /* parameters are null
205 */
206 }
207 else
208 {
209 oid = PK_DSA_OID;
210 result =
211 _gnutls_x509_write_dsa_params (pkey->params, pkey->params_size,
212 &algo_params);
213 if (result < 0)
214 {
215 gnutls_assert ();
216 return result;
217 }
218 }
219
220 if ((result =
221 asn1_create_element (_gnutls_get_pkix (),
222 "PKIX1.pkcs-8-PrivateKeyInfo",
223 pkey_info)) != ASN1_SUCCESS)
224 {
225 gnutls_assert ();
226 result = _gnutls_asn2err (result);
227 goto error;
228 }
229
230 /* Write the version.
231 */
232 result = asn1_write_value (*pkey_info, "version", &null, 1);
233 if (result != ASN1_SUCCESS)
234 {
235 gnutls_assert ();
236 result = _gnutls_asn2err (result);
237 goto error;
238 }
239
240 /* write the privateKeyAlgorithm
241 * fields. (OID+NULL data)
242 */
243 result =
244 asn1_write_value (*pkey_info, "privateKeyAlgorithm.algorithm", oid, 1);
245 if (result != ASN1_SUCCESS)
246 {
247 gnutls_assert ();
248 result = _gnutls_asn2err (result);
249 goto error;
250 }
251
252 result =
253 asn1_write_value (*pkey_info, "privateKeyAlgorithm.parameters",
254 algo_params.data, algo_params.size);
255 _gnutls_free_datum (&algo_params);
256 if (result != ASN1_SUCCESS)
257 {
258 gnutls_assert ();
259 result = _gnutls_asn2err (result);
260 goto error;
261 }
262
263 /* Write the raw private key
264 */
265 result = _encode_privkey (pkey, &algo_privkey);
266 if (result < 0)
267 {
268 gnutls_assert ();
269 goto error;
270 }
271
272 result =
273 asn1_write_value (*pkey_info, "privateKey", algo_privkey.data,
274 algo_privkey.size);
275 _gnutls_free_datum (&algo_privkey);
276
277 if (result != ASN1_SUCCESS)
278 {
279 gnutls_assert ();
280 result = _gnutls_asn2err (result);
281 goto error;
282 }
283
284 /* Append an empty Attributes field.
285 */
286 result = asn1_write_value (*pkey_info, "attributes", NULL, 0);
287 if (result != ASN1_SUCCESS)
288 {
289 gnutls_assert ();
290 result = _gnutls_asn2err (result);
291 goto error;
292 }
293
294 /* DER Encode the generated private key info.
295 */
296 len = 0;
297 result = asn1_der_coding (*pkey_info, "", NULL, &len, NULL);
298 if (result != ASN1_MEM_ERROR)
299 {
300 gnutls_assert ();
301 result = _gnutls_asn2err (result);
302 goto error;
303 }
304
305 /* allocate data for the der
306 */
307 der->size = len;
308 der->data = gnutls_malloc (len);
309 if (der->data == NULL)
310 {
311 gnutls_assert ();
312 return GNUTLS_E_MEMORY_ERROR;
313 }
314
315 result = asn1_der_coding (*pkey_info, "", der->data, &len, NULL);
316 if (result != ASN1_SUCCESS)
317 {
318 gnutls_assert ();
319 result = _gnutls_asn2err (result);
320 goto error;
321 }
322
323 return 0;
324
325 error:
326 asn1_delete_structure (pkey_info);
327 _gnutls_free_datum (&algo_params);
328 _gnutls_free_datum (&algo_privkey);
329 return result;
330
331 }
332
333/* Converts a PKCS #8 private key info to
334 * a PKCS #8 EncryptedPrivateKeyInfo.
335 */
336static int
337encode_to_pkcs8_key (schema_id schema, const gnutls_datum_t * der_key,
338 const char *password, ASN1_TYPE * out)
339 {
340 int result;
341 gnutls_datum_t key =
342 { NULL, 0};
343 gnutls_datum_t tmp =
344 { NULL, 0};
345 ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY;
346 struct pbkdf2_params kdf_params;
347 struct pbe_enc_params enc_params;
348
349 if ((result =
350 asn1_create_element (_gnutls_get_pkix (),
351 "PKIX1.pkcs-8-EncryptedPrivateKeyInfo",
352 &pkcs8_asn)) != ASN1_SUCCESS)
353 {
354 gnutls_assert ();
355 result = _gnutls_asn2err (result);
356 goto error;
357 }
358
359 /* Write the encryption schema OID
360 */
361 switch (schema)
362 {
363 case PBES2:
364 result =
365 asn1_write_value (pkcs8_asn, "encryptionAlgorithm.algorithm",
366 PBES2_OID, 1);
367 break;
368 case PKCS12_3DES_SHA1:
369 result =
370 asn1_write_value (pkcs8_asn, "encryptionAlgorithm.algorithm",
371 PKCS12_PBE_3DES_SHA1_OID, 1);
372 break;
373 case PKCS12_ARCFOUR_SHA1:
374 result =
375 asn1_write_value (pkcs8_asn, "encryptionAlgorithm.algorithm",
376 PKCS12_PBE_ARCFOUR_SHA1_OID, 1);
377 break;
378 case PKCS12_RC2_40_SHA1:
379 result =
380 asn1_write_value (pkcs8_asn, "encryptionAlgorithm.algorithm",
381 PKCS12_PBE_RC2_40_SHA1_OID, 1);
382 break;
383
384 }
385
386 if (result != ASN1_SUCCESS)
387 {
388 gnutls_assert ();
389 result = _gnutls_asn2err (result);
390 goto error;
391 }
392
393 /* Generate a symmetric key.
394 */
395
396 result = generate_key (schema, password, &kdf_params, &enc_params, &key);
397 if (result < 0)
398 {
399 gnutls_assert ();
400 goto error;
401 }
402
403 result =
404 write_schema_params (schema, pkcs8_asn,
405 "encryptionAlgorithm.parameters", &kdf_params,
406 &enc_params);
407 if (result < 0)
408 {
409 gnutls_assert ();
410 goto error;
411 }
412
413 /* Parameters have been encoded. Now
414 * encrypt the Data.
415 */
416 result = encrypt_data (der_key, &enc_params, &key, &tmp);
417 if (result < 0)
418 {
419 gnutls_assert ();
420 goto error;
421 }
422
423 /* write the encrypted data.
424 */
425 result = asn1_write_value (pkcs8_asn, "encryptedData", tmp.data, tmp.size);
426 if (result != ASN1_SUCCESS)
427 {
428 gnutls_assert ();
429 result = _gnutls_asn2err (result);
430 goto error;
431 }
432
433 _gnutls_free_datum (&tmp);
434 _gnutls_free_datum (&key);
435
436 *out = pkcs8_asn;
437
438 return 0;
439
440 error:
441 _gnutls_free_datum (&key);
442 _gnutls_free_datum (&tmp);
443 asn1_delete_structure (&pkcs8_asn);
444 return result;
445 }
446
447/**
448 * gnutls_x509_privkey_export_pkcs8 - This function will export the private key to PKCS8 format
449 * @key: Holds the key
450 * @format: the format of output params. One of PEM or DER.
451 * @password: the password that will be used to encrypt the key.
452 * @flags: an ORed sequence of gnutls_pkcs_encrypt_flags_t
453 * @output_data: will contain a private key PEM or DER encoded
454 * @output_data_size: holds the size of output_data (and will be
455 * replaced by the actual size of parameters)
456 *
457 * This function will export the private key to a PKCS8 structure.
458 * Both RSA and DSA keys can be exported. For DSA keys we use
459 * PKCS #11 definitions. If the flags do not specify the encryption
460 * cipher, then the default 3DES (PBES2) will be used.
461 *
462 * The @password can be either ASCII or UTF-8 in the default PBES2
463 * encryption schemas, or ASCII for the PKCS12 schemas.
464 *
465 * If the buffer provided is not long enough to hold the output, then
466 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
467 * be returned.
468 *
469 * If the structure is PEM encoded, it will have a header
470 * of "BEGIN ENCRYPTED PRIVATE KEY" or "BEGIN PRIVATE KEY" if
471 * encryption is not used.
472 *
473 * Return value: In case of failure a negative value will be
474 * returned, and 0 on success.
475 *
476 **/
477int
478gnutls_x509_privkey_export_pkcs8 (gnutls_x509_privkey_t key,
479 gnutls_x509_crt_fmt_t format,
480 const char *password,
481 unsigned int flags,
482 void *output_data,
483 size_t * output_data_size)
484 {
485 ASN1_TYPE pkcs8_asn, pkey_info;
486 int ret;
487 gnutls_datum_t tmp;
488 schema_id schema;
489
490 if (key == NULL)
491 {
492 gnutls_assert ();
493 return GNUTLS_E_INVALID_REQUEST;
494 }
495
496 /* Get the private key info
497 * tmp holds the DER encoding.
498 */
499 ret = encode_to_private_key_info (key, &tmp, &pkey_info);
500 if (ret < 0)
501 {
502 gnutls_assert ();
503 return ret;
504 }
505
506 if (flags & GNUTLS_PKCS_USE_PKCS12_3DES)
507 schema = PKCS12_3DES_SHA1;
508 else if (flags & GNUTLS_PKCS_USE_PKCS12_ARCFOUR)
509 schema = PKCS12_ARCFOUR_SHA1;
510 else if (flags & GNUTLS_PKCS_USE_PKCS12_RC2_40)
511 schema = PKCS12_RC2_40_SHA1;
512 else
513 schema = PBES2;
514
515 if ((flags & GNUTLS_PKCS_PLAIN) || password == NULL)
516 {
517 _gnutls_free_datum (&tmp);
518
519 ret =
520 _gnutls_x509_export_int (pkey_info, format,
521 PEM_UNENCRYPTED_PKCS8,
522 output_data, output_data_size);
523
524 asn1_delete_structure (&pkey_info);
525 }
526 else
527 {
528 asn1_delete_structure (&pkey_info); /* we don't need it */
529
530 ret = encode_to_pkcs8_key (schema, &tmp, password, &pkcs8_asn);
531 _gnutls_free_datum (&tmp);
532
533 if (ret < 0)
534 {
535 gnutls_assert ();
536 return ret;
537 }
538
539 ret =
540 _gnutls_x509_export_int (pkcs8_asn, format, PEM_PKCS8,
541 output_data, output_data_size);
542
543 asn1_delete_structure (&pkcs8_asn);
544 }
545
546 return ret;
547 }
548
549/* Read the parameters cipher, IV, salt etc using the given
550 * schema ID.
551 */
552static int
553read_pkcs_schema_params (schema_id schema, const char *password,
554 const opaque * data, int data_size,
555 struct pbkdf2_params *kdf_params,
556 struct pbe_enc_params *enc_params)
557 {
558 ASN1_TYPE pbes2_asn = ASN1_TYPE_EMPTY;
559 int result;
560 gnutls_datum_t tmp;
561
562 switch (schema)
563 {
564
565 case PBES2:
566
567 /* Now check the key derivation and the encryption
568 * functions.
569 */
570 if ((result =
571 asn1_create_element (_gnutls_get_pkix (),
572 "PKIX1.pkcs-5-PBES2-params",
573 &pbes2_asn)) != ASN1_SUCCESS)
574 {
575 gnutls_assert ();
576 result = _gnutls_asn2err (result);
577 goto error;
578 }
579
580 /* Decode the parameters.
581 */
582 result = asn1_der_decoding (&pbes2_asn, data, data_size, NULL);
583 if (result != ASN1_SUCCESS)
584 {
585 gnutls_assert ();
586 result = _gnutls_asn2err (result);
587 goto error;
588 }
589
590 tmp.data = (opaque *) data;
591 tmp.size = data_size;
592
593 result = read_pbkdf2_params (pbes2_asn, &tmp, kdf_params);
594 if (result < 0)
595 {
596 gnutls_assert ();
597 result = _gnutls_asn2err (result);
598 goto error;
599 }
600
601 result = read_pbe_enc_params (pbes2_asn, &tmp, enc_params);
602 if (result < 0)
603 {
604 gnutls_assert ();
605 result = _gnutls_asn2err (result);
606 goto error;
607 }
608
609 asn1_delete_structure (&pbes2_asn);
610 return 0;
611 break;
612
613 case PKCS12_3DES_SHA1:
614 case PKCS12_ARCFOUR_SHA1:
615 case PKCS12_RC2_40_SHA1:
616
617 if ((schema) == PKCS12_3DES_SHA1)
618 {
619 enc_params->cipher = GNUTLS_CIPHER_3DES_CBC;
620 enc_params->iv_size = 8;
621 }
622 else if ((schema) == PKCS12_ARCFOUR_SHA1)
623 {
624 enc_params->cipher = GNUTLS_CIPHER_ARCFOUR_128;
625 enc_params->iv_size = 0;
626 }
627 else if ((schema) == PKCS12_RC2_40_SHA1)
628 {
629 enc_params->cipher = GNUTLS_CIPHER_RC2_40_CBC;
630 enc_params->iv_size = 8;
631 }
632
633 if ((result =
634 asn1_create_element (_gnutls_get_pkix (),
635 "PKIX1.pkcs-12-PbeParams",
636 &pbes2_asn)) != ASN1_SUCCESS)
637 {
638 gnutls_assert ();
639 result = _gnutls_asn2err (result);
640 goto error;
641 }
642
643 /* Decode the parameters.
644 */
645 result = asn1_der_decoding (&pbes2_asn, data, data_size, NULL);
646 if (result != ASN1_SUCCESS)
647 {
648 gnutls_assert ();
649 result = _gnutls_asn2err (result);
650 goto error;
651 }
652
653 result = read_pkcs12_kdf_params (pbes2_asn, kdf_params);
654 if (result < 0)
655 {
656 gnutls_assert ();
657 goto error;
658 }
659
660 if (enc_params->iv_size)
661 {
662 result =
663 _pkcs12_string_to_key (2 /*IV*/, kdf_params->salt,
664 kdf_params->salt_size,
665 kdf_params->iter_count, password,
666 enc_params->iv_size, enc_params->iv);
667 if (result < 0)
668 {
669 gnutls_assert ();
670 goto error;
671 }
672
673 }
674
675 asn1_delete_structure (&pbes2_asn);
676
677 return 0;
678 break;
679
680 } /* switch */
681
682 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
683
684 error:
685 asn1_delete_structure (&pbes2_asn);
686 return result;
687 }
688
689/* Converts a PKCS #8 key to
690 * an internal structure (gnutls_private_key)
691 * (normally a PKCS #1 encoded RSA key)
692 */
693static int
694decode_pkcs8_key (const gnutls_datum_t * raw_key,
695 const char *password, gnutls_x509_privkey_t pkey)
696 {
697 int result, len;
698 char enc_oid[64];
699 gnutls_datum_t tmp;
700 ASN1_TYPE pbes2_asn = ASN1_TYPE_EMPTY, pkcs8_asn = ASN1_TYPE_EMPTY;
701 int params_start, params_end, params_len;
702 struct pbkdf2_params kdf_params;
703 struct pbe_enc_params enc_params;
704 schema_id schema;
705
706 if ((result =
707 asn1_create_element (_gnutls_get_pkix (),
708 "PKIX1.pkcs-8-EncryptedPrivateKeyInfo",
709 &pkcs8_asn)) != ASN1_SUCCESS)
710 {
711 gnutls_assert ();
712 result = _gnutls_asn2err (result);
713 goto error;
714 }
715
716 result = asn1_der_decoding (&pkcs8_asn, raw_key->data, raw_key->size, NULL);
717 if (result != ASN1_SUCCESS)
718 {
719 gnutls_assert ();
720 result = _gnutls_asn2err (result);
721 goto error;
722 }
723
724 /* Check the encryption schema OID
725 */
726 len = sizeof (enc_oid);
727 result =
728 asn1_read_value (pkcs8_asn, "encryptionAlgorithm.algorithm",
729 enc_oid, &len);
730 if (result != ASN1_SUCCESS)
731 {
732 gnutls_assert ();
733 goto error;
734 }
735
736 if ((result = check_schema (enc_oid)) < 0)
737 {
738 gnutls_assert ();
739 goto error;
740 }
741
742 schema = result;
743
744 /* Get the DER encoding of the parameters.
745 */
746 result =
747 asn1_der_decoding_startEnd (pkcs8_asn, raw_key->data,
748 raw_key->size,
749 "encryptionAlgorithm.parameters",
750 &params_start, &params_end);
751 if (result != ASN1_SUCCESS)
752 {
753 gnutls_assert ();
754 result = _gnutls_asn2err (result);
755 goto error;
756 }
757 params_len = params_end - params_start + 1;
758
759 result =
760 read_pkcs_schema_params (schema, password,
761 &raw_key->data[params_start],
762 params_len, &kdf_params, &enc_params);
763
764 /* Parameters have been decoded. Now
765 * decrypt the EncryptedData.
766 */
767 result =
768 decrypt_data (schema, pkcs8_asn, "encryptedData", password,
769 &kdf_params, &enc_params, &tmp);
770 if (result < 0)
771 {
772 gnutls_assert ();
773 goto error;
774 }
775
776 asn1_delete_structure (&pkcs8_asn);
777
778 result = decode_private_key_info (&tmp, pkey);
779 _gnutls_free_datum (&tmp);
780
781 if (result < 0)
782 {
783 /* We've gotten this far. In the real world it's almost certain
784 * that we're dealing with a good file, but wrong password.
785 * Sadly like 90% of random data is somehow valid DER for the
786 * a first small number of bytes, so no easy way to guarantee. */
787 if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND ||
788 result == GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND ||
789 result == GNUTLS_E_ASN1_DER_ERROR ||
790 result == GNUTLS_E_ASN1_VALUE_NOT_FOUND ||
791 result == GNUTLS_E_ASN1_GENERIC_ERROR ||
792 result == GNUTLS_E_ASN1_VALUE_NOT_VALID ||
793 result == GNUTLS_E_ASN1_TAG_ERROR ||
794 result == GNUTLS_E_ASN1_TAG_IMPLICIT ||
795 result == GNUTLS_E_ASN1_TYPE_ANY_ERROR ||
796 result == GNUTLS_E_ASN1_SYNTAX_ERROR ||
797 result == GNUTLS_E_ASN1_DER_OVERFLOW)
798 {
799 result = GNUTLS_E_DECRYPTION_FAILED;
800 }
801
802 gnutls_assert ();
803 goto error;
804 }
805
806 return 0;
807
808 error:
809 asn1_delete_structure (&pbes2_asn);
810 asn1_delete_structure (&pkcs8_asn);
811 return result;
812 }
813
814/* Decodes an RSA privateKey from a PKCS8 structure.
815 */
816static int
817_decode_pkcs8_rsa_key (ASN1_TYPE pkcs8_asn, gnutls_x509_privkey pkey)
818 {
819 int ret;
820 gnutls_datum tmp;
821
822 ret = _gnutls_x509_read_value (pkcs8_asn, "privateKey", &tmp, 0);
823 if (ret < 0)
824 {
825 gnutls_assert ();
826 goto error;
827 }
828
829 pkey->key = _gnutls_privkey_decode_pkcs1_rsa_key (&tmp, pkey);
830 _gnutls_free_datum (&tmp);
831 if (pkey->key == NULL)
832 {
833 gnutls_assert ();
834 goto error;
835 }
836
837 return 0;
838
839 error:
840 gnutls_x509_privkey_deinit (pkey);
841 return ret;
842 }
843
844/* Decodes an DSA privateKey and params from a PKCS8 structure.
845 */
846static int
847_decode_pkcs8_dsa_key (ASN1_TYPE pkcs8_asn, gnutls_x509_privkey pkey)
848 {
849 int ret;
850 gnutls_datum tmp;
851
852 ret = _gnutls_x509_read_value (pkcs8_asn, "privateKey", &tmp, 0);
853 if (ret < 0)
854 {
855 gnutls_assert ();
856 goto error;
857 }
858
859 ret = _gnutls_x509_read_der_int (tmp.data, tmp.size, &pkey->params[4]);
860 _gnutls_free_datum (&tmp);
861
862 if (ret < 0)
863 {
864 gnutls_assert ();
865 goto error;
866 }
867
868 ret =
869 _gnutls_x509_read_value (pkcs8_asn, "privateKeyAlgorithm.parameters",
870 &tmp, 0);
871 if (ret < 0)
872 {
873 gnutls_assert ();
874 goto error;
875 }
876
877 ret = _gnutls_x509_read_dsa_params (tmp.data, tmp.size, pkey->params);
878 _gnutls_free_datum (&tmp);
879 if (ret < 0)
880 {
881 gnutls_assert ();
882 goto error;
883 }
884
885 /* the public key can be generated as g^x mod p */
886 pkey->params[3] = _gnutls_mpi_alloc_like (pkey->params[0]);
887 if (pkey->params[3] == NULL)
888 {
889 gnutls_assert ();
890 goto error;
891 }
892
893 _gnutls_mpi_powm (pkey->params[3], pkey->params[2], pkey->params[4],
894 pkey->params[0]);
895
896 if (!pkey->crippled)
897 {
898 ret = _gnutls_asn1_encode_dsa (&pkey->key, pkey->params);
899 if (ret < 0)
900 {
901 gnutls_assert ();
902 goto error;
903 }
904 }
905
906 pkey->params_size = DSA_PRIVATE_PARAMS;
907
908 return 0;
909
910 error:
911 gnutls_x509_privkey_deinit (pkey);
912 return ret;
913 }
914
915static int
916decode_private_key_info (const gnutls_datum_t * der,
917 gnutls_x509_privkey_t pkey)
918 {
919 int result, len;
920 opaque oid[64];
921 ASN1_TYPE pkcs8_asn = ASN1_TYPE_EMPTY;
922
923 if ((result =
924 asn1_create_element (_gnutls_get_pkix (),
925 "PKIX1.pkcs-8-PrivateKeyInfo",
926 &pkcs8_asn)) != ASN1_SUCCESS)
927 {
928 gnutls_assert ();
929 result = _gnutls_asn2err (result);
930 goto error;
931 }
932
933 result = asn1_der_decoding (&pkcs8_asn, der->data, der->size, NULL);
934 if (result != ASN1_SUCCESS)
935 {
936 gnutls_assert ();
937 result = _gnutls_asn2err (result);
938 goto error;
939 }
940
941 /* Check the private key algorithm OID
942 */
943 len = sizeof (oid);
944 result =
945 asn1_read_value (pkcs8_asn, "privateKeyAlgorithm.algorithm", oid, &len);
946 if (result != ASN1_SUCCESS)
947 {
948 gnutls_assert ();
949 result = _gnutls_asn2err (result);
950 goto error;
951 }
952
953 /* we only support RSA and DSA private keys.
954 */
955 if (strcmp (oid, PK_PKIX1_RSA_OID) == 0)
956 pkey->pk_algorithm = GNUTLS_PK_RSA;
957 else
958 {
959 gnutls_assert ();
960 _gnutls_x509_log
961 ("PKCS #8 private key OID '%s' is unsupported.\n", oid);
962 result = GNUTLS_E_UNKNOWN_PK_ALGORITHM;
963 goto error;
964 }
965
966 /* Get the DER encoding of the actual private key.
967 */
968
969 if (pkey->pk_algorithm == GNUTLS_PK_RSA)
970 result = _decode_pkcs8_rsa_key (pkcs8_asn, pkey);
971 if (result < 0)
972 {
973 gnutls_assert ();
974 return result;
975 }
976
977 result = 0;
978
979 error:
980 asn1_delete_structure (&pkcs8_asn);
981
982 return result;
983
984 }
985
986/**
987 * gnutls_x509_privkey_import_pkcs8 - This function will import a DER or PEM PKCS8 encoded key
988 * @key: The structure to store the parsed key
989 * @data: The DER or PEM encoded key.
990 * @format: One of DER or PEM
991 * @password: the password to decrypt the key (if it is encrypted).
992 * @flags: 0 if encrypted or GNUTLS_PKCS_PLAIN if not encrypted.
993 *
994 * This function will convert the given DER or PEM encoded PKCS8 2.0 encrypted key
995 * to the native gnutls_x509_privkey_t format. The output will be stored in @key.
996 * Both RSA and DSA keys can be imported, and flags can only be used to indicate
997 * an unencrypted key.
998 *
999 * The @password can be either ASCII or UTF-8 in the default PBES2
1000 * encryption schemas, or ASCII for the PKCS12 schemas.
1001 *
1002 * If the Certificate is PEM encoded it should have a header of "ENCRYPTED PRIVATE KEY",
1003 * or "PRIVATE KEY". You only need to specify the flags if the key is DER encoded, since
1004 * in that case the encryption status cannot be auto-detected.
1005 *
1006 * Returns 0 on success.
1007 *
1008 **/
1009int
1010gnutls_x509_privkey_import_pkcs8 (gnutls_x509_privkey_t key,
1011 const gnutls_datum_t * data,
1012 gnutls_x509_crt_fmt_t format,
1013 const char *password, unsigned int flags)
1014 {
1015 int result = 0, need_free = 0;
1016 gnutls_datum_t _data;
1017
1018 if (key == NULL)
1019 {
1020 gnutls_assert ();
1021 return GNUTLS_E_INVALID_REQUEST;
1022 }
1023
1024 _data.data = data->data;
1025 _data.size = data->size;
1026
1027 key->pk_algorithm = GNUTLS_PK_UNKNOWN;
1028
1029 /* If the Certificate is in PEM format then decode it
1030 */
1031 if (format == GNUTLS_X509_FMT_PEM)
1032 {
1033 opaque *out;
1034
1035 /* Try the first header
1036 */
1037 result =
1038 _gnutls_fbase64_decode (PEM_UNENCRYPTED_PKCS8,
1039 data->data, data->size, &out);
1040
1041 if (result < 0)
1042 { /* Try the encrypted header
1043 */
1044 result =
1045 _gnutls_fbase64_decode (PEM_PKCS8, data->data, data->size, &out);
1046
1047 if (result <= 0)
1048 {
1049 if (result == 0)
1050 result = GNUTLS_E_INTERNAL_ERROR;
1051 gnutls_assert ();
1052 return result;
1053 }
1054 }
1055 else if (flags == 0)
1056 flags |= GNUTLS_PKCS_PLAIN;
1057
1058 _data.data = out;
1059 _data.size = result;
1060
1061 need_free = 1;
1062 }
1063
1064 if (flags & GNUTLS_PKCS_PLAIN)
1065 {
1066 result = decode_private_key_info (&_data, key);
1067 }
1068 else
1069 { /* encrypted. */
1070 result = decode_pkcs8_key (&_data, password, key);
1071 }
1072
1073 if (result < 0)
1074 {
1075 gnutls_assert ();
1076 goto cleanup;
1077 }
1078
1079 if (need_free)
1080 _gnutls_free_datum (&_data);
1081
1082 /* The key has now been decoded.
1083 */
1084
1085 return 0;
1086
1087 cleanup:
1088 key->pk_algorithm = GNUTLS_PK_UNKNOWN;
1089 if (need_free)
1090 _gnutls_free_datum (&_data);
1091 return result;
1092 }
1093
1094/* Reads the PBKDF2 parameters.
1095 */
1096static int
1097read_pbkdf2_params (ASN1_TYPE pbes2_asn,
1098 const gnutls_datum_t * der, struct pbkdf2_params *params)
1099 {
1100 int params_start, params_end;
1101 int params_len, len, result;
1102 ASN1_TYPE pbkdf2_asn = ASN1_TYPE_EMPTY;
1103 char oid[64];
1104
1105 memset (params, 0, sizeof (params));
1106
1107 /* Check the key derivation algorithm
1108 */
1109 len = sizeof (oid);
1110 result =
1111 asn1_read_value (pbes2_asn, "keyDerivationFunc.algorithm", oid, &len);
1112 if (result != ASN1_SUCCESS)
1113 {
1114 gnutls_assert ();
1115 return _gnutls_asn2err (result);
1116 }
1117 _gnutls_hard_log ("keyDerivationFunc.algorithm: %s\n", oid);
1118
1119 if (strcmp (oid, PBKDF2_OID) != 0)
1120 {
1121 gnutls_assert ();
1122 _gnutls_x509_log
1123 ("PKCS #8 key derivation OID '%s' is unsupported.\n", oid);
1124 return _gnutls_asn2err (result);
1125 }
1126
1127 result =
1128 asn1_der_decoding_startEnd (pbes2_asn, der->data, der->size,
1129 "keyDerivationFunc.parameters",
1130 &params_start, &params_end);
1131 if (result != ASN1_SUCCESS)
1132 {
1133 gnutls_assert ();
1134 return _gnutls_asn2err (result);
1135 }
1136 params_len = params_end - params_start + 1;
1137
1138 /* Now check the key derivation and the encryption
1139 * functions.
1140 */
1141 if ((result =
1142 asn1_create_element (_gnutls_get_pkix (),
1143 "PKIX1.pkcs-5-PBKDF2-params",
1144 &pbkdf2_asn)) != ASN1_SUCCESS)
1145 {
1146 gnutls_assert ();
1147 return _gnutls_asn2err (result);
1148 }
1149
1150 result =
1151 asn1_der_decoding (&pbkdf2_asn, &der->data[params_start],
1152 params_len, NULL);
1153 if (result != ASN1_SUCCESS)
1154 {
1155 gnutls_assert ();
1156 result = _gnutls_asn2err (result);
1157 goto error;
1158 }
1159
1160 /* read the salt */
1161 params->salt_size = sizeof (params->salt);
1162 result =
1163 asn1_read_value (pbkdf2_asn, "salt.specified", params->salt,
1164 &params->salt_size);
1165 if (result != ASN1_SUCCESS)
1166 {
1167 gnutls_assert ();
1168 result = _gnutls_asn2err (result);
1169 goto error;
1170 }
1171 _gnutls_hard_log ("salt.specified.size: %d\n", params->salt_size);
1172
1173 /* read the iteration count
1174 */
1175 result =
1176 _gnutls_x509_read_uint (pbkdf2_asn, "iterationCount",
1177 &params->iter_count);
1178 if (result != ASN1_SUCCESS)
1179 {
1180 gnutls_assert ();
1181 goto error;
1182 }
1183 _gnutls_hard_log ("iterationCount: %d\n", params->iter_count);
1184
1185 /* read the keylength, if it is set.
1186 */
1187 result =
1188 _gnutls_x509_read_uint (pbkdf2_asn, "keyLength", &params->key_size);
1189 if (result < 0)
1190 {
1191 params->key_size = 0;
1192 }
1193 _gnutls_hard_log ("keyLength: %d\n", params->key_size);
1194
1195 /* We don't read the PRF. We only use the default.
1196 */
1197
1198 return 0;
1199
1200 error:
1201 asn1_delete_structure (&pbkdf2_asn);
1202 return result;
1203
1204 }
1205
1206/* Reads the PBE parameters from PKCS-12 schemas (*&#%*&#% RSA).
1207 */
1208static int
1209read_pkcs12_kdf_params (ASN1_TYPE pbes2_asn, struct pbkdf2_params *params)
1210 {
1211 int result;
1212
1213 memset (params, 0, sizeof (params));
1214
1215 /* read the salt */
1216 params->salt_size = sizeof (params->salt);
1217 result =
1218 asn1_read_value (pbes2_asn, "salt", params->salt, &params->salt_size);
1219 if (result != ASN1_SUCCESS)
1220 {
1221 gnutls_assert ();
1222 result = _gnutls_asn2err (result);
1223 goto error;
1224 }
1225 _gnutls_hard_log ("salt.size: %d\n", params->salt_size);
1226
1227 /* read the iteration count
1228 */
1229 result =
1230 _gnutls_x509_read_uint (pbes2_asn, "iterations", &params->iter_count);
1231 if (result != ASN1_SUCCESS)
1232 {
1233 gnutls_assert ();
1234 goto error;
1235 }
1236 _gnutls_hard_log ("iterationCount: %d\n", params->iter_count);
1237
1238 params->key_size = 0;
1239
1240 return 0;
1241
1242 error:
1243 return result;
1244
1245 }
1246
1247/* Writes the PBE parameters for PKCS-12 schemas.
1248 */
1249static int
1250write_pkcs12_kdf_params (ASN1_TYPE pbes2_asn,
1251 const struct pbkdf2_params *kdf_params)
1252 {
1253 int result;
1254
1255 /* write the salt
1256 */
1257 result =
1258 asn1_write_value (pbes2_asn, "salt",
1259 kdf_params->salt, kdf_params->salt_size);
1260 if (result != ASN1_SUCCESS)
1261 {
1262 gnutls_assert ();
1263 result = _gnutls_asn2err (result);
1264 goto error;
1265 }
1266 _gnutls_hard_log ("salt.size: %d\n", kdf_params->salt_size);
1267
1268 /* write the iteration count
1269 */
1270 result =
1271 _gnutls_x509_write_uint32 (pbes2_asn, "iterations",
1272 kdf_params->iter_count);
1273 if (result < 0)
1274 {
1275 gnutls_assert ();
1276 goto error;
1277 }
1278 _gnutls_hard_log ("iterationCount: %d\n", kdf_params->iter_count);
1279
1280 return 0;
1281
1282 error:
1283 return result;
1284
1285 }
1286
1287/* Converts an OID to a gnutls cipher type.
1288 */
1289inline static int
1290oid2cipher (const char *oid, gnutls_cipher_algorithm_t * algo)
1291 {
1292
1293 *algo = 0;
1294
1295 if (strcmp (oid, DES_EDE3_CBC_OID) == 0)
1296 {
1297 *algo = GNUTLS_CIPHER_3DES_CBC;
1298 return 0;
1299 }
1300
1301 if (strcmp (oid, DES_CBC_OID) == 0)
1302 {
1303 *algo = GNUTLS_CIPHER_DES_CBC;
1304 return 0;
1305 }
1306
1307 _gnutls_x509_log ("PKCS #8 encryption OID '%s' is unsupported.\n", oid);
1308 return GNUTLS_E_UNKNOWN_CIPHER_TYPE;
1309 }
1310
1311static int
1312read_pbe_enc_params (ASN1_TYPE pbes2_asn,
1313 const gnutls_datum_t * der,
1314 struct pbe_enc_params *params)
1315 {
1316 int params_start, params_end;
1317 int params_len, len, result;
1318 ASN1_TYPE pbe_asn = ASN1_TYPE_EMPTY;
1319 char oid[64];
1320
1321 memset (params, 0, sizeof (params));
1322
1323 /* Check the encryption algorithm
1324 */
1325 len = sizeof (oid);
1326 result =
1327 asn1_read_value (pbes2_asn, "encryptionScheme.algorithm", oid, &len);
1328 if (result != ASN1_SUCCESS)
1329 {
1330 gnutls_assert ();
1331 goto error;
1332 }
1333 _gnutls_hard_log ("encryptionScheme.algorithm: %s\n", oid);
1334
1335 if ((result = oid2cipher (oid, &params->cipher)) < 0)
1336 {
1337 gnutls_assert ();
1338 goto error;
1339 }
1340
1341 result =
1342 asn1_der_decoding_startEnd (pbes2_asn, der->data, der->size,
1343 "encryptionScheme.parameters",
1344 &params_start, &params_end);
1345 if (result != ASN1_SUCCESS)
1346 {
1347 gnutls_assert ();
1348 return _gnutls_asn2err (result);
1349 }
1350 params_len = params_end - params_start + 1;
1351
1352 /* Now check the encryption parameters.
1353 */
1354 if ((result =
1355 asn1_create_element (_gnutls_get_pkix (),
1356 "PKIX1.pkcs-5-des-EDE3-CBC-params",
1357 &pbe_asn)) != ASN1_SUCCESS)
1358 {
1359 gnutls_assert ();
1360 return _gnutls_asn2err (result);
1361 }
1362
1363 result =
1364 asn1_der_decoding (&pbe_asn, &der->data[params_start], params_len, NULL);
1365 if (result != ASN1_SUCCESS)
1366 {
1367 gnutls_assert ();
1368 result = _gnutls_asn2err (result);
1369 goto error;
1370 }
1371
1372 /* read the IV */
1373 params->iv_size = sizeof (params->iv);
1374 result = asn1_read_value (pbe_asn, "", params->iv, &params->iv_size);
1375 if (result != ASN1_SUCCESS)
1376 {
1377 gnutls_assert ();
1378 result = _gnutls_asn2err (result);
1379 goto error;
1380 }
1381 _gnutls_hard_log ("IV.size: %d\n", params->iv_size);
1382
1383 return 0;
1384
1385 error:
1386 asn1_delete_structure (&pbe_asn);
1387 return result;
1388
1389 }
1390
1391static int
1392decrypt_data (schema_id schema, ASN1_TYPE pkcs8_asn,
1393 const char *root, const char *password,
1394 const struct pbkdf2_params *kdf_params,
1395 const struct pbe_enc_params *enc_params,
1396 gnutls_datum_t * decrypted_data)
1397 {
1398 int result;
1399 int data_size;
1400 opaque *data = NULL, *key = NULL;
1401 gnutls_datum_t dkey, d_iv;
1402 cipher_hd_t ch = NULL;
1403 int key_size;
1404
1405 data_size = 0;
1406 result = asn1_read_value (pkcs8_asn, root, NULL, &data_size);
1407 if (result != ASN1_MEM_ERROR)
1408 {
1409 gnutls_assert ();
1410 return _gnutls_asn2err (result);
1411 }
1412
1413 data = gnutls_malloc (data_size);
1414 if (data == NULL)
1415 {
1416 gnutls_assert ();
1417 return GNUTLS_E_MEMORY_ERROR;
1418 }
1419
1420 result = asn1_read_value (pkcs8_asn, root, data, &data_size);
1421 if (result != ASN1_SUCCESS)
1422 {
1423 gnutls_assert ();
1424 result = _gnutls_asn2err (result);
1425 goto error;
1426 }
1427
1428 if (kdf_params->key_size == 0)
1429 {
1430 key_size = gnutls_cipher_get_key_size (enc_params->cipher);
1431 }
1432 else
1433 key_size = kdf_params->key_size;
1434
1435 key = gnutls_alloca (key_size);
1436 if (key == NULL)
1437 {
1438 gnutls_assert ();
1439 result = GNUTLS_E_MEMORY_ERROR;
1440 goto error;
1441 }
1442
1443 /* generate the key
1444 */
1445 if (schema == PBES2)
1446 {
1447 result = gc_pbkdf2_sha1 (password, strlen (password),
1448 kdf_params->salt, kdf_params->salt_size,
1449 kdf_params->iter_count, key, key_size);
1450
1451 if (result != GC_OK)
1452 {
1453 gnutls_assert ();
1454 result = GNUTLS_E_DECRYPTION_FAILED;
1455 goto error;
1456 }
1457 }
1458 else
1459 {
1460 result =
1461 _pkcs12_string_to_key (1 /*KEY*/, kdf_params->salt,
1462 kdf_params->salt_size,
1463 kdf_params->iter_count, password,
1464 key_size, key);
1465
1466 if (result < 0)
1467 {
1468 gnutls_assert ();
1469 goto error;
1470 }
1471 }
1472
1473 /* do the decryption.
1474 */
1475 dkey.data = key;
1476 dkey.size = key_size;
1477
1478 d_iv.data = (opaque *) enc_params->iv;
1479 d_iv.size = enc_params->iv_size;
1480 ch = _gnutls_cipher_init (enc_params->cipher, &dkey, &d_iv);
1481
1482 gnutls_afree (key);
1483 key = NULL;
1484
1485 if (ch == NULL)
1486 {
1487 gnutls_assert ();
1488 result = GNUTLS_E_DECRYPTION_FAILED;
1489 goto error;
1490 }
1491
1492 result = _gnutls_cipher_decrypt (ch, data, data_size);
1493 if (result < 0)
1494 {
1495 gnutls_assert ();
1496 goto error;
1497 }
1498
1499 decrypted_data->data = data;
1500
1501 if (_gnutls_cipher_get_block_size (enc_params->cipher) != 1)
1502 decrypted_data->size = data_size - data[data_size - 1];
1503 else
1504 decrypted_data->size = data_size;
1505
1506 _gnutls_cipher_deinit (ch);
1507
1508 return 0;
1509
1510 error:
1511 gnutls_free (data);
1512 gnutls_afree (key);
1513 if (ch != NULL)
1514 _gnutls_cipher_deinit (ch);
1515 return result;
1516 }
1517
1518/* Writes the PBKDF2 parameters.
1519 */
1520static int
1521write_pbkdf2_params (ASN1_TYPE pbes2_asn,
1522 const struct pbkdf2_params *kdf_params)
1523 {
1524 int result;
1525 ASN1_TYPE pbkdf2_asn = ASN1_TYPE_EMPTY;
1526 opaque tmp[64];
1527
1528 /* Write the key derivation algorithm
1529 */
1530 result =
1531 asn1_write_value (pbes2_asn, "keyDerivationFunc.algorithm",
1532 PBKDF2_OID, 1);
1533 if (result != ASN1_SUCCESS)
1534 {
1535 gnutls_assert ();
1536 return _gnutls_asn2err (result);
1537 }
1538
1539 /* Now write the key derivation and the encryption
1540 * functions.
1541 */
1542 if ((result =
1543 asn1_create_element (_gnutls_get_pkix (),
1544 "PKIX1.pkcs-5-PBKDF2-params",
1545 &pbkdf2_asn)) != ASN1_SUCCESS)
1546 {
1547 gnutls_assert ();
1548 return _gnutls_asn2err (result);
1549 }
1550
1551 result = asn1_write_value (pbkdf2_asn, "salt", "specified", 1);
1552 if (result != ASN1_SUCCESS)
1553 {
1554 gnutls_assert ();
1555 result = _gnutls_asn2err (result);
1556 goto error;
1557 }
1558
1559 /* write the salt
1560 */
1561 result =
1562 asn1_write_value (pbkdf2_asn, "salt.specified",
1563 kdf_params->salt, kdf_params->salt_size);
1564 if (result != ASN1_SUCCESS)
1565 {
1566 gnutls_assert ();
1567 result = _gnutls_asn2err (result);
1568 goto error;
1569 }
1570 _gnutls_hard_log ("salt.specified.size: %d\n", kdf_params->salt_size);
1571
1572 /* write the iteration count
1573 */
1574 _gnutls_write_uint32 (kdf_params->iter_count, tmp);
1575
1576 result = asn1_write_value (pbkdf2_asn, "iterationCount", tmp, 4);
1577 if (result != ASN1_SUCCESS)
1578 {
1579 gnutls_assert ();
1580 result = _gnutls_asn2err (result);
1581 goto error;
1582 }
1583 _gnutls_hard_log ("iterationCount: %d\n", kdf_params->iter_count);
1584
1585 /* write the keylength, if it is set.
1586 */
1587 result = asn1_write_value (pbkdf2_asn, "keyLength", NULL, 0);
1588 if (result != ASN1_SUCCESS)
1589 {
1590 gnutls_assert ();
1591 result = _gnutls_asn2err (result);
1592 goto error;
1593 }
1594
1595 /* We write an emptry prf.
1596 */
1597 result = asn1_write_value (pbkdf2_asn, "prf", NULL, 0);
1598 if (result != ASN1_SUCCESS)
1599 {
1600 gnutls_assert ();
1601 result = _gnutls_asn2err (result);
1602 goto error;
1603 }
1604
1605 /* now encode them an put the DER output
1606 * in the keyDerivationFunc.parameters
1607 */
1608 result = _gnutls_x509_der_encode_and_copy (pbkdf2_asn, "",
1609 pbes2_asn,
1610 "keyDerivationFunc.parameters",
1611 0);
1612 if (result < 0)
1613 {
1614 gnutls_assert ();
1615 goto error;
1616 }
1617
1618 return 0;
1619
1620 error:
1621 asn1_delete_structure (&pbkdf2_asn);
1622 return result;
1623
1624 }
1625
1626static int
1627write_pbe_enc_params (ASN1_TYPE pbes2_asn,
1628 const struct pbe_enc_params *params)
1629 {
1630 int result;
1631 ASN1_TYPE pbe_asn = ASN1_TYPE_EMPTY;
1632
1633 /* Write the encryption algorithm
1634 */
1635 result =
1636 asn1_write_value (pbes2_asn, "encryptionScheme.algorithm",
1637 DES_EDE3_CBC_OID, 1);
1638 if (result != ASN1_SUCCESS)
1639 {
1640 gnutls_assert ();
1641 goto error;
1642 }
1643 _gnutls_hard_log ("encryptionScheme.algorithm: %s\n", DES_EDE3_CBC_OID);
1644
1645 /* Now check the encryption parameters.
1646 */
1647 if ((result =
1648 asn1_create_element (_gnutls_get_pkix (),
1649 "PKIX1.pkcs-5-des-EDE3-CBC-params",
1650 &pbe_asn)) != ASN1_SUCCESS)
1651 {
1652 gnutls_assert ();
1653 return _gnutls_asn2err (result);
1654 }
1655
1656 /* read the salt */
1657 result = asn1_write_value (pbe_asn, "", params->iv, params->iv_size);
1658 if (result != ASN1_SUCCESS)
1659 {
1660 gnutls_assert ();
1661 result = _gnutls_asn2err (result);
1662 goto error;
1663 }
1664 _gnutls_hard_log ("IV.size: %d\n", params->iv_size);
1665
1666 /* now encode them an put the DER output
1667 * in the encryptionScheme.parameters
1668 */
1669 result = _gnutls_x509_der_encode_and_copy (pbe_asn, "",
1670 pbes2_asn,
1671 "encryptionScheme.parameters",
1672 0);
1673 if (result < 0)
1674 {
1675 gnutls_assert ();
1676 goto error;
1677 }
1678
1679 return 0;
1680
1681 error:
1682 asn1_delete_structure (&pbe_asn);
1683 return result;
1684
1685 }
1686
1687/* Generates a key and also stores the key parameters.
1688 */
1689static int
1690generate_key (schema_id schema,
1691 const char *password,
1692 struct pbkdf2_params *kdf_params,
1693 struct pbe_enc_params *enc_params, gnutls_datum_t * key)
1694 {
1695 opaque rnd[2];
1696 int ret;
1697
1698 /* We should use the flags here to use different
1699 * encryption algorithms etc.
1700 */
1701
1702 if (schema == PKCS12_ARCFOUR_SHA1)
1703 enc_params->cipher = GNUTLS_CIPHER_ARCFOUR_128;
1704 else if (schema == PKCS12_3DES_SHA1)
1705 enc_params->cipher = GNUTLS_CIPHER_3DES_CBC;
1706 else if (schema == PKCS12_RC2_40_SHA1)
1707 enc_params->cipher = GNUTLS_CIPHER_RC2_40_CBC;
1708
1709 if (gc_pseudo_random (rnd, 2) != GC_OK)
1710 {
1711 gnutls_assert ();
1712 return GNUTLS_E_RANDOM_FAILED;
1713 }
1714
1715 /* generate salt */
1716
1717 if (schema == PBES2)
1718 {
1719 kdf_params->salt_size = MIN (sizeof (kdf_params->salt), (unsigned) (10 + (rnd[1] % 10)));
1720 }
1721 else
1722 kdf_params->salt_size = 8;
1723
1724 if (gc_pseudo_random (kdf_params->salt, kdf_params->salt_size) != GC_OK)
1725 {
1726 gnutls_assert ();
1727 return GNUTLS_E_RANDOM_FAILED;
1728 }
1729
1730 kdf_params->iter_count = 256 + rnd[0];
1731 key->size = kdf_params->key_size =
1732 gnutls_cipher_get_key_size (enc_params->cipher);
1733
1734 enc_params->iv_size = _gnutls_cipher_get_iv_size (enc_params->cipher);
1735
1736 key->data = gnutls_secure_malloc (key->size);
1737 if (key->data == NULL)
1738 {
1739 gnutls_assert ();
1740 return GNUTLS_E_MEMORY_ERROR;
1741 }
1742
1743 /* now generate the key.
1744 */
1745
1746 if (schema == PBES2)
1747 {
1748
1749 ret = gc_pbkdf2_sha1 (password, strlen (password),
1750 kdf_params->salt, kdf_params->salt_size,
1751 kdf_params->iter_count,
1752 key->data, kdf_params->key_size);
1753 if (ret != GC_OK)
1754 {
1755 gnutls_assert ();
1756 return GNUTLS_E_ENCRYPTION_FAILED;
1757 }
1758
1759 if (enc_params->iv_size &&
1760 gc_nonce (enc_params->iv, enc_params->iv_size) != GC_OK)
1761 {
1762 gnutls_assert ();
1763 return GNUTLS_E_RANDOM_FAILED;
1764 }
1765 }
1766 else
1767 { /* PKCS12 schemas */
1768 ret =
1769 _pkcs12_string_to_key (1 /*KEY*/, kdf_params->salt,
1770 kdf_params->salt_size,
1771 kdf_params->iter_count, password,
1772 kdf_params->key_size, key->data);
1773 if (ret < 0)
1774 {
1775 gnutls_assert ();
1776 return ret;
1777 }
1778
1779 /* Now generate the IV
1780 */
1781 if (enc_params->iv_size)
1782 {
1783 ret =
1784 _pkcs12_string_to_key (2 /*IV*/, kdf_params->salt,
1785 kdf_params->salt_size,
1786 kdf_params->iter_count, password,
1787 enc_params->iv_size, enc_params->iv);
1788 if (ret < 0)
1789 {
1790 gnutls_assert ();
1791 return ret;
1792 }
1793 }
1794 }
1795
1796 return 0;
1797 }
1798
1799/* Encodes the parameters to be written in the encryptionAlgorithm.parameters
1800 * part.
1801 */
1802static int
1803write_schema_params (schema_id schema, ASN1_TYPE pkcs8_asn,
1804 const char *where,
1805 const struct pbkdf2_params *kdf_params,
1806 const struct pbe_enc_params *enc_params)
1807 {
1808 int result;
1809 ASN1_TYPE pbes2_asn = ASN1_TYPE_EMPTY;
1810
1811 if (schema == PBES2)
1812 {
1813 if ((result =
1814 asn1_create_element (_gnutls_get_pkix (),
1815 "PKIX1.pkcs-5-PBES2-params",
1816 &pbes2_asn)) != ASN1_SUCCESS)
1817 {
1818 gnutls_assert ();
1819 return _gnutls_asn2err (result);
1820 }
1821
1822 result = write_pbkdf2_params (pbes2_asn, kdf_params);
1823 if (result < 0)
1824 {
1825 gnutls_assert ();
1826 goto error;
1827 }
1828
1829 result = write_pbe_enc_params (pbes2_asn, enc_params);
1830 if (result < 0)
1831 {
1832 gnutls_assert ();
1833 goto error;
1834 }
1835
1836 result = _gnutls_x509_der_encode_and_copy (pbes2_asn, "",
1837 pkcs8_asn, where, 0);
1838 if (result < 0)
1839 {
1840 gnutls_assert ();
1841 goto error;
1842 }
1843
1844 asn1_delete_structure (&pbes2_asn);
1845 }
1846 else
1847 { /* PKCS12 schemas */
1848
1849 if ((result =
1850 asn1_create_element (_gnutls_get_pkix (),
1851 "PKIX1.pkcs-12-PbeParams",
1852 &pbes2_asn)) != ASN1_SUCCESS)
1853 {
1854 gnutls_assert ();
1855 result = _gnutls_asn2err (result);
1856 goto error;
1857 }
1858
1859 result = write_pkcs12_kdf_params (pbes2_asn, kdf_params);
1860 if (result < 0)
1861 {
1862 gnutls_assert ();
1863 goto error;
1864 }
1865
1866 result = _gnutls_x509_der_encode_and_copy (pbes2_asn, "",
1867 pkcs8_asn, where, 0);
1868 if (result < 0)
1869 {
1870 gnutls_assert ();
1871 goto error;
1872 }
1873
1874 asn1_delete_structure (&pbes2_asn);
1875
1876 }
1877
1878 return 0;
1879
1880 error:
1881 asn1_delete_structure (&pbes2_asn);
1882 return result;
1883
1884 }
1885
1886static int
1887encrypt_data (const gnutls_datum_t * plain,
1888 const struct pbe_enc_params *enc_params,
1889 gnutls_datum_t * key, gnutls_datum_t * encrypted)
1890 {
1891 int result;
1892 int data_size;
1893 opaque *data = NULL;
1894 gnutls_datum_t d_iv;
1895 cipher_hd_t ch = NULL;
1896 opaque pad, pad_size;
1897
1898 pad_size = _gnutls_cipher_get_block_size (enc_params->cipher);
1899
1900 if (pad_size == 1) /* stream */
1901 pad_size = 0;
1902
1903 data = gnutls_malloc (plain->size + pad_size);
1904 if (data == NULL)
1905 {
1906 gnutls_assert ();
1907 return GNUTLS_E_MEMORY_ERROR;
1908 }
1909
1910 memcpy (data, plain->data, plain->size);
1911
1912 if (pad_size> 0)
1913 {
1914 pad = pad_size - (plain->size % pad_size);
1915 if (pad == 0)
1916 pad = pad_size;
1917 memset (&data[plain->size], pad, pad);
1918 }
1919 else
1920 pad = 0;
1921
1922 data_size = plain->size + pad;
1923
1924 d_iv.data = (opaque *) enc_params->iv;
1925 d_iv.size = enc_params->iv_size;
1926 ch = _gnutls_cipher_init (enc_params->cipher, key, &d_iv);
1927
1928 if (ch == GNUTLS_CIPHER_FAILED)
1929 {
1930 gnutls_assert ();
1931 result = GNUTLS_E_ENCRYPTION_FAILED;
1932 goto error;
1933 }
1934
1935 result = _gnutls_cipher_encrypt (ch, data, data_size);
1936 if (result < 0)
1937 {
1938 gnutls_assert ();
1939 goto error;
1940 }
1941
1942 encrypted->data = data;
1943 encrypted->size = data_size;
1944
1945 _gnutls_cipher_deinit (ch);
1946
1947 return 0;
1948
1949 error:
1950 gnutls_free (data);
1951 if (ch != NULL)
1952 _gnutls_cipher_deinit (ch);
1953 return result;
1954 }
1955
1956/* Decrypts a PKCS #7 encryptedData. The output is allocated
1957 * and stored in dec.
1958 */
1959int
1960_gnutls_pkcs7_decrypt_data (const gnutls_datum_t * data,
1961 const char *password, gnutls_datum_t * dec)
1962 {
1963 int result, len;
1964 char enc_oid[64];
1965 gnutls_datum_t tmp;
1966 ASN1_TYPE pbes2_asn = ASN1_TYPE_EMPTY, pkcs7_asn = ASN1_TYPE_EMPTY;
1967 int params_start, params_end, params_len;
1968 struct pbkdf2_params kdf_params;
1969 struct pbe_enc_params enc_params;
1970 schema_id schema;
1971
1972 if ((result =
1973 asn1_create_element (_gnutls_get_pkix (),
1974 "PKIX1.pkcs-7-EncryptedData",
1975 &pkcs7_asn)) != ASN1_SUCCESS)
1976 {
1977 gnutls_assert ();
1978 result = _gnutls_asn2err (result);
1979 goto error;
1980 }
1981
1982 result = asn1_der_decoding (&pkcs7_asn, data->data, data->size, NULL);
1983 if (result != ASN1_SUCCESS)
1984 {
1985 gnutls_assert ();
1986 result = _gnutls_asn2err (result);
1987 goto error;
1988 }
1989
1990 /* Check the encryption schema OID
1991 */
1992 len = sizeof (enc_oid);
1993 result =
1994 asn1_read_value (pkcs7_asn,
1995 "encryptedContentInfo.contentEncryptionAlgorithm.algorithm",
1996 enc_oid, &len);
1997 if (result != ASN1_SUCCESS)
1998 {
1999 gnutls_assert ();
2000 result = _gnutls_asn2err (result);
2001 goto error;
2002 }
2003
2004 if ((result = check_schema (enc_oid)) < 0)
2005 {
2006 gnutls_assert ();
2007 goto error;
2008 }
2009 schema = result;
2010
2011 /* Get the DER encoding of the parameters.
2012 */
2013 result =
2014 asn1_der_decoding_startEnd (pkcs7_asn, data->data, data->size,
2015 "encryptedContentInfo.contentEncryptionAlgorithm.parameters",
2016 &params_start, &params_end);
2017 if (result != ASN1_SUCCESS)
2018 {
2019 gnutls_assert ();
2020 result = _gnutls_asn2err (result);
2021 goto error;
2022 }
2023 params_len = params_end - params_start + 1;
2024
2025 result =
2026 read_pkcs_schema_params (schema, password,
2027 &data->data[params_start],
2028 params_len, &kdf_params, &enc_params);
2029 if (result < ASN1_SUCCESS)
2030 {
2031 gnutls_assert ();
2032 result = _gnutls_asn2err (result);
2033 goto error;
2034 }
2035
2036 /* Parameters have been decoded. Now
2037 * decrypt the EncryptedData.
2038 */
2039
2040 result =
2041 decrypt_data (schema, pkcs7_asn,
2042 "encryptedContentInfo.encryptedContent", password,
2043 &kdf_params, &enc_params, &tmp);
2044 if (result < 0)
2045 {
2046 gnutls_assert ();
2047 goto error;
2048 }
2049
2050 asn1_delete_structure (&pkcs7_asn);
2051
2052 *dec = tmp;
2053
2054 return 0;
2055
2056 error:
2057 asn1_delete_structure (&pbes2_asn);
2058 asn1_delete_structure (&pkcs7_asn);
2059 return result;
2060 }
2061
2062/* Encrypts to a PKCS #7 encryptedData. The output is allocated
2063 * and stored in enc.
2064 */
2065int
2066_gnutls_pkcs7_encrypt_data (schema_id schema,
2067 const gnutls_datum_t * data,
2068 const char *password, gnutls_datum_t * enc)
2069 {
2070 int result;
2071 gnutls_datum_t key =
2072 { NULL, 0};
2073 gnutls_datum_t tmp =
2074 { NULL, 0};
2075 ASN1_TYPE pkcs7_asn = ASN1_TYPE_EMPTY;
2076 struct pbkdf2_params kdf_params;
2077 struct pbe_enc_params enc_params;
2078
2079 if ((result =
2080 asn1_create_element (_gnutls_get_pkix (),
2081 "PKIX1.pkcs-7-EncryptedData",
2082 &pkcs7_asn)) != ASN1_SUCCESS)
2083 {
2084 gnutls_assert ();
2085 result = _gnutls_asn2err (result);
2086 goto error;
2087 }
2088
2089 /* Write the encryption schema OID
2090 */
2091 switch (schema)
2092 {
2093 case PBES2:
2094 result =
2095 asn1_write_value (pkcs7_asn,
2096 "encryptedContentInfo.contentEncryptionAlgorithm.algorithm",
2097 PBES2_OID, 1);
2098 break;
2099 case PKCS12_3DES_SHA1:
2100 result =
2101 asn1_write_value (pkcs7_asn,
2102 "encryptedContentInfo.contentEncryptionAlgorithm.algorithm",
2103 PKCS12_PBE_3DES_SHA1_OID, 1);
2104 break;
2105 case PKCS12_ARCFOUR_SHA1:
2106 result =
2107 asn1_write_value (pkcs7_asn,
2108 "encryptedContentInfo.contentEncryptionAlgorithm.algorithm",
2109 PKCS12_PBE_ARCFOUR_SHA1_OID, 1);
2110 break;
2111 case PKCS12_RC2_40_SHA1:
2112 result =
2113 asn1_write_value (pkcs7_asn,
2114 "encryptedContentInfo.contentEncryptionAlgorithm.algorithm",
2115 PKCS12_PBE_RC2_40_SHA1_OID, 1);
2116 break;
2117
2118 }
2119
2120 if (result != ASN1_SUCCESS)
2121 {
2122 gnutls_assert ();
2123 result = _gnutls_asn2err (result);
2124 goto error;
2125 }
2126
2127 /* Generate a symmetric key.
2128 */
2129
2130 result = generate_key (schema, password, &kdf_params, &enc_params, &key);
2131 if (result < 0)
2132 {
2133 gnutls_assert ();
2134 goto error;
2135 }
2136
2137 result = write_schema_params (schema, pkcs7_asn,
2138 "encryptedContentInfo.contentEncryptionAlgorithm.parameters",
2139 &kdf_params, &enc_params);
2140 if (result < 0)
2141 {
2142 gnutls_assert ();
2143 goto error;
2144 }
2145
2146 /* Parameters have been encoded. Now
2147 * encrypt the Data.
2148 */
2149 result = encrypt_data (data, &enc_params, &key, &tmp);
2150 if (result < 0)
2151 {
2152 gnutls_assert ();
2153 goto error;
2154 }
2155
2156 /* write the encrypted data.
2157 */
2158 result =
2159 asn1_write_value (pkcs7_asn,
2160 "encryptedContentInfo.encryptedContent", tmp.data,
2161 tmp.size);
2162 if (result != ASN1_SUCCESS)
2163 {
2164 gnutls_assert ();
2165 result = _gnutls_asn2err (result);
2166 goto error;
2167 }
2168
2169 _gnutls_free_datum (&tmp);
2170 _gnutls_free_datum (&key);
2171
2172 /* Now write the rest of the pkcs-7 stuff.
2173 */
2174
2175 result = _gnutls_x509_write_uint32 (pkcs7_asn, "version", 0);
2176 if (result < 0)
2177 {
2178 gnutls_assert ();
2179 goto error;
2180 }
2181
2182 result =
2183 asn1_write_value (pkcs7_asn, "encryptedContentInfo.contentType",
2184 DATA_OID, 1);
2185 if (result != ASN1_SUCCESS)
2186 {
2187 gnutls_assert ();
2188 result = _gnutls_asn2err (result);
2189 goto error;
2190 }
2191
2192 result = asn1_write_value (pkcs7_asn, "unprotectedAttrs", NULL, 0);
2193 if (result != ASN1_SUCCESS)
2194 {
2195 gnutls_assert ();
2196 result = _gnutls_asn2err (result);
2197 goto error;
2198 }
2199
2200 /* Now encode and copy the DER stuff.
2201 */
2202 result = _gnutls_x509_der_encode (pkcs7_asn, "", enc, 0);
2203
2204 asn1_delete_structure (&pkcs7_asn);
2205
2206 if (result < 0)
2207 {
2208 gnutls_assert ();
2209 goto error;
2210 }
2211
2212 error:
2213 _gnutls_free_datum (&key);
2214 _gnutls_free_datum (&tmp);
2215 asn1_delete_structure (&pkcs7_asn);
2216 return result;
2217 }
2218
2219#endif
diff --git a/src/daemon/https/x509/rfc2818.h b/src/daemon/https/x509/rfc2818.h
new file mode 100644
index 00000000..c3399145
--- /dev/null
+++ b/src/daemon/https/x509/rfc2818.h
@@ -0,0 +1,26 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25int _gnutls_hostname_compare (const char *certname, const char *hostname);
26#define MAX_CN 256
diff --git a/src/daemon/https/x509/rfc2818_hostname.c b/src/daemon/https/x509/rfc2818_hostname.c
new file mode 100644
index 00000000..93a96589
--- /dev/null
+++ b/src/daemon/https/x509/rfc2818_hostname.c
@@ -0,0 +1,160 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation
3 * Copyright (C) 2002 Andrew McDonald
4 *
5 * This file is part of GNUTLS.
6 *
7 * The GNUTLS library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 * USA
21 *
22 */
23
24#include <gnutls_int.h>
25#include <x509.h>
26#include <dn.h>
27#include <common.h>
28#include <rfc2818.h>
29#include <gnutls_errors.h>
30
31/* compare hostname against certificate, taking account of wildcards
32 * return 1 on success or 0 on error
33 */
34int
35_gnutls_hostname_compare (const char *certname, const char *hostname)
36{
37 const char *cmpstr1, *cmpstr2;
38
39 if (strlen (certname) == 0 || strlen (hostname) == 0)
40 return 0;
41
42 if (strlen (certname) > 2 && strncmp (certname, "*.", 2) == 0)
43 {
44 /* a wildcard certificate */
45
46 cmpstr1 = certname + 1;
47
48 /* find the first dot in hostname, compare from there on */
49 cmpstr2 = strchr (hostname, '.');
50
51 if (cmpstr2 == NULL)
52 {
53 /* error, the hostname we're connecting to is only a local part */
54 return 0;
55 }
56
57 if (strcasecmp (cmpstr1, cmpstr2) == 0)
58 {
59 return 1;
60 }
61
62 return 0;
63 }
64
65 if (strcasecmp (certname, hostname) == 0)
66 {
67 return 1;
68 }
69
70 return 0;
71}
72
73/**
74 * gnutls_x509_crt_check_hostname - This function compares the given hostname with the hostname in the certificate
75 * @cert: should contain an gnutls_x509_crt_t structure
76 * @hostname: A null terminated string that contains a DNS name
77 *
78 * This function will check if the given certificate's subject
79 * matches the given hostname. This is a basic implementation of the
80 * matching described in RFC2818 (HTTPS), which takes into account
81 * wildcards, and the DNSName/IPAddress subject alternative name PKIX
82 * extension.
83 *
84 * Returns non zero for a successful match, and zero on failure.
85 **/
86int
87gnutls_x509_crt_check_hostname (gnutls_x509_crt_t cert, const char *hostname)
88{
89
90 char dnsname[MAX_CN];
91 size_t dnsnamesize;
92 int found_dnsname = 0;
93 int ret = 0;
94 int i = 0;
95
96 /* try matching against:
97 * 1) a DNS name as an alternative name (subjectAltName) extension
98 * in the certificate
99 * 2) the common name (CN) in the certificate
100 *
101 * either of these may be of the form: *.domain.tld
102 *
103 * only try (2) if there is no subjectAltName extension of
104 * type dNSName
105 */
106
107 /* Check through all included subjectAltName extensions, comparing
108 * against all those of type dNSName.
109 */
110 for (i = 0; !(ret < 0); i++)
111 {
112
113 dnsnamesize = sizeof (dnsname);
114 ret = gnutls_x509_crt_get_subject_alt_name (cert, i,
115 dnsname, &dnsnamesize,
116 NULL);
117
118 if (ret == GNUTLS_SAN_DNSNAME)
119 {
120 found_dnsname = 1;
121 if (_gnutls_hostname_compare (dnsname, hostname))
122 {
123 return 1;
124 }
125 }
126 else if (ret == GNUTLS_SAN_IPADDRESS)
127 {
128 found_dnsname = 1; /* RFC 2818 is unclear whether the CN
129 should be compared for IP addresses
130 too, but we won't do it. */
131 if (_gnutls_hostname_compare (dnsname, hostname))
132 {
133 return 1;
134 }
135 }
136 }
137
138 if (!found_dnsname)
139 {
140 /* not got the necessary extension, use CN instead
141 */
142 dnsnamesize = sizeof (dnsname);
143 if (gnutls_x509_crt_get_dn_by_oid (cert, OID_X520_COMMON_NAME, 0,
144 0, dnsname, &dnsnamesize) < 0)
145 {
146 /* got an error, can't find a name
147 */
148 return 0;
149 }
150
151 if (_gnutls_hostname_compare (dnsname, hostname))
152 {
153 return 1;
154 }
155 }
156
157 /* not found a matching name
158 */
159 return 0;
160}
diff --git a/src/daemon/https/x509/sign.c b/src/daemon/https/x509/sign.c
new file mode 100644
index 00000000..275fc3f7
--- /dev/null
+++ b/src/daemon/https/x509/sign.c
@@ -0,0 +1,346 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* All functions which relate to X.509 certificate signing stuff are
26 * included here
27 */
28
29#include <gnutls_int.h>
30
31#ifdef ENABLE_PKI
32
33#include <gnutls_errors.h>
34#include <gnutls_cert.h>
35#include <libtasn1.h>
36#include <gnutls_global.h>
37#include <gnutls_num.h> /* MAX */
38#include <gnutls_sig.h>
39#include <gnutls_str.h>
40#include <gnutls_datum.h>
41#include <dn.h>
42#include <x509.h>
43#include <mpi.h>
44#include <sign.h>
45#include <common.h>
46#include <verify.h>
47
48/* Writes the digest information and the digest in a DER encoded
49 * structure. The digest info is allocated and stored into the info structure.
50 */
51static int
52encode_ber_digest_info (gnutls_digest_algorithm_t hash,
53 const gnutls_datum_t * digest, gnutls_datum_t * info)
54{
55 ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
56 int result;
57 const char *algo;
58
59 algo = _gnutls_x509_mac_to_oid ((gnutls_mac_algorithm_t) hash);
60 if (algo == NULL)
61 {
62 gnutls_assert ();
63 _gnutls_x509_log ("Hash algorithm: %d\n", hash);
64 return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
65 }
66
67 if ((result = asn1_create_element (_gnutls_get_gnutls_asn (),
68 "GNUTLS.DigestInfo",
69 &dinfo)) != ASN1_SUCCESS)
70 {
71 gnutls_assert ();
72 return _gnutls_asn2err (result);
73 }
74
75 result = asn1_write_value (dinfo, "digestAlgorithm.algorithm", algo, 1);
76 if (result != ASN1_SUCCESS)
77 {
78 gnutls_assert ();
79 asn1_delete_structure (&dinfo);
80 return _gnutls_asn2err (result);
81 }
82
83 /* Write an ASN.1 NULL in the parameters field. This matches RFC
84 3279 and RFC 4055, although is arguable incorrect from a historic
85 perspective (see those documents for more information).
86 Regardless of what is correct, this appears to be what most
87 implementations do. */
88 result = asn1_write_value (dinfo, "digestAlgorithm.parameters",
89 "\x05\x00", 2);
90 if (result != ASN1_SUCCESS)
91 {
92 gnutls_assert ();
93 asn1_delete_structure (&dinfo);
94 return _gnutls_asn2err (result);
95 }
96
97 result = asn1_write_value (dinfo, "digest", digest->data, digest->size);
98 if (result != ASN1_SUCCESS)
99 {
100 gnutls_assert ();
101 asn1_delete_structure (&dinfo);
102 return _gnutls_asn2err (result);
103 }
104
105 info->size = 0;
106 asn1_der_coding (dinfo, "", NULL, &info->size, NULL);
107
108 info->data = gnutls_malloc (info->size);
109 if (info->data == NULL)
110 {
111 gnutls_assert ();
112 asn1_delete_structure (&dinfo);
113 return GNUTLS_E_MEMORY_ERROR;
114 }
115
116 result = asn1_der_coding (dinfo, "", info->data, &info->size, NULL);
117 if (result != ASN1_SUCCESS)
118 {
119 gnutls_assert ();
120 asn1_delete_structure (&dinfo);
121 return _gnutls_asn2err (result);
122 }
123
124 asn1_delete_structure (&dinfo);
125
126 return 0;
127}
128
129/* if hash==MD5 then we do RSA-MD5
130 * if hash==SHA then we do RSA-SHA
131 * params[0] is modulus
132 * params[1] is public key
133 */
134static int
135pkcs1_rsa_sign (gnutls_digest_algorithm_t hash, const gnutls_datum_t * text,
136 mpi_t * params, int params_len, gnutls_datum_t * signature)
137{
138 int ret;
139 opaque _digest[MAX_HASH_SIZE];
140 GNUTLS_HASH_HANDLE hd;
141 gnutls_datum_t digest, info;
142
143 hd = _gnutls_hash_init (HASH2MAC (hash));
144 if (hd == NULL)
145 {
146 gnutls_assert ();
147 return GNUTLS_E_HASH_FAILED;
148 }
149
150 _gnutls_hash (hd, text->data, text->size);
151 _gnutls_hash_deinit (hd, _digest);
152
153 digest.data = _digest;
154 digest.size = _gnutls_hash_get_algo_len (HASH2MAC (hash));
155
156 /* Encode the digest as a DigestInfo
157 */
158 if ((ret = encode_ber_digest_info (hash, &digest, &info)) != 0)
159 {
160 gnutls_assert ();
161 return ret;
162 }
163
164 if ((ret =
165 _gnutls_sign (GNUTLS_PK_RSA, params, params_len, &info,
166 signature)) < 0)
167 {
168 gnutls_assert ();
169 _gnutls_free_datum (&info);
170 return ret;
171 }
172
173 _gnutls_free_datum (&info);
174
175 return 0;
176}
177
178/* Signs the given data using the parameters from the signer's
179 * private key.
180 *
181 * returns 0 on success.
182 *
183 * 'tbs' is the data to be signed
184 * 'signature' will hold the signature!
185 * 'hash' is only used in PKCS1 RSA signing.
186 */
187int
188_gnutls_x509_sign (const gnutls_datum_t * tbs,
189 gnutls_digest_algorithm_t hash,
190 gnutls_x509_privkey_t signer, gnutls_datum_t * signature)
191{
192 int ret;
193
194 switch (signer->pk_algorithm)
195 {
196 case GNUTLS_PK_RSA:
197 ret =
198 pkcs1_rsa_sign (hash, tbs, signer->params, signer->params_size,
199 signature);
200 if (ret < 0)
201 {
202 gnutls_assert ();
203 return ret;
204 }
205 return 0;
206 break;
207 default:
208 gnutls_assert ();
209 return GNUTLS_E_INTERNAL_ERROR;
210 }
211
212}
213
214/* This is the same as the _gnutls_x509_sign, but this one will decode
215 * the ASN1_TYPE given, and sign the DER data. Actually used to get the DER
216 * of the TBS and sign it on the fly.
217 */
218int
219_gnutls_x509_sign_tbs (ASN1_TYPE cert, const char *tbs_name,
220 gnutls_digest_algorithm_t hash,
221 gnutls_x509_privkey_t signer,
222 gnutls_datum_t * signature)
223{
224 int result;
225 opaque *buf;
226 int buf_size;
227 gnutls_datum_t tbs;
228
229 buf_size = 0;
230 asn1_der_coding (cert, tbs_name, NULL, &buf_size, NULL);
231
232 buf = gnutls_alloca (buf_size);
233 if (buf == NULL)
234 {
235 gnutls_assert ();
236 return GNUTLS_E_MEMORY_ERROR;
237 }
238
239 result = asn1_der_coding (cert, tbs_name, buf, &buf_size, NULL);
240
241 if (result != ASN1_SUCCESS)
242 {
243 gnutls_assert ();
244 gnutls_afree (buf);
245 return _gnutls_asn2err (result);
246 }
247
248 tbs.data = buf;
249 tbs.size = buf_size;
250
251 result = _gnutls_x509_sign (&tbs, hash, signer, signature);
252 gnutls_afree (buf);
253
254 return result;
255}
256
257/*-
258 * _gnutls_x509_pkix_sign - This function will sign a CRL or a certificate with a key
259 * @src: should contain an ASN1_TYPE
260 * @issuer: is the certificate of the certificate issuer
261 * @issuer_key: holds the issuer's private key
262 *
263 * This function will sign a CRL or a certificate with the issuer's private key, and
264 * will copy the issuer's information into the CRL or certificate.
265 *
266 * Returns 0 on success.
267 *
268 -*/
269int
270_gnutls_x509_pkix_sign (ASN1_TYPE src, const char *src_name,
271 gnutls_digest_algorithm_t dig,
272 gnutls_x509_crt_t issuer,
273 gnutls_x509_privkey_t issuer_key)
274{
275 int result;
276 gnutls_datum_t signature;
277 char name[128];
278
279 /* Step 1. Copy the issuer's name into the certificate.
280 */
281 _gnutls_str_cpy (name, sizeof (name), src_name);
282 _gnutls_str_cat (name, sizeof (name), ".issuer");
283
284 result = asn1_copy_node (src, name, issuer->cert, "tbsCertificate.subject");
285 if (result != ASN1_SUCCESS)
286 {
287 gnutls_assert ();
288 return _gnutls_asn2err (result);
289 }
290
291 /* Step 1.5. Write the signature stuff in the tbsCertificate.
292 */
293 _gnutls_str_cpy (name, sizeof (name), src_name);
294 _gnutls_str_cat (name, sizeof (name), ".signature");
295
296 result = _gnutls_x509_write_sig_params (src, name,
297 issuer_key->pk_algorithm, dig,
298 issuer_key->params,
299 issuer_key->params_size);
300 if (result < 0)
301 {
302 gnutls_assert ();
303 return result;
304 }
305
306 /* Step 2. Sign the certificate.
307 */
308 result = _gnutls_x509_sign_tbs (src, src_name, dig, issuer_key, &signature);
309
310 if (result < 0)
311 {
312 gnutls_assert ();
313 return result;
314 }
315
316 /* write the signature (bits)
317 */
318 result =
319 asn1_write_value (src, "signature", signature.data, signature.size * 8);
320
321 _gnutls_free_datum (&signature);
322
323 if (result != ASN1_SUCCESS)
324 {
325 gnutls_assert ();
326 return _gnutls_asn2err (result);
327 }
328
329 /* Step 3. Move up and write the AlgorithmIdentifier, which is also
330 * the same.
331 */
332
333 result = _gnutls_x509_write_sig_params (src, "signatureAlgorithm",
334 issuer_key->pk_algorithm, dig,
335 issuer_key->params,
336 issuer_key->params_size);
337 if (result < 0)
338 {
339 gnutls_assert ();
340 return result;
341 }
342
343 return 0;
344}
345
346#endif
diff --git a/src/daemon/https/x509/sign.h b/src/daemon/https/x509/sign.h
new file mode 100644
index 00000000..e1bf46d4
--- /dev/null
+++ b/src/daemon/https/x509/sign.h
@@ -0,0 +1,36 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25int _gnutls_x509_sign (const gnutls_datum_t * tbs,
26 gnutls_digest_algorithm_t hash,
27 gnutls_x509_privkey_t signer,
28 gnutls_datum_t * signature);
29int _gnutls_x509_sign_tbs (ASN1_TYPE cert, const char *tbs_name,
30 gnutls_digest_algorithm_t hash,
31 gnutls_x509_privkey_t signer,
32 gnutls_datum_t * signature);
33int _gnutls_x509_pkix_sign (ASN1_TYPE src, const char *src_name,
34 gnutls_digest_algorithm_t,
35 gnutls_x509_crt_t issuer,
36 gnutls_x509_privkey_t issuer_key);
diff --git a/src/daemon/https/x509/verify.h b/src/daemon/https/x509/verify.h
new file mode 100644
index 00000000..d7ca5151
--- /dev/null
+++ b/src/daemon/https/x509/verify.h
@@ -0,0 +1,34 @@
1/*
2 * Copyright (C) 2003, 2004, 2005 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include "x509.h"
26
27int gnutls_x509_crt_is_issuer (gnutls_x509_crt_t cert,
28 gnutls_x509_crt_t issuer);
29int _gnutls_x509_verify_signature (const gnutls_datum_t * tbs,
30 const gnutls_datum_t * signature,
31 gnutls_x509_crt_t issuer);
32int _gnutls_x509_privkey_verify_signature (const gnutls_datum_t * tbs,
33 const gnutls_datum_t * signature,
34 gnutls_x509_privkey_t issuer);
diff --git a/src/daemon/https/x509/x509-api.texi b/src/daemon/https/x509/x509-api.texi
new file mode 100644
index 00000000..f4dd35b9
--- /dev/null
+++ b/src/daemon/https/x509/x509-api.texi
@@ -0,0 +1,2943 @@
1
2@subheading gnutls_x509_crl_init
3@anchor{gnutls_x509_crl_init}
4@deftypefun {int} {gnutls_x509_crl_init} (gnutls_x509_crl_t * @var{crl})
5@var{crl}: The structure to be initialized
6
7This function will initialize a CRL structure. CRL stands for
8Certificate Revocation List. A revocation list usually contains
9lists of certificate serial numbers that have been revoked
10by an Authority. The revocation lists are always signed with
11the authority's private key.
12
13Returns 0 on success.
14@end deftypefun
15
16@subheading gnutls_x509_crl_deinit
17@anchor{gnutls_x509_crl_deinit}
18@deftypefun {void} {gnutls_x509_crl_deinit} (gnutls_x509_crl_t @var{crl})
19@var{crl}: The structure to be initialized
20
21This function will deinitialize a CRL structure.
22@end deftypefun
23
24@subheading gnutls_x509_crl_import
25@anchor{gnutls_x509_crl_import}
26@deftypefun {int} {gnutls_x509_crl_import} (gnutls_x509_crl_t @var{crl}, const gnutls_datum_t * @var{data}, gnutls_x509_crt_fmt_t @var{format})
27@var{crl}: The structure to store the parsed CRL.
28
29@var{data}: The DER or PEM encoded CRL.
30
31@var{format}: One of DER or PEM
32
33This function will convert the given DER or PEM encoded CRL
34to the native gnutls_x509_crl_t format. The output will be stored in 'crl'.
35
36If the CRL is PEM encoded it should have a header of "X509 CRL".
37
38Returns 0 on success.
39@end deftypefun
40
41@subheading gnutls_x509_crl_get_issuer_dn
42@anchor{gnutls_x509_crl_get_issuer_dn}
43@deftypefun {int} {gnutls_x509_crl_get_issuer_dn} (const gnutls_x509_crl_t @var{crl}, char * @var{buf}, size_t * @var{sizeof_buf})
44@var{crl}: should contain a gnutls_x509_crl_t structure
45
46@var{buf}: a pointer to a structure to hold the peer's name (may be null)
47
48@var{sizeof_buf}: initially holds the size of @code{buf}
49
50This function will copy the name of the CRL issuer in the provided buffer. The name
51will be in the form "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output
52string will be ASCII or UTF-8 encoded, depending on the certificate data.
53
54If buf is null then only the size will be filled.
55
56Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not long enough, and
57in that case the sizeof_buf will be updated with the required size, and
580 on success.
59@end deftypefun
60
61@subheading gnutls_x509_crl_get_issuer_dn_by_oid
62@anchor{gnutls_x509_crl_get_issuer_dn_by_oid}
63@deftypefun {int} {gnutls_x509_crl_get_issuer_dn_by_oid} (gnutls_x509_crl_t @var{crl}, const char * @var{oid}, int @var{indx}, unsigned int @var{raw_flag}, void * @var{buf}, size_t * @var{sizeof_buf})
64@var{crl}: should contain a gnutls_x509_crl_t structure
65
66@var{oid}: holds an Object Identified in null terminated string
67
68@var{indx}: In case multiple same OIDs exist in the RDN, this specifies which to send. Use zero to get the first one.
69
70@var{raw_flag}: If non zero returns the raw DER data of the DN part.
71
72@var{buf}: a pointer to a structure to hold the peer's name (may be null)
73
74@var{sizeof_buf}: initially holds the size of @code{buf}
75
76This function will extract the part of the name of the CRL issuer specified
77by the given OID. The output will be encoded as described in RFC2253. The output
78string will be ASCII or UTF-8 encoded, depending on the certificate data.
79
80Some helper macros with popular OIDs can be found in gnutls/x509.h
81If raw flag is zero, this function will only return known OIDs as text. Other OIDs
82will be DER encoded, as described in RFC2253 -- in hex format with a '\#' prefix.
83You can check about known OIDs using @code{gnutls_x509_dn_oid_known()}.
84
85If buf is null then only the size will be filled.
86
87Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not long enough, and
88in that case the sizeof_buf will be updated with the required size,
89and 0 on success.
90@end deftypefun
91
92@subheading gnutls_x509_crl_get_dn_oid
93@anchor{gnutls_x509_crl_get_dn_oid}
94@deftypefun {int} {gnutls_x509_crl_get_dn_oid} (gnutls_x509_crl_t @var{crl}, int @var{indx}, void * @var{oid}, size_t * @var{sizeof_oid})
95@var{crl}: should contain a gnutls_x509_crl_t structure
96
97@var{indx}: Specifies which DN OID to send. Use zero to get the first one.
98
99@var{oid}: a pointer to a structure to hold the name (may be null)
100
101@var{sizeof_oid}: initially holds the size of 'oid'
102
103This function will extract the requested OID of the name of the CRL issuer, specified
104by the given index.
105
106If oid is null then only the size will be filled.
107
108Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not long enough, and
109in that case the sizeof_oid will be updated with the required size.
110On success 0 is returned.
111@end deftypefun
112
113@subheading gnutls_x509_crl_get_signature_algorithm
114@anchor{gnutls_x509_crl_get_signature_algorithm}
115@deftypefun {int} {gnutls_x509_crl_get_signature_algorithm} (gnutls_x509_crl_t @var{crl})
116@var{crl}: should contain a gnutls_x509_crl_t structure
117
118This function will return a value of the gnutls_sign_algorithm_t enumeration that
119is the signature algorithm.
120
121Returns a negative value on error.
122@end deftypefun
123
124@subheading gnutls_x509_crl_get_signature
125@anchor{gnutls_x509_crl_get_signature}
126@deftypefun {int} {gnutls_x509_crl_get_signature} (gnutls_x509_crl_t @var{crl}, char * @var{sig}, size_t * @var{sizeof_sig})
127@var{crl}: should contain a gnutls_x509_crl_t structure
128
129@var{sig}: a pointer where the signature part will be copied (may be null).
130
131@var{sizeof_sig}: initially holds the size of @code{sig}
132
133This function will extract the signature field of a CRL.
134
135Returns 0 on success, and a negative value on error.
136@end deftypefun
137
138@subheading gnutls_x509_crl_get_version
139@anchor{gnutls_x509_crl_get_version}
140@deftypefun {int} {gnutls_x509_crl_get_version} (gnutls_x509_crl_t @var{crl})
141@var{crl}: should contain a gnutls_x509_crl_t structure
142
143This function will return the version of the specified CRL.
144
145Returns a negative value on error.
146@end deftypefun
147
148@subheading gnutls_x509_crl_get_this_update
149@anchor{gnutls_x509_crl_get_this_update}
150@deftypefun {time_t} {gnutls_x509_crl_get_this_update} (gnutls_x509_crl_t @var{crl})
151@var{crl}: should contain a gnutls_x509_crl_t structure
152
153This function will return the time this CRL was issued.
154
155Returns (time_t)-1 on error.
156@end deftypefun
157
158@subheading gnutls_x509_crl_get_next_update
159@anchor{gnutls_x509_crl_get_next_update}
160@deftypefun {time_t} {gnutls_x509_crl_get_next_update} (gnutls_x509_crl_t @var{crl})
161@var{crl}: should contain a gnutls_x509_crl_t structure
162
163This function will return the time the next CRL will be issued.
164This field is optional in a CRL so it might be normal to get
165an error instead.
166
167Returns (time_t)-1 on error.
168@end deftypefun
169
170@subheading gnutls_x509_crl_get_crt_count
171@anchor{gnutls_x509_crl_get_crt_count}
172@deftypefun {int} {gnutls_x509_crl_get_crt_count} (gnutls_x509_crl_t @var{crl})
173@var{crl}: should contain a gnutls_x509_crl_t structure
174
175This function will return the number of revoked certificates in the
176given CRL.
177
178Returns a negative value on failure.
179@end deftypefun
180
181@subheading gnutls_x509_crl_get_crt_serial
182@anchor{gnutls_x509_crl_get_crt_serial}
183@deftypefun {int} {gnutls_x509_crl_get_crt_serial} (gnutls_x509_crl_t @var{crl}, int @var{indx}, unsigned char * @var{serial}, size_t * @var{serial_size}, time_t * @var{t})
184@var{crl}: should contain a gnutls_x509_crl_t structure
185
186@var{indx}: the index of the certificate to extract (starting from 0)
187
188@var{serial}: where the serial number will be copied
189
190@var{serial_size}: initially holds the size of serial
191
192@var{t}: if non null, will hold the time this certificate was revoked
193
194This function will return the serial number of the specified, by
195the index, revoked certificate.
196
197Returns a negative value on failure.
198@end deftypefun
199
200@subheading gnutls_x509_crl_export
201@anchor{gnutls_x509_crl_export}
202@deftypefun {int} {gnutls_x509_crl_export} (gnutls_x509_crl_t @var{crl}, gnutls_x509_crt_fmt_t @var{format}, void * @var{output_data}, size_t * @var{output_data_size})
203@var{crl}: Holds the revocation list
204
205@var{format}: the format of output params. One of PEM or DER.
206
207@var{output_data}: will contain a private key PEM or DER encoded
208
209@var{output_data_size}: holds the size of output_data (and will be replaced by the actual size of parameters)
210
211This function will export the revocation list to DER or PEM format.
212
213If the buffer provided is not long enough to hold the output, then
214GNUTLS_E_SHORT_MEMORY_BUFFER will be returned.
215
216If the structure is PEM encoded, it will have a header
217of "BEGIN X509 CRL".
218
219Returns 0 on success, and a negative value on failure.
220@end deftypefun
221
222@subheading gnutls_x509_rdn_get
223@anchor{gnutls_x509_rdn_get}
224@deftypefun {int} {gnutls_x509_rdn_get} (const gnutls_datum_t * @var{idn}, char * @var{buf}, size_t * @var{sizeof_buf})
225@var{idn}: should contain a DER encoded RDN sequence
226
227@var{buf}: a pointer to a structure to hold the peer's name
228
229@var{sizeof_buf}: holds the size of @code{buf}
230
231This function will return the name of the given RDN sequence. The
232name will be in the form "C=xxxx,O=yyyy,CN=zzzz" as described in
233RFC2253.
234
235If the provided buffer is not long enough, returns
236GNUTLS_E_SHORT_MEMORY_BUFFER and *sizeof_buf will be updated. On
237success 0 is returned.
238@end deftypefun
239
240@subheading gnutls_x509_rdn_get_by_oid
241@anchor{gnutls_x509_rdn_get_by_oid}
242@deftypefun {int} {gnutls_x509_rdn_get_by_oid} (const gnutls_datum_t * @var{idn}, const char * @var{oid}, int @var{indx}, unsigned int @var{raw_flag}, void * @var{buf}, size_t * @var{sizeof_buf})
243@var{idn}: should contain a DER encoded RDN sequence
244
245@var{oid}: an Object Identifier
246
247@var{indx}: In case multiple same OIDs exist in the RDN indicates which
248to send. Use 0 for the first one.
249
250@var{raw_flag}: If non zero then the raw DER data are returned.
251
252@var{buf}: a pointer to a structure to hold the peer's name
253
254@var{sizeof_buf}: holds the size of @code{buf}
255
256This function will return the name of the given Object identifier,
257of the RDN sequence. The name will be encoded using the rules
258from RFC2253.
259
260Returns GNUTLS_E_SHORT_MEMORY_BUFFER and updates *sizeof_buf if
261the provided buffer is not long enough, and 0 on success.
262@end deftypefun
263
264@subheading gnutls_x509_rdn_get_oid
265@anchor{gnutls_x509_rdn_get_oid}
266@deftypefun {int} {gnutls_x509_rdn_get_oid} (const gnutls_datum_t * @var{idn}, int @var{indx}, void * @var{buf}, size_t * @var{sizeof_buf})
267@var{idn}: should contain a DER encoded RDN sequence
268
269@var{indx}: Indicates which OID to return. Use 0 for the first one.
270
271This function will return the specified Object identifier, of the
272RDN sequence.
273
274Returns GNUTLS_E_SHORT_MEMORY_BUFFER and updates *sizeof_buf if
275the provided buffer is not long enough, and 0 on success.
276@end deftypefun
277
278@subheading gnutls_x509_dn_oid_known
279@anchor{gnutls_x509_dn_oid_known}
280@deftypefun {int} {gnutls_x509_dn_oid_known} (const char * @var{oid})
281@var{oid}: holds an Object Identifier in a null terminated string
282
283This function will inform about known DN OIDs. This is useful since functions
284like @code{gnutls_x509_crt_set_dn_by_oid()} use the information on known
285OIDs to properly encode their input. Object Identifiers that are not
286known are not encoded by these functions, and their input is stored directly
287into the ASN.1 structure. In that case of unknown OIDs, you have
288the responsibility of DER encoding your data.
289
290Returns 1 on known OIDs and 0 otherwise.
291@end deftypefun
292
293@subheading gnutls_x509_crt_init
294@anchor{gnutls_x509_crt_init}
295@deftypefun {int} {gnutls_x509_crt_init} (gnutls_x509_crt_t * @var{cert})
296@var{cert}: The structure to be initialized
297
298This function will initialize an X.509 certificate structure.
299
300Returns 0 on success.
301@end deftypefun
302
303@subheading gnutls_x509_crt_deinit
304@anchor{gnutls_x509_crt_deinit}
305@deftypefun {void} {gnutls_x509_crt_deinit} (gnutls_x509_crt_t @var{cert})
306@var{cert}: The structure to be initialized
307
308This function will deinitialize a CRL structure.
309@end deftypefun
310
311@subheading gnutls_x509_crt_import
312@anchor{gnutls_x509_crt_import}
313@deftypefun {int} {gnutls_x509_crt_import} (gnutls_x509_crt_t @var{cert}, const gnutls_datum_t * @var{data}, gnutls_x509_crt_fmt_t @var{format})
314@var{cert}: The structure to store the parsed certificate.
315
316@var{data}: The DER or PEM encoded certificate.
317
318@var{format}: One of DER or PEM
319
320This function will convert the given DER or PEM encoded Certificate
321to the native gnutls_x509_crt_t format. The output will be stored in @code{cert}.
322
323If the Certificate is PEM encoded it should have a header of "X509 CERTIFICATE", or
324"CERTIFICATE".
325
326Returns 0 on success.
327@end deftypefun
328
329@subheading gnutls_x509_crt_get_issuer_dn
330@anchor{gnutls_x509_crt_get_issuer_dn}
331@deftypefun {int} {gnutls_x509_crt_get_issuer_dn} (gnutls_x509_crt_t @var{cert}, char * @var{buf}, size_t * @var{sizeof_buf})
332@var{cert}: should contain a gnutls_x509_crt_t structure
333
334@var{buf}: a pointer to a structure to hold the name (may be null)
335
336@var{sizeof_buf}: initially holds the size of @code{buf}
337
338This function will copy the name of the Certificate issuer in the
339provided buffer. The name will be in the form
340"C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output string
341will be ASCII or UTF-8 encoded, depending on the certificate data.
342
343If @code{buf} is null then only the size will be filled.
344
345Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
346long enough, and in that case the *sizeof_buf will be updated with
347the required size. On success 0 is returned.
348@end deftypefun
349
350@subheading gnutls_x509_crt_get_issuer_dn_by_oid
351@anchor{gnutls_x509_crt_get_issuer_dn_by_oid}
352@deftypefun {int} {gnutls_x509_crt_get_issuer_dn_by_oid} (gnutls_x509_crt_t @var{cert}, const char * @var{oid}, int @var{indx}, unsigned int @var{raw_flag}, void * @var{buf}, size_t * @var{sizeof_buf})
353@var{cert}: should contain a gnutls_x509_crt_t structure
354
355@var{oid}: holds an Object Identified in null terminated string
356
357@var{indx}: In case multiple same OIDs exist in the RDN, this specifies which to send. Use zero to get the first one.
358
359@var{raw_flag}: If non zero returns the raw DER data of the DN part.
360
361@var{buf}: a pointer to a structure to hold the name (may be null)
362
363@var{sizeof_buf}: initially holds the size of @code{buf}
364
365This function will extract the part of the name of the Certificate
366issuer specified by the given OID. The output, if the raw flag is not
367used, will be encoded as described in RFC2253. Thus a string that is
368ASCII or UTF-8 encoded, depending on the certificate data.
369
370Some helper macros with popular OIDs can be found in gnutls/x509.h
371If raw flag is zero, this function will only return known OIDs as
372text. Other OIDs will be DER encoded, as described in RFC2253 --
373in hex format with a '\#' prefix. You can check about known OIDs
374using @code{gnutls_x509_dn_oid_known()}.
375
376If @code{buf} is null then only the size will be filled.
377
378Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
379long enough, and in that case the *sizeof_buf will be updated with
380the required size. On success 0 is returned.
381@end deftypefun
382
383@subheading gnutls_x509_crt_get_issuer_dn_oid
384@anchor{gnutls_x509_crt_get_issuer_dn_oid}
385@deftypefun {int} {gnutls_x509_crt_get_issuer_dn_oid} (gnutls_x509_crt_t @var{cert}, int @var{indx}, void * @var{oid}, size_t * @var{sizeof_oid})
386@var{cert}: should contain a gnutls_x509_crt_t structure
387
388@var{indx}: This specifies which OID to return. Use zero to get the first one.
389
390@var{oid}: a pointer to a buffer to hold the OID (may be null)
391
392@var{sizeof_oid}: initially holds the size of @code{oid}
393
394This function will extract the OIDs of the name of the Certificate
395issuer specified by the given index.
396
397If @code{oid} is null then only the size will be filled.
398
399Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
400long enough, and in that case the *sizeof_oid will be updated with
401the required size. On success 0 is returned.
402@end deftypefun
403
404@subheading gnutls_x509_crt_get_dn
405@anchor{gnutls_x509_crt_get_dn}
406@deftypefun {int} {gnutls_x509_crt_get_dn} (gnutls_x509_crt_t @var{cert}, char * @var{buf}, size_t * @var{sizeof_buf})
407@var{cert}: should contain a gnutls_x509_crt_t structure
408
409@var{buf}: a pointer to a structure to hold the name (may be null)
410
411@var{sizeof_buf}: initially holds the size of @code{buf}
412
413This function will copy the name of the Certificate in the
414provided buffer. The name will be in the form
415"C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output string
416will be ASCII or UTF-8 encoded, depending on the certificate data.
417
418If @code{buf} is null then only the size will be filled.
419
420Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
421long enough, and in that case the *sizeof_buf will be updated with
422the required size. On success 0 is returned.
423@end deftypefun
424
425@subheading gnutls_x509_crt_get_dn_by_oid
426@anchor{gnutls_x509_crt_get_dn_by_oid}
427@deftypefun {int} {gnutls_x509_crt_get_dn_by_oid} (gnutls_x509_crt_t @var{cert}, const char * @var{oid}, int @var{indx}, unsigned int @var{raw_flag}, void * @var{buf}, size_t * @var{sizeof_buf})
428@var{cert}: should contain a gnutls_x509_crt_t structure
429
430@var{oid}: holds an Object Identified in null terminated string
431
432@var{indx}: In case multiple same OIDs exist in the RDN, this specifies which to send. Use zero to get the first one.
433
434@var{raw_flag}: If non zero returns the raw DER data of the DN part.
435
436@var{buf}: a pointer where the DN part will be copied (may be null).
437
438@var{sizeof_buf}: initially holds the size of @code{buf}
439
440This function will extract the part of the name of the Certificate
441subject specified by the given OID. The output, if the raw flag is not
442used, will be encoded as described in RFC2253. Thus a string that is
443ASCII or UTF-8 encoded, depending on the certificate data.
444
445Some helper macros with popular OIDs can be found in gnutls/x509.h
446If raw flag is zero, this function will only return known OIDs as
447text. Other OIDs will be DER encoded, as described in RFC2253 --
448in hex format with a '\#' prefix. You can check about known OIDs
449using @code{gnutls_x509_dn_oid_known()}.
450
451If @code{buf} is null then only the size will be filled.
452
453Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
454long enough, and in that case the *sizeof_buf will be updated with
455the required size. On success 0 is returned.
456@end deftypefun
457
458@subheading gnutls_x509_crt_get_dn_oid
459@anchor{gnutls_x509_crt_get_dn_oid}
460@deftypefun {int} {gnutls_x509_crt_get_dn_oid} (gnutls_x509_crt_t @var{cert}, int @var{indx}, void * @var{oid}, size_t * @var{sizeof_oid})
461@var{cert}: should contain a gnutls_x509_crt_t structure
462
463@var{indx}: This specifies which OID to return. Use zero to get the first one.
464
465@var{oid}: a pointer to a buffer to hold the OID (may be null)
466
467@var{sizeof_oid}: initially holds the size of @code{oid}
468
469This function will extract the OIDs of the name of the Certificate
470subject specified by the given index.
471
472If oid is null then only the size will be filled.
473
474Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
475long enough, and in that case the *sizeof_oid will be updated with
476the required size. On success 0 is returned.
477@end deftypefun
478
479@subheading gnutls_x509_crt_get_signature_algorithm
480@anchor{gnutls_x509_crt_get_signature_algorithm}
481@deftypefun {int} {gnutls_x509_crt_get_signature_algorithm} (gnutls_x509_crt_t @var{cert})
482@var{cert}: should contain a gnutls_x509_crt_t structure
483
484This function will return a value of the gnutls_sign_algorithm_t enumeration that
485is the signature algorithm.
486
487Returns a negative value on error.
488@end deftypefun
489
490@subheading gnutls_x509_crt_get_signature
491@anchor{gnutls_x509_crt_get_signature}
492@deftypefun {int} {gnutls_x509_crt_get_signature} (gnutls_x509_crt_t @var{cert}, char * @var{sig}, size_t * @var{sizeof_sig})
493@var{cert}: should contain a gnutls_x509_crt_t structure
494
495@var{sig}: a pointer where the signature part will be copied (may be null).
496
497@var{sizeof_sig}: initially holds the size of @code{sig}
498
499This function will extract the signature field of a certificate.
500
501Returns 0 on success, and a negative value on error.
502@end deftypefun
503
504@subheading gnutls_x509_crt_get_version
505@anchor{gnutls_x509_crt_get_version}
506@deftypefun {int} {gnutls_x509_crt_get_version} (gnutls_x509_crt_t @var{cert})
507@var{cert}: should contain a gnutls_x509_crt_t structure
508
509This function will return the version of the specified Certificate.
510
511Returns a negative value on error.
512@end deftypefun
513
514@subheading gnutls_x509_crt_get_activation_time
515@anchor{gnutls_x509_crt_get_activation_time}
516@deftypefun {time_t} {gnutls_x509_crt_get_activation_time} (gnutls_x509_crt_t @var{cert})
517@var{cert}: should contain a gnutls_x509_crt_t structure
518
519This function will return the time this Certificate was or will be activated.
520
521Returns (time_t)-1 on error.
522@end deftypefun
523
524@subheading gnutls_x509_crt_get_expiration_time
525@anchor{gnutls_x509_crt_get_expiration_time}
526@deftypefun {time_t} {gnutls_x509_crt_get_expiration_time} (gnutls_x509_crt_t @var{cert})
527@var{cert}: should contain a gnutls_x509_crt_t structure
528
529This function will return the time this Certificate was or will be expired.
530
531Returns (time_t)-1 on error.
532@end deftypefun
533
534@subheading gnutls_x509_crt_get_serial
535@anchor{gnutls_x509_crt_get_serial}
536@deftypefun {int} {gnutls_x509_crt_get_serial} (gnutls_x509_crt_t @var{cert}, void * @var{result}, size_t * @var{result_size})
537@var{cert}: should contain a gnutls_x509_crt_t structure
538
539@var{result}: The place where the serial number will be copied
540
541@var{result_size}: Holds the size of the result field.
542
543This function will return the X.509 certificate's serial number.
544This is obtained by the X509 Certificate serialNumber
545field. Serial is not always a 32 or 64bit number. Some CAs use
546large serial numbers, thus it may be wise to handle it as something
547opaque.
548
549Returns 0 on success and a negative value in case of an error.
550@end deftypefun
551
552@subheading gnutls_x509_crt_get_subject_key_id
553@anchor{gnutls_x509_crt_get_subject_key_id}
554@deftypefun {int} {gnutls_x509_crt_get_subject_key_id} (gnutls_x509_crt_t @var{cert}, void * @var{ret}, size_t * @var{ret_size}, unsigned int * @var{critical})
555@var{cert}: should contain a gnutls_x509_crt_t structure
556
557@var{ret}: The place where the identifier will be copied
558
559@var{ret_size}: Holds the size of the result field.
560
561@var{critical}: will be non zero if the extension is marked as critical (may be null)
562
563This function will return the X.509v3 certificate's subject key identifier.
564This is obtained by the X.509 Subject Key identifier extension
565field (2.5.29.14).
566
567Returns 0 on success and a negative value in case of an error.
568@end deftypefun
569
570@subheading gnutls_x509_crt_get_authority_key_id
571@anchor{gnutls_x509_crt_get_authority_key_id}
572@deftypefun {int} {gnutls_x509_crt_get_authority_key_id} (gnutls_x509_crt_t @var{cert}, void * @var{ret}, size_t * @var{ret_size}, unsigned int * @var{critical})
573@var{cert}: should contain a gnutls_x509_crt_t structure
574
575@var{critical}: will be non zero if the extension is marked as critical (may be null)
576
577This function will return the X.509v3 certificate authority's key identifier.
578This is obtained by the X.509 Authority Key identifier extension
579field (2.5.29.35). Note that this function only returns the keyIdentifier
580field of the extension.
581
582Returns 0 on success and a negative value in case of an error.
583@end deftypefun
584
585@subheading gnutls_x509_crt_get_pk_algorithm
586@anchor{gnutls_x509_crt_get_pk_algorithm}
587@deftypefun {int} {gnutls_x509_crt_get_pk_algorithm} (gnutls_x509_crt_t @var{cert}, unsigned int * @var{bits})
588@var{cert}: should contain a gnutls_x509_crt_t structure
589
590@var{bits}: if bits is non null it will hold the size of the parameters' in bits
591
592This function will return the public key algorithm of an X.509
593certificate.
594
595If bits is non null, it should have enough size to hold the parameters
596size in bits. For RSA the bits returned is the modulus.
597For DSA the bits returned are of the public
598exponent.
599
600Returns a member of the gnutls_pk_algorithm_t enumeration on success,
601or a negative value on error.
602@end deftypefun
603
604@subheading gnutls_x509_crt_get_subject_alt_name
605@anchor{gnutls_x509_crt_get_subject_alt_name}
606@deftypefun {int} {gnutls_x509_crt_get_subject_alt_name} (gnutls_x509_crt_t @var{cert}, unsigned int @var{seq}, void * @var{ret}, size_t * @var{ret_size}, unsigned int * @var{critical})
607@var{cert}: should contain a gnutls_x509_crt_t structure
608
609@var{seq}: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
610
611@var{ret}: is the place where the alternative name will be copied to
612
613@var{ret_size}: holds the size of ret.
614
615@var{critical}: will be non zero if the extension is marked as critical (may be null)
616
617This function will return the alternative names, contained in the
618given certificate.
619
620This is specified in X509v3 Certificate Extensions. GNUTLS will
621return the Alternative name (2.5.29.17), or a negative error code.
622
623When the SAN type is otherName, it will extract the data in the
624otherName's value field, and @code{GNUTLS_SAN_OTHERNAME} is returned.
625You may use @code{gnutls_x509_crt_get_subject_alt_othername_oid()} to get
626the corresponding OID and the "virtual" SAN types (e.g.,
627@code{GNUTLS_SAN_OTHERNAME_XMPP}).
628
629If an otherName OID is known, the data will be decoded. Otherwise
630the returned data will be DER encoded, and you will have to decode
631it yourself. Currently, only the RFC 3920 id-on-xmppAddr SAN is
632recognized.
633
634Returns the alternative subject name type on success. The type is
635one of the enumerated gnutls_x509_subject_alt_name_t. It will
636return @code{GNUTLS_E_SHORT_MEMORY_BUFFER} if @code{ret_size} is not large
637enough to hold the value. In that case @code{ret_size} will be updated
638with the required size. If the certificate does not have an
639Alternative name with the specified sequence number then
640@code{GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE} is returned.
641@end deftypefun
642
643@subheading gnutls_x509_crt_get_subject_alt_name2
644@anchor{gnutls_x509_crt_get_subject_alt_name2}
645@deftypefun {int} {gnutls_x509_crt_get_subject_alt_name2} (gnutls_x509_crt_t @var{cert}, unsigned int @var{seq}, void * @var{ret}, size_t * @var{ret_size}, unsigned int* @var{ret_type}, unsigned int * @var{critical})
646@var{cert}: should contain a gnutls_x509_crt_t structure
647
648@var{seq}: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
649
650@var{ret}: is the place where the alternative name will be copied to
651
652@var{ret_size}: holds the size of ret.
653
654@var{ret_type}: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
655
656@var{critical}: will be non zero if the extension is marked as critical (may be null)
657
658This function will return the alternative names, contained in the
659given certificate. It is the same as @code{gnutls_x509_crt_get_subject_alt_name()}
660except for the fact that it will return the type of the alternative
661name in @code{ret_type} even if the function fails for some reason (i.e.
662the buffer provided is not enough).
663
664The return values are the same as with @code{gnutls_x509_crt_get_subject_alt_name()}.
665@end deftypefun
666
667@subheading gnutls_x509_crt_get_subject_alt_othername_oid
668@anchor{gnutls_x509_crt_get_subject_alt_othername_oid}
669@deftypefun {int} {gnutls_x509_crt_get_subject_alt_othername_oid} (gnutls_x509_crt_t @var{cert}, unsigned int @var{seq}, void * @var{ret}, size_t * @var{ret_size})
670@var{cert}: should contain a gnutls_x509_crt_t structure
671
672@var{seq}: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
673
674@var{ret}: is the place where the otherName OID will be copied to
675
676@var{ret_size}: holds the size of ret.
677
678This function will extract the type OID of an otherName Subject
679Alternative Name, contained in the given certificate, and return
680the type as an enumerated element.
681
682This function is only useful if
683@code{gnutls_x509_crt_get_subject_alt_name()} returned
684@code{GNUTLS_SAN_OTHERNAME}.
685
686Returns the alternative subject name type on success. The type is
687one of the enumerated gnutls_x509_subject_alt_name_t. For
688supported OIDs, it will return one of the virtual
689(GNUTLS_SAN_OTHERNAME_*) types, e.g. @code{GNUTLS_SAN_OTHERNAME_XMPP},
690and @code{GNUTLS_SAN_OTHERNAME} for unknown OIDs. It will return
691@code{GNUTLS_E_SHORT_MEMORY_BUFFER} if @code{ret_size} is not large enough to
692hold the value. In that case @code{ret_size} will be updated with the
693required size. If the certificate does not have an Alternative
694name with the specified sequence number and with the otherName type
695then @code{GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE} is returned.
696@end deftypefun
697
698@subheading gnutls_x509_crt_get_basic_constraints
699@anchor{gnutls_x509_crt_get_basic_constraints}
700@deftypefun {int} {gnutls_x509_crt_get_basic_constraints} (gnutls_x509_crt_t @var{cert}, unsigned int * @var{critical}, int * @var{ca}, int * @var{pathlen})
701@var{cert}: should contain a gnutls_x509_crt_t structure
702
703@var{critical}: will be non zero if the extension is marked as critical
704
705@var{ca}: pointer to output integer indicating CA status, may be NULL,
706value is 1 if the certificate CA flag is set, 0 otherwise.
707
708@var{pathlen}: pointer to output integer indicating path length (may be
709NULL), non-negative values indicate a present pathLenConstraint
710field and the actual value, -1 indicate that the field is absent.
711
712This function will read the certificate's basic constraints, and
713return the certificates CA status. It reads the basicConstraints
714X.509 extension (2.5.29.19).
715
716@strong{Return value:} If the certificate is a CA a positive value will be
717returned, or zero if the certificate does not have CA flag set. A
718negative value may be returned in case of errors. If the
719certificate does not contain the basicConstraints extension
720GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
721@end deftypefun
722
723@subheading gnutls_x509_crt_get_ca_status
724@anchor{gnutls_x509_crt_get_ca_status}
725@deftypefun {int} {gnutls_x509_crt_get_ca_status} (gnutls_x509_crt_t @var{cert}, unsigned int * @var{critical})
726@var{cert}: should contain a gnutls_x509_crt_t structure
727
728@var{critical}: will be non zero if the extension is marked as critical
729
730This function will return certificates CA status, by reading the
731basicConstraints X.509 extension (2.5.29.19). If the certificate is
732a CA a positive value will be returned, or zero if the certificate
733does not have CA flag set.
734
735Use @code{gnutls_x509_crt_get_basic_constraints()} if you want to read the
736pathLenConstraint field too.
737
738A negative value may be returned in case of parsing error.
739If the certificate does not contain the basicConstraints extension
740GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
741@end deftypefun
742
743@subheading gnutls_x509_crt_get_key_usage
744@anchor{gnutls_x509_crt_get_key_usage}
745@deftypefun {int} {gnutls_x509_crt_get_key_usage} (gnutls_x509_crt_t @var{cert}, unsigned int * @var{key_usage}, unsigned int * @var{critical})
746@var{cert}: should contain a gnutls_x509_crt_t structure
747
748@var{key_usage}: where the key usage bits will be stored
749
750@var{critical}: will be non zero if the extension is marked as critical
751
752This function will return certificate's key usage, by reading the
753keyUsage X.509 extension (2.5.29.15). The key usage value will ORed values of the:
754GNUTLS_KEY_DIGITAL_SIGNATURE, GNUTLS_KEY_NON_REPUDIATION,
755GNUTLS_KEY_KEY_ENCIPHERMENT, GNUTLS_KEY_DATA_ENCIPHERMENT,
756GNUTLS_KEY_KEY_AGREEMENT, GNUTLS_KEY_KEY_CERT_SIGN,
757GNUTLS_KEY_CRL_SIGN, GNUTLS_KEY_ENCIPHER_ONLY,
758GNUTLS_KEY_DECIPHER_ONLY.
759
760A negative value may be returned in case of parsing error.
761If the certificate does not contain the keyUsage extension
762GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
763@end deftypefun
764
765@subheading gnutls_x509_crt_get_proxy
766@anchor{gnutls_x509_crt_get_proxy}
767@deftypefun {int} {gnutls_x509_crt_get_proxy} (gnutls_x509_crt_t @var{cert}, unsigned int * @var{critical}, int * @var{pathlen}, char ** @var{policyLanguage}, char ** @var{policy}, size_t * @var{sizeof_policy})
768@var{cert}: should contain a gnutls_x509_crt_t structure
769
770@var{critical}: will be non zero if the extension is marked as critical
771
772@var{pathlen}: pointer to output integer indicating path length (may be
773NULL), non-negative values indicate a present pCPathLenConstraint
774field and the actual value, -1 indicate that the field is absent.
775
776This function will read the certificate's basic constraints, and
777return the certificates CA status. It reads the basicConstraints
778X.509 extension (2.5.29.19).
779
780@strong{Return value:} If the certificate is a CA a positive value will be
781returned, or zero if the certificate does not have CA flag set. A
782negative value may be returned in case of errors. If the
783certificate does not contain the basicConstraints extension
784GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
785@end deftypefun
786
787@subheading gnutls_x509_crt_get_extension_by_oid
788@anchor{gnutls_x509_crt_get_extension_by_oid}
789@deftypefun {int} {gnutls_x509_crt_get_extension_by_oid} (gnutls_x509_crt_t @var{cert}, const char * @var{oid}, int @var{indx}, void * @var{buf}, size_t * @var{sizeof_buf}, unsigned int * @var{critical})
790@var{cert}: should contain a gnutls_x509_crt_t structure
791
792@var{oid}: holds an Object Identified in null terminated string
793
794@var{indx}: In case multiple same OIDs exist in the extensions, this specifies which to send. Use zero to get the first one.
795
796@var{buf}: a pointer to a structure to hold the name (may be null)
797
798@var{sizeof_buf}: initially holds the size of @code{buf}
799
800@var{critical}: will be non zero if the extension is marked as critical
801
802This function will return the extension specified by the OID in the certificate.
803The extensions will be returned as binary data DER encoded, in the provided
804buffer.
805
806A negative value may be returned in case of parsing error.
807If the certificate does not contain the specified extension
808GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
809@end deftypefun
810
811@subheading gnutls_x509_crt_get_extension_oid
812@anchor{gnutls_x509_crt_get_extension_oid}
813@deftypefun {int} {gnutls_x509_crt_get_extension_oid} (gnutls_x509_crt_t @var{cert}, int @var{indx}, void * @var{oid}, size_t * @var{sizeof_oid})
814@var{cert}: should contain a gnutls_x509_crt_t structure
815
816@var{indx}: Specifies which extension OID to send. Use zero to get the first one.
817
818@var{oid}: a pointer to a structure to hold the OID (may be null)
819
820@var{sizeof_oid}: initially holds the size of @code{oid}
821
822This function will return the requested extension OID in the certificate.
823The extension OID will be stored as a string in the provided buffer.
824
825A negative value may be returned in case of parsing error.
826If your have reached the last extension available
827GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
828@end deftypefun
829
830@subheading gnutls_x509_crt_get_extension_info
831@anchor{gnutls_x509_crt_get_extension_info}
832@deftypefun {int} {gnutls_x509_crt_get_extension_info} (gnutls_x509_crt_t @var{cert}, int @var{indx}, void * @var{oid}, size_t * @var{sizeof_oid}, int * @var{critical})
833@var{cert}: should contain a gnutls_x509_crt_t structure
834
835@var{indx}: Specifies which extension OID to send. Use zero to get the first one.
836
837@var{oid}: a pointer to a structure to hold the OID
838
839@var{sizeof_oid}: initially holds the size of @code{oid}
840
841@var{critical}: output variable with critical flag, may be NULL.
842
843This function will return the requested extension OID in the
844certificate, and the critical flag for it. The extension OID will
845be stored as a string in the provided buffer. Use
846@code{gnutls_x509_crt_get_extension_data()} to extract the data.
847
848Return 0 on success. A negative value may be returned in case of
849parsing error. If you have reached the last extension available
850GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
851@end deftypefun
852
853@subheading gnutls_x509_crt_get_extension_data
854@anchor{gnutls_x509_crt_get_extension_data}
855@deftypefun {int} {gnutls_x509_crt_get_extension_data} (gnutls_x509_crt_t @var{cert}, int @var{indx}, void * @var{data}, size_t * @var{sizeof_data})
856@var{cert}: should contain a gnutls_x509_crt_t structure
857
858@var{indx}: Specifies which extension OID to send. Use zero to get the first one.
859
860@var{data}: a pointer to a structure to hold the data (may be null)
861
862@var{sizeof_data}: initially holds the size of @code{oid}
863
864This function will return the requested extension data in the
865certificate. The extension data will be stored as a string in the
866provided buffer.
867
868Use @code{gnutls_x509_crt_get_extension_info()} to extract the OID and
869critical flag. Use @code{gnutls_x509_crt_get_extension_by_oid()} instead,
870if you want to get data indexed by the extension OID rather than
871sequence.
872
873Return 0 on success. A negative value may be returned in case of
874parsing error. If you have reached the last extension available
875GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
876@end deftypefun
877
878@subheading gnutls_x509_crt_get_raw_issuer_dn
879@anchor{gnutls_x509_crt_get_raw_issuer_dn}
880@deftypefun {int} {gnutls_x509_crt_get_raw_issuer_dn} (gnutls_x509_crt_t @var{cert}, gnutls_datum_t * @var{start})
881@var{cert}: should contain a gnutls_x509_crt_t structure
882
883@var{start}: will hold the starting point of the DN
884
885This function will return a pointer to the DER encoded DN structure
886and the length.
887
888Returns 0 on success or a negative value on error.
889@end deftypefun
890
891@subheading gnutls_x509_crt_get_raw_dn
892@anchor{gnutls_x509_crt_get_raw_dn}
893@deftypefun {int} {gnutls_x509_crt_get_raw_dn} (gnutls_x509_crt_t @var{cert}, gnutls_datum_t * @var{start})
894@var{cert}: should contain a gnutls_x509_crt_t structure
895
896@var{start}: will hold the starting point of the DN
897
898This function will return a pointer to the DER encoded DN structure and
899the length.
900
901Returns 0 on success, or a negative value on error.
902@end deftypefun
903
904@subheading gnutls_x509_crt_get_subject
905@anchor{gnutls_x509_crt_get_subject}
906@deftypefun {int} {gnutls_x509_crt_get_subject} (gnutls_x509_crt_t @var{cert}, gnutls_x509_dn_t * @var{dn})
907@var{cert}: should contain a gnutls_x509_crt_t structure
908
909@var{dn}: output variable with pointer to opaque DN.
910
911Return the Certificate's Subject DN as an opaque data type. You
912may use @code{gnutls_x509_dn_get_rdn_ava()} to decode the DN.
913
914@strong{Returns:} Returns 0 on success, or an error code.
915@end deftypefun
916
917@subheading gnutls_x509_crt_get_issuer
918@anchor{gnutls_x509_crt_get_issuer}
919@deftypefun {int} {gnutls_x509_crt_get_issuer} (gnutls_x509_crt_t @var{cert}, gnutls_x509_dn_t * @var{dn})
920@var{cert}: should contain a gnutls_x509_crt_t structure
921
922@var{dn}: output variable with pointer to opaque DN
923
924Return the Certificate's Issuer DN as an opaque data type. You may
925use @code{gnutls_x509_dn_get_rdn_ava()} to decode the DN.
926
927Note that @code{dn} points into the @code{cert} object, and thus you may not
928deallocate @code{cert} and continue to access @code{dn}.
929
930@strong{Returns:} Returns 0 on success, or an error code.
931@end deftypefun
932
933@subheading gnutls_x509_dn_get_rdn_ava
934@anchor{gnutls_x509_dn_get_rdn_ava}
935@deftypefun {int} {gnutls_x509_dn_get_rdn_ava} (gnutls_x509_dn_t @var{dn}, int @var{irdn}, int @var{iava}, gnutls_x509_ava_st * @var{ava})
936@var{dn}: input variable with opaque DN pointer
937
938@var{irdn}: index of RDN
939
940@var{iava}: index of AVA.
941
942@var{ava}: Pointer to structure which will hold output information.
943
944Get pointers to data within the DN.
945
946Note that @code{ava} will contain pointers into the @code{dn} structure, so you
947should not modify any data or deallocate it. Note also that the DN
948in turn points into the original certificate structure, and thus
949you may not deallocate the certificate and continue to access @code{dn}.
950
951@strong{Returns:} Returns 0 on success, or an error code.
952@end deftypefun
953
954@subheading gnutls_x509_crt_get_fingerprint
955@anchor{gnutls_x509_crt_get_fingerprint}
956@deftypefun {int} {gnutls_x509_crt_get_fingerprint} (gnutls_x509_crt_t @var{cert}, gnutls_digest_algorithm_t @var{algo}, void * @var{buf}, size_t * @var{sizeof_buf})
957@var{cert}: should contain a gnutls_x509_crt_t structure
958
959@var{algo}: is a digest algorithm
960
961@var{buf}: a pointer to a structure to hold the fingerprint (may be null)
962
963@var{sizeof_buf}: initially holds the size of @code{buf}
964
965This function will calculate and copy the certificate's fingerprint
966in the provided buffer.
967
968If the buffer is null then only the size will be filled.
969
970@strong{Returns:} @code{GNUTLS_E_SHORT_MEMORY_BUFFER} if the provided buffer is
971not long enough, and in that case the *sizeof_buf will be updated
972with the required size. On success 0 is returned.
973@end deftypefun
974
975@subheading gnutls_x509_crt_export
976@anchor{gnutls_x509_crt_export}
977@deftypefun {int} {gnutls_x509_crt_export} (gnutls_x509_crt_t @var{cert}, gnutls_x509_crt_fmt_t @var{format}, void * @var{output_data}, size_t * @var{output_data_size})
978@var{cert}: Holds the certificate
979
980@var{format}: the format of output params. One of PEM or DER.
981
982@var{output_data}: will contain a certificate PEM or DER encoded
983
984@var{output_data_size}: holds the size of output_data (and will be
985replaced by the actual size of parameters)
986
987This function will export the certificate to DER or PEM format.
988
989If the buffer provided is not long enough to hold the output, then
990*output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
991be returned.
992
993If the structure is PEM encoded, it will have a header
994of "BEGIN CERTIFICATE".
995
996@strong{Return value:} In case of failure a negative value will be
997returned, and 0 on success.
998@end deftypefun
999
1000@subheading gnutls_x509_crt_get_key_id
1001@anchor{gnutls_x509_crt_get_key_id}
1002@deftypefun {int} {gnutls_x509_crt_get_key_id} (gnutls_x509_crt_t @var{crt}, unsigned int @var{flags}, unsigned char * @var{output_data}, size_t * @var{output_data_size})
1003@var{crt}: Holds the certificate
1004
1005@var{flags}: should be 0 for now
1006
1007@var{output_data}: will contain the key ID
1008
1009@var{output_data_size}: holds the size of output_data (and will be
1010replaced by the actual size of parameters)
1011
1012This function will return a unique ID the depends on the public
1013key parameters. This ID can be used in checking whether a
1014certificate corresponds to the given private key.
1015
1016If the buffer provided is not long enough to hold the output, then
1017*output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
1018be returned. The output will normally be a SHA-1 hash output,
1019which is 20 bytes.
1020
1021@strong{Return value:} In case of failure a negative value will be
1022returned, and 0 on success.
1023@end deftypefun
1024
1025@subheading gnutls_x509_crt_check_revocation
1026@anchor{gnutls_x509_crt_check_revocation}
1027@deftypefun {int} {gnutls_x509_crt_check_revocation} (gnutls_x509_crt_t @var{cert}, const gnutls_x509_crl_t * @var{crl_list}, int @var{crl_list_length})
1028@var{cert}: should contain a gnutls_x509_crt_t structure
1029
1030@var{crl_list}: should contain a list of gnutls_x509_crl_t structures
1031
1032@var{crl_list_length}: the length of the crl_list
1033
1034This function will return check if the given certificate is
1035revoked. It is assumed that the CRLs have been verified before.
1036
1037@strong{Returns:} 0 if the certificate is NOT revoked, and 1 if it is. A
1038negative value is returned on error.
1039@end deftypefun
1040
1041@subheading gnutls_x509_crt_verify_data
1042@anchor{gnutls_x509_crt_verify_data}
1043@deftypefun {int} {gnutls_x509_crt_verify_data} (gnutls_x509_crt_t @var{crt}, unsigned int @var{flags}, const gnutls_datum_t * @var{data}, const gnutls_datum_t * @var{signature})
1044@var{crt}: Holds the certificate
1045
1046@var{flags}: should be 0 for now
1047
1048@var{data}: holds the data to be signed
1049
1050@var{signature}: contains the signature
1051
1052This function will verify the given signed data, using the
1053parameters from the certificate.
1054
1055@strong{Returns:} In case of a verification failure 0 is returned, and 1 on
1056success.
1057@end deftypefun
1058
1059@subheading gnutls_x509_crt_get_crl_dist_points
1060@anchor{gnutls_x509_crt_get_crl_dist_points}
1061@deftypefun {int} {gnutls_x509_crt_get_crl_dist_points} (gnutls_x509_crt_t @var{cert}, unsigned int @var{seq}, void * @var{ret}, size_t * @var{ret_size}, unsigned int * @var{reason_flags}, unsigned int * @var{critical})
1062@var{cert}: should contain a gnutls_x509_crt_t structure
1063
1064@var{seq}: specifies the sequence number of the distribution point (0 for the first one, 1 for the second etc.)
1065
1066@var{ret}: is the place where the distribution point will be copied to
1067
1068@var{ret_size}: holds the size of ret.
1069
1070@var{reason_flags}: Revocation reasons flags.
1071
1072@var{critical}: will be non zero if the extension is marked as critical (may be null)
1073
1074This function will return the CRL distribution points (2.5.29.31),
1075contained in the given certificate.
1076
1077@code{reason_flags} should be an ORed sequence of
1078GNUTLS_CRL_REASON_UNUSED, GNUTLS_CRL_REASON_KEY_COMPROMISE,
1079GNUTLS_CRL_REASON_CA_COMPROMISE,
1080GNUTLS_CRL_REASON_AFFILIATION_CHANGED,
1081GNUTLS_CRL_REASON_SUPERSEEDED,
1082GNUTLS_CRL_REASON_CESSATION_OF_OPERATION,
1083GNUTLS_CRL_REASON_CERTIFICATE_HOLD,
1084GNUTLS_CRL_REASON_PRIVILEGE_WITHDRAWN,
1085GNUTLS_CRL_REASON_AA_COMPROMISE, or zero for all possible reasons.
1086
1087This is specified in X509v3 Certificate Extensions. GNUTLS will
1088return the distribution point type, or a negative error code on
1089error.
1090
1091Returns @code{GNUTLS_E_SHORT_MEMORY_BUFFER} and updates &@code{ret_size} if
1092&@code{ret_size} is not enough to hold the distribution point, or the
1093type of the distribution point if everything was ok. The type is
1094one of the enumerated @code{gnutls_x509_subject_alt_name_t}. If the
1095certificate does not have an Alternative name with the specified
1096sequence number then @code{GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE} is
1097returned.
1098@end deftypefun
1099
1100@subheading gnutls_x509_crt_get_key_purpose_oid
1101@anchor{gnutls_x509_crt_get_key_purpose_oid}
1102@deftypefun {int} {gnutls_x509_crt_get_key_purpose_oid} (gnutls_x509_crt_t @var{cert}, int @var{indx}, void * @var{oid}, size_t * @var{sizeof_oid}, unsigned int * @var{critical})
1103@var{cert}: should contain a gnutls_x509_crt_t structure
1104
1105@var{indx}: This specifies which OID to return. Use zero to get the first one.
1106
1107@var{oid}: a pointer to a buffer to hold the OID (may be null)
1108
1109@var{sizeof_oid}: initially holds the size of @code{oid}
1110
1111This function will extract the key purpose OIDs of the Certificate
1112specified by the given index. These are stored in the Extended Key
1113Usage extension (2.5.29.37) See the GNUTLS_KP_* definitions for
1114human readable names.
1115
1116If @code{oid} is null then only the size will be filled.
1117
1118@strong{Returns:} @code{GNUTLS_E_SHORT_MEMORY_BUFFER} if the provided buffer is
1119not long enough, and in that case the *sizeof_oid will be updated
1120with the required size. On success 0 is returned.
1121@end deftypefun
1122
1123@subheading gnutls_x509_crt_get_pk_rsa_raw
1124@anchor{gnutls_x509_crt_get_pk_rsa_raw}
1125@deftypefun {int} {gnutls_x509_crt_get_pk_rsa_raw} (gnutls_x509_crt_t @var{crt}, gnutls_datum_t * @var{m}, gnutls_datum_t * @var{e})
1126@var{crt}: Holds the certificate
1127
1128@var{m}: will hold the modulus
1129
1130@var{e}: will hold the public exponent
1131
1132This function will export the RSA public key's parameters found in
1133the given structure. The new parameters will be allocated using
1134@code{gnutls_malloc()} and will be stored in the appropriate datum.
1135
1136@strong{Returns:} @code{GNUTLS_E_SUCCESS} on success, otherwise an error.
1137@end deftypefun
1138
1139@subheading gnutls_x509_crt_get_pk_dsa_raw
1140@anchor{gnutls_x509_crt_get_pk_dsa_raw}
1141@deftypefun {int} {gnutls_x509_crt_get_pk_dsa_raw} (gnutls_x509_crt_t @var{crt}, gnutls_datum_t * @var{p}, gnutls_datum_t * @var{q}, gnutls_datum_t * @var{g}, gnutls_datum_t * @var{y})
1142@var{crt}: Holds the certificate
1143
1144@var{p}: will hold the p
1145
1146@var{q}: will hold the q
1147
1148@var{g}: will hold the g
1149
1150@var{y}: will hold the y
1151
1152This function will export the DSA public key's parameters found in
1153the given certificate. The new parameters will be allocated using
1154@code{gnutls_malloc()} and will be stored in the appropriate datum.
1155
1156@strong{Returns:} @code{GNUTLS_E_SUCCESS} on success, otherwise an error.
1157@end deftypefun
1158
1159@subheading gnutls_x509_crt_list_import
1160@anchor{gnutls_x509_crt_list_import}
1161@deftypefun {int} {gnutls_x509_crt_list_import} (gnutls_x509_crt_t * @var{certs}, unsigned int * @var{cert_max}, const gnutls_datum_t * @var{data}, gnutls_x509_crt_fmt_t @var{format}, unsigned int @var{flags})
1162@var{certs}: The structures to store the parsed certificate. Must not be initialized.
1163
1164@var{cert_max}: Initially must hold the maximum number of certs. It will be updated with the number of certs available.
1165
1166@var{data}: The PEM encoded certificate.
1167
1168@var{format}: One of DER or PEM.
1169
1170@var{flags}: must be zero or an OR'd sequence of gnutls_certificate_import_flags.
1171
1172This function will convert the given PEM encoded certificate list
1173to the native gnutls_x509_crt_t format. The output will be stored
1174in @code{certs}. They will be automatically initialized.
1175
1176If the Certificate is PEM encoded it should have a header of "X509
1177CERTIFICATE", or "CERTIFICATE".
1178
1179@strong{Returns:} the number of certificates read or a negative error value.
1180@end deftypefun
1181
1182@subheading gnutls_x509_crt_check_hostname
1183@anchor{gnutls_x509_crt_check_hostname}
1184@deftypefun {int} {gnutls_x509_crt_check_hostname} (gnutls_x509_crt_t @var{cert}, const char * @var{hostname})
1185@var{cert}: should contain an gnutls_x509_crt_t structure
1186
1187@var{hostname}: A null terminated string that contains a DNS name
1188
1189This function will check if the given certificate's subject
1190matches the given hostname. This is a basic implementation of the
1191matching described in RFC2818 (HTTPS), which takes into account
1192wildcards, and the DNSName/IPAddress subject alternative name PKIX
1193extension.
1194
1195Returns non zero for a successful match, and zero on failure.
1196@end deftypefun
1197
1198@subheading gnutls_x509_crt_check_issuer
1199@anchor{gnutls_x509_crt_check_issuer}
1200@deftypefun {int} {gnutls_x509_crt_check_issuer} (gnutls_x509_crt_t @var{cert}, gnutls_x509_crt_t @var{issuer})
1201@var{cert}: is the certificate to be checked
1202
1203@var{issuer}: is the certificate of a possible issuer
1204
1205This function will check if the given certificate was issued by the
1206given issuer. It will return true (1) if the given certificate is issued
1207by the given issuer, and false (0) if not.
1208
1209A negative value is returned in case of an error.
1210@end deftypefun
1211
1212@subheading gnutls_x509_crt_list_verify
1213@anchor{gnutls_x509_crt_list_verify}
1214@deftypefun {int} {gnutls_x509_crt_list_verify} (const gnutls_x509_crt_t * @var{cert_list}, int @var{cert_list_length}, const gnutls_x509_crt_t * @var{CA_list}, int @var{CA_list_length}, const gnutls_x509_crl_t * @var{CRL_list}, int @var{CRL_list_length}, unsigned int @var{flags}, unsigned int * @var{verify})
1215@var{cert_list}: is the certificate list to be verified
1216
1217@var{cert_list_length}: holds the number of certificate in cert_list
1218
1219@var{CA_list}: is the CA list which will be used in verification
1220
1221@var{CA_list_length}: holds the number of CA certificate in CA_list
1222
1223@var{CRL_list}: holds a list of CRLs.
1224
1225@var{CRL_list_length}: the length of CRL list.
1226
1227@var{flags}: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
1228
1229@var{verify}: will hold the certificate verification output.
1230
1231This function will try to verify the given certificate list and return its status.
1232Note that expiration and activation dates are not checked
1233by this function, you should check them using the appropriate functions.
1234
1235If no flags are specified (0), this function will use the
1236basicConstraints (2.5.29.19) PKIX extension. This means that only a certificate
1237authority is allowed to sign a certificate.
1238
1239You must also check the peer's name in order to check if the verified
1240certificate belongs to the actual peer.
1241
1242The certificate verification output will be put in @code{verify} and will be
1243one or more of the gnutls_certificate_status_t enumerated elements bitwise or'd.
1244For a more detailed verification status use @code{gnutls_x509_crt_verify()} per list
1245element.
1246
1247@strong{GNUTLS_CERT_INVALID:} the certificate chain is not valid.
1248
1249@strong{GNUTLS_CERT_REVOKED:} a certificate in the chain has been revoked.
1250
1251Returns 0 on success and a negative value in case of an error.
1252@end deftypefun
1253
1254@subheading gnutls_x509_crt_verify
1255@anchor{gnutls_x509_crt_verify}
1256@deftypefun {int} {gnutls_x509_crt_verify} (gnutls_x509_crt_t @var{cert}, const gnutls_x509_crt_t * @var{CA_list}, int @var{CA_list_length}, unsigned int @var{flags}, unsigned int * @var{verify})
1257@var{cert}: is the certificate to be verified
1258
1259@var{CA_list}: is one certificate that is considered to be trusted one
1260
1261@var{CA_list_length}: holds the number of CA certificate in CA_list
1262
1263@var{flags}: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
1264
1265@var{verify}: will hold the certificate verification output.
1266
1267This function will try to verify the given certificate and return its status.
1268The verification output in this functions cannot be GNUTLS_CERT_NOT_VALID.
1269
1270Returns 0 on success and a negative value in case of an error.
1271@end deftypefun
1272
1273@subheading gnutls_x509_crl_check_issuer
1274@anchor{gnutls_x509_crl_check_issuer}
1275@deftypefun {int} {gnutls_x509_crl_check_issuer} (gnutls_x509_crl_t @var{cert}, gnutls_x509_crt_t @var{issuer})
1276@var{issuer}: is the certificate of a possible issuer
1277
1278This function will check if the given CRL was issued by the
1279given issuer certificate. It will return true (1) if the given CRL was issued
1280by the given issuer, and false (0) if not.
1281
1282A negative value is returned in case of an error.
1283@end deftypefun
1284
1285@subheading gnutls_x509_crl_verify
1286@anchor{gnutls_x509_crl_verify}
1287@deftypefun {int} {gnutls_x509_crl_verify} (gnutls_x509_crl_t @var{crl}, const gnutls_x509_crt_t * @var{CA_list}, int @var{CA_list_length}, unsigned int @var{flags}, unsigned int * @var{verify})
1288@var{crl}: is the crl to be verified
1289
1290@var{CA_list}: is a certificate list that is considered to be trusted one
1291
1292@var{CA_list_length}: holds the number of CA certificates in CA_list
1293
1294@var{flags}: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
1295
1296@var{verify}: will hold the crl verification output.
1297
1298This function will try to verify the given crl and return its status.
1299See @code{gnutls_x509_crt_list_verify()} for a detailed description of
1300return values.
1301
1302Returns 0 on success and a negative value in case of an error.
1303@end deftypefun
1304
1305@subheading gnutls_x509_privkey_init
1306@anchor{gnutls_x509_privkey_init}
1307@deftypefun {int} {gnutls_x509_privkey_init} (gnutls_x509_privkey_t * @var{key})
1308@var{key}: The structure to be initialized
1309
1310This function will initialize an private key structure.
1311
1312Returns 0 on success.
1313@end deftypefun
1314
1315@subheading gnutls_x509_privkey_deinit
1316@anchor{gnutls_x509_privkey_deinit}
1317@deftypefun {void} {gnutls_x509_privkey_deinit} (gnutls_x509_privkey_t @var{key})
1318@var{key}: The structure to be initialized
1319
1320This function will deinitialize a private key structure.
1321@end deftypefun
1322
1323@subheading gnutls_x509_privkey_cpy
1324@anchor{gnutls_x509_privkey_cpy}
1325@deftypefun {int} {gnutls_x509_privkey_cpy} (gnutls_x509_privkey_t @var{dst}, gnutls_x509_privkey_t @var{src})
1326@var{dst}: The destination key, which should be initialized.
1327
1328@var{src}: The source key
1329
1330This function will copy a private key from source to destination key.
1331@end deftypefun
1332
1333@subheading gnutls_x509_privkey_import
1334@anchor{gnutls_x509_privkey_import}
1335@deftypefun {int} {gnutls_x509_privkey_import} (gnutls_x509_privkey_t @var{key}, const gnutls_datum_t * @var{data}, gnutls_x509_crt_fmt_t @var{format})
1336@var{key}: The structure to store the parsed key
1337
1338@var{data}: The DER or PEM encoded certificate.
1339
1340@var{format}: One of DER or PEM
1341
1342This function will convert the given DER or PEM encoded key
1343to the native gnutls_x509_privkey_t format. The output will be stored in @code{key} .
1344
1345If the key is PEM encoded it should have a header of "RSA PRIVATE KEY", or
1346"DSA PRIVATE KEY".
1347
1348Returns 0 on success.
1349@end deftypefun
1350
1351@subheading gnutls_x509_privkey_import_rsa_raw
1352@anchor{gnutls_x509_privkey_import_rsa_raw}
1353@deftypefun {int} {gnutls_x509_privkey_import_rsa_raw} (gnutls_x509_privkey_t @var{key}, const gnutls_datum_t * @var{m}, const gnutls_datum_t * @var{e}, const gnutls_datum_t * @var{d}, const gnutls_datum_t * @var{p}, const gnutls_datum_t * @var{q}, const gnutls_datum_t * @var{u})
1354@var{key}: The structure to store the parsed key
1355
1356@var{m}: holds the modulus
1357
1358@var{e}: holds the public exponent
1359
1360@var{d}: holds the private exponent
1361
1362@var{p}: holds the first prime (p)
1363
1364@var{q}: holds the second prime (q)
1365
1366@var{u}: holds the coefficient
1367
1368This function will convert the given RSA raw parameters
1369to the native gnutls_x509_privkey_t format. The output will be stored in @code{key}.
1370@end deftypefun
1371
1372@subheading gnutls_x509_privkey_import_dsa_raw
1373@anchor{gnutls_x509_privkey_import_dsa_raw}
1374@deftypefun {int} {gnutls_x509_privkey_import_dsa_raw} (gnutls_x509_privkey_t @var{key}, const gnutls_datum_t * @var{p}, const gnutls_datum_t * @var{q}, const gnutls_datum_t * @var{g}, const gnutls_datum_t * @var{y}, const gnutls_datum_t * @var{x})
1375@var{key}: The structure to store the parsed key
1376
1377@var{p}: holds the p
1378
1379@var{q}: holds the q
1380
1381@var{g}: holds the g
1382
1383@var{y}: holds the y
1384
1385@var{x}: holds the x
1386
1387This function will convert the given DSA raw parameters
1388to the native gnutls_x509_privkey_t format. The output will be stored in @code{key}.
1389@end deftypefun
1390
1391@subheading gnutls_x509_privkey_get_pk_algorithm
1392@anchor{gnutls_x509_privkey_get_pk_algorithm}
1393@deftypefun {int} {gnutls_x509_privkey_get_pk_algorithm} (gnutls_x509_privkey_t @var{key})
1394@var{key}: should contain a gnutls_x509_privkey_t structure
1395
1396This function will return the public key algorithm of a private
1397key.
1398
1399Returns a member of the gnutls_pk_algorithm_t enumeration on success,
1400or a negative value on error.
1401@end deftypefun
1402
1403@subheading gnutls_x509_privkey_export
1404@anchor{gnutls_x509_privkey_export}
1405@deftypefun {int} {gnutls_x509_privkey_export} (gnutls_x509_privkey_t @var{key}, gnutls_x509_crt_fmt_t @var{format}, void * @var{output_data}, size_t * @var{output_data_size})
1406@var{key}: Holds the key
1407
1408@var{format}: the format of output params. One of PEM or DER.
1409
1410@var{output_data}: will contain a private key PEM or DER encoded
1411
1412@var{output_data_size}: holds the size of output_data (and will be
1413replaced by the actual size of parameters)
1414
1415This function will export the private key to a PKCS1 structure for
1416RSA keys, or an integer sequence for DSA keys. The DSA keys are in
1417the same format with the parameters used by openssl.
1418
1419If the buffer provided is not long enough to hold the output, then
1420*output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
1421be returned.
1422
1423If the structure is PEM encoded, it will have a header
1424of "BEGIN RSA PRIVATE KEY".
1425
1426@strong{Return value:} In case of failure a negative value will be
1427returned, and 0 on success.
1428@end deftypefun
1429
1430@subheading gnutls_x509_privkey_export_rsa_raw
1431@anchor{gnutls_x509_privkey_export_rsa_raw}
1432@deftypefun {int} {gnutls_x509_privkey_export_rsa_raw} (gnutls_x509_privkey_t @var{key}, gnutls_datum_t * @var{m}, gnutls_datum_t * @var{e}, gnutls_datum_t * @var{d}, gnutls_datum_t * @var{p}, gnutls_datum_t * @var{q}, gnutls_datum_t * @var{u})
1433@var{key}: a structure that holds the rsa parameters
1434
1435@var{m}: will hold the modulus
1436
1437@var{e}: will hold the public exponent
1438
1439@var{d}: will hold the private exponent
1440
1441@var{p}: will hold the first prime (p)
1442
1443@var{q}: will hold the second prime (q)
1444
1445@var{u}: will hold the coefficient
1446
1447This function will export the RSA private key's parameters found in the given
1448structure. The new parameters will be allocated using
1449@code{gnutls_malloc()} and will be stored in the appropriate datum.
1450@end deftypefun
1451
1452@subheading gnutls_x509_privkey_export_dsa_raw
1453@anchor{gnutls_x509_privkey_export_dsa_raw}
1454@deftypefun {int} {gnutls_x509_privkey_export_dsa_raw} (gnutls_x509_privkey_t @var{key}, gnutls_datum_t * @var{p}, gnutls_datum_t * @var{q}, gnutls_datum_t * @var{g}, gnutls_datum_t * @var{y}, gnutls_datum_t * @var{x})
1455@var{p}: will hold the p
1456
1457@var{q}: will hold the q
1458
1459@var{g}: will hold the g
1460
1461@var{y}: will hold the y
1462
1463@var{x}: will hold the x
1464
1465This function will export the DSA private key's parameters found in the given
1466structure. The new parameters will be allocated using
1467@code{gnutls_malloc()} and will be stored in the appropriate datum.
1468@end deftypefun
1469
1470@subheading gnutls_x509_privkey_generate
1471@anchor{gnutls_x509_privkey_generate}
1472@deftypefun {int} {gnutls_x509_privkey_generate} (gnutls_x509_privkey_t @var{key}, gnutls_pk_algorithm_t @var{algo}, unsigned int @var{bits}, unsigned int @var{flags})
1473@var{key}: should contain a gnutls_x509_privkey_t structure
1474
1475@var{algo}: is one of RSA or DSA.
1476
1477@var{bits}: the size of the modulus
1478
1479@var{flags}: unused for now. Must be 0.
1480
1481This function will generate a random private key. Note that
1482this function must be called on an empty private key.
1483
1484Returns 0 on success or a negative value on error.
1485@end deftypefun
1486
1487@subheading gnutls_x509_privkey_get_key_id
1488@anchor{gnutls_x509_privkey_get_key_id}
1489@deftypefun {int} {gnutls_x509_privkey_get_key_id} (gnutls_x509_privkey_t @var{key}, unsigned int @var{flags}, unsigned char * @var{output_data}, size_t * @var{output_data_size})
1490@var{key}: Holds the key
1491
1492@var{flags}: should be 0 for now
1493
1494@var{output_data}: will contain the key ID
1495
1496@var{output_data_size}: holds the size of output_data (and will be
1497replaced by the actual size of parameters)
1498
1499This function will return a unique ID the depends on the public key
1500parameters. This ID can be used in checking whether a certificate
1501corresponds to the given key.
1502
1503If the buffer provided is not long enough to hold the output, then
1504*output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
1505be returned. The output will normally be a SHA-1 hash output,
1506which is 20 bytes.
1507
1508@strong{Return value:} In case of failure a negative value will be
1509returned, and 0 on success.
1510@end deftypefun
1511
1512@subheading gnutls_x509_privkey_sign_data
1513@anchor{gnutls_x509_privkey_sign_data}
1514@deftypefun {int} {gnutls_x509_privkey_sign_data} (gnutls_x509_privkey_t @var{key}, gnutls_digest_algorithm_t @var{digest}, unsigned int @var{flags}, const gnutls_datum_t * @var{data}, void * @var{signature}, size_t * @var{signature_size})
1515@var{key}: Holds the key
1516
1517@var{digest}: should be MD5 or SHA1
1518
1519@var{flags}: should be 0 for now
1520
1521@var{data}: holds the data to be signed
1522
1523@var{signature}: will contain the signature
1524
1525@var{signature_size}: holds the size of signature (and will be replaced
1526by the new size)
1527
1528This function will sign the given data using a signature algorithm
1529supported by the private key. Signature algorithms are always used
1530together with a hash functions. Different hash functions may be
1531used for the RSA algorithm, but only SHA-1 for the DSA keys.
1532
1533If the buffer provided is not long enough to hold the output, then
1534*signature_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
1535be returned.
1536
1537In case of failure a negative value will be returned, and
15380 on success.
1539@end deftypefun
1540
1541@subheading gnutls_x509_privkey_sign_hash
1542@anchor{gnutls_x509_privkey_sign_hash}
1543@deftypefun {int} {gnutls_x509_privkey_sign_hash} (gnutls_x509_privkey_t @var{key}, const gnutls_datum_t * @var{hash}, gnutls_datum_t * @var{signature})
1544@var{key}: Holds the key
1545
1546@var{hash}: holds the data to be signed
1547
1548@var{signature}: will contain newly allocated signature
1549
1550This function will sign the given hash using the private key.
1551
1552@strong{Return value:} In case of failure a negative value will be returned,
1553and 0 on success.
1554@end deftypefun
1555
1556@subheading gnutls_x509_privkey_verify_data
1557@anchor{gnutls_x509_privkey_verify_data}
1558@deftypefun {int} {gnutls_x509_privkey_verify_data} (gnutls_x509_privkey_t @var{key}, unsigned int @var{flags}, const gnutls_datum_t * @var{data}, const gnutls_datum_t * @var{signature})
1559@var{key}: Holds the key
1560
1561@var{flags}: should be 0 for now
1562
1563@var{data}: holds the data to be signed
1564
1565@var{signature}: contains the signature
1566
1567This function will verify the given signed data, using the parameters in the
1568private key.
1569
1570In case of a verification failure 0 is returned, and
15711 on success.
1572@end deftypefun
1573
1574@subheading gnutls_x509_privkey_fix
1575@anchor{gnutls_x509_privkey_fix}
1576@deftypefun {int} {gnutls_x509_privkey_fix} (gnutls_x509_privkey_t @var{key})
1577@var{key}: Holds the key
1578
1579This function will recalculate the secondary parameters in a key.
1580In RSA keys, this can be the coefficient and exponent1,2.
1581
1582@strong{Return value:} In case of failure a negative value will be
1583returned, and 0 on success.
1584@end deftypefun
1585
1586@subheading gnutls_pkcs7_init
1587@anchor{gnutls_pkcs7_init}
1588@deftypefun {int} {gnutls_pkcs7_init} (gnutls_pkcs7_t * @var{pkcs7})
1589@var{pkcs7}: The structure to be initialized
1590
1591This function will initialize a PKCS7 structure. PKCS7 structures
1592usually contain lists of X.509 Certificates and X.509 Certificate
1593revocation lists.
1594
1595Returns 0 on success.
1596@end deftypefun
1597
1598@subheading gnutls_pkcs7_deinit
1599@anchor{gnutls_pkcs7_deinit}
1600@deftypefun {void} {gnutls_pkcs7_deinit} (gnutls_pkcs7_t @var{pkcs7})
1601@var{pkcs7}: The structure to be initialized
1602
1603This function will deinitialize a PKCS7 structure.
1604@end deftypefun
1605
1606@subheading gnutls_pkcs7_import
1607@anchor{gnutls_pkcs7_import}
1608@deftypefun {int} {gnutls_pkcs7_import} (gnutls_pkcs7_t @var{pkcs7}, const gnutls_datum_t * @var{data}, gnutls_x509_crt_fmt_t @var{format})
1609@var{pkcs7}: The structure to store the parsed PKCS7.
1610
1611@var{data}: The DER or PEM encoded PKCS7.
1612
1613@var{format}: One of DER or PEM
1614
1615This function will convert the given DER or PEM encoded PKCS7
1616to the native gnutls_pkcs7_t format. The output will be stored in 'pkcs7'.
1617
1618If the PKCS7 is PEM encoded it should have a header of "PKCS7".
1619
1620Returns 0 on success.
1621@end deftypefun
1622
1623@subheading gnutls_pkcs7_get_crt_raw
1624@anchor{gnutls_pkcs7_get_crt_raw}
1625@deftypefun {int} {gnutls_pkcs7_get_crt_raw} (gnutls_pkcs7_t @var{pkcs7}, int @var{indx}, void * @var{certificate}, size_t * @var{certificate_size})
1626@var{indx}: contains the index of the certificate to extract
1627
1628@var{certificate}: the contents of the certificate will be copied there (may be null)
1629
1630@var{certificate_size}: should hold the size of the certificate
1631
1632This function will return a certificate of the PKCS7 or RFC2630 certificate set.
1633Returns 0 on success. If the provided buffer is not long enough,
1634then @code{certificate_size} is updated and GNUTLS_E_SHORT_MEMORY_BUFFER is returned.
1635
1636After the last certificate has been read GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1637will be returned.
1638@end deftypefun
1639
1640@subheading gnutls_pkcs7_get_crt_count
1641@anchor{gnutls_pkcs7_get_crt_count}
1642@deftypefun {int} {gnutls_pkcs7_get_crt_count} (gnutls_pkcs7_t @var{pkcs7})
1643This function will return the number of certifcates in the PKCS7 or
1644RFC2630 certificate set.
1645
1646Returns a negative value on failure.
1647@end deftypefun
1648
1649@subheading gnutls_pkcs7_export
1650@anchor{gnutls_pkcs7_export}
1651@deftypefun {int} {gnutls_pkcs7_export} (gnutls_pkcs7_t @var{pkcs7}, gnutls_x509_crt_fmt_t @var{format}, void * @var{output_data}, size_t * @var{output_data_size})
1652@var{pkcs7}: Holds the pkcs7 structure
1653
1654@var{format}: the format of output params. One of PEM or DER.
1655
1656@var{output_data}: will contain a structure PEM or DER encoded
1657
1658@var{output_data_size}: holds the size of output_data (and will be
1659replaced by the actual size of parameters)
1660
1661This function will export the pkcs7 structure to DER or PEM format.
1662
1663If the buffer provided is not long enough to hold the output, then
1664*output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
1665be returned.
1666
1667If the structure is PEM encoded, it will have a header
1668of "BEGIN PKCS7".
1669
1670@strong{Return value:} In case of failure a negative value will be
1671returned, and 0 on success.
1672@end deftypefun
1673
1674@subheading gnutls_pkcs7_set_crt_raw
1675@anchor{gnutls_pkcs7_set_crt_raw}
1676@deftypefun {int} {gnutls_pkcs7_set_crt_raw} (gnutls_pkcs7_t @var{pkcs7}, const gnutls_datum_t * @var{crt})
1677@var{crt}: the DER encoded certificate to be added
1678
1679This function will add a certificate to the PKCS7 or RFC2630 certificate set.
1680Returns 0 on success.
1681@end deftypefun
1682
1683@subheading gnutls_pkcs7_set_crt
1684@anchor{gnutls_pkcs7_set_crt}
1685@deftypefun {int} {gnutls_pkcs7_set_crt} (gnutls_pkcs7_t @var{pkcs7}, gnutls_x509_crt_t @var{crt})
1686@var{crt}: the certificate to be copied.
1687
1688This function will add a parsed certificate to the PKCS7 or RFC2630 certificate set.
1689This is a wrapper function over @code{gnutls_pkcs7_set_crt_raw()} .
1690
1691Returns 0 on success.
1692@end deftypefun
1693
1694@subheading gnutls_pkcs7_delete_crt
1695@anchor{gnutls_pkcs7_delete_crt}
1696@deftypefun {int} {gnutls_pkcs7_delete_crt} (gnutls_pkcs7_t @var{pkcs7}, int @var{indx})
1697@var{indx}: the index of the certificate to delete
1698
1699This function will delete a certificate from a PKCS7 or RFC2630 certificate set.
1700Index starts from 0. Returns 0 on success.
1701@end deftypefun
1702
1703@subheading gnutls_pkcs7_get_crl_raw
1704@anchor{gnutls_pkcs7_get_crl_raw}
1705@deftypefun {int} {gnutls_pkcs7_get_crl_raw} (gnutls_pkcs7_t @var{pkcs7}, int @var{indx}, void * @var{crl}, size_t * @var{crl_size})
1706@var{indx}: contains the index of the crl to extract
1707
1708@var{crl}: the contents of the crl will be copied there (may be null)
1709
1710@var{crl_size}: should hold the size of the crl
1711
1712This function will return a crl of the PKCS7 or RFC2630 crl set.
1713Returns 0 on success. If the provided buffer is not long enough,
1714then @code{crl_size} is updated and GNUTLS_E_SHORT_MEMORY_BUFFER is returned.
1715
1716After the last crl has been read GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
1717will be returned.
1718@end deftypefun
1719
1720@subheading gnutls_pkcs7_get_crl_count
1721@anchor{gnutls_pkcs7_get_crl_count}
1722@deftypefun {int} {gnutls_pkcs7_get_crl_count} (gnutls_pkcs7_t @var{pkcs7})
1723This function will return the number of certifcates in the PKCS7 or
1724RFC2630 crl set.
1725
1726Returns a negative value on failure.
1727@end deftypefun
1728
1729@subheading gnutls_pkcs7_set_crl_raw
1730@anchor{gnutls_pkcs7_set_crl_raw}
1731@deftypefun {int} {gnutls_pkcs7_set_crl_raw} (gnutls_pkcs7_t @var{pkcs7}, const gnutls_datum_t * @var{crl})
1732@var{crl}: the DER encoded crl to be added
1733
1734This function will add a crl to the PKCS7 or RFC2630 crl set.
1735Returns 0 on success.
1736@end deftypefun
1737
1738@subheading gnutls_pkcs7_set_crl
1739@anchor{gnutls_pkcs7_set_crl}
1740@deftypefun {int} {gnutls_pkcs7_set_crl} (gnutls_pkcs7_t @var{pkcs7}, gnutls_x509_crl_t @var{crl})
1741@var{crl}: the DER encoded crl to be added
1742
1743This function will add a parsed crl to the PKCS7 or RFC2630 crl set.
1744Returns 0 on success.
1745@end deftypefun
1746
1747@subheading gnutls_pkcs7_delete_crl
1748@anchor{gnutls_pkcs7_delete_crl}
1749@deftypefun {int} {gnutls_pkcs7_delete_crl} (gnutls_pkcs7_t @var{pkcs7}, int @var{indx})
1750@var{indx}: the index of the crl to delete
1751
1752This function will delete a crl from a PKCS7 or RFC2630 crl set.
1753Index starts from 0. Returns 0 on success.
1754@end deftypefun
1755
1756@subheading gnutls_x509_crq_init
1757@anchor{gnutls_x509_crq_init}
1758@deftypefun {int} {gnutls_x509_crq_init} (gnutls_x509_crq_t * @var{crq})
1759@var{crq}: The structure to be initialized
1760
1761This function will initialize a PKCS10 certificate request structure.
1762
1763Returns 0 on success.
1764@end deftypefun
1765
1766@subheading gnutls_x509_crq_deinit
1767@anchor{gnutls_x509_crq_deinit}
1768@deftypefun {void} {gnutls_x509_crq_deinit} (gnutls_x509_crq_t @var{crq})
1769@var{crq}: The structure to be initialized
1770
1771This function will deinitialize a CRL structure.
1772@end deftypefun
1773
1774@subheading gnutls_x509_crq_import
1775@anchor{gnutls_x509_crq_import}
1776@deftypefun {int} {gnutls_x509_crq_import} (gnutls_x509_crq_t @var{crq}, const gnutls_datum_t * @var{data}, gnutls_x509_crt_fmt_t @var{format})
1777@var{crq}: The structure to store the parsed certificate request.
1778
1779@var{data}: The DER or PEM encoded certificate.
1780
1781@var{format}: One of DER or PEM
1782
1783This function will convert the given DER or PEM encoded Certificate
1784to the native gnutls_x509_crq_t format. The output will be stored in @code{cert}.
1785
1786If the Certificate is PEM encoded it should have a header of "NEW CERTIFICATE REQUEST".
1787
1788Returns 0 on success.
1789@end deftypefun
1790
1791@subheading gnutls_x509_crq_get_dn
1792@anchor{gnutls_x509_crq_get_dn}
1793@deftypefun {int} {gnutls_x509_crq_get_dn} (gnutls_x509_crq_t @var{crq}, char * @var{buf}, size_t * @var{sizeof_buf})
1794@var{crq}: should contain a gnutls_x509_crq_t structure
1795
1796@var{buf}: a pointer to a structure to hold the name (may be null)
1797
1798@var{sizeof_buf}: initially holds the size of @code{buf}
1799
1800This function will copy the name of the Certificate request
1801subject in the provided buffer. The name will be in the form
1802"C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output string
1803will be ASCII or UTF-8 encoded, depending on the certificate data.
1804
1805If @code{buf} is null then only the size will be filled.
1806
1807Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
1808long enough, and in that case the *sizeof_buf will be updated with
1809the required size. On success 0 is returned.
1810@end deftypefun
1811
1812@subheading gnutls_x509_crq_get_dn_by_oid
1813@anchor{gnutls_x509_crq_get_dn_by_oid}
1814@deftypefun {int} {gnutls_x509_crq_get_dn_by_oid} (gnutls_x509_crq_t @var{crq}, const char * @var{oid}, int @var{indx}, unsigned int @var{raw_flag}, void * @var{buf}, size_t * @var{sizeof_buf})
1815@var{crq}: should contain a gnutls_x509_crq_t structure
1816
1817@var{oid}: holds an Object Identified in null terminated string
1818
1819@var{indx}: In case multiple same OIDs exist in the RDN, this specifies
1820which to send. Use zero to get the first one.
1821
1822@var{raw_flag}: If non zero returns the raw DER data of the DN part.
1823
1824@var{buf}: a pointer to a structure to hold the name (may be null)
1825
1826@var{sizeof_buf}: initially holds the size of @code{buf}
1827
1828This function will extract the part of the name of the Certificate
1829request subject, specified by the given OID. The output will be
1830encoded as described in RFC2253. The output string will be ASCII
1831or UTF-8 encoded, depending on the certificate data.
1832
1833Some helper macros with popular OIDs can be found in gnutls/x509.h
1834If raw flag is zero, this function will only return known OIDs as
1835text. Other OIDs will be DER encoded, as described in RFC2253 --
1836in hex format with a '\#' prefix. You can check about known OIDs
1837using @code{gnutls_x509_dn_oid_known()}.
1838
1839If @code{buf} is null then only the size will be filled.
1840
1841Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
1842long enough, and in that case the *sizeof_buf will be updated with
1843the required size. On success 0 is returned.
1844@end deftypefun
1845
1846@subheading gnutls_x509_crq_get_dn_oid
1847@anchor{gnutls_x509_crq_get_dn_oid}
1848@deftypefun {int} {gnutls_x509_crq_get_dn_oid} (gnutls_x509_crq_t @var{crq}, int @var{indx}, void * @var{oid}, size_t * @var{sizeof_oid})
1849@var{crq}: should contain a gnutls_x509_crq_t structure
1850
1851@var{indx}: Specifies which DN OID to send. Use zero to get the first one.
1852
1853@var{oid}: a pointer to a structure to hold the name (may be null)
1854
1855@var{sizeof_oid}: initially holds the size of @code{oid}
1856
1857This function will extract the requested OID of the name of the
1858Certificate request subject, specified by the given index.
1859
1860If oid is null then only the size will be filled.
1861
1862Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
1863long enough, and in that case the *sizeof_oid will be updated with
1864the required size. On success 0 is returned.
1865@end deftypefun
1866
1867@subheading gnutls_x509_crq_get_challenge_password
1868@anchor{gnutls_x509_crq_get_challenge_password}
1869@deftypefun {int} {gnutls_x509_crq_get_challenge_password} (gnutls_x509_crq_t @var{crq}, char * @var{pass}, size_t * @var{sizeof_pass})
1870@var{crq}: should contain a gnutls_x509_crq_t structure
1871
1872@var{pass}: will hold a null terminated password
1873
1874@var{sizeof_pass}: Initially holds the size of @code{pass}.
1875
1876This function will return the challenge password in the
1877request.
1878
1879Returns 0 on success.
1880@end deftypefun
1881
1882@subheading gnutls_x509_crq_set_attribute_by_oid
1883@anchor{gnutls_x509_crq_set_attribute_by_oid}
1884@deftypefun {int} {gnutls_x509_crq_set_attribute_by_oid} (gnutls_x509_crq_t @var{crq}, const char * @var{oid}, void * @var{buf}, size_t @var{sizeof_buf})
1885@var{crq}: should contain a gnutls_x509_crq_t structure
1886
1887@var{oid}: holds an Object Identified in null terminated string
1888
1889@var{buf}: a pointer to a structure that holds the attribute data
1890
1891@var{sizeof_buf}: holds the size of @code{buf}
1892
1893This function will set the attribute in the certificate request specified
1894by the given Object ID. The attribute must be be DER encoded.
1895
1896Returns 0 on success.
1897@end deftypefun
1898
1899@subheading gnutls_x509_crq_get_attribute_by_oid
1900@anchor{gnutls_x509_crq_get_attribute_by_oid}
1901@deftypefun {int} {gnutls_x509_crq_get_attribute_by_oid} (gnutls_x509_crq_t @var{crq}, const char * @var{oid}, int @var{indx}, void * @var{buf}, size_t * @var{sizeof_buf})
1902@var{crq}: should contain a gnutls_x509_crq_t structure
1903
1904@var{oid}: holds an Object Identified in null terminated string
1905
1906@var{indx}: In case multiple same OIDs exist in the attribute list, this specifies
1907which to send. Use zero to get the first one.
1908
1909@var{buf}: a pointer to a structure to hold the attribute data (may be null)
1910
1911@var{sizeof_buf}: initially holds the size of @code{buf}
1912
1913This function will return the attribute in the certificate request specified
1914by the given Object ID. The attribute will be DER encoded.
1915
1916Returns 0 on success.
1917@end deftypefun
1918
1919@subheading gnutls_x509_crq_set_dn_by_oid
1920@anchor{gnutls_x509_crq_set_dn_by_oid}
1921@deftypefun {int} {gnutls_x509_crq_set_dn_by_oid} (gnutls_x509_crq_t @var{crq}, const char * @var{oid}, unsigned int @var{raw_flag}, const void * @var{data}, unsigned int @var{sizeof_data})
1922@var{crq}: should contain a gnutls_x509_crq_t structure
1923
1924@var{oid}: holds an Object Identifier in a null terminated string
1925
1926@var{raw_flag}: must be 0, or 1 if the data are DER encoded
1927
1928@var{data}: a pointer to the input data
1929
1930@var{sizeof_data}: holds the size of @code{data}
1931
1932This function will set the part of the name of the Certificate request subject, specified
1933by the given OID. The input string should be ASCII or UTF-8 encoded.
1934
1935Some helper macros with popular OIDs can be found in gnutls/x509.h
1936With this function you can only set the known OIDs. You can test
1937for known OIDs using @code{gnutls_x509_dn_oid_known()}. For OIDs that are
1938not known (by gnutls) you should properly DER encode your data, and
1939call this function with raw_flag set.
1940
1941Returns 0 on success.
1942@end deftypefun
1943
1944@subheading gnutls_x509_crq_set_version
1945@anchor{gnutls_x509_crq_set_version}
1946@deftypefun {int} {gnutls_x509_crq_set_version} (gnutls_x509_crq_t @var{crq}, unsigned int @var{version})
1947@var{crq}: should contain a gnutls_x509_crq_t structure
1948
1949@var{version}: holds the version number. For v1 Requests must be 1.
1950
1951This function will set the version of the certificate request. For
1952version 1 requests this must be one.
1953
1954Returns 0 on success.
1955@end deftypefun
1956
1957@subheading gnutls_x509_crq_get_version
1958@anchor{gnutls_x509_crq_get_version}
1959@deftypefun {int} {gnutls_x509_crq_get_version} (gnutls_x509_crq_t @var{crq})
1960@var{crq}: should contain a gnutls_x509_crq_t structure
1961
1962This function will return the version of the specified Certificate request.
1963
1964Returns a negative value on error.
1965@end deftypefun
1966
1967@subheading gnutls_x509_crq_set_key
1968@anchor{gnutls_x509_crq_set_key}
1969@deftypefun {int} {gnutls_x509_crq_set_key} (gnutls_x509_crq_t @var{crq}, gnutls_x509_privkey_t @var{key})
1970@var{crq}: should contain a gnutls_x509_crq_t structure
1971
1972@var{key}: holds a private key
1973
1974This function will set the public parameters from the given private key to the
1975request. Only RSA keys are currently supported.
1976
1977Returns 0 on success.
1978@end deftypefun
1979
1980@subheading gnutls_x509_crq_set_challenge_password
1981@anchor{gnutls_x509_crq_set_challenge_password}
1982@deftypefun {int} {gnutls_x509_crq_set_challenge_password} (gnutls_x509_crq_t @var{crq}, const char * @var{pass})
1983@var{crq}: should contain a gnutls_x509_crq_t structure
1984
1985@var{pass}: holds a null terminated password
1986
1987This function will set a challenge password to be used when revoking the request.
1988
1989Returns 0 on success.
1990@end deftypefun
1991
1992@subheading gnutls_x509_crq_sign2
1993@anchor{gnutls_x509_crq_sign2}
1994@deftypefun {int} {gnutls_x509_crq_sign2} (gnutls_x509_crq_t @var{crq}, gnutls_x509_privkey_t @var{key}, gnutls_digest_algorithm_t @var{dig}, unsigned int @var{flags})
1995@var{crq}: should contain a gnutls_x509_crq_t structure
1996
1997@var{key}: holds a private key
1998
1999@var{dig}: The message digest to use. GNUTLS_DIG_SHA1 is the safe choice unless you know what you're doing.
2000
2001@var{flags}: must be 0
2002
2003This function will sign the certificate request with a private key.
2004This must be the same key as the one used in @code{gnutls_x509_crt_set_key()} since a
2005certificate request is self signed.
2006
2007This must be the last step in a certificate request generation since all
2008the previously set parameters are now signed.
2009
2010Returns 0 on success.
2011@end deftypefun
2012
2013@subheading gnutls_x509_crq_sign
2014@anchor{gnutls_x509_crq_sign}
2015@deftypefun {int} {gnutls_x509_crq_sign} (gnutls_x509_crq_t @var{crq}, gnutls_x509_privkey_t @var{key})
2016@var{crq}: should contain a gnutls_x509_crq_t structure
2017
2018@var{key}: holds a private key
2019
2020This function is the same a @code{gnutls_x509_crq_sign2()} with no flags, and
2021SHA1 as the hash algorithm.
2022
2023Returns 0 on success.
2024@end deftypefun
2025
2026@subheading gnutls_x509_crq_export
2027@anchor{gnutls_x509_crq_export}
2028@deftypefun {int} {gnutls_x509_crq_export} (gnutls_x509_crq_t @var{crq}, gnutls_x509_crt_fmt_t @var{format}, void * @var{output_data}, size_t * @var{output_data_size})
2029@var{crq}: Holds the request
2030
2031@var{format}: the format of output params. One of PEM or DER.
2032
2033@var{output_data}: will contain a certificate request PEM or DER encoded
2034
2035@var{output_data_size}: holds the size of output_data (and will be
2036replaced by the actual size of parameters)
2037
2038This function will export the certificate request to a PKCS10
2039
2040If the buffer provided is not long enough to hold the output, then
2041GNUTLS_E_SHORT_MEMORY_BUFFER will be returned and
2042*output_data_size will be updated.
2043
2044If the structure is PEM encoded, it will have a header of "BEGIN
2045NEW CERTIFICATE REQUEST".
2046
2047@strong{Return value:} In case of failure a negative value will be
2048returned, and 0 on success.
2049@end deftypefun
2050
2051@subheading gnutls_x509_crq_get_pk_algorithm
2052@anchor{gnutls_x509_crq_get_pk_algorithm}
2053@deftypefun {int} {gnutls_x509_crq_get_pk_algorithm} (gnutls_x509_crq_t @var{crq}, unsigned int * @var{bits})
2054@var{crq}: should contain a gnutls_x509_crq_t structure
2055
2056@var{bits}: if bits is non null it will hold the size of the parameters' in bits
2057
2058This function will return the public key algorithm of a PKCS \@code{10}
2059certificate request.
2060
2061If bits is non null, it should have enough size to hold the parameters
2062size in bits. For RSA the bits returned is the modulus.
2063For DSA the bits returned are of the public
2064exponent.
2065
2066Returns a member of the gnutls_pk_algorithm_t enumeration on success,
2067or a negative value on error.
2068@end deftypefun
2069
2070@subheading gnutls_x509_privkey_export_pkcs8
2071@anchor{gnutls_x509_privkey_export_pkcs8}
2072@deftypefun {int} {gnutls_x509_privkey_export_pkcs8} (gnutls_x509_privkey_t @var{key}, gnutls_x509_crt_fmt_t @var{format}, const char * @var{password}, unsigned int @var{flags}, void * @var{output_data}, size_t * @var{output_data_size})
2073@var{key}: Holds the key
2074
2075@var{format}: the format of output params. One of PEM or DER.
2076
2077@var{password}: the password that will be used to encrypt the key.
2078
2079@var{flags}: an ORed sequence of gnutls_pkcs_encrypt_flags_t
2080
2081@var{output_data}: will contain a private key PEM or DER encoded
2082
2083@var{output_data_size}: holds the size of output_data (and will be
2084replaced by the actual size of parameters)
2085
2086This function will export the private key to a PKCS8 structure.
2087Both RSA and DSA keys can be exported. For DSA keys we use
2088PKCS @code{11} definitions. If the flags do not specify the encryption
2089cipher, then the default 3DES (PBES2) will be used.
2090
2091The @code{password} can be either ASCII or UTF-8 in the default PBES2
2092encryption schemas, or ASCII for the PKCS12 schemas.
2093
2094If the buffer provided is not long enough to hold the output, then
2095*output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2096be returned.
2097
2098If the structure is PEM encoded, it will have a header
2099of "BEGIN ENCRYPTED PRIVATE KEY" or "BEGIN PRIVATE KEY" if
2100encryption is not used.
2101
2102@strong{Return value:} In case of failure a negative value will be
2103returned, and 0 on success.
2104@end deftypefun
2105
2106@subheading gnutls_x509_privkey_import_pkcs8
2107@anchor{gnutls_x509_privkey_import_pkcs8}
2108@deftypefun {int} {gnutls_x509_privkey_import_pkcs8} (gnutls_x509_privkey_t @var{key}, const gnutls_datum_t * @var{data}, gnutls_x509_crt_fmt_t @var{format}, const char * @var{password}, unsigned int @var{flags})
2109@var{key}: The structure to store the parsed key
2110
2111@var{data}: The DER or PEM encoded key.
2112
2113@var{format}: One of DER or PEM
2114
2115@var{password}: the password to decrypt the key (if it is encrypted).
2116
2117@var{flags}: 0 if encrypted or GNUTLS_PKCS_PLAIN if not encrypted.
2118
2119This function will convert the given DER or PEM encoded PKCS8 2.0 encrypted key
2120to the native gnutls_x509_privkey_t format. The output will be stored in @code{key}.
2121Both RSA and DSA keys can be imported, and flags can only be used to indicate
2122an unencrypted key.
2123
2124The @code{password} can be either ASCII or UTF-8 in the default PBES2
2125encryption schemas, or ASCII for the PKCS12 schemas.
2126
2127If the Certificate is PEM encoded it should have a header of "ENCRYPTED PRIVATE KEY",
2128or "PRIVATE KEY". You only need to specify the flags if the key is DER encoded, since
2129in that case the encryption status cannot be auto-detected.
2130
2131Returns 0 on success.
2132@end deftypefun
2133
2134@subheading gnutls_pkcs12_init
2135@anchor{gnutls_pkcs12_init}
2136@deftypefun {int} {gnutls_pkcs12_init} (gnutls_pkcs12_t * @var{pkcs12})
2137@var{pkcs12}: The structure to be initialized
2138
2139This function will initialize a PKCS12 structure. PKCS12 structures
2140usually contain lists of X.509 Certificates and X.509 Certificate
2141revocation lists.
2142
2143Returns 0 on success.
2144@end deftypefun
2145
2146@subheading gnutls_pkcs12_deinit
2147@anchor{gnutls_pkcs12_deinit}
2148@deftypefun {void} {gnutls_pkcs12_deinit} (gnutls_pkcs12_t @var{pkcs12})
2149@var{pkcs12}: The structure to be initialized
2150
2151This function will deinitialize a PKCS12 structure.
2152@end deftypefun
2153
2154@subheading gnutls_pkcs12_import
2155@anchor{gnutls_pkcs12_import}
2156@deftypefun {int} {gnutls_pkcs12_import} (gnutls_pkcs12_t @var{pkcs12}, const gnutls_datum_t * @var{data}, gnutls_x509_crt_fmt_t @var{format}, unsigned int @var{flags})
2157@var{pkcs12}: The structure to store the parsed PKCS12.
2158
2159@var{data}: The DER or PEM encoded PKCS12.
2160
2161@var{format}: One of DER or PEM
2162
2163@var{flags}: an ORed sequence of gnutls_privkey_pkcs8_flags
2164
2165This function will convert the given DER or PEM encoded PKCS12
2166to the native gnutls_pkcs12_t format. The output will be stored in 'pkcs12'.
2167
2168If the PKCS12 is PEM encoded it should have a header of "PKCS12".
2169
2170Returns 0 on success.
2171@end deftypefun
2172
2173@subheading gnutls_pkcs12_export
2174@anchor{gnutls_pkcs12_export}
2175@deftypefun {int} {gnutls_pkcs12_export} (gnutls_pkcs12_t @var{pkcs12}, gnutls_x509_crt_fmt_t @var{format}, void * @var{output_data}, size_t * @var{output_data_size})
2176@var{pkcs12}: Holds the pkcs12 structure
2177
2178@var{format}: the format of output params. One of PEM or DER.
2179
2180@var{output_data}: will contain a structure PEM or DER encoded
2181
2182@var{output_data_size}: holds the size of output_data (and will be
2183replaced by the actual size of parameters)
2184
2185This function will export the pkcs12 structure to DER or PEM format.
2186
2187If the buffer provided is not long enough to hold the output, then
2188*output_data_size will be updated and GNUTLS_E_SHORT_MEMORY_BUFFER
2189will be returned.
2190
2191If the structure is PEM encoded, it will have a header
2192of "BEGIN PKCS12".
2193
2194@strong{Return value:} In case of failure a negative value will be
2195returned, and 0 on success.
2196@end deftypefun
2197
2198@subheading gnutls_pkcs12_get_bag
2199@anchor{gnutls_pkcs12_get_bag}
2200@deftypefun {int} {gnutls_pkcs12_get_bag} (gnutls_pkcs12_t @var{pkcs12}, int @var{indx}, gnutls_pkcs12_bag_t @var{bag})
2201@var{pkcs12}: should contain a gnutls_pkcs12_t structure
2202
2203@var{indx}: contains the index of the bag to extract
2204
2205@var{bag}: An initialized bag, where the contents of the bag will be copied
2206
2207This function will return a Bag from the PKCS12 structure.
2208Returns 0 on success.
2209
2210After the last Bag has been read GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
2211will be returned.
2212@end deftypefun
2213
2214@subheading gnutls_pkcs12_set_bag
2215@anchor{gnutls_pkcs12_set_bag}
2216@deftypefun {int} {gnutls_pkcs12_set_bag} (gnutls_pkcs12_t @var{pkcs12}, gnutls_pkcs12_bag_t @var{bag})
2217@var{pkcs12}: should contain a gnutls_pkcs12_t structure
2218
2219@var{bag}: An initialized bag
2220
2221This function will insert a Bag into the PKCS12 structure.
2222Returns 0 on success.
2223@end deftypefun
2224
2225@subheading gnutls_pkcs12_generate_mac
2226@anchor{gnutls_pkcs12_generate_mac}
2227@deftypefun {int} {gnutls_pkcs12_generate_mac} (gnutls_pkcs12_t @var{pkcs12}, const char * @var{pass})
2228@var{pkcs12}: should contain a gnutls_pkcs12_t structure
2229
2230@var{pass}: The password for the MAC
2231
2232This function will generate a MAC for the PKCS12 structure.
2233Returns 0 on success.
2234@end deftypefun
2235
2236@subheading gnutls_pkcs12_verify_mac
2237@anchor{gnutls_pkcs12_verify_mac}
2238@deftypefun {int} {gnutls_pkcs12_verify_mac} (gnutls_pkcs12_t @var{pkcs12}, const char * @var{pass})
2239@var{pkcs12}: should contain a gnutls_pkcs12_t structure
2240
2241@var{pass}: The password for the MAC
2242
2243This function will verify the MAC for the PKCS12 structure.
2244Returns 0 on success.
2245@end deftypefun
2246
2247@subheading gnutls_pkcs12_bag_init
2248@anchor{gnutls_pkcs12_bag_init}
2249@deftypefun {int} {gnutls_pkcs12_bag_init} (gnutls_pkcs12_bag_t * @var{bag})
2250@var{bag}: The structure to be initialized
2251
2252This function will initialize a PKCS12 bag structure. PKCS12 Bags
2253usually contain private keys, lists of X.509 Certificates and X.509 Certificate
2254revocation lists.
2255
2256Returns 0 on success.
2257@end deftypefun
2258
2259@subheading gnutls_pkcs12_bag_deinit
2260@anchor{gnutls_pkcs12_bag_deinit}
2261@deftypefun {void} {gnutls_pkcs12_bag_deinit} (gnutls_pkcs12_bag_t @var{bag})
2262@var{bag}: The structure to be initialized
2263
2264This function will deinitialize a PKCS12 Bag structure.
2265@end deftypefun
2266
2267@subheading gnutls_pkcs12_bag_get_type
2268@anchor{gnutls_pkcs12_bag_get_type}
2269@deftypefun {gnutls_pkcs12_bag_type_t} {gnutls_pkcs12_bag_get_type} (gnutls_pkcs12_bag_t @var{bag}, int @var{indx})
2270@var{bag}: The bag
2271
2272@var{indx}: The element of the bag to get the type
2273
2274This function will return the bag's type. One of the gnutls_pkcs12_bag_type_t
2275enumerations.
2276@end deftypefun
2277
2278@subheading gnutls_pkcs12_bag_get_count
2279@anchor{gnutls_pkcs12_bag_get_count}
2280@deftypefun {int} {gnutls_pkcs12_bag_get_count} (gnutls_pkcs12_bag_t @var{bag})
2281@var{bag}: The bag
2282
2283This function will return the number of the elements withing the bag.
2284@end deftypefun
2285
2286@subheading gnutls_pkcs12_bag_get_data
2287@anchor{gnutls_pkcs12_bag_get_data}
2288@deftypefun {int} {gnutls_pkcs12_bag_get_data} (gnutls_pkcs12_bag_t @var{bag}, int @var{indx}, gnutls_datum_t * @var{data})
2289@var{bag}: The bag
2290
2291@var{indx}: The element of the bag to get the data from
2292
2293@var{data}: where the bag's data will be. Should be treated as constant.
2294
2295This function will return the bag's data. The data is a constant
2296that is stored into the bag. Should not be accessed after the bag
2297is deleted.
2298
2299Returns 0 on success and a negative error code on error.
2300@end deftypefun
2301
2302@subheading gnutls_pkcs12_bag_set_data
2303@anchor{gnutls_pkcs12_bag_set_data}
2304@deftypefun {int} {gnutls_pkcs12_bag_set_data} (gnutls_pkcs12_bag_t @var{bag}, gnutls_pkcs12_bag_type_t @var{type}, const gnutls_datum_t * @var{data})
2305@var{bag}: The bag
2306
2307@var{type}: The data's type
2308
2309@var{data}: the data to be copied.
2310
2311This function will insert the given data of the given type into the
2312bag.
2313
2314Returns the index of the added bag on success, or a negative
2315value on error.
2316@end deftypefun
2317
2318@subheading gnutls_pkcs12_bag_set_crt
2319@anchor{gnutls_pkcs12_bag_set_crt}
2320@deftypefun {int} {gnutls_pkcs12_bag_set_crt} (gnutls_pkcs12_bag_t @var{bag}, gnutls_x509_crt_t @var{crt})
2321@var{bag}: The bag
2322
2323@var{crt}: the certificate to be copied.
2324
2325This function will insert the given certificate into the
2326bag. This is just a wrapper over @code{gnutls_pkcs12_bag_set_data()}.
2327
2328Returns the index of the added bag on success, or a negative
2329value on failure.
2330@end deftypefun
2331
2332@subheading gnutls_pkcs12_bag_set_crl
2333@anchor{gnutls_pkcs12_bag_set_crl}
2334@deftypefun {int} {gnutls_pkcs12_bag_set_crl} (gnutls_pkcs12_bag_t @var{bag}, gnutls_x509_crl_t @var{crl})
2335@var{bag}: The bag
2336
2337@var{crl}: the CRL to be copied.
2338
2339This function will insert the given CRL into the
2340bag. This is just a wrapper over @code{gnutls_pkcs12_bag_set_data()}.
2341
2342Returns the index of the added bag on success, or a negative
2343value on failure.
2344@end deftypefun
2345
2346@subheading gnutls_pkcs12_bag_set_key_id
2347@anchor{gnutls_pkcs12_bag_set_key_id}
2348@deftypefun {int} {gnutls_pkcs12_bag_set_key_id} (gnutls_pkcs12_bag_t @var{bag}, int @var{indx}, const gnutls_datum_t * @var{id})
2349@var{bag}: The bag
2350
2351@var{indx}: The bag's element to add the id
2352
2353@var{id}: the ID
2354
2355This function will add the given key ID, to the specified, by the index, bag
2356element. The key ID will be encoded as a 'Local key identifier' bag attribute,
2357which is usually used to distinguish the local private key and the certificate pair.
2358
2359Returns 0 on success, or a negative value on error.
2360@end deftypefun
2361
2362@subheading gnutls_pkcs12_bag_get_key_id
2363@anchor{gnutls_pkcs12_bag_get_key_id}
2364@deftypefun {int} {gnutls_pkcs12_bag_get_key_id} (gnutls_pkcs12_bag_t @var{bag}, int @var{indx}, gnutls_datum_t * @var{id})
2365@var{bag}: The bag
2366
2367@var{indx}: The bag's element to add the id
2368
2369@var{id}: where the ID will be copied (to be treated as const)
2370
2371This function will return the key ID, of the specified bag element.
2372The key ID is usually used to distinguish the local private key and the certificate pair.
2373
2374Returns 0 on success, or a negative value on error.
2375@end deftypefun
2376
2377@subheading gnutls_pkcs12_bag_get_friendly_name
2378@anchor{gnutls_pkcs12_bag_get_friendly_name}
2379@deftypefun {int} {gnutls_pkcs12_bag_get_friendly_name} (gnutls_pkcs12_bag_t @var{bag}, int @var{indx}, char ** @var{name})
2380@var{bag}: The bag
2381
2382@var{indx}: The bag's element to add the id
2383
2384@var{name}: will hold a pointer to the name (to be treated as const)
2385
2386This function will return the friendly name, of the specified bag element.
2387The key ID is usually used to distinguish the local private key and the certificate pair.
2388
2389Returns 0 on success, or a negative value on error.
2390@end deftypefun
2391
2392@subheading gnutls_pkcs12_bag_set_friendly_name
2393@anchor{gnutls_pkcs12_bag_set_friendly_name}
2394@deftypefun {int} {gnutls_pkcs12_bag_set_friendly_name} (gnutls_pkcs12_bag_t @var{bag}, int @var{indx}, const char * @var{name})
2395@var{bag}: The bag
2396
2397@var{indx}: The bag's element to add the id
2398
2399@var{name}: the name
2400
2401This function will add the given key friendly name, to the specified, by the index, bag
2402element. The name will be encoded as a 'Friendly name' bag attribute,
2403which is usually used to set a user name to the local private key and the certificate pair.
2404
2405Returns 0 on success, or a negative value on error.
2406@end deftypefun
2407
2408@subheading gnutls_pkcs12_bag_decrypt
2409@anchor{gnutls_pkcs12_bag_decrypt}
2410@deftypefun {int} {gnutls_pkcs12_bag_decrypt} (gnutls_pkcs12_bag_t @var{bag}, const char * @var{pass})
2411@var{bag}: The bag
2412
2413@var{pass}: The password used for encryption. This can only be ASCII.
2414
2415This function will decrypt the given encrypted bag and return 0 on success.
2416@end deftypefun
2417
2418@subheading gnutls_pkcs12_bag_encrypt
2419@anchor{gnutls_pkcs12_bag_encrypt}
2420@deftypefun {int} {gnutls_pkcs12_bag_encrypt} (gnutls_pkcs12_bag_t @var{bag}, const char * @var{pass}, unsigned int @var{flags})
2421@var{bag}: The bag
2422
2423@var{pass}: The password used for encryption. This can only be ASCII.
2424
2425@var{flags}: should be one of gnutls_pkcs_encrypt_flags_t elements bitwise or'd
2426
2427This function will encrypt the given bag and return 0 on success.
2428@end deftypefun
2429
2430@subheading gnutls_x509_crt_set_dn_by_oid
2431@anchor{gnutls_x509_crt_set_dn_by_oid}
2432@deftypefun {int} {gnutls_x509_crt_set_dn_by_oid} (gnutls_x509_crt_t @var{crt}, const char * @var{oid}, unsigned int @var{raw_flag}, const void * @var{name}, unsigned int @var{sizeof_name})
2433@var{crt}: should contain a gnutls_x509_crt_t structure
2434
2435@var{oid}: holds an Object Identifier in a null terminated string
2436
2437@var{raw_flag}: must be 0, or 1 if the data are DER encoded
2438
2439@var{name}: a pointer to the name
2440
2441@var{sizeof_name}: holds the size of @code{name}
2442
2443This function will set the part of the name of the Certificate subject, specified
2444by the given OID. The input string should be ASCII or UTF-8 encoded.
2445
2446Some helper macros with popular OIDs can be found in gnutls/x509.h
2447With this function you can only set the known OIDs. You can test
2448for known OIDs using @code{gnutls_x509_dn_oid_known()}. For OIDs that are
2449not known (by gnutls) you should properly DER encode your data, and
2450call this function with raw_flag set.
2451
2452Returns 0 on success.
2453@end deftypefun
2454
2455@subheading gnutls_x509_crt_set_issuer_dn_by_oid
2456@anchor{gnutls_x509_crt_set_issuer_dn_by_oid}
2457@deftypefun {int} {gnutls_x509_crt_set_issuer_dn_by_oid} (gnutls_x509_crt_t @var{crt}, const char * @var{oid}, unsigned int @var{raw_flag}, const void * @var{name}, unsigned int @var{sizeof_name})
2458@var{crt}: should contain a gnutls_x509_crt_t structure
2459
2460@var{oid}: holds an Object Identifier in a null terminated string
2461
2462@var{raw_flag}: must be 0, or 1 if the data are DER encoded
2463
2464@var{name}: a pointer to the name
2465
2466@var{sizeof_name}: holds the size of @code{name}
2467
2468This function will set the part of the name of the Certificate issuer, specified
2469by the given OID. The input string should be ASCII or UTF-8 encoded.
2470
2471Some helper macros with popular OIDs can be found in gnutls/x509.h
2472With this function you can only set the known OIDs. You can test
2473for known OIDs using @code{gnutls_x509_dn_oid_known()}. For OIDs that are
2474not known (by gnutls) you should properly DER encode your data, and
2475call this function with raw_flag set.
2476
2477Normally you do not need to call this function, since the signing
2478operation will copy the signer's name as the issuer of the certificate.
2479
2480Returns 0 on success.
2481@end deftypefun
2482
2483@subheading gnutls_x509_crt_set_proxy_dn
2484@anchor{gnutls_x509_crt_set_proxy_dn}
2485@deftypefun {int} {gnutls_x509_crt_set_proxy_dn} (gnutls_x509_crt_t @var{crt}, gnutls_x509_crt_t @var{eecrt}, unsigned int @var{raw_flag}, const void * @var{name}, unsigned int @var{sizeof_name})
2486@var{crt}: a gnutls_x509_crt_t structure with the new proxy cert
2487
2488@var{eecrt}: the end entity certificate that will be issuing the proxy
2489
2490@var{raw_flag}: must be 0, or 1 if the CN is DER encoded
2491
2492@var{name}: a pointer to the CN name, may be NULL (but MUST then be added later)
2493
2494@var{sizeof_name}: holds the size of @code{name}
2495
2496This function will set the subject in @code{crt} to the end entity's
2497@code{eecrt} subject name, and add a single Common Name component @code{name}
2498of size @code{sizeof_name}. This corresponds to the required proxy
2499certificate naming style. Note that if @code{name} is @code{NULL}, you MUST
2500set it later by using @code{gnutls_x509_crt_set_dn_by_oid()} or similar.
2501
2502Returns 0 on success.
2503@end deftypefun
2504
2505@subheading gnutls_x509_crt_set_version
2506@anchor{gnutls_x509_crt_set_version}
2507@deftypefun {int} {gnutls_x509_crt_set_version} (gnutls_x509_crt_t @var{crt}, unsigned int @var{version})
2508@var{crt}: should contain a gnutls_x509_crt_t structure
2509
2510@var{version}: holds the version number. For X.509v1 certificates must be 1.
2511
2512This function will set the version of the certificate. This must
2513be one for X.509 version 1, and so on. Plain certificates without
2514extensions must have version set to one.
2515
2516To create well-formed certificates, you must specify version 3 if
2517you use any certificate extensions. Extensions are created by
2518functions such as gnutls_x509_crt_set_subject_alternative_name or
2519gnutls_x509_crt_set_key_usage.
2520
2521Returns 0 on success.
2522@end deftypefun
2523
2524@subheading gnutls_x509_crt_set_key
2525@anchor{gnutls_x509_crt_set_key}
2526@deftypefun {int} {gnutls_x509_crt_set_key} (gnutls_x509_crt_t @var{crt}, gnutls_x509_privkey_t @var{key})
2527@var{crt}: should contain a gnutls_x509_crt_t structure
2528
2529@var{key}: holds a private key
2530
2531This function will set the public parameters from the given private key to the
2532certificate. Only RSA keys are currently supported.
2533
2534Returns 0 on success.
2535@end deftypefun
2536
2537@subheading gnutls_x509_crt_set_crq
2538@anchor{gnutls_x509_crt_set_crq}
2539@deftypefun {int} {gnutls_x509_crt_set_crq} (gnutls_x509_crt_t @var{crt}, gnutls_x509_crq_t @var{crq})
2540@var{crt}: should contain a gnutls_x509_crt_t structure
2541
2542@var{crq}: holds a certificate request
2543
2544This function will set the name and public parameters from the given certificate request to the
2545certificate. Only RSA keys are currently supported.
2546
2547Returns 0 on success.
2548@end deftypefun
2549
2550@subheading gnutls_x509_crt_set_extension_by_oid
2551@anchor{gnutls_x509_crt_set_extension_by_oid}
2552@deftypefun {int} {gnutls_x509_crt_set_extension_by_oid} (gnutls_x509_crt_t @var{crt}, const char * @var{oid}, const void * @var{buf}, size_t @var{sizeof_buf}, unsigned int @var{critical})
2553@var{crt}: should contain a gnutls_x509_crt_t structure
2554
2555@var{oid}: holds an Object Identified in null terminated string
2556
2557@var{buf}: a pointer to a DER encoded data
2558
2559@var{sizeof_buf}: holds the size of @code{buf}
2560
2561@var{critical}: should be non zero if the extension is to be marked as critical
2562
2563This function will set an the extension, by the specified OID, in the certificate.
2564The extension data should be binary data DER encoded.
2565
2566Returns 0 on success and a negative value in case of an error.
2567@end deftypefun
2568
2569@subheading gnutls_x509_crt_set_basic_constraints
2570@anchor{gnutls_x509_crt_set_basic_constraints}
2571@deftypefun {int} {gnutls_x509_crt_set_basic_constraints} (gnutls_x509_crt_t @var{crt}, unsigned int @var{ca}, int @var{pathLenConstraint})
2572@var{crt}: should contain a gnutls_x509_crt_t structure
2573
2574@var{ca}: true(1) or false(0). Depending on the Certificate authority status.
2575
2576@var{pathLenConstraint}: non-negative values indicate maximum length of path,
2577and negative values indicate that the pathLenConstraints field should
2578not be present.
2579
2580This function will set the basicConstraints certificate extension.
2581
2582Returns 0 on success.
2583@end deftypefun
2584
2585@subheading gnutls_x509_crt_set_ca_status
2586@anchor{gnutls_x509_crt_set_ca_status}
2587@deftypefun {int} {gnutls_x509_crt_set_ca_status} (gnutls_x509_crt_t @var{crt}, unsigned int @var{ca})
2588@var{crt}: should contain a gnutls_x509_crt_t structure
2589
2590@var{ca}: true(1) or false(0). Depending on the Certificate authority status.
2591
2592This function will set the basicConstraints certificate extension.
2593Use @code{gnutls_x509_crt_set_basic_constraints()} if you want to control
2594the pathLenConstraint field too.
2595
2596Returns 0 on success.
2597@end deftypefun
2598
2599@subheading gnutls_x509_crt_set_key_usage
2600@anchor{gnutls_x509_crt_set_key_usage}
2601@deftypefun {int} {gnutls_x509_crt_set_key_usage} (gnutls_x509_crt_t @var{crt}, unsigned int @var{usage})
2602@var{crt}: should contain a gnutls_x509_crt_t structure
2603
2604@var{usage}: an ORed sequence of the GNUTLS_KEY_* elements.
2605
2606This function will set the keyUsage certificate extension.
2607
2608Returns 0 on success.
2609@end deftypefun
2610
2611@subheading gnutls_x509_crt_set_subject_alternative_name
2612@anchor{gnutls_x509_crt_set_subject_alternative_name}
2613@deftypefun {int} {gnutls_x509_crt_set_subject_alternative_name} (gnutls_x509_crt_t @var{crt}, gnutls_x509_subject_alt_name_t @var{type}, const char * @var{data_string})
2614@var{crt}: should contain a gnutls_x509_crt_t structure
2615
2616@var{type}: is one of the gnutls_x509_subject_alt_name_t enumerations
2617
2618@var{data_string}: The data to be set
2619
2620This function will set the subject alternative name certificate extension.
2621
2622Returns 0 on success.
2623@end deftypefun
2624
2625@subheading gnutls_x509_crt_set_proxy
2626@anchor{gnutls_x509_crt_set_proxy}
2627@deftypefun {int} {gnutls_x509_crt_set_proxy} (gnutls_x509_crt_t @var{crt}, int @var{pathLenConstraint}, const char * @var{policyLanguage}, const char * @var{policy}, size_t @var{sizeof_policy})
2628@var{crt}: should contain a gnutls_x509_crt_t structure
2629
2630@var{pathLenConstraint}: non-negative values indicate maximum length of path,
2631and negative values indicate that the pathLenConstraints field should
2632not be present.
2633
2634@var{policyLanguage}: OID describing the language of @code{policy}.
2635
2636@var{policy}: opaque byte array with policy language, can be @code{NULL}
2637
2638@var{sizeof_policy}: size of @code{policy}.
2639
2640This function will set the proxyCertInfo extension.
2641
2642Returns 0 on success.
2643@end deftypefun
2644
2645@subheading gnutls_x509_crt_sign2
2646@anchor{gnutls_x509_crt_sign2}
2647@deftypefun {int} {gnutls_x509_crt_sign2} (gnutls_x509_crt_t @var{crt}, gnutls_x509_crt_t @var{issuer}, gnutls_x509_privkey_t @var{issuer_key}, gnutls_digest_algorithm_t @var{dig}, unsigned int @var{flags})
2648@var{crt}: should contain a gnutls_x509_crt_t structure
2649
2650@var{issuer}: is the certificate of the certificate issuer
2651
2652@var{issuer_key}: holds the issuer's private key
2653
2654@var{dig}: The message digest to use. GNUTLS_DIG_SHA1 is the safe choice unless you know what you're doing.
2655
2656@var{flags}: must be 0
2657
2658This function will sign the certificate with the issuer's private key, and
2659will copy the issuer's information into the certificate.
2660
2661This must be the last step in a certificate generation since all
2662the previously set parameters are now signed.
2663
2664Returns 0 on success.
2665@end deftypefun
2666
2667@subheading gnutls_x509_crt_sign
2668@anchor{gnutls_x509_crt_sign}
2669@deftypefun {int} {gnutls_x509_crt_sign} (gnutls_x509_crt_t @var{crt}, gnutls_x509_crt_t @var{issuer}, gnutls_x509_privkey_t @var{issuer_key})
2670@var{crt}: should contain a gnutls_x509_crt_t structure
2671
2672@var{issuer}: is the certificate of the certificate issuer
2673
2674@var{issuer_key}: holds the issuer's private key
2675
2676This function is the same a @code{gnutls_x509_crt_sign2()} with no flags, and
2677SHA1 as the hash algorithm.
2678
2679Returns 0 on success.
2680@end deftypefun
2681
2682@subheading gnutls_x509_crt_set_activation_time
2683@anchor{gnutls_x509_crt_set_activation_time}
2684@deftypefun {int} {gnutls_x509_crt_set_activation_time} (gnutls_x509_crt_t @var{cert}, time_t @var{act_time})
2685@var{cert}: should contain a gnutls_x509_crt_t structure
2686
2687@var{act_time}: The actual time
2688
2689This function will set the time this Certificate was or will be activated.
2690
2691Returns 0 on success, or a negative value in case of an error.
2692@end deftypefun
2693
2694@subheading gnutls_x509_crt_set_expiration_time
2695@anchor{gnutls_x509_crt_set_expiration_time}
2696@deftypefun {int} {gnutls_x509_crt_set_expiration_time} (gnutls_x509_crt_t @var{cert}, time_t @var{exp_time})
2697@var{cert}: should contain a gnutls_x509_crt_t structure
2698
2699@var{exp_time}: The actual time
2700
2701This function will set the time this Certificate will expire.
2702
2703Returns 0 on success, or a negative value in case of an error.
2704@end deftypefun
2705
2706@subheading gnutls_x509_crt_set_serial
2707@anchor{gnutls_x509_crt_set_serial}
2708@deftypefun {int} {gnutls_x509_crt_set_serial} (gnutls_x509_crt_t @var{cert}, const void * @var{serial}, size_t @var{serial_size})
2709@var{cert}: should contain a gnutls_x509_crt_t structure
2710
2711@var{serial}: The serial number
2712
2713@var{serial_size}: Holds the size of the serial field.
2714
2715This function will set the X.509 certificate's serial number.
2716Serial is not always a 32 or 64bit number. Some CAs use
2717large serial numbers, thus it may be wise to handle it as something
2718opaque.
2719
2720Returns 0 on success, or a negative value in case of an error.
2721@end deftypefun
2722
2723@subheading gnutls_x509_crt_set_crl_dist_points
2724@anchor{gnutls_x509_crt_set_crl_dist_points}
2725@deftypefun {int} {gnutls_x509_crt_set_crl_dist_points} (gnutls_x509_crt_t @var{crt}, gnutls_x509_subject_alt_name_t @var{type}, const void * @var{data_string}, unsigned int @var{reason_flags})
2726@var{crt}: should contain a gnutls_x509_crt_t structure
2727
2728@var{type}: is one of the gnutls_x509_subject_alt_name_t enumerations
2729
2730@var{data_string}: The data to be set
2731
2732@var{reason_flags}: revocation reasons
2733
2734This function will set the CRL distribution points certificate extension.
2735
2736Returns 0 on success.
2737@end deftypefun
2738
2739@subheading gnutls_x509_crt_cpy_crl_dist_points
2740@anchor{gnutls_x509_crt_cpy_crl_dist_points}
2741@deftypefun {int} {gnutls_x509_crt_cpy_crl_dist_points} (gnutls_x509_crt_t @var{dst}, gnutls_x509_crt_t @var{src})
2742@var{dst}: should contain a gnutls_x509_crt_t structure
2743
2744@var{src}: the certificate where the dist points will be copied from
2745
2746This function will copy the CRL distribution points certificate
2747extension, from the source to the destination certificate.
2748This may be useful to copy from a CA certificate to issued ones.
2749
2750Returns 0 on success.
2751@end deftypefun
2752
2753@subheading gnutls_x509_crt_set_subject_key_id
2754@anchor{gnutls_x509_crt_set_subject_key_id}
2755@deftypefun {int} {gnutls_x509_crt_set_subject_key_id} (gnutls_x509_crt_t @var{cert}, const void * @var{id}, size_t @var{id_size})
2756@var{cert}: should contain a gnutls_x509_crt_t structure
2757
2758@var{id}: The key ID
2759
2760@var{id_size}: Holds the size of the serial field.
2761
2762This function will set the X.509 certificate's subject key ID extension.
2763
2764Returns 0 on success, or a negative value in case of an error.
2765@end deftypefun
2766
2767@subheading gnutls_x509_crt_set_authority_key_id
2768@anchor{gnutls_x509_crt_set_authority_key_id}
2769@deftypefun {int} {gnutls_x509_crt_set_authority_key_id} (gnutls_x509_crt_t @var{cert}, const void * @var{id}, size_t @var{id_size})
2770@var{cert}: should contain a gnutls_x509_crt_t structure
2771
2772@var{id}: The key ID
2773
2774@var{id_size}: Holds the size of the serial field.
2775
2776This function will set the X.509 certificate's authority key ID extension.
2777Only the keyIdentifier field can be set with this function.
2778
2779Returns 0 on success, or a negative value in case of an error.
2780@end deftypefun
2781
2782@subheading gnutls_x509_crt_set_key_purpose_oid
2783@anchor{gnutls_x509_crt_set_key_purpose_oid}
2784@deftypefun {int} {gnutls_x509_crt_set_key_purpose_oid} (gnutls_x509_crt_t @var{cert}, const void * @var{oid}, unsigned int @var{critical})
2785@var{cert}: should contain a gnutls_x509_crt_t structure
2786
2787@var{oid}: a pointer to a null terminated string that holds the OID
2788
2789@var{critical}: Whether this extension will be critical or not
2790
2791This function will set the key purpose OIDs of the Certificate.
2792These are stored in the Extended Key Usage extension (2.5.29.37)
2793See the GNUTLS_KP_* definitions for human readable names.
2794
2795Subsequent calls to this function will append OIDs to the OID list.
2796
2797On success 0 is returned.
2798@end deftypefun
2799
2800@subheading gnutls_x509_crl_set_version
2801@anchor{gnutls_x509_crl_set_version}
2802@deftypefun {int} {gnutls_x509_crl_set_version} (gnutls_x509_crl_t @var{crl}, unsigned int @var{version})
2803@var{crl}: should contain a gnutls_x509_crl_t structure
2804
2805@var{version}: holds the version number. For CRLv1 crls must be 1.
2806
2807This function will set the version of the CRL. This
2808must be one for CRL version 1, and so on. The CRLs generated
2809by gnutls should have a version number of 2.
2810
2811Returns 0 on success.
2812@end deftypefun
2813
2814@subheading gnutls_x509_crl_sign2
2815@anchor{gnutls_x509_crl_sign2}
2816@deftypefun {int} {gnutls_x509_crl_sign2} (gnutls_x509_crl_t @var{crl}, gnutls_x509_crt_t @var{issuer}, gnutls_x509_privkey_t @var{issuer_key}, gnutls_digest_algorithm_t @var{dig}, unsigned int @var{flags})
2817@var{crl}: should contain a gnutls_x509_crl_t structure
2818
2819@var{issuer}: is the certificate of the certificate issuer
2820
2821@var{issuer_key}: holds the issuer's private key
2822
2823@var{dig}: The message digest to use. GNUTLS_DIG_SHA1 is the safe choice unless you know what you're doing.
2824
2825@var{flags}: must be 0
2826
2827This function will sign the CRL with the issuer's private key, and
2828will copy the issuer's information into the CRL.
2829
2830This must be the last step in a certificate CRL since all
2831the previously set parameters are now signed.
2832
2833Returns 0 on success.
2834@end deftypefun
2835
2836@subheading gnutls_x509_crl_sign
2837@anchor{gnutls_x509_crl_sign}
2838@deftypefun {int} {gnutls_x509_crl_sign} (gnutls_x509_crl_t @var{crl}, gnutls_x509_crt_t @var{issuer}, gnutls_x509_privkey_t @var{issuer_key})
2839@var{crl}: should contain a gnutls_x509_crl_t structure
2840
2841@var{issuer}: is the certificate of the certificate issuer
2842
2843@var{issuer_key}: holds the issuer's private key
2844
2845This function is the same a @code{gnutls_x509_crl_sign2()} with no flags, and
2846SHA1 as the hash algorithm.
2847
2848Returns 0 on success.
2849@end deftypefun
2850
2851@subheading gnutls_x509_crl_set_this_update
2852@anchor{gnutls_x509_crl_set_this_update}
2853@deftypefun {int} {gnutls_x509_crl_set_this_update} (gnutls_x509_crl_t @var{crl}, time_t @var{act_time})
2854@var{crl}: should contain a gnutls_x509_crl_t structure
2855
2856@var{act_time}: The actual time
2857
2858This function will set the time this CRL was issued.
2859
2860Returns 0 on success, or a negative value in case of an error.
2861@end deftypefun
2862
2863@subheading gnutls_x509_crl_set_next_update
2864@anchor{gnutls_x509_crl_set_next_update}
2865@deftypefun {int} {gnutls_x509_crl_set_next_update} (gnutls_x509_crl_t @var{crl}, time_t @var{exp_time})
2866@var{crl}: should contain a gnutls_x509_crl_t structure
2867
2868@var{exp_time}: The actual time
2869
2870This function will set the time this CRL will be updated.
2871
2872Returns 0 on success, or a negative value in case of an error.
2873@end deftypefun
2874
2875@subheading gnutls_x509_crl_set_crt_serial
2876@anchor{gnutls_x509_crl_set_crt_serial}
2877@deftypefun {int} {gnutls_x509_crl_set_crt_serial} (gnutls_x509_crl_t @var{crl}, const void * @var{serial}, size_t @var{serial_size}, time_t @var{revocation_time})
2878@var{crl}: should contain a gnutls_x509_crl_t structure
2879
2880@var{serial}: The revoked certificate's serial number
2881
2882@var{serial_size}: Holds the size of the serial field.
2883
2884@var{revocation_time}: The time this certificate was revoked
2885
2886This function will set a revoked certificate's serial number to the CRL.
2887
2888Returns 0 on success, or a negative value in case of an error.
2889@end deftypefun
2890
2891@subheading gnutls_x509_crl_set_crt
2892@anchor{gnutls_x509_crl_set_crt}
2893@deftypefun {int} {gnutls_x509_crl_set_crt} (gnutls_x509_crl_t @var{crl}, gnutls_x509_crt_t @var{crt}, time_t @var{revocation_time})
2894@var{crl}: should contain a gnutls_x509_crl_t structure
2895
2896@var{crt}: should contain a gnutls_x509_crt_t structure with the revoked certificate
2897
2898@var{revocation_time}: The time this certificate was revoked
2899
2900This function will set a revoked certificate's serial number to the CRL.
2901
2902Returns 0 on success, or a negative value in case of an error.
2903@end deftypefun
2904
2905@subheading gnutls_x509_crt_print
2906@anchor{gnutls_x509_crt_print}
2907@deftypefun {int} {gnutls_x509_crt_print} (gnutls_x509_crt_t @var{cert}, gnutls_certificate_print_formats_t @var{format}, gnutls_datum_t * @var{out})
2908@var{cert}: The structure to be printed
2909
2910@var{format}: Indicate the format to use
2911
2912@var{out}: Newly allocated datum with zero terminated string.
2913
2914This function will pretty print a X.509 certificate, suitable for
2915display to a human.
2916
2917If the format is @code{GNUTLS_X509_CRT_FULL} then all fields of the
2918certificate will be output, on multiple lines. The
2919@code{GNUTLS_X509_CRT_ONELINE} format will generate one line with some
2920selected fields, which is useful for logging purposes.
2921
2922The output @code{out} needs to be deallocate using @code{gnutls_free()}.
2923
2924Returns 0 on success.
2925@end deftypefun
2926
2927@subheading gnutls_x509_crl_print
2928@anchor{gnutls_x509_crl_print}
2929@deftypefun {int} {gnutls_x509_crl_print} (gnutls_x509_crl_t @var{crl}, gnutls_certificate_print_formats_t @var{format}, gnutls_datum_t * @var{out})
2930@var{crl}: The structure to be printed
2931
2932@var{format}: Indicate the format to use
2933
2934@var{out}: Newly allocated datum with zero terminated string.
2935
2936This function will pretty print a X.509 certificate revocation
2937list, suitable for display to a human.
2938
2939The output @code{out} needs to be deallocate using @code{gnutls_free()}.
2940
2941Returns 0 on success.
2942@end deftypefun
2943
diff --git a/src/daemon/https/x509/x509.c b/src/daemon/https/x509/x509.c
new file mode 100644
index 00000000..96999d27
--- /dev/null
+++ b/src/daemon/https/x509/x509.c
@@ -0,0 +1,2851 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 * Author: Nikos Mavrogiannopoulos, Simon Josefsson, Howard Chu
4 *
5 * This file is part of GNUTLS.
6 *
7 * The GNUTLS library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20 * USA
21 *
22 */
23
24/* Functions on X.509 Certificate parsing
25 */
26
27#include <gnutls_int.h>
28#include <gnutls_datum.h>
29#include <gnutls_global.h>
30#include <gnutls_errors.h>
31#include <common.h>
32#include <gnutls_x509.h>
33#include <x509_b64.h>
34#include <x509.h>
35#include <dn.h>
36#include <extensions.h>
37#include <libtasn1.h>
38#include <mpi.h>
39#include <privkey.h>
40#include <verify.h>
41
42/**
43 * gnutls_x509_crt_init - This function initializes a gnutls_x509_crt_t structure
44 * @cert: The structure to be initialized
45 *
46 * This function will initialize an X.509 certificate structure.
47 *
48 * Returns 0 on success.
49 *
50 **/
51int
52gnutls_x509_crt_init (gnutls_x509_crt_t * cert)
53{
54 gnutls_x509_crt_t tmp = gnutls_calloc (1, sizeof (gnutls_x509_crt_int));
55 int result;
56
57 if (!tmp)
58 return GNUTLS_E_MEMORY_ERROR;
59
60 result = asn1_create_element (_gnutls_get_pkix (),
61 "PKIX1.Certificate", &tmp->cert);
62 if (result != ASN1_SUCCESS)
63 {
64 gnutls_assert ();
65 gnutls_free (tmp);
66 return _gnutls_asn2err (result);
67 }
68
69 *cert = tmp;
70
71 return 0; /* success */
72}
73
74/*-
75 * _gnutls_x509_crt_cpy - This function copies a gnutls_x509_crt_t structure
76 * @dest: The structure where to copy
77 * @src: The structure to be copied
78 *
79 * This function will copy an X.509 certificate structure.
80 *
81 * Returns 0 on success.
82 *
83 -*/
84int
85_gnutls_x509_crt_cpy (gnutls_x509_crt_t dest, gnutls_x509_crt_t src)
86{
87 int ret;
88 size_t der_size;
89 opaque *der;
90 gnutls_datum_t tmp;
91
92 ret = gnutls_x509_crt_export (src, GNUTLS_X509_FMT_DER, NULL, &der_size);
93 if (ret != GNUTLS_E_SHORT_MEMORY_BUFFER)
94 {
95 gnutls_assert ();
96 return ret;
97 }
98
99 der = gnutls_alloca (der_size);
100 if (der == NULL)
101 {
102 gnutls_assert ();
103 return GNUTLS_E_MEMORY_ERROR;
104 }
105
106 ret = gnutls_x509_crt_export (src, GNUTLS_X509_FMT_DER, der, &der_size);
107 if (ret < 0)
108 {
109 gnutls_assert ();
110 gnutls_afree (der);
111 return ret;
112 }
113
114 tmp.data = der;
115 tmp.size = der_size;
116 ret = gnutls_x509_crt_import (dest, &tmp, GNUTLS_X509_FMT_DER);
117
118 gnutls_afree (der);
119
120 if (ret < 0)
121 {
122 gnutls_assert ();
123 return ret;
124 }
125
126 return 0;
127
128}
129
130/**
131 * gnutls_x509_crt_deinit - This function deinitializes memory used by a gnutls_x509_crt_t structure
132 * @cert: The structure to be initialized
133 *
134 * This function will deinitialize a CRL structure.
135 *
136 **/
137void
138gnutls_x509_crt_deinit (gnutls_x509_crt_t cert)
139{
140 if (!cert)
141 return;
142
143 if (cert->cert)
144 asn1_delete_structure (&cert->cert);
145
146 gnutls_free (cert);
147}
148
149/**
150 * gnutls_x509_crt_import - This function will import a DER or PEM encoded Certificate
151 * @cert: The structure to store the parsed certificate.
152 * @data: The DER or PEM encoded certificate.
153 * @format: One of DER or PEM
154 *
155 * This function will convert the given DER or PEM encoded Certificate
156 * to the native gnutls_x509_crt_t format. The output will be stored in @cert.
157 *
158 * If the Certificate is PEM encoded it should have a header of "X509 CERTIFICATE", or
159 * "CERTIFICATE".
160 *
161 * Returns 0 on success.
162 *
163 **/
164int
165gnutls_x509_crt_import (gnutls_x509_crt_t cert,
166 const gnutls_datum_t * data,
167 gnutls_x509_crt_fmt_t format)
168{
169 int result = 0, need_free = 0;
170 gnutls_datum_t _data;
171 opaque *signature = NULL;
172
173 if (cert == NULL)
174 {
175 gnutls_assert ();
176 return GNUTLS_E_INVALID_REQUEST;
177 }
178
179 _data.data = data->data;
180 _data.size = data->size;
181
182 /* If the Certificate is in PEM format then decode it
183 */
184 if (format == GNUTLS_X509_FMT_PEM)
185 {
186 opaque *out;
187
188 /* Try the first header */
189 result = _gnutls_fbase64_decode (PEM_X509_CERT2, data->data, data->size,
190 &out);
191
192 if (result <= 0)
193 {
194 /* try for the second header */
195 result = _gnutls_fbase64_decode (PEM_X509_CERT, data->data,
196 data->size, &out);
197
198 if (result <= 0)
199 {
200 if (result == 0)
201 result = GNUTLS_E_INTERNAL_ERROR;
202 gnutls_assert ();
203 return result;
204 }
205 }
206
207 _data.data = out;
208 _data.size = result;
209
210 need_free = 1;
211 }
212
213 result = asn1_der_decoding (&cert->cert, _data.data, _data.size, NULL);
214 if (result != ASN1_SUCCESS)
215 {
216 result = _gnutls_asn2err (result);
217 gnutls_assert ();
218 goto cleanup;
219 }
220
221 /* Since we do not want to disable any extension
222 */
223 cert->use_extensions = 1;
224 if (need_free)
225 _gnutls_free_datum (&_data);
226
227 return 0;
228
229cleanup:gnutls_free (signature);
230 if (need_free)
231 _gnutls_free_datum (&_data);
232 return result;
233}
234
235/**
236 * gnutls_x509_crt_get_issuer_dn - This function returns the Certificate's issuer distinguished name
237 * @cert: should contain a gnutls_x509_crt_t structure
238 * @buf: a pointer to a structure to hold the name (may be null)
239 * @sizeof_buf: initially holds the size of @buf
240 *
241 * This function will copy the name of the Certificate issuer in the
242 * provided buffer. The name will be in the form
243 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output string
244 * will be ASCII or UTF-8 encoded, depending on the certificate data.
245 *
246 * If @buf is null then only the size will be filled.
247 *
248 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
249 * long enough, and in that case the *sizeof_buf will be updated with
250 * the required size. On success 0 is returned.
251 *
252 **/
253int
254gnutls_x509_crt_get_issuer_dn (gnutls_x509_crt_t cert,
255 char *buf, size_t * sizeof_buf)
256{
257 if (cert == NULL)
258 {
259 gnutls_assert ();
260 return GNUTLS_E_INVALID_REQUEST;
261 }
262
263 return _gnutls_x509_parse_dn (cert->cert,
264 "tbsCertificate.issuer.rdnSequence", buf,
265 sizeof_buf);
266}
267
268/**
269 * gnutls_x509_crt_get_issuer_dn_by_oid - This function returns the Certificate's issuer distinguished name
270 * @cert: should contain a gnutls_x509_crt_t structure
271 * @oid: holds an Object Identified in null terminated string
272 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use zero to get the first one.
273 * @raw_flag: If non zero returns the raw DER data of the DN part.
274 * @buf: a pointer to a structure to hold the name (may be null)
275 * @sizeof_buf: initially holds the size of @buf
276 *
277 * This function will extract the part of the name of the Certificate
278 * issuer specified by the given OID. The output, if the raw flag is not
279 * used, will be encoded as described in RFC2253. Thus a string that is
280 * ASCII or UTF-8 encoded, depending on the certificate data.
281 *
282 * Some helper macros with popular OIDs can be found in gnutls/x509.h
283 * If raw flag is zero, this function will only return known OIDs as
284 * text. Other OIDs will be DER encoded, as described in RFC2253 --
285 * in hex format with a '\#' prefix. You can check about known OIDs
286 * using gnutls_x509_dn_oid_known().
287 *
288 * If @buf is null then only the size will be filled.
289 *
290 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
291 * long enough, and in that case the *sizeof_buf will be updated with
292 * the required size. On success 0 is returned.
293 *
294 **/
295int
296gnutls_x509_crt_get_issuer_dn_by_oid (gnutls_x509_crt_t cert,
297 const char *oid,
298 int indx,
299 unsigned int raw_flag,
300 void *buf, size_t * sizeof_buf)
301{
302 if (cert == NULL)
303 {
304 gnutls_assert ();
305 return GNUTLS_E_INVALID_REQUEST;
306 }
307
308 return _gnutls_x509_parse_dn_oid (cert->cert,
309 "tbsCertificate.issuer.rdnSequence", oid,
310 indx, raw_flag, buf, sizeof_buf);
311}
312
313/**
314 * gnutls_x509_crt_get_issuer_dn_oid - This function returns the Certificate's issuer distinguished name OIDs
315 * @cert: should contain a gnutls_x509_crt_t structure
316 * @indx: This specifies which OID to return. Use zero to get the first one.
317 * @oid: a pointer to a buffer to hold the OID (may be null)
318 * @sizeof_oid: initially holds the size of @oid
319 *
320 * This function will extract the OIDs of the name of the Certificate
321 * issuer specified by the given index.
322 *
323 * If @oid is null then only the size will be filled.
324 *
325 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
326 * long enough, and in that case the *sizeof_oid will be updated with
327 * the required size. On success 0 is returned.
328 *
329 **/
330int
331gnutls_x509_crt_get_issuer_dn_oid (gnutls_x509_crt_t cert,
332 int indx, void *oid, size_t * sizeof_oid)
333{
334 if (cert == NULL)
335 {
336 gnutls_assert ();
337 return GNUTLS_E_INVALID_REQUEST;
338 }
339
340 return _gnutls_x509_get_dn_oid (cert->cert,
341 "tbsCertificate.issuer.rdnSequence", indx,
342 oid, sizeof_oid);
343}
344
345/**
346 * gnutls_x509_crt_get_dn - This function returns the Certificate's distinguished name
347 * @cert: should contain a gnutls_x509_crt_t structure
348 * @buf: a pointer to a structure to hold the name (may be null)
349 * @sizeof_buf: initially holds the size of @buf
350 *
351 * This function will copy the name of the Certificate in the
352 * provided buffer. The name will be in the form
353 * "C=xxxx,O=yyyy,CN=zzzz" as described in RFC2253. The output string
354 * will be ASCII or UTF-8 encoded, depending on the certificate data.
355 *
356 * If @buf is null then only the size will be filled.
357 *
358 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
359 * long enough, and in that case the *sizeof_buf will be updated with
360 * the required size. On success 0 is returned.
361 *
362 **/
363int
364gnutls_x509_crt_get_dn (gnutls_x509_crt_t cert,
365 char *buf, size_t * sizeof_buf)
366{
367 if (cert == NULL)
368 {
369 gnutls_assert ();
370 return GNUTLS_E_INVALID_REQUEST;
371 }
372
373 return _gnutls_x509_parse_dn (cert->cert,
374 "tbsCertificate.subject.rdnSequence", buf,
375 sizeof_buf);
376}
377
378/**
379 * gnutls_x509_crt_get_dn_by_oid - This function returns the Certificate's distinguished name
380 * @cert: should contain a gnutls_x509_crt_t structure
381 * @oid: holds an Object Identified in null terminated string
382 * @indx: In case multiple same OIDs exist in the RDN, this specifies which to send. Use zero to get the first one.
383 * @raw_flag: If non zero returns the raw DER data of the DN part.
384 * @buf: a pointer where the DN part will be copied (may be null).
385 * @sizeof_buf: initially holds the size of @buf
386 *
387 * This function will extract the part of the name of the Certificate
388 * subject specified by the given OID. The output, if the raw flag is not
389 * used, will be encoded as described in RFC2253. Thus a string that is
390 * ASCII or UTF-8 encoded, depending on the certificate data.
391 *
392 * Some helper macros with popular OIDs can be found in gnutls/x509.h
393 * If raw flag is zero, this function will only return known OIDs as
394 * text. Other OIDs will be DER encoded, as described in RFC2253 --
395 * in hex format with a '\#' prefix. You can check about known OIDs
396 * using gnutls_x509_dn_oid_known().
397 *
398 * If @buf is null then only the size will be filled.
399 *
400 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
401 * long enough, and in that case the *sizeof_buf will be updated with
402 * the required size. On success 0 is returned.
403 *
404 **/
405int
406gnutls_x509_crt_get_dn_by_oid (gnutls_x509_crt_t cert,
407 const char *oid,
408 int indx,
409 unsigned int raw_flag,
410 void *buf, size_t * sizeof_buf)
411{
412 if (cert == NULL)
413 {
414 gnutls_assert ();
415 return GNUTLS_E_INVALID_REQUEST;
416 }
417
418 return _gnutls_x509_parse_dn_oid (cert->cert,
419 "tbsCertificate.subject.rdnSequence", oid,
420 indx, raw_flag, buf, sizeof_buf);
421}
422
423/**
424 * gnutls_x509_crt_get_dn_oid - This function returns the Certificate's subject distinguished name OIDs
425 * @cert: should contain a gnutls_x509_crt_t structure
426 * @indx: This specifies which OID to return. Use zero to get the first one.
427 * @oid: a pointer to a buffer to hold the OID (may be null)
428 * @sizeof_oid: initially holds the size of @oid
429 *
430 * This function will extract the OIDs of the name of the Certificate
431 * subject specified by the given index.
432 *
433 * If oid is null then only the size will be filled.
434 *
435 * Returns GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is not
436 * long enough, and in that case the *sizeof_oid will be updated with
437 * the required size. On success 0 is returned.
438 *
439 **/
440int
441gnutls_x509_crt_get_dn_oid (gnutls_x509_crt_t cert,
442 int indx, void *oid, size_t * sizeof_oid)
443{
444 if (cert == NULL)
445 {
446 gnutls_assert ();
447 return GNUTLS_E_INVALID_REQUEST;
448 }
449
450 return _gnutls_x509_get_dn_oid (cert->cert,
451 "tbsCertificate.subject.rdnSequence", indx,
452 oid, sizeof_oid);
453}
454
455/**
456 * gnutls_x509_crt_get_signature_algorithm - This function returns the Certificate's signature algorithm
457 * @cert: should contain a gnutls_x509_crt_t structure
458 *
459 * This function will return a value of the gnutls_sign_algorithm_t enumeration that
460 * is the signature algorithm.
461 *
462 * Returns a negative value on error.
463 *
464 **/
465int
466gnutls_x509_crt_get_signature_algorithm (gnutls_x509_crt_t cert)
467{
468 int result;
469 gnutls_datum_t sa;
470
471 if (cert == NULL)
472 {
473 gnutls_assert ();
474 return GNUTLS_E_INVALID_REQUEST;
475 }
476
477 /* Read the signature algorithm. Note that parameters are not
478 * read. They will be read from the issuer's certificate if needed.
479 */
480 result =
481 _gnutls_x509_read_value (cert->cert, "signatureAlgorithm.algorithm", &sa,
482 0);
483
484 if (result < 0)
485 {
486 gnutls_assert ();
487 return result;
488 }
489
490 result = _gnutls_x509_oid2sign_algorithm (sa.data);
491
492 _gnutls_free_datum (&sa);
493
494 return result;
495}
496
497/**
498 * gnutls_x509_crt_get_signature - Returns the Certificate's signature
499 * @cert: should contain a gnutls_x509_crt_t structure
500 * @sig: a pointer where the signature part will be copied (may be null).
501 * @sizeof_sig: initially holds the size of @sig
502 *
503 * This function will extract the signature field of a certificate.
504 *
505 * Returns 0 on success, and a negative value on error.
506 **/
507int
508gnutls_x509_crt_get_signature (gnutls_x509_crt_t cert,
509 char *sig, size_t * sizeof_sig)
510{
511 int result;
512 int bits, len;
513
514 if (cert == NULL)
515 {
516 gnutls_assert ();
517 return GNUTLS_E_INVALID_REQUEST;
518 }
519
520 bits = 0;
521 result = asn1_read_value (cert->cert, "signature", NULL, &bits);
522 if (result != ASN1_MEM_ERROR)
523 {
524 gnutls_assert ();
525 return _gnutls_asn2err (result);
526 }
527
528 if (bits % 8 != 0)
529 {
530 gnutls_assert ();
531 return GNUTLS_E_CERTIFICATE_ERROR;
532 }
533
534 len = bits / 8;
535
536 if (*sizeof_sig < len)
537 {
538 *sizeof_sig = bits / 8;
539 return GNUTLS_E_SHORT_MEMORY_BUFFER;
540 }
541
542 result = asn1_read_value (cert->cert, "signature", sig, &len);
543 if (result != ASN1_SUCCESS)
544 {
545 gnutls_assert ();
546 return _gnutls_asn2err (result);
547 }
548
549 return 0;
550}
551
552/**
553 * gnutls_x509_crt_get_version - This function returns the Certificate's version number
554 * @cert: should contain a gnutls_x509_crt_t structure
555 *
556 * This function will return the version of the specified Certificate.
557 *
558 * Returns a negative value on error.
559 *
560 **/
561int
562gnutls_x509_crt_get_version (gnutls_x509_crt_t cert)
563{
564 opaque version[5];
565 int len, result;
566
567 if (cert == NULL)
568 {
569 gnutls_assert ();
570 return GNUTLS_E_INVALID_REQUEST;
571 }
572
573 len = sizeof (version);
574 if ((result =
575 asn1_read_value (cert->cert, "tbsCertificate.version", version,
576 &len)) != ASN1_SUCCESS)
577 {
578
579 if (result == ASN1_ELEMENT_NOT_FOUND)
580 return 1; /* the DEFAULT version */
581 gnutls_assert ();
582 return _gnutls_asn2err (result);
583 }
584
585 return (int) version[0] + 1;
586}
587
588/**
589 * gnutls_x509_crt_get_activation_time - This function returns the Certificate's activation time
590 * @cert: should contain a gnutls_x509_crt_t structure
591 *
592 * This function will return the time this Certificate was or will be activated.
593 *
594 * Returns (time_t)-1 on error.
595 *
596 **/
597time_t
598gnutls_x509_crt_get_activation_time (gnutls_x509_crt_t cert)
599{
600 if (cert == NULL)
601 {
602 gnutls_assert ();
603 return (time_t) - 1;
604 }
605
606 return _gnutls_x509_get_time (cert->cert,
607 "tbsCertificate.validity.notBefore");
608}
609
610/**
611 * gnutls_x509_crt_get_expiration_time - This function returns the Certificate's expiration time
612 * @cert: should contain a gnutls_x509_crt_t structure
613 *
614 * This function will return the time this Certificate was or will be expired.
615 *
616 * Returns (time_t)-1 on error.
617 *
618 **/
619time_t
620gnutls_x509_crt_get_expiration_time (gnutls_x509_crt_t cert)
621{
622 if (cert == NULL)
623 {
624 gnutls_assert ();
625 return (time_t) - 1;
626 }
627
628 return _gnutls_x509_get_time (cert->cert,
629 "tbsCertificate.validity.notAfter");
630}
631
632/**
633 * gnutls_x509_crt_get_serial - This function returns the certificate's serial number
634 * @cert: should contain a gnutls_x509_crt_t structure
635 * @result: The place where the serial number will be copied
636 * @result_size: Holds the size of the result field.
637 *
638 * This function will return the X.509 certificate's serial number.
639 * This is obtained by the X509 Certificate serialNumber
640 * field. Serial is not always a 32 or 64bit number. Some CAs use
641 * large serial numbers, thus it may be wise to handle it as something
642 * opaque.
643 *
644 * Returns 0 on success and a negative value in case of an error.
645 *
646 **/
647int
648gnutls_x509_crt_get_serial (gnutls_x509_crt_t cert,
649 void *result, size_t * result_size)
650{
651 int ret, len;
652
653 if (cert == NULL)
654 {
655 gnutls_assert ();
656 return GNUTLS_E_INVALID_REQUEST;
657 }
658
659 len = *result_size;
660 ret
661 =
662 asn1_read_value (cert->cert, "tbsCertificate.serialNumber", result, &len);
663 *result_size = len;
664
665 if (ret != ASN1_SUCCESS)
666 {
667 gnutls_assert ();
668 return _gnutls_asn2err (ret);
669 }
670
671 return 0;
672}
673
674/**
675 * gnutls_x509_crt_get_subject_key_id - This function returns the certificate's key identifier
676 * @cert: should contain a gnutls_x509_crt_t structure
677 * @ret: The place where the identifier will be copied
678 * @ret_size: Holds the size of the result field.
679 * @critical: will be non zero if the extension is marked as critical (may be null)
680 *
681 * This function will return the X.509v3 certificate's subject key identifier.
682 * This is obtained by the X.509 Subject Key identifier extension
683 * field (2.5.29.14).
684 *
685 * Returns 0 on success and a negative value in case of an error.
686 *
687 **/
688int
689gnutls_x509_crt_get_subject_key_id (gnutls_x509_crt_t cert,
690 void *ret,
691 size_t * ret_size, unsigned int *critical)
692{
693 int result, len;
694 gnutls_datum_t id;
695 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
696
697 if (cert == NULL)
698 {
699 gnutls_assert ();
700 return GNUTLS_E_INVALID_REQUEST;
701 }
702
703 if (ret)
704 memset (ret, 0, *ret_size);
705 else
706 *ret_size = 0;
707
708 if ((result = _gnutls_x509_crt_get_extension (cert, "2.5.29.14", 0, &id,
709 critical)) < 0)
710 {
711 return result;
712 }
713
714 if (id.size == 0 || id.data == NULL)
715 {
716 gnutls_assert ();
717 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
718 }
719
720 result =
721 asn1_create_element (_gnutls_get_pkix (), "PKIX1.SubjectKeyIdentifier",
722 &c2);
723 if (result != ASN1_SUCCESS)
724 {
725 gnutls_assert ();
726 _gnutls_free_datum (&id);
727 return _gnutls_asn2err (result);
728 }
729
730 result = asn1_der_decoding (&c2, id.data, id.size, NULL);
731 _gnutls_free_datum (&id);
732
733 if (result != ASN1_SUCCESS)
734 {
735 gnutls_assert ();
736 asn1_delete_structure (&c2);
737 return _gnutls_asn2err (result);
738 }
739
740 len = *ret_size;
741 result = asn1_read_value (c2, "", ret, &len);
742
743 *ret_size = len;
744 asn1_delete_structure (&c2);
745
746 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
747 {
748 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
749 }
750
751 if (result != ASN1_SUCCESS)
752 {
753 gnutls_assert ();
754 return _gnutls_asn2err (result);
755 }
756
757 return 0;
758}
759
760/**
761 * gnutls_x509_crt_get_authority_key_id - This function returns the certificate authority's identifier
762 * @cert: should contain a gnutls_x509_crt_t structure
763 * @result: The place where the identifier will be copied
764 * @result_size: Holds the size of the result field.
765 * @critical: will be non zero if the extension is marked as critical (may be null)
766 *
767 * This function will return the X.509v3 certificate authority's key identifier.
768 * This is obtained by the X.509 Authority Key identifier extension
769 * field (2.5.29.35). Note that this function only returns the keyIdentifier
770 * field of the extension.
771 *
772 * Returns 0 on success and a negative value in case of an error.
773 *
774 **/
775int
776gnutls_x509_crt_get_authority_key_id (gnutls_x509_crt_t cert,
777 void *ret,
778 size_t * ret_size,
779 unsigned int *critical)
780{
781 int result, len;
782 gnutls_datum_t id;
783 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
784
785 if (cert == NULL)
786 {
787 gnutls_assert ();
788 return GNUTLS_E_INVALID_REQUEST;
789 }
790
791 if (ret)
792 memset (ret, 0, *ret_size);
793 else
794 *ret_size = 0;
795
796 if ((result = _gnutls_x509_crt_get_extension (cert, "2.5.29.35", 0, &id,
797 critical)) < 0)
798 {
799 return result;
800 }
801
802 if (id.size == 0 || id.data == NULL)
803 {
804 gnutls_assert ();
805 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
806 }
807
808 result =
809 asn1_create_element (_gnutls_get_pkix (), "PKIX1.AuthorityKeyIdentifier",
810 &c2);
811 if (result != ASN1_SUCCESS)
812 {
813 gnutls_assert ();
814 _gnutls_free_datum (&id);
815 return _gnutls_asn2err (result);
816 }
817
818 result = asn1_der_decoding (&c2, id.data, id.size, NULL);
819 _gnutls_free_datum (&id);
820
821 if (result != ASN1_SUCCESS)
822 {
823 gnutls_assert ();
824 asn1_delete_structure (&c2);
825 return _gnutls_asn2err (result);
826 }
827
828 len = *ret_size;
829 result = asn1_read_value (c2, "keyIdentifier", ret, &len);
830
831 *ret_size = len;
832 asn1_delete_structure (&c2);
833
834 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
835 {
836 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
837 }
838
839 if (result != ASN1_SUCCESS)
840 {
841 gnutls_assert ();
842 return _gnutls_asn2err (result);
843 }
844
845 return 0;
846}
847
848/**
849 * gnutls_x509_crt_get_pk_algorithm - This function returns the certificate's PublicKey algorithm
850 * @cert: should contain a gnutls_x509_crt_t structure
851 * @bits: if bits is non null it will hold the size of the parameters' in bits
852 *
853 * This function will return the public key algorithm of an X.509
854 * certificate.
855 *
856 * If bits is non null, it should have enough size to hold the parameters
857 * size in bits. For RSA the bits returned is the modulus.
858 * For DSA the bits returned are of the public
859 * exponent.
860 *
861 * Returns a member of the gnutls_pk_algorithm_t enumeration on success,
862 * or a negative value on error.
863 *
864 **/
865int
866gnutls_x509_crt_get_pk_algorithm (gnutls_x509_crt_t cert, unsigned int *bits)
867{
868 int result;
869
870 if (cert == NULL)
871 {
872 gnutls_assert ();
873 return GNUTLS_E_INVALID_REQUEST;
874 }
875
876 result = _gnutls_x509_get_pk_algorithm (cert->cert,
877 "tbsCertificate.subjectPublicKeyInfo",
878 bits);
879
880 if (result < 0)
881 {
882 gnutls_assert ();
883 return result;
884 }
885
886 return result;
887
888}
889
890inline static int
891is_type_printable (int type)
892{
893 if (type == GNUTLS_SAN_DNSNAME || type == GNUTLS_SAN_RFC822NAME || type
894 == GNUTLS_SAN_URI)
895 return 1;
896 else
897 return 0;
898}
899
900#define XMPP_OID "1.3.6.1.5.5.7.8.5"
901
902/* returns the type and the name on success.
903 * Type is also returned as a parameter in case of an error.
904 */
905static int
906parse_general_name (ASN1_TYPE src,
907 const char *src_name,
908 int seq,
909 void *name,
910 size_t * name_size,
911 unsigned int *ret_type, int othername_oid)
912{
913 int len;
914 char nptr[MAX_NAME_SIZE];
915 int result;
916 opaque choice_type[128];
917 gnutls_x509_subject_alt_name_t type;
918
919 seq++; /* 0->1, 1->2 etc */
920
921 if (src_name[0] != 0)
922 snprintf (nptr, sizeof (nptr), "%s.?%u", src_name, seq);
923 else
924 snprintf (nptr, sizeof (nptr), "?%u", seq);
925
926 len = sizeof (choice_type);
927 result = asn1_read_value (src, nptr, choice_type, &len);
928
929 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
930 {
931 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
932 }
933
934 if (result != ASN1_SUCCESS)
935 {
936 gnutls_assert ();
937 return _gnutls_asn2err (result);
938 }
939
940 type = _gnutls_x509_san_find_type (choice_type);
941 if (type == (gnutls_x509_subject_alt_name_t) - 1)
942 {
943 gnutls_assert ();
944 return GNUTLS_E_X509_UNKNOWN_SAN;
945 }
946
947 if (ret_type)
948 *ret_type = type;
949
950 if (type == GNUTLS_SAN_OTHERNAME)
951 {
952 if (othername_oid)
953 _gnutls_str_cat (nptr, sizeof (nptr), ".otherName.type-id");
954 else
955 _gnutls_str_cat (nptr, sizeof (nptr), ".otherName.value");
956
957 len = *name_size;
958 result = asn1_read_value (src, nptr, name, &len);
959 *name_size = len;
960
961 if (result == ASN1_MEM_ERROR)
962 return GNUTLS_E_SHORT_MEMORY_BUFFER;
963
964 if (result != ASN1_SUCCESS)
965 {
966 gnutls_assert ();
967 return _gnutls_asn2err (result);
968 }
969
970 if (othername_oid)
971 {
972 if (len > strlen (XMPP_OID) && strcmp (name, XMPP_OID) == 0)
973 type = GNUTLS_SAN_OTHERNAME_XMPP;
974 }
975 else
976 {
977 char oid[42];
978
979 if (src_name[0] != 0)
980 snprintf (nptr, sizeof (nptr), "%s.?%u.otherName.type-id",
981 src_name, seq);
982 else
983 snprintf (nptr, sizeof (nptr), "?%u.otherName.type-id", seq);
984
985 len = sizeof (oid);
986 result = asn1_read_value (src, nptr, oid, &len);
987 if (result != ASN1_SUCCESS)
988 {
989 gnutls_assert ();
990 return _gnutls_asn2err (result);
991 }
992
993 if (len > strlen (XMPP_OID) && strcmp (oid, XMPP_OID) == 0)
994 {
995 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
996
997 result =
998 asn1_create_element (_gnutls_get_pkix (), "PKIX1.XmppAddr",
999 &c2);
1000 if (result != ASN1_SUCCESS)
1001 {
1002 gnutls_assert ();
1003 return _gnutls_asn2err (result);
1004 }
1005
1006 result = asn1_der_decoding (&c2, name, *name_size, NULL);
1007 if (result != ASN1_SUCCESS)
1008 {
1009 gnutls_assert ();
1010 asn1_delete_structure (&c2);
1011 return _gnutls_asn2err (result);
1012 }
1013
1014 result = asn1_read_value (c2, "", name, &len);
1015 *name_size = len;
1016 if (result != ASN1_SUCCESS)
1017 {
1018 gnutls_assert ();
1019 asn1_delete_structure (&c2);
1020 return _gnutls_asn2err (result);
1021 }
1022 asn1_delete_structure (&c2);
1023 }
1024 }
1025 }
1026 else if (type == GNUTLS_SAN_DN)
1027 {
1028 _gnutls_str_cat (nptr, sizeof (nptr), ".directoryName");
1029 result = _gnutls_x509_parse_dn (src, nptr, name, name_size);
1030 if (result < 0)
1031 {
1032 gnutls_assert ();
1033 return result;
1034 }
1035 }
1036 else if (othername_oid)
1037 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1038 else
1039 {
1040 size_t orig_name_size = *name_size;
1041
1042 _gnutls_str_cat (nptr, sizeof (nptr), ".");
1043 _gnutls_str_cat (nptr, sizeof (nptr), choice_type);
1044
1045 len = *name_size;
1046 result = asn1_read_value (src, nptr, name, &len);
1047 *name_size = len;
1048
1049 if (result == ASN1_MEM_ERROR)
1050 {
1051 if (is_type_printable (type))
1052 (*name_size)++;
1053 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1054 }
1055
1056 if (result != ASN1_SUCCESS)
1057 {
1058 gnutls_assert ();
1059 return _gnutls_asn2err (result);
1060 }
1061
1062 if (is_type_printable (type))
1063 {
1064
1065 if (len + 1 > orig_name_size)
1066 {
1067 gnutls_assert ();
1068 (*name_size)++;
1069 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1070 }
1071
1072 /* null terminate it */
1073 ((char *) name)[*name_size] = 0;
1074 }
1075
1076 }
1077
1078 return type;
1079}
1080
1081static int
1082get_subject_alt_name (gnutls_x509_crt_t cert,
1083 unsigned int seq,
1084 void *ret,
1085 size_t * ret_size,
1086 unsigned int *ret_type,
1087 unsigned int *critical, int othername_oid)
1088{
1089 int result;
1090 gnutls_datum_t dnsname;
1091 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1092 gnutls_x509_subject_alt_name_t type;
1093
1094 if (cert == NULL)
1095 {
1096 gnutls_assert ();
1097 return GNUTLS_E_INVALID_REQUEST;
1098 }
1099
1100 if (ret)
1101 memset (ret, 0, *ret_size);
1102 else
1103 *ret_size = 0;
1104
1105 if ((result =
1106 _gnutls_x509_crt_get_extension (cert, "2.5.29.17", 0, &dnsname,
1107 critical)) < 0)
1108 {
1109 return result;
1110 }
1111
1112 if (dnsname.size == 0 || dnsname.data == NULL)
1113 {
1114 gnutls_assert ();
1115 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1116 }
1117
1118 result =
1119 asn1_create_element (_gnutls_get_pkix (), "PKIX1.SubjectAltName", &c2);
1120 if (result != ASN1_SUCCESS)
1121 {
1122 gnutls_assert ();
1123 _gnutls_free_datum (&dnsname);
1124 return _gnutls_asn2err (result);
1125 }
1126
1127 result = asn1_der_decoding (&c2, dnsname.data, dnsname.size, NULL);
1128 _gnutls_free_datum (&dnsname);
1129
1130 if (result != ASN1_SUCCESS)
1131 {
1132 gnutls_assert ();
1133 asn1_delete_structure (&c2);
1134 return _gnutls_asn2err (result);
1135 }
1136
1137 result = parse_general_name (c2, "", seq, ret, ret_size, ret_type,
1138 othername_oid);
1139
1140 asn1_delete_structure (&c2);
1141
1142 if (result < 0)
1143 {
1144 return result;
1145 }
1146
1147 type = result;
1148
1149 return type;
1150}
1151
1152/**
1153 * gnutls_x509_crt_get_subject_alt_name - Get certificate's alternative name, if any
1154 * @cert: should contain a gnutls_x509_crt_t structure
1155 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1156 * @ret: is the place where the alternative name will be copied to
1157 * @ret_size: holds the size of ret.
1158 * @critical: will be non zero if the extension is marked as critical (may be null)
1159 *
1160 * This function will return the alternative names, contained in the
1161 * given certificate.
1162 *
1163 * This is specified in X509v3 Certificate Extensions. GNUTLS will
1164 * return the Alternative name (2.5.29.17), or a negative error code.
1165 *
1166 * When the SAN type is otherName, it will extract the data in the
1167 * otherName's value field, and %GNUTLS_SAN_OTHERNAME is returned.
1168 * You may use gnutls_x509_crt_get_subject_alt_othername_oid() to get
1169 * the corresponding OID and the "virtual" SAN types (e.g.,
1170 * %GNUTLS_SAN_OTHERNAME_XMPP).
1171 *
1172 * If an otherName OID is known, the data will be decoded. Otherwise
1173 * the returned data will be DER encoded, and you will have to decode
1174 * it yourself. Currently, only the RFC 3920 id-on-xmppAddr SAN is
1175 * recognized.
1176 *
1177 * Returns the alternative subject name type on success. The type is
1178 * one of the enumerated gnutls_x509_subject_alt_name_t. It will
1179 * return %GNUTLS_E_SHORT_MEMORY_BUFFER if @ret_size is not large
1180 * enough to hold the value. In that case @ret_size will be updated
1181 * with the required size. If the certificate does not have an
1182 * Alternative name with the specified sequence number then
1183 * %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1184 *
1185 **/
1186int
1187gnutls_x509_crt_get_subject_alt_name (gnutls_x509_crt_t cert,
1188 unsigned int seq,
1189 void *ret,
1190 size_t * ret_size,
1191 unsigned int *critical)
1192{
1193 return get_subject_alt_name (cert, seq, ret, ret_size, NULL, critical, 0);
1194}
1195
1196/**
1197 * gnutls_x509_crt_get_subject_alt_name2 - Get certificate's alternative name, if any
1198 * @cert: should contain a gnutls_x509_crt_t structure
1199 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1200 * @ret: is the place where the alternative name will be copied to
1201 * @ret_size: holds the size of ret.
1202 * @ret_type: holds the type of the alternative name (one of gnutls_x509_subject_alt_name_t).
1203 * @critical: will be non zero if the extension is marked as critical (may be null)
1204 *
1205 * This function will return the alternative names, contained in the
1206 * given certificate. It is the same as gnutls_x509_crt_get_subject_alt_name()
1207 * except for the fact that it will return the type of the alternative
1208 * name in @ret_type even if the function fails for some reason (i.e.
1209 * the buffer provided is not enough).
1210 *
1211 * The return values are the same as with gnutls_x509_crt_get_subject_alt_name().
1212 *
1213 **/
1214int
1215gnutls_x509_crt_get_subject_alt_name2 (gnutls_x509_crt_t cert,
1216 unsigned int seq,
1217 void *ret,
1218 size_t * ret_size,
1219 unsigned int *ret_type,
1220 unsigned int *critical)
1221{
1222 return get_subject_alt_name (cert, seq, ret, ret_size, ret_type, critical,
1223 0);
1224}
1225
1226/**
1227 * gnutls_x509_crt_get_subject_alt_othername_oid - Get SAN otherName OID
1228 * @cert: should contain a gnutls_x509_crt_t structure
1229 * @seq: specifies the sequence number of the alt name (0 for the first one, 1 for the second etc.)
1230 * @ret: is the place where the otherName OID will be copied to
1231 * @ret_size: holds the size of ret.
1232 *
1233 * This function will extract the type OID of an otherName Subject
1234 * Alternative Name, contained in the given certificate, and return
1235 * the type as an enumerated element.
1236 *
1237 * This function is only useful if
1238 * gnutls_x509_crt_get_subject_alt_name() returned
1239 * %GNUTLS_SAN_OTHERNAME.
1240 *
1241 * Returns the alternative subject name type on success. The type is
1242 * one of the enumerated gnutls_x509_subject_alt_name_t. For
1243 * supported OIDs, it will return one of the virtual
1244 * (GNUTLS_SAN_OTHERNAME_*) types, e.g. %GNUTLS_SAN_OTHERNAME_XMPP,
1245 * and %GNUTLS_SAN_OTHERNAME for unknown OIDs. It will return
1246 * %GNUTLS_E_SHORT_MEMORY_BUFFER if @ret_size is not large enough to
1247 * hold the value. In that case @ret_size will be updated with the
1248 * required size. If the certificate does not have an Alternative
1249 * name with the specified sequence number and with the otherName type
1250 * then %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned.
1251 **/
1252int
1253gnutls_x509_crt_get_subject_alt_othername_oid (gnutls_x509_crt_t cert,
1254 unsigned int seq,
1255 void *ret, size_t * ret_size)
1256{
1257 return get_subject_alt_name (cert, seq, ret, ret_size, NULL, NULL, 1);
1258}
1259
1260/**
1261 * gnutls_x509_crt_get_basic_constraints - This function returns the certificate basic constraints
1262 * @cert: should contain a gnutls_x509_crt_t structure
1263 * @critical: will be non zero if the extension is marked as critical
1264 * @ca: pointer to output integer indicating CA status, may be NULL,
1265 * value is 1 if the certificate CA flag is set, 0 otherwise.
1266 * @pathlen: pointer to output integer indicating path length (may be
1267 * NULL), non-negative values indicate a present pathLenConstraint
1268 * field and the actual value, -1 indicate that the field is absent.
1269 *
1270 * This function will read the certificate's basic constraints, and
1271 * return the certificates CA status. It reads the basicConstraints
1272 * X.509 extension (2.5.29.19).
1273 *
1274 * Return value: If the certificate is a CA a positive value will be
1275 * returned, or zero if the certificate does not have CA flag set. A
1276 * negative value may be returned in case of errors. If the
1277 * certificate does not contain the basicConstraints extension
1278 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1279 **/
1280int
1281gnutls_x509_crt_get_basic_constraints (gnutls_x509_crt_t cert,
1282 unsigned int *critical,
1283 int *ca, int *pathlen)
1284{
1285 int result;
1286 gnutls_datum_t basicConstraints;
1287 int tmp_ca;
1288
1289 if (cert == NULL)
1290 {
1291 gnutls_assert ();
1292 return GNUTLS_E_INVALID_REQUEST;
1293 }
1294
1295 if ((result = _gnutls_x509_crt_get_extension (cert, "2.5.29.19", 0,
1296 &basicConstraints, critical))
1297 < 0)
1298 {
1299 return result;
1300 }
1301
1302 if (basicConstraints.size == 0 || basicConstraints.data == NULL)
1303 {
1304 gnutls_assert ();
1305 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1306 }
1307
1308 result = _gnutls_x509_ext_extract_basicConstraints (&tmp_ca, pathlen,
1309 basicConstraints.data,
1310 basicConstraints.size);
1311 if (ca)
1312 *ca = tmp_ca;
1313 _gnutls_free_datum (&basicConstraints);
1314
1315 if (result < 0)
1316 {
1317 gnutls_assert ();
1318 return result;
1319 }
1320
1321 return tmp_ca;
1322}
1323
1324/**
1325 * gnutls_x509_crt_get_ca_status - This function returns the certificate CA status
1326 * @cert: should contain a gnutls_x509_crt_t structure
1327 * @critical: will be non zero if the extension is marked as critical
1328 *
1329 * This function will return certificates CA status, by reading the
1330 * basicConstraints X.509 extension (2.5.29.19). If the certificate is
1331 * a CA a positive value will be returned, or zero if the certificate
1332 * does not have CA flag set.
1333 *
1334 * Use gnutls_x509_crt_get_basic_constraints() if you want to read the
1335 * pathLenConstraint field too.
1336 *
1337 * A negative value may be returned in case of parsing error.
1338 * If the certificate does not contain the basicConstraints extension
1339 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1340 *
1341 **/
1342int
1343gnutls_x509_crt_get_ca_status (gnutls_x509_crt_t cert, unsigned int *critical)
1344{
1345 int ca, pathlen;
1346 return gnutls_x509_crt_get_basic_constraints (cert, critical, &ca,
1347 &pathlen);
1348}
1349
1350/**
1351 * gnutls_x509_crt_get_key_usage - This function returns the certificate's key usage
1352 * @cert: should contain a gnutls_x509_crt_t structure
1353 * @key_usage: where the key usage bits will be stored
1354 * @critical: will be non zero if the extension is marked as critical
1355 *
1356 * This function will return certificate's key usage, by reading the
1357 * keyUsage X.509 extension (2.5.29.15). The key usage value will ORed values of the:
1358 * GNUTLS_KEY_DIGITAL_SIGNATURE, GNUTLS_KEY_NON_REPUDIATION,
1359 * GNUTLS_KEY_KEY_ENCIPHERMENT, GNUTLS_KEY_DATA_ENCIPHERMENT,
1360 * GNUTLS_KEY_KEY_AGREEMENT, GNUTLS_KEY_KEY_CERT_SIGN,
1361 * GNUTLS_KEY_CRL_SIGN, GNUTLS_KEY_ENCIPHER_ONLY,
1362 * GNUTLS_KEY_DECIPHER_ONLY.
1363 *
1364 * A negative value may be returned in case of parsing error.
1365 * If the certificate does not contain the keyUsage extension
1366 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1367 *
1368 **/
1369int
1370gnutls_x509_crt_get_key_usage (gnutls_x509_crt_t cert,
1371 unsigned int *key_usage,
1372 unsigned int *critical)
1373{
1374 int result;
1375 gnutls_datum_t keyUsage;
1376 uint16_t _usage;
1377
1378 if (cert == NULL)
1379 {
1380 gnutls_assert ();
1381 return GNUTLS_E_INVALID_REQUEST;
1382 }
1383
1384 if ((result =
1385 _gnutls_x509_crt_get_extension (cert, "2.5.29.15", 0, &keyUsage,
1386 critical)) < 0)
1387 {
1388 return result;
1389 }
1390
1391 if (keyUsage.size == 0 || keyUsage.data == NULL)
1392 {
1393 gnutls_assert ();
1394 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1395 }
1396
1397 result = _gnutls_x509_ext_extract_keyUsage (&_usage, keyUsage.data,
1398 keyUsage.size);
1399 _gnutls_free_datum (&keyUsage);
1400
1401 *key_usage = _usage;
1402
1403 if (result < 0)
1404 {
1405 gnutls_assert ();
1406 return result;
1407 }
1408
1409 return 0;
1410}
1411
1412/**
1413 * gnutls_x509_crt_get_proxy - This function returns the proxy certificate info
1414 * @cert: should contain a gnutls_x509_crt_t structure
1415 * @critical: will be non zero if the extension is marked as critical
1416 * @pathlen: pointer to output integer indicating path length (may be
1417 * NULL), non-negative values indicate a present pCPathLenConstraint
1418 * field and the actual value, -1 indicate that the field is absent.
1419 *
1420 * This function will read the certificate's basic constraints, and
1421 * return the certificates CA status. It reads the basicConstraints
1422 * X.509 extension (2.5.29.19).
1423 *
1424 * Return value: If the certificate is a CA a positive value will be
1425 * returned, or zero if the certificate does not have CA flag set. A
1426 * negative value may be returned in case of errors. If the
1427 * certificate does not contain the basicConstraints extension
1428 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1429 **/
1430int
1431gnutls_x509_crt_get_proxy (gnutls_x509_crt_t cert,
1432 unsigned int *critical,
1433 int *pathlen,
1434 char **policyLanguage,
1435 char **policy, size_t * sizeof_policy)
1436{
1437 int result;
1438 gnutls_datum_t proxyCertInfo;
1439
1440 if (cert == NULL)
1441 {
1442 gnutls_assert ();
1443 return GNUTLS_E_INVALID_REQUEST;
1444 }
1445
1446 if ((result = _gnutls_x509_crt_get_extension (cert, "1.3.6.1.5.5.7.1.14", 0,
1447 &proxyCertInfo,
1448 critical)) < 0)
1449 {
1450 return result;
1451 }
1452
1453 if (proxyCertInfo.size == 0 || proxyCertInfo.data == NULL)
1454 {
1455 gnutls_assert ();
1456 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1457 }
1458
1459 result = _gnutls_x509_ext_extract_proxyCertInfo (pathlen, policyLanguage,
1460 policy, sizeof_policy,
1461 proxyCertInfo.data,
1462 proxyCertInfo.size);
1463 _gnutls_free_datum (&proxyCertInfo);
1464 if (result < 0)
1465 {
1466 gnutls_assert ();
1467 return result;
1468 }
1469
1470 return 0;
1471}
1472
1473/**
1474 * gnutls_x509_crt_get_extension_by_oid - This function returns the specified extension
1475 * @cert: should contain a gnutls_x509_crt_t structure
1476 * @oid: holds an Object Identified in null terminated string
1477 * @indx: In case multiple same OIDs exist in the extensions, this specifies which to send. Use zero to get the first one.
1478 * @buf: a pointer to a structure to hold the name (may be null)
1479 * @sizeof_buf: initially holds the size of @buf
1480 * @critical: will be non zero if the extension is marked as critical
1481 *
1482 * This function will return the extension specified by the OID in the certificate.
1483 * The extensions will be returned as binary data DER encoded, in the provided
1484 * buffer.
1485 *
1486 * A negative value may be returned in case of parsing error.
1487 * If the certificate does not contain the specified extension
1488 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1489 *
1490 **/
1491int
1492gnutls_x509_crt_get_extension_by_oid (gnutls_x509_crt_t cert,
1493 const char *oid,
1494 int indx,
1495 void *buf,
1496 size_t * sizeof_buf,
1497 unsigned int *critical)
1498{
1499 int result;
1500 gnutls_datum_t output;
1501
1502 if (cert == NULL)
1503 {
1504 gnutls_assert ();
1505 return GNUTLS_E_INVALID_REQUEST;
1506 }
1507
1508 if ((result = _gnutls_x509_crt_get_extension (cert, oid, indx, &output,
1509 critical)) < 0)
1510 {
1511 gnutls_assert ();
1512 return result;
1513 }
1514
1515 if (output.size == 0 || output.data == NULL)
1516 {
1517 gnutls_assert ();
1518 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1519 }
1520
1521 if (output.size > (unsigned int) *sizeof_buf)
1522 {
1523 *sizeof_buf = output.size;
1524 _gnutls_free_datum (&output);
1525 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1526 }
1527
1528 *sizeof_buf = output.size;
1529
1530 if (buf)
1531 memcpy (buf, output.data, output.size);
1532
1533 _gnutls_free_datum (&output);
1534
1535 return 0;
1536
1537}
1538
1539/**
1540 * gnutls_x509_crt_get_extension_oid - This function returns the specified extension OID
1541 * @cert: should contain a gnutls_x509_crt_t structure
1542 * @indx: Specifies which extension OID to send. Use zero to get the first one.
1543 * @oid: a pointer to a structure to hold the OID (may be null)
1544 * @sizeof_oid: initially holds the size of @oid
1545 *
1546 * This function will return the requested extension OID in the certificate.
1547 * The extension OID will be stored as a string in the provided buffer.
1548 *
1549 * A negative value may be returned in case of parsing error.
1550 * If your have reached the last extension available
1551 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1552 *
1553 **/
1554int
1555gnutls_x509_crt_get_extension_oid (gnutls_x509_crt_t cert,
1556 int indx, void *oid, size_t * sizeof_oid)
1557{
1558 int result;
1559
1560 if (cert == NULL)
1561 {
1562 gnutls_assert ();
1563 return GNUTLS_E_INVALID_REQUEST;
1564 }
1565
1566 result = _gnutls_x509_crt_get_extension_oid (cert, indx, oid, sizeof_oid);
1567 if (result < 0)
1568 {
1569 return result;
1570 }
1571
1572 return 0;
1573
1574}
1575
1576/**
1577 * gnutls_x509_crt_get_extension_info - Get extension id and criticality
1578 * @cert: should contain a gnutls_x509_crt_t structure
1579 * @indx: Specifies which extension OID to send. Use zero to get the first one.
1580 * @oid: a pointer to a structure to hold the OID
1581 * @sizeof_oid: initially holds the size of @oid
1582 * @critical: output variable with critical flag, may be NULL.
1583 *
1584 * This function will return the requested extension OID in the
1585 * certificate, and the critical flag for it. The extension OID will
1586 * be stored as a string in the provided buffer. Use
1587 * gnutls_x509_crt_get_extension_data() to extract the data.
1588 *
1589 * Return 0 on success. A negative value may be returned in case of
1590 * parsing error. If you have reached the last extension available
1591 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1592 *
1593 **/
1594int
1595gnutls_x509_crt_get_extension_info (gnutls_x509_crt_t cert,
1596 int indx,
1597 void *oid,
1598 size_t * sizeof_oid, int *critical)
1599{
1600 int result;
1601 char str_critical[10];
1602 char name[MAX_NAME_SIZE];
1603 int len;
1604
1605 if (!cert)
1606 {
1607 gnutls_assert ();
1608 return GNUTLS_E_INVALID_REQUEST;
1609 }
1610
1611 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u.extnID",
1612 indx + 1);
1613
1614 len = *sizeof_oid;
1615 result = asn1_read_value (cert->cert, name, oid, &len);
1616 *sizeof_oid = len;
1617
1618 if (result == ASN1_ELEMENT_NOT_FOUND)
1619 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1620 else if (result < 0)
1621 {
1622 gnutls_assert ();
1623 return _gnutls_asn2err (result);
1624 }
1625
1626 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u.critical",
1627 indx + 1);
1628 len = sizeof (str_critical);
1629 result = asn1_read_value (cert->cert, name, str_critical, &len);
1630 if (result < 0)
1631 {
1632 gnutls_assert ();
1633 return _gnutls_asn2err (result);
1634 }
1635
1636 if (critical)
1637 {
1638 if (str_critical[0] == 'T')
1639 *critical = 1;
1640 else
1641 *critical = 0;
1642 }
1643
1644 return 0;
1645
1646}
1647
1648/**
1649 * gnutls_x509_crt_get_extension_data - Get the specified extension data
1650 * @cert: should contain a gnutls_x509_crt_t structure
1651 * @indx: Specifies which extension OID to send. Use zero to get the first one.
1652 * @data: a pointer to a structure to hold the data (may be null)
1653 * @sizeof_data: initially holds the size of @oid
1654 *
1655 * This function will return the requested extension data in the
1656 * certificate. The extension data will be stored as a string in the
1657 * provided buffer.
1658 *
1659 * Use gnutls_x509_crt_get_extension_info() to extract the OID and
1660 * critical flag. Use gnutls_x509_crt_get_extension_by_oid() instead,
1661 * if you want to get data indexed by the extension OID rather than
1662 * sequence.
1663 *
1664 * Return 0 on success. A negative value may be returned in case of
1665 * parsing error. If you have reached the last extension available
1666 * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE will be returned.
1667 **/
1668int
1669gnutls_x509_crt_get_extension_data (gnutls_x509_crt_t cert,
1670 int indx,
1671 void *data, size_t * sizeof_data)
1672{
1673 int result, len;
1674 char name[MAX_NAME_SIZE];
1675
1676 if (!cert)
1677 {
1678 gnutls_assert ();
1679 return GNUTLS_E_INVALID_REQUEST;
1680 }
1681
1682 snprintf (name, sizeof (name), "tbsCertificate.extensions.?%u.extnValue",
1683 indx + 1);
1684
1685 len = *sizeof_data;
1686 result = asn1_read_value (cert->cert, name, data, &len);
1687 *sizeof_data = len;
1688
1689 if (result == ASN1_ELEMENT_NOT_FOUND)
1690 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
1691 else if (result < 0)
1692 {
1693 gnutls_assert ();
1694 return _gnutls_asn2err (result);
1695 }
1696
1697 return 0;
1698}
1699
1700static int
1701_gnutls_x509_crt_get_raw_dn2 (gnutls_x509_crt_t cert,
1702 const char *whom, gnutls_datum_t * start)
1703{
1704 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1705 int result, len1;
1706 int start1, end1;
1707 gnutls_datum_t signed_data = { NULL,
1708 0
1709 };
1710
1711 /* get the issuer of 'cert'
1712 */
1713 if ((result =
1714 asn1_create_element (_gnutls_get_pkix (), "PKIX1.TBSCertificate",
1715 &c2)) != ASN1_SUCCESS)
1716 {
1717 gnutls_assert ();
1718 return _gnutls_asn2err (result);
1719 }
1720
1721 result = _gnutls_x509_get_signed_data (cert->cert, "tbsCertificate",
1722 &signed_data);
1723 if (result < 0)
1724 {
1725 gnutls_assert ();
1726 goto cleanup;
1727 }
1728
1729 result = asn1_der_decoding (&c2, signed_data.data, signed_data.size, NULL);
1730 if (result != ASN1_SUCCESS)
1731 {
1732 gnutls_assert ();
1733 asn1_delete_structure (&c2);
1734 result = _gnutls_asn2err (result);
1735 goto cleanup;
1736 }
1737
1738 result = asn1_der_decoding_startEnd (c2, signed_data.data, signed_data.size,
1739 whom, &start1, &end1);
1740
1741 if (result != ASN1_SUCCESS)
1742 {
1743 gnutls_assert ();
1744 result = _gnutls_asn2err (result);
1745 goto cleanup;
1746 }
1747
1748 len1 = end1 - start1 + 1;
1749
1750 _gnutls_set_datum (start, &signed_data.data[start1], len1);
1751
1752 result = 0;
1753
1754cleanup:asn1_delete_structure (&c2);
1755 _gnutls_free_datum (&signed_data);
1756 return result;
1757}
1758
1759/**
1760 * gnutls_x509_crt_get_raw_issuer_dn - This function returns the issuer's DN DER encoded
1761 * @cert: should contain a gnutls_x509_crt_t structure
1762 * @start: will hold the starting point of the DN
1763 *
1764 * This function will return a pointer to the DER encoded DN structure
1765 * and the length.
1766 *
1767 * Returns 0 on success or a negative value on error.
1768 *
1769 **/
1770int
1771gnutls_x509_crt_get_raw_issuer_dn (gnutls_x509_crt_t cert,
1772 gnutls_datum_t * start)
1773{
1774 return _gnutls_x509_crt_get_raw_dn2 (cert, "issuer", start);
1775}
1776
1777/**
1778 * gnutls_x509_crt_get_raw_dn - This function returns the subject's DN DER encoded
1779 * @cert: should contain a gnutls_x509_crt_t structure
1780 * @start: will hold the starting point of the DN
1781 *
1782 * This function will return a pointer to the DER encoded DN structure and
1783 * the length.
1784 *
1785 * Returns 0 on success, or a negative value on error.
1786 *
1787 **/
1788int
1789gnutls_x509_crt_get_raw_dn (gnutls_x509_crt_t cert, gnutls_datum_t * start)
1790{
1791 return _gnutls_x509_crt_get_raw_dn2 (cert, "subject", start);
1792}
1793
1794static int
1795get_dn (gnutls_x509_crt_t cert, const char *whom, gnutls_x509_dn_t * dn)
1796{
1797 *dn = asn1_find_node (cert->cert, whom);
1798 if (!*dn)
1799 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
1800 return 0;
1801}
1802
1803/**
1804 * gnutls_x509_crt_get_subject: get opaque subject DN pointer
1805 * @cert: should contain a gnutls_x509_crt_t structure
1806 * @dn: output variable with pointer to opaque DN.
1807 *
1808 * Return the Certificate's Subject DN as an opaque data type. You
1809 * may use gnutls_x509_dn_get_rdn_ava() to decode the DN.
1810 *
1811 * Returns: Returns 0 on success, or an error code.
1812 **/
1813int
1814gnutls_x509_crt_get_subject (gnutls_x509_crt_t cert, gnutls_x509_dn_t * dn)
1815{
1816 return get_dn (cert, "tbsCertificate.subject.rdnSequence", dn);
1817}
1818
1819/**
1820 * gnutls_x509_crt_get_issuer: get opaque issuer DN pointer
1821 * @cert: should contain a gnutls_x509_crt_t structure
1822 * @dn: output variable with pointer to opaque DN
1823 *
1824 * Return the Certificate's Issuer DN as an opaque data type. You may
1825 * use gnutls_x509_dn_get_rdn_ava() to decode the DN.
1826 *
1827 * Note that @dn points into the @cert object, and thus you may not
1828 * deallocate @cert and continue to access @dn.
1829 *
1830 * Returns: Returns 0 on success, or an error code.
1831 **/
1832int
1833gnutls_x509_crt_get_issuer (gnutls_x509_crt_t cert, gnutls_x509_dn_t * dn)
1834{
1835 return get_dn (cert, "tbsCertificate.issuer.rdnSequence", dn);
1836}
1837
1838/**
1839 * gnutls_x509_dn_get_rdn_ava:
1840 * @dn: input variable with opaque DN pointer
1841 * @irdn: index of RDN
1842 * @iava: index of AVA.
1843 * @ava: Pointer to structure which will hold output information.
1844 *
1845 * Get pointers to data within the DN.
1846 *
1847 * Note that @ava will contain pointers into the @dn structure, so you
1848 * should not modify any data or deallocate it. Note also that the DN
1849 * in turn points into the original certificate structure, and thus
1850 * you may not deallocate the certificate and continue to access @dn.
1851 *
1852 * Returns: Returns 0 on success, or an error code.
1853 **/
1854int
1855gnutls_x509_dn_get_rdn_ava (gnutls_x509_dn_t dn,
1856 int irdn, int iava, gnutls_x509_ava_st * ava)
1857{
1858 ASN1_TYPE rdn, elem;
1859 long len;
1860 int lenlen, remlen, ret;
1861 char rbuf[MAX_NAME_SIZE];
1862 unsigned char cls, *ptr;
1863
1864 iava++;
1865 irdn++; /* 0->1, 1->2 etc */
1866
1867 snprintf (rbuf, sizeof (rbuf), "rdnSequence.?%d.?%d", irdn, iava);
1868 rdn = asn1_find_node (dn, rbuf);
1869 if (!rdn)
1870 {
1871 gnutls_assert ();
1872 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
1873 }
1874
1875 snprintf (rbuf, sizeof (rbuf), "?%d.type", iava);
1876 elem = asn1_find_node (rdn, rbuf);
1877 if (!elem)
1878 {
1879 gnutls_assert ();
1880 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
1881 }
1882
1883 ava->oid.data = elem->value;
1884 ava->oid.size = elem->value_len;
1885
1886 snprintf (rbuf, sizeof (rbuf), "?%d.value", iava);
1887 elem = asn1_find_node (rdn, rbuf);
1888 if (!elem)
1889 {
1890 gnutls_assert ();
1891 return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
1892 }
1893
1894 /* The value still has the previous tag's length bytes, plus the
1895 * current value's tag and length bytes. Decode them.
1896 */
1897
1898 ptr = elem->value;
1899 remlen = elem->value_len;
1900 len = asn1_get_length_der (ptr, remlen, &lenlen);
1901 if (len < 0)
1902 {
1903 gnutls_assert ();
1904 return GNUTLS_E_ASN1_DER_ERROR;
1905 }
1906
1907 ptr += lenlen;
1908 remlen -= lenlen;
1909 ret = asn1_get_tag_der (ptr, remlen, &cls, &lenlen, &ava->value_tag);
1910 if (ret)
1911 {
1912 gnutls_assert ();
1913 return _gnutls_asn2err (ret);
1914 }
1915
1916 ptr += lenlen;
1917 remlen -= lenlen;
1918
1919 ava->value.size = asn1_get_length_der (ptr, remlen, &lenlen);
1920 if (ava->value.size < 0)
1921 {
1922 gnutls_assert ();
1923 return GNUTLS_E_ASN1_DER_ERROR;
1924 }
1925 ava->value.data = ptr + lenlen;
1926
1927 return 0;
1928}
1929
1930/**
1931 * gnutls_x509_crt_get_fingerprint - This function returns the Certificate's fingerprint
1932 * @cert: should contain a gnutls_x509_crt_t structure
1933 * @algo: is a digest algorithm
1934 * @buf: a pointer to a structure to hold the fingerprint (may be null)
1935 * @sizeof_buf: initially holds the size of @buf
1936 *
1937 * This function will calculate and copy the certificate's fingerprint
1938 * in the provided buffer.
1939 *
1940 * If the buffer is null then only the size will be filled.
1941 *
1942 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
1943 * not long enough, and in that case the *sizeof_buf will be updated
1944 * with the required size. On success 0 is returned.
1945 **/
1946int
1947gnutls_x509_crt_get_fingerprint (gnutls_x509_crt_t cert,
1948 gnutls_digest_algorithm_t algo,
1949 void *buf, size_t * sizeof_buf)
1950{
1951 opaque *cert_buf;
1952 int cert_buf_size;
1953 int result;
1954 gnutls_datum_t tmp;
1955
1956 if (sizeof_buf == 0 || cert == NULL)
1957 {
1958 return GNUTLS_E_INVALID_REQUEST;
1959 }
1960
1961 cert_buf_size = 0;
1962 asn1_der_coding (cert->cert, "", NULL, &cert_buf_size, NULL);
1963
1964 cert_buf = gnutls_alloca (cert_buf_size);
1965 if (cert_buf == NULL)
1966 {
1967 gnutls_assert ();
1968 return GNUTLS_E_MEMORY_ERROR;
1969 }
1970
1971 result = asn1_der_coding (cert->cert, "", cert_buf, &cert_buf_size, NULL);
1972
1973 if (result != ASN1_SUCCESS)
1974 {
1975 gnutls_assert ();
1976 gnutls_afree (cert_buf);
1977 return _gnutls_asn2err (result);
1978 }
1979
1980 tmp.data = cert_buf;
1981 tmp.size = cert_buf_size;
1982
1983 result = gnutls_fingerprint (algo, &tmp, buf, sizeof_buf);
1984 gnutls_afree (cert_buf);
1985
1986 return result;
1987}
1988
1989/**
1990 * gnutls_x509_crt_export - This function will export the certificate
1991 * @cert: Holds the certificate
1992 * @format: the format of output params. One of PEM or DER.
1993 * @output_data: will contain a certificate PEM or DER encoded
1994 * @output_data_size: holds the size of output_data (and will be
1995 * replaced by the actual size of parameters)
1996 *
1997 * This function will export the certificate to DER or PEM format.
1998 *
1999 * If the buffer provided is not long enough to hold the output, then
2000 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2001 * be returned.
2002 *
2003 * If the structure is PEM encoded, it will have a header
2004 * of "BEGIN CERTIFICATE".
2005 *
2006 * Return value: In case of failure a negative value will be
2007 * returned, and 0 on success.
2008 **/
2009int
2010gnutls_x509_crt_export (gnutls_x509_crt_t cert,
2011 gnutls_x509_crt_fmt_t format,
2012 void *output_data, size_t * output_data_size)
2013{
2014 if (cert == NULL)
2015 {
2016 gnutls_assert ();
2017 return GNUTLS_E_INVALID_REQUEST;
2018 }
2019
2020 return _gnutls_x509_export_int (cert->cert, format, "CERTIFICATE",
2021 output_data, output_data_size);
2022}
2023
2024static int
2025rsadsa_get_key_id (gnutls_x509_crt_t crt,
2026 int pk,
2027 unsigned char *output_data, size_t * output_data_size)
2028{
2029 mpi_t params[MAX_PUBLIC_PARAMS_SIZE];
2030 int params_size = MAX_PUBLIC_PARAMS_SIZE;
2031 int i, result = 0;
2032 gnutls_datum_t der = { NULL,
2033 0
2034 };
2035 GNUTLS_HASH_HANDLE hd;
2036
2037 result = _gnutls_x509_crt_get_mpis (crt, params, &params_size);
2038 if (result < 0)
2039 {
2040 gnutls_assert ();
2041 return result;
2042 }
2043
2044 if (pk == GNUTLS_PK_RSA)
2045 {
2046 result = _gnutls_x509_write_rsa_params (params, params_size, &der);
2047 if (result < 0)
2048 {
2049 gnutls_assert ();
2050 goto cleanup;
2051 }
2052 }
2053 else
2054 return GNUTLS_E_INTERNAL_ERROR;
2055
2056 hd = _gnutls_hash_init (GNUTLS_MAC_SHA1);
2057 if (hd == GNUTLS_HASH_FAILED)
2058 {
2059 gnutls_assert ();
2060 result = GNUTLS_E_INTERNAL_ERROR;
2061 goto cleanup;
2062 }
2063
2064 _gnutls_hash (hd, der.data, der.size);
2065
2066 _gnutls_hash_deinit (hd, output_data);
2067 *output_data_size = 20;
2068
2069 result = 0;
2070
2071cleanup:
2072
2073 _gnutls_free_datum (&der);
2074
2075 /* release all allocated MPIs
2076 */
2077 for (i = 0; i < params_size; i++)
2078 {
2079 _gnutls_mpi_release (&params[i]);
2080 }
2081 return result;
2082}
2083
2084/**
2085 * gnutls_x509_crt_get_key_id - Return unique ID of public key's parameters
2086 * @crt: Holds the certificate
2087 * @flags: should be 0 for now
2088 * @output_data: will contain the key ID
2089 * @output_data_size: holds the size of output_data (and will be
2090 * replaced by the actual size of parameters)
2091 *
2092 * This function will return a unique ID the depends on the public
2093 * key parameters. This ID can be used in checking whether a
2094 * certificate corresponds to the given private key.
2095 *
2096 * If the buffer provided is not long enough to hold the output, then
2097 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
2098 * be returned. The output will normally be a SHA-1 hash output,
2099 * which is 20 bytes.
2100 *
2101 * Return value: In case of failure a negative value will be
2102 * returned, and 0 on success.
2103 **/
2104int
2105gnutls_x509_crt_get_key_id (gnutls_x509_crt_t crt,
2106 unsigned int flags,
2107 unsigned char *output_data,
2108 size_t * output_data_size)
2109{
2110 int pk, result = 0;
2111 gnutls_datum_t pubkey;
2112
2113 if (crt == NULL)
2114 {
2115 gnutls_assert ();
2116 return GNUTLS_E_INVALID_REQUEST;
2117 }
2118
2119 if (*output_data_size < 20)
2120 {
2121 gnutls_assert ();
2122 *output_data_size = 20;
2123 return GNUTLS_E_SHORT_MEMORY_BUFFER;
2124 }
2125
2126 pk = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
2127 if (pk < 0)
2128 {
2129 gnutls_assert ();
2130 return pk;
2131 }
2132
2133 if (pk == GNUTLS_PK_RSA)
2134 {
2135 /* This is for compatibility with what GnuTLS has printed for
2136 RSA/DSA before the code below was added. The code below is
2137 applicable to all types, and it would probably be a better
2138 idea to use it for RSA/DSA too, but doing so would break
2139 backwards compatibility. */
2140 return rsadsa_get_key_id (crt, pk, output_data, output_data_size);
2141 }
2142
2143 pubkey.size = 0;
2144 result = asn1_der_coding (crt->cert, "tbsCertificate.subjectPublicKeyInfo",
2145 NULL, &pubkey.size, NULL);
2146 if (result != ASN1_MEM_ERROR)
2147 {
2148 gnutls_assert ();
2149 return _gnutls_asn2err (result);
2150 }
2151
2152 pubkey.data = gnutls_alloca (pubkey.size);
2153 if (pubkey.data == NULL)
2154 {
2155 gnutls_assert ();
2156 return GNUTLS_E_MEMORY_ERROR;
2157 }
2158
2159 result = asn1_der_coding (crt->cert, "tbsCertificate.subjectPublicKeyInfo",
2160 pubkey.data, &pubkey.size, NULL);
2161 if (result != ASN1_SUCCESS)
2162 {
2163 gnutls_assert ();
2164 gnutls_afree (pubkey.data);
2165 return _gnutls_asn2err (result);
2166 }
2167
2168 result = gnutls_fingerprint (GNUTLS_DIG_SHA1, &pubkey, output_data,
2169 output_data_size);
2170
2171 gnutls_afree (pubkey.data);
2172
2173 return result;
2174}
2175
2176#ifdef ENABLE_PKI
2177
2178/**
2179 * gnutls_x509_crt_check_revocation - This function checks if the given certificate is revoked
2180 * @cert: should contain a gnutls_x509_crt_t structure
2181 * @crl_list: should contain a list of gnutls_x509_crl_t structures
2182 * @crl_list_length: the length of the crl_list
2183 *
2184 * This function will return check if the given certificate is
2185 * revoked. It is assumed that the CRLs have been verified before.
2186 *
2187 * Returns: 0 if the certificate is NOT revoked, and 1 if it is. A
2188 * negative value is returned on error.
2189 **/
2190int
2191gnutls_x509_crt_check_revocation (gnutls_x509_crt_t cert,
2192 const gnutls_x509_crl_t * crl_list,
2193 int crl_list_length)
2194{
2195 opaque serial[64];
2196 opaque cert_serial[64];
2197 size_t serial_size, cert_serial_size;
2198 int ncerts, ret, i, j;
2199 gnutls_datum_t dn1, dn2;
2200
2201 if (cert == NULL)
2202 {
2203 gnutls_assert ();
2204 return GNUTLS_E_INVALID_REQUEST;
2205 }
2206
2207 for (j = 0; j < crl_list_length; j++)
2208 { /* do for all the crls */
2209
2210 /* Step 1. check if issuer's DN match
2211 */
2212 ret = _gnutls_x509_crl_get_raw_issuer_dn (crl_list[j], &dn1);
2213 if (ret < 0)
2214 {
2215 gnutls_assert ();
2216 return ret;
2217 }
2218
2219 ret = gnutls_x509_crt_get_raw_issuer_dn (cert, &dn2);
2220 if (ret < 0)
2221 {
2222 gnutls_assert ();
2223 return ret;
2224 }
2225
2226 ret = _gnutls_x509_compare_raw_dn (&dn1, &dn2);
2227 _gnutls_free_datum (&dn1);
2228 _gnutls_free_datum (&dn2);
2229 if (ret == 0)
2230 {
2231 /* issuers do not match so don't even
2232 * bother checking.
2233 */
2234 continue;
2235 }
2236
2237 /* Step 2. Read the certificate's serial number
2238 */
2239 cert_serial_size = sizeof (cert_serial);
2240 ret = gnutls_x509_crt_get_serial (cert, cert_serial, &cert_serial_size);
2241 if (ret < 0)
2242 {
2243 gnutls_assert ();
2244 return ret;
2245 }
2246
2247 /* Step 3. cycle through the CRL serials and compare with
2248 * certificate serial we have.
2249 */
2250
2251 ncerts = gnutls_x509_crl_get_crt_count (crl_list[j]);
2252 if (ncerts < 0)
2253 {
2254 gnutls_assert ();
2255 return ncerts;
2256 }
2257
2258 for (i = 0; i < ncerts; i++)
2259 {
2260 serial_size = sizeof (serial);
2261 ret = gnutls_x509_crl_get_crt_serial (crl_list[j], i, serial,
2262 &serial_size, NULL);
2263
2264 if (ret < 0)
2265 {
2266 gnutls_assert ();
2267 return ret;
2268 }
2269
2270 if (serial_size == cert_serial_size)
2271 {
2272 if (memcmp (serial, cert_serial, serial_size) == 0)
2273 {
2274 /* serials match */
2275 return 1; /* revoked! */
2276 }
2277 }
2278 }
2279
2280 }
2281 return 0; /* not revoked. */
2282}
2283
2284/**
2285 * gnutls_x509_crt_verify_data - This function will verify the given signed data.
2286 * @crt: Holds the certificate
2287 * @flags: should be 0 for now
2288 * @data: holds the data to be signed
2289 * @signature: contains the signature
2290 *
2291 * This function will verify the given signed data, using the
2292 * parameters from the certificate.
2293 *
2294 * Returns: In case of a verification failure 0 is returned, and 1 on
2295 * success.
2296 **/
2297int
2298gnutls_x509_crt_verify_data (gnutls_x509_crt_t crt,
2299 unsigned int flags,
2300 const gnutls_datum_t * data,
2301 const gnutls_datum_t * signature)
2302{
2303 int result;
2304
2305 if (crt == NULL)
2306 {
2307 gnutls_assert ();
2308 return GNUTLS_E_INVALID_REQUEST;
2309 }
2310
2311 result = _gnutls_x509_verify_signature (data, signature, crt);
2312 if (result < 0)
2313 {
2314 gnutls_assert ();
2315 return 0;
2316 }
2317
2318 return result;
2319}
2320
2321/**
2322 * gnutls_x509_crt_get_crl_dist_points - This function returns the CRL distribution points
2323 * @cert: should contain a gnutls_x509_crt_t structure
2324 * @seq: specifies the sequence number of the distribution point (0 for the first one, 1 for the second etc.)
2325 * @ret: is the place where the distribution point will be copied to
2326 * @ret_size: holds the size of ret.
2327 * @reason_flags: Revocation reasons flags.
2328 * @critical: will be non zero if the extension is marked as critical (may be null)
2329 *
2330 * This function will return the CRL distribution points (2.5.29.31),
2331 * contained in the given certificate.
2332 *
2333 * @reason_flags should be an ORed sequence of
2334 * GNUTLS_CRL_REASON_UNUSED, GNUTLS_CRL_REASON_KEY_COMPROMISE,
2335 * GNUTLS_CRL_REASON_CA_COMPROMISE,
2336 * GNUTLS_CRL_REASON_AFFILIATION_CHANGED,
2337 * GNUTLS_CRL_REASON_SUPERSEEDED,
2338 * GNUTLS_CRL_REASON_CESSATION_OF_OPERATION,
2339 * GNUTLS_CRL_REASON_CERTIFICATE_HOLD,
2340 * GNUTLS_CRL_REASON_PRIVILEGE_WITHDRAWN,
2341 * GNUTLS_CRL_REASON_AA_COMPROMISE, or zero for all possible reasons.
2342 *
2343 * This is specified in X509v3 Certificate Extensions. GNUTLS will
2344 * return the distribution point type, or a negative error code on
2345 * error.
2346 *
2347 * Returns %GNUTLS_E_SHORT_MEMORY_BUFFER and updates &@ret_size if
2348 * &@ret_size is not enough to hold the distribution point, or the
2349 * type of the distribution point if everything was ok. The type is
2350 * one of the enumerated %gnutls_x509_subject_alt_name_t. If the
2351 * certificate does not have an Alternative name with the specified
2352 * sequence number then %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is
2353 * returned.
2354 **/
2355int
2356gnutls_x509_crt_get_crl_dist_points (gnutls_x509_crt_t cert,
2357 unsigned int seq,
2358 void *ret,
2359 size_t * ret_size,
2360 unsigned int *reason_flags,
2361 unsigned int *critical)
2362{
2363 int result;
2364 gnutls_datum_t dist_points = { NULL,
2365 0
2366 };
2367 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2368 char name[MAX_NAME_SIZE];
2369 int len;
2370 gnutls_x509_subject_alt_name_t type;
2371 uint8_t reasons[2];
2372
2373 if (cert == NULL)
2374 {
2375 gnutls_assert ();
2376 return GNUTLS_E_INVALID_REQUEST;
2377 }
2378
2379 if (*ret_size > 0 && ret)
2380 memset (ret, 0, *ret_size);
2381 else
2382 *ret_size = 0;
2383
2384 if (reason_flags)
2385 *reason_flags = 0;
2386
2387 result = _gnutls_x509_crt_get_extension (cert, "2.5.29.31", 0, &dist_points,
2388 critical);
2389 if (result < 0)
2390 {
2391 return result;
2392 }
2393
2394 if (dist_points.size == 0 || dist_points.data == NULL)
2395 {
2396 gnutls_assert ();
2397 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2398 }
2399
2400 result =
2401 asn1_create_element (_gnutls_get_pkix (), "PKIX1.CRLDistributionPoints",
2402 &c2);
2403 if (result != ASN1_SUCCESS)
2404 {
2405 gnutls_assert ();
2406 _gnutls_free_datum (&dist_points);
2407 return _gnutls_asn2err (result);
2408 }
2409
2410 result = asn1_der_decoding (&c2, dist_points.data, dist_points.size, NULL);
2411 _gnutls_free_datum (&dist_points);
2412
2413 if (result != ASN1_SUCCESS)
2414 {
2415 gnutls_assert ();
2416 asn1_delete_structure (&c2);
2417 return _gnutls_asn2err (result);
2418 }
2419
2420 /* Return the different names from the first CRLDistr. point.
2421 * The whole thing is a mess.
2422 */
2423 _gnutls_str_cpy (name, sizeof (name), "?1.distributionPoint.fullName");
2424
2425 result = parse_general_name (c2, name, seq, ret, ret_size, NULL, 0);
2426 if (result < 0)
2427 {
2428 asn1_delete_structure (&c2);
2429 return result;
2430 }
2431
2432 type = result;
2433
2434 /* Read the CRL reasons.
2435 */
2436 if (reason_flags)
2437 {
2438 _gnutls_str_cpy (name, sizeof (name), "?1.reasons");
2439
2440 reasons[0] = reasons[1] = 0;
2441
2442 len = sizeof (reasons);
2443 result = asn1_read_value (c2, name, reasons, &len);
2444
2445 if (result != ASN1_VALUE_NOT_FOUND && result != ASN1_SUCCESS)
2446 {
2447 gnutls_assert ();
2448 asn1_delete_structure (&c2);
2449 return _gnutls_asn2err (result);
2450 }
2451
2452 *reason_flags = reasons[0] | (reasons[1] << 8);
2453 }
2454
2455 return type;
2456}
2457
2458/**
2459 * gnutls_x509_crt_get_key_purpose_oid - This function returns the Certificate's key purpose OIDs
2460 * @cert: should contain a gnutls_x509_crt_t structure
2461 * @indx: This specifies which OID to return. Use zero to get the first one.
2462 * @oid: a pointer to a buffer to hold the OID (may be null)
2463 * @sizeof_oid: initially holds the size of @oid
2464 *
2465 * This function will extract the key purpose OIDs of the Certificate
2466 * specified by the given index. These are stored in the Extended Key
2467 * Usage extension (2.5.29.37) See the GNUTLS_KP_* definitions for
2468 * human readable names.
2469 *
2470 * If @oid is null then only the size will be filled.
2471 *
2472 * Returns: %GNUTLS_E_SHORT_MEMORY_BUFFER if the provided buffer is
2473 * not long enough, and in that case the *sizeof_oid will be updated
2474 * with the required size. On success 0 is returned.
2475 **/
2476int
2477gnutls_x509_crt_get_key_purpose_oid (gnutls_x509_crt_t cert,
2478 int indx,
2479 void *oid,
2480 size_t * sizeof_oid,
2481 unsigned int *critical)
2482{
2483 char tmpstr[MAX_NAME_SIZE];
2484 int result, len;
2485 gnutls_datum_t id;
2486 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
2487
2488 if (cert == NULL)
2489 {
2490 gnutls_assert ();
2491 return GNUTLS_E_INVALID_REQUEST;
2492 }
2493
2494 if (oid)
2495 memset (oid, 0, *sizeof_oid);
2496 else
2497 *sizeof_oid = 0;
2498
2499 if ((result = _gnutls_x509_crt_get_extension (cert, "2.5.29.37", 0, &id,
2500 critical)) < 0)
2501 {
2502 return result;
2503 }
2504
2505 if (id.size == 0 || id.data == NULL)
2506 {
2507 gnutls_assert ();
2508 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2509 }
2510
2511 result =
2512 asn1_create_element (_gnutls_get_pkix (), "PKIX1.ExtKeyUsageSyntax", &c2);
2513 if (result != ASN1_SUCCESS)
2514 {
2515 gnutls_assert ();
2516 _gnutls_free_datum (&id);
2517 return _gnutls_asn2err (result);
2518 }
2519
2520 result = asn1_der_decoding (&c2, id.data, id.size, NULL);
2521 _gnutls_free_datum (&id);
2522
2523 if (result != ASN1_SUCCESS)
2524 {
2525 gnutls_assert ();
2526 asn1_delete_structure (&c2);
2527 return _gnutls_asn2err (result);
2528 }
2529
2530 indx++;
2531 /* create a string like "?1"
2532 */
2533 snprintf (tmpstr, sizeof (tmpstr), "?%u", indx);
2534
2535 len = *sizeof_oid;
2536 result = asn1_read_value (c2, tmpstr, oid, &len);
2537
2538 *sizeof_oid = len;
2539 asn1_delete_structure (&c2);
2540
2541 if (result == ASN1_VALUE_NOT_FOUND || result == ASN1_ELEMENT_NOT_FOUND)
2542 {
2543 return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
2544 }
2545
2546 if (result != ASN1_SUCCESS)
2547 {
2548 gnutls_assert ();
2549 return _gnutls_asn2err (result);
2550 }
2551
2552 return 0;
2553
2554}
2555
2556/**
2557 * gnutls_x509_crt_get_pk_rsa_raw - This function will export the RSA public key
2558 * @crt: Holds the certificate
2559 * @m: will hold the modulus
2560 * @e: will hold the public exponent
2561 *
2562 * This function will export the RSA public key's parameters found in
2563 * the given structure. The new parameters will be allocated using
2564 * gnutls_malloc() and will be stored in the appropriate datum.
2565 *
2566 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
2567 **/
2568int
2569gnutls_x509_crt_get_pk_rsa_raw (gnutls_x509_crt_t crt,
2570 gnutls_datum_t * m, gnutls_datum_t * e)
2571{
2572 int ret;
2573 mpi_t params[MAX_PUBLIC_PARAMS_SIZE];
2574 int params_size = MAX_PUBLIC_PARAMS_SIZE;
2575 int i;
2576
2577 if (crt == NULL)
2578 {
2579 gnutls_assert ();
2580 return GNUTLS_E_INVALID_REQUEST;
2581 }
2582
2583 ret = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
2584 if (ret != GNUTLS_PK_RSA)
2585 {
2586 gnutls_assert ();
2587 return GNUTLS_E_INVALID_REQUEST;
2588 }
2589
2590 ret = _gnutls_x509_crt_get_mpis (crt, params, &params_size);
2591 if (ret < 0)
2592 {
2593 gnutls_assert ();
2594 return ret;
2595 }
2596
2597 ret = _gnutls_mpi_dprint (m, params[0]);
2598 if (ret < 0)
2599 {
2600 gnutls_assert ();
2601 goto cleanup;
2602 }
2603
2604 ret = _gnutls_mpi_dprint (e, params[1]);
2605 if (ret < 0)
2606 {
2607 gnutls_assert ();
2608 _gnutls_free_datum (m);
2609 goto cleanup;
2610 }
2611
2612 ret = 0;
2613
2614cleanup:for (i = 0; i < params_size; i++)
2615 {
2616 _gnutls_mpi_release (&params[i]);
2617 }
2618 return ret;
2619}
2620
2621/**
2622 * gnutls_x509_crt_get_pk_dsa_raw - This function will export the DSA public key
2623 * @crt: Holds the certificate
2624 * @p: will hold the p
2625 * @q: will hold the q
2626 * @g: will hold the g
2627 * @y: will hold the y
2628 *
2629 * This function will export the DSA public key's parameters found in
2630 * the given certificate. The new parameters will be allocated using
2631 * gnutls_malloc() and will be stored in the appropriate datum.
2632 *
2633 * Returns: %GNUTLS_E_SUCCESS on success, otherwise an error.
2634 **/
2635int
2636gnutls_x509_crt_get_pk_dsa_raw (gnutls_x509_crt_t crt,
2637 gnutls_datum_t * p,
2638 gnutls_datum_t * q,
2639 gnutls_datum_t * g, gnutls_datum_t * y)
2640{
2641 int ret;
2642 mpi_t params[MAX_PUBLIC_PARAMS_SIZE];
2643 int params_size = MAX_PUBLIC_PARAMS_SIZE;
2644 int i;
2645
2646 if (crt == NULL)
2647 {
2648 gnutls_assert ();
2649 return GNUTLS_E_INVALID_REQUEST;
2650 }
2651
2652 ret = gnutls_x509_crt_get_pk_algorithm (crt, NULL);
2653
2654 ret = _gnutls_x509_crt_get_mpis (crt, params, &params_size);
2655 if (ret < 0)
2656 {
2657 gnutls_assert ();
2658 return ret;
2659 }
2660
2661 /* P */
2662 ret = _gnutls_mpi_dprint (p, params[0]);
2663 if (ret < 0)
2664 {
2665 gnutls_assert ();
2666 goto cleanup;
2667 }
2668
2669 /* Q */
2670 ret = _gnutls_mpi_dprint (q, params[1]);
2671 if (ret < 0)
2672 {
2673 gnutls_assert ();
2674 _gnutls_free_datum (p);
2675 goto cleanup;
2676 }
2677
2678 /* G */
2679 ret = _gnutls_mpi_dprint (g, params[2]);
2680 if (ret < 0)
2681 {
2682 gnutls_assert ();
2683 _gnutls_free_datum (p);
2684 _gnutls_free_datum (q);
2685 goto cleanup;
2686 }
2687
2688 /* Y */
2689 ret = _gnutls_mpi_dprint (y, params[3]);
2690 if (ret < 0)
2691 {
2692 gnutls_assert ();
2693 _gnutls_free_datum (p);
2694 _gnutls_free_datum (g);
2695 _gnutls_free_datum (q);
2696 goto cleanup;
2697 }
2698
2699 ret = 0;
2700
2701cleanup:for (i = 0; i < params_size; i++)
2702 {
2703 _gnutls_mpi_release (&params[i]);
2704 }
2705 return ret;
2706
2707}
2708
2709#endif
2710
2711/**
2712 * gnutls_x509_crt_list_import - This function will import a PEM encoded certificate list
2713 * @certs: The structures to store the parsed certificate. Must not be initialized.
2714 * @cert_max: Initially must hold the maximum number of certs. It will be updated with the number of certs available.
2715 * @data: The PEM encoded certificate.
2716 * @format: One of DER or PEM.
2717 * @flags: must be zero or an OR'd sequence of gnutls_certificate_import_flags.
2718 *
2719 * This function will convert the given PEM encoded certificate list
2720 * to the native gnutls_x509_crt_t format. The output will be stored
2721 * in @certs. They will be automatically initialized.
2722 *
2723 * If the Certificate is PEM encoded it should have a header of "X509
2724 * CERTIFICATE", or "CERTIFICATE".
2725 *
2726 * Returns: the number of certificates read or a negative error value.
2727 **/
2728int
2729gnutls_x509_crt_list_import (gnutls_x509_crt_t * certs,
2730 unsigned int *cert_max,
2731 const gnutls_datum_t * data,
2732 gnutls_x509_crt_fmt_t format, unsigned int flags)
2733{
2734 int size;
2735 const char *ptr;
2736 gnutls_datum_t tmp;
2737 int ret, nocopy = 0;
2738 unsigned int count = 0, j;
2739
2740 if (format == GNUTLS_X509_FMT_DER)
2741 {
2742 if (*cert_max < 1)
2743 {
2744 *cert_max = 1;
2745 return GNUTLS_E_SHORT_MEMORY_BUFFER;
2746 }
2747
2748 count = 1; /* import only the first one */
2749
2750 ret = gnutls_x509_crt_init (&certs[0]);
2751 if (ret < 0)
2752 {
2753 gnutls_assert ();
2754 goto error;
2755 }
2756
2757 ret = gnutls_x509_crt_import (certs[0], data, format);
2758 if (ret < 0)
2759 {
2760 gnutls_assert ();
2761 goto error;
2762 }
2763
2764 *cert_max = 1;
2765 return 1;
2766 }
2767
2768 /* move to the certificate
2769 */
2770 ptr = memmem (data->data, data->size,
2771 PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
2772 if (ptr == NULL)
2773 ptr = memmem (data->data, data->size,
2774 PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
2775
2776 if (ptr == NULL)
2777 {
2778 gnutls_assert ();
2779 return GNUTLS_E_BASE64_DECODING_ERROR;
2780 }
2781 size = data->size - (ptr - (char *) data->data);
2782
2783 count = 0;
2784
2785 do
2786 {
2787 if (count >= *cert_max)
2788 {
2789 if (!(flags & GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED))
2790 break;
2791 else
2792 nocopy = 1;
2793 }
2794
2795 if (!nocopy)
2796 {
2797 ret = gnutls_x509_crt_init (&certs[count]);
2798 if (ret < 0)
2799 {
2800 gnutls_assert ();
2801 goto error;
2802 }
2803
2804 tmp.data = (void *) ptr;
2805 tmp.size = size;
2806
2807 ret =
2808 gnutls_x509_crt_import (certs[count], &tmp, GNUTLS_X509_FMT_PEM);
2809 if (ret < 0)
2810 {
2811 gnutls_assert ();
2812 goto error;
2813 }
2814 }
2815
2816 /* now we move ptr after the pem header
2817 */
2818 ptr++;
2819 /* find the next certificate (if any)
2820 */
2821 size = data->size - (ptr - (char *) data->data);
2822
2823 if (size > 0)
2824 {
2825 char *ptr2;
2826
2827 ptr2 = memmem (ptr, size, PEM_CERT_SEP, sizeof (PEM_CERT_SEP) - 1);
2828 if (ptr2 == NULL)
2829 ptr2 =
2830 memmem (ptr, size, PEM_CERT_SEP2, sizeof (PEM_CERT_SEP2) - 1);
2831
2832 ptr = ptr2;
2833 }
2834 else
2835 ptr = NULL;
2836
2837 count++;
2838 }
2839 while (ptr != NULL);
2840
2841 *cert_max = count;
2842
2843 if (nocopy == 0)
2844 return count;
2845 else
2846 return GNUTLS_E_SHORT_MEMORY_BUFFER;
2847
2848error:for (j = 0; j < count; j++)
2849 gnutls_x509_crt_deinit (certs[j]);
2850 return ret;
2851}
diff --git a/src/daemon/https/x509/x509.h b/src/daemon/https/x509/x509.h
new file mode 100644
index 00000000..c9bb22ef
--- /dev/null
+++ b/src/daemon/https/x509/x509.h
@@ -0,0 +1,928 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#ifndef X509_H
26# define X509_H
27
28#define MIN(X,Y) ((X) > (Y) ? (Y) : (X));
29
30#ifdef __cplusplus
31extern "C"
32 {
33#endif
34
35#include <gnutls.h>
36// TODO #include "libtasn1.h"
37#include "gnutls_mpi.h"
38
39/* Some OIDs usually found in Distinguished names, or
40 * in Subject Directory Attribute extensions.
41 */
42#define GNUTLS_OID_X520_COUNTRY_NAME "2.5.4.6"
43#define GNUTLS_OID_X520_ORGANIZATION_NAME "2.5.4.10"
44#define GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME "2.5.4.11"
45#define GNUTLS_OID_X520_COMMON_NAME "2.5.4.3"
46#define GNUTLS_OID_X520_LOCALITY_NAME "2.5.4.7"
47#define GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME "2.5.4.8"
48
49#define GNUTLS_OID_X520_INITIALS "2.5.4.43"
50#define GNUTLS_OID_X520_GENERATION_QUALIFIER "2.5.4.44"
51#define GNUTLS_OID_X520_SURNAME "2.5.4.4"
52#define GNUTLS_OID_X520_GIVEN_NAME "2.5.4.42"
53#define GNUTLS_OID_X520_TITLE "2.5.4.12"
54#define GNUTLS_OID_X520_DN_QUALIFIER "2.5.4.46"
55#define GNUTLS_OID_X520_PSEUDONYM "2.5.4.65"
56
57#define GNUTLS_OID_LDAP_DC "0.9.2342.19200300.100.1.25"
58#define GNUTLS_OID_LDAP_UID "0.9.2342.19200300.100.1.1"
59
60/* The following should not be included in DN.
61 */
62#define GNUTLS_OID_PKCS9_EMAIL "1.2.840.113549.1.9.1"
63
64#define GNUTLS_OID_PKIX_DATE_OF_BIRTH "1.3.6.1.5.5.7.9.1"
65#define GNUTLS_OID_PKIX_PLACE_OF_BIRTH "1.3.6.1.5.5.7.9.2"
66#define GNUTLS_OID_PKIX_GENDER "1.3.6.1.5.5.7.9.3"
67#define GNUTLS_OID_PKIX_COUNTRY_OF_CITIZENSHIP "1.3.6.1.5.5.7.9.4"
68#define GNUTLS_OID_PKIX_COUNTRY_OF_RESIDENCE "1.3.6.1.5.5.7.9.5"
69
70/* Key purpose Object Identifiers.
71 */
72#define GNUTLS_KP_TLS_WWW_SERVER "1.3.6.1.5.5.7.3.1"
73#define GNUTLS_KP_TLS_WWW_CLIENT "1.3.6.1.5.5.7.3.2"
74#define GNUTLS_KP_CODE_SIGNING "1.3.6.1.5.5.7.3.3"
75#define GNUTLS_KP_EMAIL_PROTECTION "1.3.6.1.5.5.7.3.4"
76#define GNUTLS_KP_TIME_STAMPING "1.3.6.1.5.5.7.3.8"
77#define GNUTLS_KP_OCSP_SIGNING "1.3.6.1.5.5.7.3.9"
78#define GNUTLS_KP_ANY "2.5.29.37.0"
79
80/* Certificate handling functions.
81 */
82typedef enum gnutls_certificate_import_flags
83 {
84 /* Fail if the certificates in the buffer are more than the space
85 * allocated for certificates. The error code will be
86 * GNUTLS_E_SHORT_MEMORY_BUFFER.
87 */
88 GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED = 1
89 } gnutls_certificate_import_flags;
90
91int gnutls_x509_crt_init(gnutls_x509_crt_t * cert);
92void gnutls_x509_crt_deinit(gnutls_x509_crt_t cert);
93int gnutls_x509_crt_import(gnutls_x509_crt_t cert,
94 const gnutls_datum_t * data,
95 gnutls_x509_crt_fmt_t format);
96int gnutls_x509_crt_list_import(gnutls_x509_crt_t * certs,
97 unsigned int *cert_max,
98 const gnutls_datum_t * data,
99 gnutls_x509_crt_fmt_t format,
100 unsigned int flags);
101int gnutls_x509_crt_export(gnutls_x509_crt_t cert,
102 gnutls_x509_crt_fmt_t format,
103 void *output_data,
104 size_t * output_data_size);
105int gnutls_x509_crt_get_issuer_dn(gnutls_x509_crt_t cert,
106 char *buf,
107 size_t * sizeof_buf);
108int gnutls_x509_crt_get_issuer_dn_oid(gnutls_x509_crt_t cert,
109 int indx,
110 void *oid,
111 size_t * sizeof_oid);
112int gnutls_x509_crt_get_issuer_dn_by_oid(gnutls_x509_crt_t cert,
113 const char *oid,
114 int indx,
115 unsigned int raw_flag,
116 void *buf,
117 size_t * sizeof_buf);
118int gnutls_x509_crt_get_dn(gnutls_x509_crt_t cert,
119 char *buf,
120 size_t * sizeof_buf);
121int gnutls_x509_crt_get_dn_oid(gnutls_x509_crt_t cert,
122 int indx,
123 void *oid,
124 size_t * sizeof_oid);
125int gnutls_x509_crt_get_dn_by_oid(gnutls_x509_crt_t cert,
126 const char *oid,
127 int indx,
128 unsigned int raw_flag,
129 void *buf,
130 size_t * sizeof_buf);
131int gnutls_x509_crt_check_hostname(gnutls_x509_crt_t cert,
132 const char *hostname);
133
134int gnutls_x509_crt_get_signature_algorithm(gnutls_x509_crt_t cert);
135int gnutls_x509_crt_get_signature(gnutls_x509_crt_t cert,
136 char *sig,
137 size_t *sizeof_sig);
138int gnutls_x509_crt_get_version(gnutls_x509_crt_t cert);
139int gnutls_x509_crt_get_key_id(gnutls_x509_crt_t crt,
140 unsigned int flags,
141 unsigned char *output_data,
142 size_t * output_data_size);
143
144int gnutls_x509_crt_set_authority_key_id(gnutls_x509_crt_t cert,
145 const void *id,
146 size_t id_size);
147int gnutls_x509_crt_get_authority_key_id(gnutls_x509_crt_t cert,
148 void *ret,
149 size_t * ret_size,
150 unsigned int *critical);
151
152int gnutls_x509_crt_get_subject_key_id(gnutls_x509_crt_t cert,
153 void *ret,
154 size_t * ret_size,
155 unsigned int *critical);
156
157#define GNUTLS_CRL_REASON_UNUSED 128
158#define GNUTLS_CRL_REASON_KEY_COMPROMISE 64
159#define GNUTLS_CRL_REASON_CA_COMPROMISE 32
160#define GNUTLS_CRL_REASON_AFFILIATION_CHANGED 16
161#define GNUTLS_CRL_REASON_SUPERSEEDED 8
162#define GNUTLS_CRL_REASON_CESSATION_OF_OPERATION 4
163#define GNUTLS_CRL_REASON_CERTIFICATE_HOLD 2
164#define GNUTLS_CRL_REASON_PRIVILEGE_WITHDRAWN 1
165#define GNUTLS_CRL_REASON_AA_COMPROMISE 32768
166
167int gnutls_x509_crt_get_crl_dist_points(gnutls_x509_crt_t cert,
168 unsigned int seq,
169 void *ret,
170 size_t * ret_size,
171 unsigned int *reason_flags,
172 unsigned int *critical);
173int gnutls_x509_crt_set_crl_dist_points(gnutls_x509_crt_t crt,
174 gnutls_x509_subject_alt_name_t
175 type,
176 const void *data_string,
177 unsigned int reason_flags);
178int gnutls_x509_crt_cpy_crl_dist_points(gnutls_x509_crt_t dst,
179 gnutls_x509_crt_t src);
180
181time_t gnutls_x509_crt_get_activation_time(gnutls_x509_crt_t cert);
182time_t gnutls_x509_crt_get_expiration_time(gnutls_x509_crt_t cert);
183int gnutls_x509_crt_get_serial(gnutls_x509_crt_t cert,
184 void *result,
185 size_t * result_size);
186
187int gnutls_x509_crt_get_pk_algorithm(gnutls_x509_crt_t cert,
188 unsigned int *bits);
189int gnutls_x509_crt_get_pk_rsa_raw(gnutls_x509_crt_t crt,
190 gnutls_datum_t * m,
191 gnutls_datum_t * e);
192int gnutls_x509_crt_get_pk_dsa_raw(gnutls_x509_crt_t crt,
193 gnutls_datum_t * p,
194 gnutls_datum_t * q,
195 gnutls_datum_t * g,
196 gnutls_datum_t * y);
197
198int gnutls_x509_crt_get_subject_alt_name(gnutls_x509_crt_t cert,
199 unsigned int seq,
200 void *ret,
201 size_t * ret_size,
202 unsigned int *critical);
203int gnutls_x509_crt_get_subject_alt_name2(gnutls_x509_crt_t cert,
204 unsigned int seq,
205 void *ret,
206 size_t * ret_size,
207 unsigned int* ret_type,
208 unsigned int *critical);
209
210int gnutls_x509_crt_get_subject_alt_othername_oid(gnutls_x509_crt_t cert,
211 unsigned int seq,
212 void *ret,
213 size_t * ret_size);
214
215int gnutls_x509_crt_get_ca_status(gnutls_x509_crt_t cert,
216 unsigned int *critical);
217int gnutls_x509_crt_get_basic_constraints(gnutls_x509_crt_t cert,
218 unsigned int *critical,
219 int *ca,
220 int *pathlen);
221
222/* The key_usage flags are defined in gnutls.h. They are the
223 * GNUTLS_KEY_* definitions.
224 */
225int gnutls_x509_crt_get_key_usage(gnutls_x509_crt_t cert,
226 unsigned int *key_usage,
227 unsigned int *critical);
228int gnutls_x509_crt_set_key_usage(gnutls_x509_crt_t crt,
229 unsigned int usage);
230
231int gnutls_x509_crt_get_proxy(gnutls_x509_crt_t cert,
232 unsigned int *critical,
233 int *pathlen,
234 char **policyLanguage,
235 char **policy,
236 size_t *sizeof_policy);
237
238int gnutls_x509_dn_oid_known(const char *oid);
239
240/* Read extensions by OID. */
241int gnutls_x509_crt_get_extension_oid(gnutls_x509_crt_t cert,
242 int indx,
243 void *oid,
244 size_t * sizeof_oid);
245int gnutls_x509_crt_get_extension_by_oid(gnutls_x509_crt_t cert,
246 const char *oid,
247 int indx,
248 void *buf,
249 size_t * sizeof_buf,
250 unsigned int *critical);
251
252/* Read extensions by sequence number. */
253int gnutls_x509_crt_get_extension_info(gnutls_x509_crt_t cert,
254 int indx,
255 void *oid,
256 size_t * sizeof_oid,
257 int *critical);
258int gnutls_x509_crt_get_extension_data(gnutls_x509_crt_t cert,
259 int indx,
260 void *data,
261 size_t * sizeof_data);
262
263int gnutls_x509_crt_set_extension_by_oid(gnutls_x509_crt_t crt,
264 const char *oid,
265 const void *buf,
266 size_t sizeof_buf,
267 unsigned int critical);
268
269/* X.509 Certificate writing.
270 */
271int gnutls_x509_crt_set_dn_by_oid(gnutls_x509_crt_t crt,
272 const char *oid,
273 unsigned int raw_flag,
274 const void *name,
275 unsigned int sizeof_name);
276int gnutls_x509_crt_set_issuer_dn_by_oid(gnutls_x509_crt_t crt,
277 const char *oid,
278 unsigned int raw_flag,
279 const void *name,
280 unsigned int sizeof_name);
281int gnutls_x509_crt_set_version(gnutls_x509_crt_t crt,
282 unsigned int version);
283int gnutls_x509_crt_set_key(gnutls_x509_crt_t crt,
284 gnutls_x509_privkey_t key);
285int gnutls_x509_crt_set_ca_status(gnutls_x509_crt_t crt,
286 unsigned int ca);
287int gnutls_x509_crt_set_basic_constraints(gnutls_x509_crt_t crt,
288 unsigned int ca,
289 int pathLenConstraint);
290int gnutls_x509_crt_set_subject_alternative_name(gnutls_x509_crt_t crt,
291 gnutls_x509_subject_alt_name_t
292 type,
293 const char *data_string);
294int gnutls_x509_crt_sign(gnutls_x509_crt_t crt,
295 gnutls_x509_crt_t issuer,
296 gnutls_x509_privkey_t issuer_key);
297int gnutls_x509_crt_sign2(gnutls_x509_crt_t crt,
298 gnutls_x509_crt_t issuer,
299 gnutls_x509_privkey_t issuer_key,
300 gnutls_digest_algorithm_t,
301 unsigned int flags);
302int gnutls_x509_crt_set_activation_time(gnutls_x509_crt_t cert,
303 time_t act_time);
304int gnutls_x509_crt_set_expiration_time(gnutls_x509_crt_t cert,
305 time_t exp_time);
306int gnutls_x509_crt_set_serial(gnutls_x509_crt_t cert,
307 const void *serial,
308 size_t serial_size);
309
310int gnutls_x509_crt_set_subject_key_id(gnutls_x509_crt_t cert,
311 const void *id,
312 size_t id_size);
313
314int gnutls_x509_crt_set_proxy_dn(gnutls_x509_crt_t crt,
315 gnutls_x509_crt_t eecrt,
316 unsigned int raw_flag,
317 const void *name,
318 unsigned int sizeof_name);
319int gnutls_x509_crt_set_proxy(gnutls_x509_crt_t crt,
320 int pathLenConstraint,
321 const char *policyLanguage,
322 const char *policy,
323 size_t sizeof_policy);
324
325typedef enum gnutls_certificate_print_formats
326 {
327 GNUTLS_X509_CRT_FULL,
328 GNUTLS_X509_CRT_ONELINE,
329 GNUTLS_X509_CRT_UNSIGNED_FULL
330 } gnutls_certificate_print_formats_t;
331
332int gnutls_x509_crt_print(gnutls_x509_crt_t cert,
333 gnutls_certificate_print_formats_t format,
334 gnutls_datum_t *out);
335int gnutls_x509_crl_print(gnutls_x509_crl_t crl,
336 gnutls_certificate_print_formats_t format,
337 gnutls_datum_t *out);
338
339/* Access to internal Certificate fields.
340 */
341int gnutls_x509_crt_get_raw_issuer_dn(gnutls_x509_crt_t cert,
342 gnutls_datum_t * start);
343int gnutls_x509_crt_get_raw_dn(gnutls_x509_crt_t cert,
344 gnutls_datum_t * start);
345
346/* RDN handling.
347 */
348int gnutls_x509_rdn_get(const gnutls_datum_t * idn,
349 char *buf,
350 size_t * sizeof_buf);
351int gnutls_x509_rdn_get_oid(const gnutls_datum_t * idn,
352 int indx,
353 void *buf,
354 size_t * sizeof_buf);
355
356int gnutls_x509_rdn_get_by_oid(const gnutls_datum_t * idn,
357 const char *oid,
358 int indx,
359 unsigned int raw_flag,
360 void *buf,
361 size_t * sizeof_buf);
362
363typedef void *gnutls_x509_dn_t;
364
365typedef struct gnutls_x509_ava_st
366 {
367 gnutls_datum_t oid;
368 gnutls_datum_t value;
369 unsigned long value_tag;
370 } gnutls_x509_ava_st;
371
372int gnutls_x509_crt_get_subject(gnutls_x509_crt_t cert,
373 gnutls_x509_dn_t *dn);
374int gnutls_x509_crt_get_issuer(gnutls_x509_crt_t cert,
375 gnutls_x509_dn_t *dn);
376int gnutls_x509_dn_get_rdn_ava(gnutls_x509_dn_t dn,
377 int irdn,
378 int iava,
379 gnutls_x509_ava_st *avast);
380
381/* CRL handling functions.
382 */
383int gnutls_x509_crl_init(gnutls_x509_crl_t * crl);
384void gnutls_x509_crl_deinit(gnutls_x509_crl_t crl);
385
386int gnutls_x509_crl_import(gnutls_x509_crl_t crl,
387 const gnutls_datum_t * data,
388 gnutls_x509_crt_fmt_t format);
389int gnutls_x509_crl_export(gnutls_x509_crl_t crl,
390 gnutls_x509_crt_fmt_t format,
391 void *output_data,
392 size_t * output_data_size);
393
394int gnutls_x509_crl_get_issuer_dn(const gnutls_x509_crl_t crl,
395 char *buf,
396 size_t * sizeof_buf);
397int gnutls_x509_crl_get_issuer_dn_by_oid(gnutls_x509_crl_t crl,
398 const char *oid,
399 int indx,
400 unsigned int raw_flag,
401 void *buf,
402 size_t * sizeof_buf);
403int gnutls_x509_crl_get_dn_oid(gnutls_x509_crl_t crl,
404 int indx,
405 void *oid,
406 size_t * sizeof_oid);
407
408int gnutls_x509_crl_get_signature_algorithm(gnutls_x509_crl_t crl);
409int gnutls_x509_crl_get_signature(gnutls_x509_crl_t crl,
410 char *sig,
411 size_t *sizeof_sig);
412int gnutls_x509_crl_get_version(gnutls_x509_crl_t crl);
413
414time_t gnutls_x509_crl_get_this_update(gnutls_x509_crl_t crl);
415time_t gnutls_x509_crl_get_next_update(gnutls_x509_crl_t crl);
416
417int gnutls_x509_crl_get_crt_count(gnutls_x509_crl_t crl);
418int gnutls_x509_crl_get_crt_serial(gnutls_x509_crl_t crl,
419 int indx,
420 unsigned char *serial,
421 size_t * serial_size,
422 time_t * t);
423#define gnutls_x509_crl_get_certificate_count gnutls_x509_crl_get_crt_count
424#define gnutls_x509_crl_get_certificate gnutls_x509_crl_get_crt_serial
425
426int gnutls_x509_crl_check_issuer(gnutls_x509_crl_t crl,
427 gnutls_x509_crt_t issuer);
428
429/* CRL writing.
430 */
431int gnutls_x509_crl_set_version(gnutls_x509_crl_t crl,
432 unsigned int version);
433int gnutls_x509_crl_sign(gnutls_x509_crl_t crl,
434 gnutls_x509_crt_t issuer,
435 gnutls_x509_privkey_t issuer_key);
436int gnutls_x509_crl_sign2(gnutls_x509_crl_t crl,
437 gnutls_x509_crt_t issuer,
438 gnutls_x509_privkey_t issuer_key,
439 gnutls_digest_algorithm_t,
440 unsigned int flags);
441int gnutls_x509_crl_set_this_update(gnutls_x509_crl_t crl,
442 time_t act_time);
443int gnutls_x509_crl_set_next_update(gnutls_x509_crl_t crl,
444 time_t exp_time);
445int gnutls_x509_crl_set_crt_serial(gnutls_x509_crl_t crl,
446 const void *serial,
447 size_t serial_size,
448 time_t revocation_time);
449int gnutls_x509_crl_set_crt(gnutls_x509_crl_t crl,
450 gnutls_x509_crt_t crt,
451 time_t revocation_time);
452
453/* PKCS7 structures handling
454 */
455struct gnutls_pkcs7_int;
456typedef struct gnutls_pkcs7_int *gnutls_pkcs7_t;
457
458int gnutls_pkcs7_init(gnutls_pkcs7_t * pkcs7);
459void gnutls_pkcs7_deinit(gnutls_pkcs7_t pkcs7);
460int gnutls_pkcs7_import(gnutls_pkcs7_t pkcs7,
461 const gnutls_datum_t * data,
462 gnutls_x509_crt_fmt_t format);
463int gnutls_pkcs7_export(gnutls_pkcs7_t pkcs7,
464 gnutls_x509_crt_fmt_t format,
465 void *output_data,
466 size_t * output_data_size);
467
468int gnutls_pkcs7_get_crt_count(gnutls_pkcs7_t pkcs7);
469int gnutls_pkcs7_get_crt_raw(gnutls_pkcs7_t pkcs7,
470 int indx,
471 void *certificate,
472 size_t * certificate_size);
473
474int gnutls_pkcs7_set_crt_raw(gnutls_pkcs7_t pkcs7,
475 const gnutls_datum_t * crt);
476int gnutls_pkcs7_set_crt(gnutls_pkcs7_t pkcs7,
477 gnutls_x509_crt_t crt);
478int gnutls_pkcs7_delete_crt(gnutls_pkcs7_t pkcs7,
479 int indx);
480
481int gnutls_pkcs7_get_crl_raw(gnutls_pkcs7_t pkcs7,
482 int indx,
483 void *crl,
484 size_t * crl_size);
485int gnutls_pkcs7_get_crl_count(gnutls_pkcs7_t pkcs7);
486
487int gnutls_pkcs7_set_crl_raw(gnutls_pkcs7_t pkcs7,
488 const gnutls_datum_t * crt);
489int gnutls_pkcs7_set_crl(gnutls_pkcs7_t pkcs7,
490 gnutls_x509_crl_t crl);
491int gnutls_pkcs7_delete_crl(gnutls_pkcs7_t pkcs7,
492 int indx);
493
494/* X.509 Certificate verification functions.
495 */
496typedef enum gnutls_certificate_verify_flags
497 {
498 /* If set a signer does not have to be a certificate authority. This
499 * flag should normaly be disabled, unless you know what this means.
500 */
501 GNUTLS_VERIFY_DISABLE_CA_SIGN = 1,
502
503 /* Allow only trusted CA certificates that have version 1. This is
504 * safer than GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT, and should be
505 * used instead. That way only signers in your trusted list will be
506 * allowed to have certificates of version 1.
507 */
508 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT = 2,
509
510 /* If a certificate is not signed by anyone trusted but exists in
511 * the trusted CA list do not treat it as trusted.
512 */
513 GNUTLS_VERIFY_DO_NOT_ALLOW_SAME = 4,
514
515 /* Allow CA certificates that have version 1 (both root and
516 * intermediate). This might be dangerous since those haven't the
517 * basicConstraints extension. Must be used in combination with
518 * GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT.
519 */
520 GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT = 8,
521
522 /* Allow certificates to be signed using the broken MD2 algorithm.
523 */
524 GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2 = 16,
525
526 /* Allow certificates to be signed using the broken MD5 algorithm.
527 */
528 GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5 = 32
529 } gnutls_certificate_verify_flags;
530
531int gnutls_x509_crt_check_issuer(gnutls_x509_crt_t cert,
532 gnutls_x509_crt_t issuer);
533
534int gnutls_x509_crt_list_verify(const gnutls_x509_crt_t * cert_list,
535 int cert_list_length,
536 const gnutls_x509_crt_t * CA_list,
537 int CA_list_length,
538 const gnutls_x509_crl_t * CRL_list,
539 int CRL_list_length,
540 unsigned int flags,
541 unsigned int *verify);
542
543int gnutls_x509_crt_verify(gnutls_x509_crt_t cert,
544 const gnutls_x509_crt_t * CA_list,
545 int CA_list_length,
546 unsigned int flags,
547 unsigned int *verify);
548int gnutls_x509_crl_verify(gnutls_x509_crl_t crl,
549 const gnutls_x509_crt_t * CA_list,
550 int CA_list_length,
551 unsigned int flags,
552 unsigned int *verify);
553
554int gnutls_x509_crt_check_revocation(gnutls_x509_crt_t cert,
555 const gnutls_x509_crl_t *
556 crl_list,
557 int crl_list_length);
558
559int gnutls_x509_crt_get_fingerprint(gnutls_x509_crt_t cert,
560 gnutls_digest_algorithm_t algo,
561 void *buf,
562 size_t * sizeof_buf);
563
564int gnutls_x509_crt_get_key_purpose_oid(gnutls_x509_crt_t cert,
565 int indx,
566 void *oid,
567 size_t * sizeof_oid,
568 unsigned int *critical);
569int gnutls_x509_crt_set_key_purpose_oid(gnutls_x509_crt_t cert,
570 const void *oid,
571 unsigned int critical);
572
573/* Private key handling.
574 */
575
576/* Flags for the gnutls_x509_privkey_export_pkcs8() function.
577 */
578typedef enum gnutls_pkcs_encrypt_flags_t
579 {
580 GNUTLS_PKCS_PLAIN = 1, /* if set the private key will not
581 * be encrypted.
582 */
583 GNUTLS_PKCS_USE_PKCS12_3DES = 2,
584 GNUTLS_PKCS_USE_PKCS12_ARCFOUR = 4,
585 GNUTLS_PKCS_USE_PKCS12_RC2_40 = 8,
586 GNUTLS_PKCS_USE_PBES2_3DES = 16
587 } gnutls_pkcs_encrypt_flags_t;
588
589#define GNUTLS_PKCS8_PLAIN GNUTLS_PKCS_PLAIN
590#define GNUTLS_PKCS8_USE_PKCS12_3DES GNUTLS_PKCS_USE_PKCS12_3DES
591#define GNUTLS_PKCS8_USE_PKCS12_ARCFOUR GNUTLS_PKCS_USE_PKCS12_ARCFOUR
592#define GNUTLS_PKCS8_USE_PKCS12_RC2_40 GNUTLS_PKCS_USE_PKCS12_RC2_40
593
594int gnutls_x509_privkey_init(gnutls_x509_privkey_t * key);
595void gnutls_x509_privkey_deinit(gnutls_x509_privkey_t key);
596int gnutls_x509_privkey_cpy(gnutls_x509_privkey_t dst,
597 gnutls_x509_privkey_t src);
598int gnutls_x509_privkey_import(gnutls_x509_privkey_t key,
599 const gnutls_datum_t * data,
600 gnutls_x509_crt_fmt_t format);
601int gnutls_x509_privkey_import_pkcs8(gnutls_x509_privkey_t key,
602 const gnutls_datum_t * data,
603 gnutls_x509_crt_fmt_t format,
604 const char *pass,
605 unsigned int flags);
606int gnutls_x509_privkey_import_rsa_raw(gnutls_x509_privkey_t key,
607 const gnutls_datum_t * m,
608 const gnutls_datum_t * e,
609 const gnutls_datum_t * d,
610 const gnutls_datum_t * p,
611 const gnutls_datum_t * q,
612 const gnutls_datum_t * u);
613int gnutls_x509_privkey_fix(gnutls_x509_privkey_t key);
614
615int gnutls_x509_privkey_export_dsa_raw(gnutls_x509_privkey_t key,
616 gnutls_datum_t * p,
617 gnutls_datum_t * q,
618 gnutls_datum_t * g,
619 gnutls_datum_t * y,
620 gnutls_datum_t * x);
621int gnutls_x509_privkey_import_dsa_raw(gnutls_x509_privkey_t key,
622 const gnutls_datum_t * p,
623 const gnutls_datum_t * q,
624 const gnutls_datum_t * g,
625 const gnutls_datum_t * y,
626 const gnutls_datum_t * x);
627
628int gnutls_x509_privkey_get_pk_algorithm(gnutls_x509_privkey_t key);
629int gnutls_x509_privkey_get_key_id(gnutls_x509_privkey_t key,
630 unsigned int flags,
631 unsigned char *output_data,
632 size_t * output_data_size);
633
634int gnutls_x509_privkey_generate(gnutls_x509_privkey_t key,
635 gnutls_pk_algorithm_t algo,
636 unsigned int bits,
637 unsigned int flags);
638
639int gnutls_x509_privkey_export(gnutls_x509_privkey_t key,
640 gnutls_x509_crt_fmt_t format,
641 void *output_data,
642 size_t * output_data_size);
643int gnutls_x509_privkey_export_pkcs8(gnutls_x509_privkey_t key,
644 gnutls_x509_crt_fmt_t format,
645 const char *password,
646 unsigned int flags,
647 void *output_data,
648 size_t * output_data_size);
649int gnutls_x509_privkey_export_rsa_raw(gnutls_x509_privkey_t key,
650 gnutls_datum_t * m,
651 gnutls_datum_t * e,
652 gnutls_datum_t * d,
653 gnutls_datum_t * p,
654 gnutls_datum_t * q,
655 gnutls_datum_t * u);
656
657/* Signing stuff.
658 */
659int gnutls_x509_privkey_sign_data(gnutls_x509_privkey_t key,
660 gnutls_digest_algorithm_t digest,
661 unsigned int flags,
662 const gnutls_datum_t * data,
663 void *signature,
664 size_t * signature_size);
665int gnutls_x509_privkey_verify_data(gnutls_x509_privkey_t key,
666 unsigned int flags,
667 const gnutls_datum_t * data,
668 const gnutls_datum_t * signature);
669int gnutls_x509_crt_verify_data(gnutls_x509_crt_t crt,
670 unsigned int flags,
671 const gnutls_datum_t * data,
672 const gnutls_datum_t * signature);
673
674int gnutls_x509_privkey_sign_hash(gnutls_x509_privkey_t key,
675 const gnutls_datum_t * hash,
676 gnutls_datum_t * signature);
677
678/* Certificate request stuff.
679 */
680struct gnutls_x509_crq_int;
681typedef struct gnutls_x509_crq_int *gnutls_x509_crq_t;
682
683int gnutls_x509_crq_init(gnutls_x509_crq_t * crq);
684void gnutls_x509_crq_deinit(gnutls_x509_crq_t crq);
685int gnutls_x509_crq_import(gnutls_x509_crq_t crq,
686 const gnutls_datum_t * data,
687 gnutls_x509_crt_fmt_t format);
688int gnutls_x509_crq_get_pk_algorithm(gnutls_x509_crq_t crq,
689 unsigned int *bits);
690int gnutls_x509_crq_get_dn(gnutls_x509_crq_t crq,
691 char *buf,
692 size_t * sizeof_buf);
693int gnutls_x509_crq_get_dn_oid(gnutls_x509_crq_t crq,
694 int indx,
695 void *oid,
696 size_t * sizeof_oid);
697int gnutls_x509_crq_get_dn_by_oid(gnutls_x509_crq_t crq,
698 const char *oid,
699 int indx,
700 unsigned int raw_flag,
701 void *buf,
702 size_t * sizeof_buf);
703int gnutls_x509_crq_set_dn_by_oid(gnutls_x509_crq_t crq,
704 const char *oid,
705 unsigned int raw_flag,
706 const void *name,
707 unsigned int sizeof_name);
708int gnutls_x509_crq_set_version(gnutls_x509_crq_t crq,
709 unsigned int version);
710int gnutls_x509_crq_set_key(gnutls_x509_crq_t crq,
711 gnutls_x509_privkey_t key);
712int gnutls_x509_crq_sign2(gnutls_x509_crq_t crq,
713 gnutls_x509_privkey_t key,
714 gnutls_digest_algorithm_t,
715 unsigned int flags);
716int gnutls_x509_crq_sign(gnutls_x509_crq_t crq,
717 gnutls_x509_privkey_t key);
718
719int gnutls_x509_crq_set_challenge_password(gnutls_x509_crq_t crq,
720 const char *pass);
721int gnutls_x509_crq_get_challenge_password(gnutls_x509_crq_t crq,
722 char *pass,
723 size_t * sizeof_pass);
724
725int gnutls_x509_crq_set_attribute_by_oid(gnutls_x509_crq_t crq,
726 const char *oid,
727 void *buf,
728 size_t sizeof_buf);
729int gnutls_x509_crq_get_attribute_by_oid(gnutls_x509_crq_t crq,
730 const char *oid,
731 int indx,
732 void *buf,
733 size_t * sizeof_buf);
734
735int gnutls_x509_crq_export(gnutls_x509_crq_t crq,
736 gnutls_x509_crt_fmt_t format,
737 void *output_data,
738 size_t * output_data_size);
739
740int gnutls_x509_crt_set_crq(gnutls_x509_crt_t crt,
741 gnutls_x509_crq_t crq);
742
743#ifdef __cplusplus
744}
745#endif
746
747#define HASH_OID_SHA1 "1.3.14.3.2.26"
748#define HASH_OID_MD5 "1.2.840.113549.2.5"
749#define HASH_OID_MD2 "1.2.840.113549.2.2"
750#define HASH_OID_RMD160 "1.3.36.3.2.1"
751#define HASH_OID_SHA256 "2.16.840.1.101.3.4.2.1"
752#define HASH_OID_SHA384 "2.16.840.1.101.3.4.2.2"
753#define HASH_OID_SHA512 "2.16.840.1.101.3.4.2.3"
754
755typedef struct gnutls_x509_crl_int
756 {
757 ASN1_TYPE crl;
758 } gnutls_x509_crl_int;
759
760typedef struct gnutls_x509_crt_int
761 {
762 ASN1_TYPE cert;
763 int use_extensions;
764 } gnutls_x509_crt_int;
765
766#define MAX_PRIV_PARAMS_SIZE 6 /* ok for RSA and DSA */
767
768/* parameters should not be larger than this limit */
769#define DSA_PRIVATE_PARAMS 5
770#define DSA_PUBLIC_PARAMS 4
771#define RSA_PRIVATE_PARAMS 6
772#define RSA_PUBLIC_PARAMS 2
773
774#if MAX_PRIV_PARAMS_SIZE - RSA_PRIVATE_PARAMS < 0
775# error INCREASE MAX_PRIV_PARAMS
776#endif
777
778#if MAX_PRIV_PARAMS_SIZE - DSA_PRIVATE_PARAMS < 0
779# error INCREASE MAX_PRIV_PARAMS
780#endif
781
782typedef struct gnutls_x509_privkey_int
783 {
784 mpi_t params[MAX_PRIV_PARAMS_SIZE]; /* the size of params depends on the public
785 * key algorithm
786 */
787 /*
788 * RSA: [0] is modulus
789 * [1] is public exponent
790 * [2] is private exponent
791 * [3] is prime1 (p)
792 * [4] is prime2 (q)
793 * [5] is coefficient (u == inverse of p mod q)
794 * note that other packages used inverse of q mod p,
795 * so we need to perform conversions.
796 * DSA: [0] is p
797 * [1] is q
798 * [2] is g
799 * [3] is y (public key)
800 * [4] is x (private key)
801 */
802 int params_size; /* holds the number of params */
803
804 gnutls_pk_algorithm_t pk_algorithm;
805
806 int crippled; /* The crippled keys will not use the ASN1_TYPE key.
807 * The encoding will only be performed at the export
808 * phase, to optimize copying etc. Cannot be used with
809 * the exported API (used internally only).
810 */
811 ASN1_TYPE key;
812 } gnutls_x509_privkey_int;
813
814int gnutls_x509_crt_get_issuer_dn_by_oid(gnutls_x509_crt_t cert,
815 const char *oid,
816 int indx,
817 unsigned int raw_flag,
818 void *buf,
819 size_t * sizeof_buf);
820int gnutls_x509_crt_get_subject_alt_name(gnutls_x509_crt_t cert,
821 unsigned int seq,
822 void *ret,
823 size_t * ret_size,
824 unsigned int *critical);
825int gnutls_x509_crt_get_dn_by_oid(gnutls_x509_crt_t cert,
826 const char *oid,
827 int indx,
828 unsigned int raw_flag,
829 void *buf,
830 size_t * sizeof_buf);
831int gnutls_x509_crt_get_ca_status(gnutls_x509_crt_t cert,
832 unsigned int *critical);
833int gnutls_x509_crt_get_pk_algorithm(gnutls_x509_crt_t cert,
834 unsigned int *bits);
835
836int _gnutls_x509_crt_cpy(gnutls_x509_crt_t dest,
837 gnutls_x509_crt_t src);
838
839int gnutls_x509_crt_get_serial(gnutls_x509_crt_t cert,
840 void *result,
841 size_t * result_size);
842
843int _gnutls_x509_compare_raw_dn(const gnutls_datum_t * dn1,
844 const gnutls_datum_t * dn2);
845
846int gnutls_x509_crt_check_revocation(gnutls_x509_crt_t cert,
847 const gnutls_x509_crl_t * crl_list,
848 int crl_list_length);
849
850int _gnutls_x509_crl_cpy(gnutls_x509_crl_t dest,
851 gnutls_x509_crl_t src);
852int _gnutls_x509_crl_get_raw_issuer_dn(gnutls_x509_crl_t crl,
853 gnutls_datum_t * dn);
854int gnutls_x509_crl_get_crt_count(gnutls_x509_crl_t crl);
855int gnutls_x509_crl_get_crt_serial(gnutls_x509_crl_t crl,
856 int indx,
857 unsigned char *serial,
858 size_t * serial_size,
859 time_t * t);
860
861void gnutls_x509_crl_deinit(gnutls_x509_crl_t crl);
862int gnutls_x509_crl_init(gnutls_x509_crl_t * crl);
863int gnutls_x509_crl_import(gnutls_x509_crl_t crl,
864 const gnutls_datum_t * data,
865 gnutls_x509_crt_fmt_t format);
866int gnutls_x509_crl_export(gnutls_x509_crl_t crl,
867 gnutls_x509_crt_fmt_t format,
868 void *output_data,
869 size_t * output_data_size);
870
871int gnutls_x509_crt_init(gnutls_x509_crt_t * cert);
872void gnutls_x509_crt_deinit(gnutls_x509_crt_t cert);
873int gnutls_x509_crt_import(gnutls_x509_crt_t cert,
874 const gnutls_datum_t * data,
875 gnutls_x509_crt_fmt_t format);
876int gnutls_x509_crt_export(gnutls_x509_crt_t cert,
877 gnutls_x509_crt_fmt_t format,
878 void *output_data,
879 size_t * output_data_size);
880
881int gnutls_x509_crt_get_key_usage(gnutls_x509_crt_t cert,
882 unsigned int *key_usage,
883 unsigned int *critical);
884int gnutls_x509_crt_get_signature_algorithm(gnutls_x509_crt_t cert);
885int gnutls_x509_crt_get_version(gnutls_x509_crt_t cert);
886
887int gnutls_x509_privkey_init(gnutls_x509_privkey_t * key);
888void gnutls_x509_privkey_deinit(gnutls_x509_privkey_t key);
889
890int gnutls_x509_privkey_generate(gnutls_x509_privkey_t key,
891 gnutls_pk_algorithm_t algo,
892 unsigned int bits,
893 unsigned int flags);
894
895int gnutls_x509_privkey_import(gnutls_x509_privkey_t key,
896 const gnutls_datum_t * data,
897 gnutls_x509_crt_fmt_t format);
898int gnutls_x509_privkey_get_pk_algorithm(gnutls_x509_privkey_t key);
899int gnutls_x509_privkey_import_rsa_raw(gnutls_x509_privkey_t key,
900 const gnutls_datum_t * m,
901 const gnutls_datum_t * e,
902 const gnutls_datum_t * d,
903 const gnutls_datum_t * p,
904 const gnutls_datum_t * q,
905 const gnutls_datum_t * u);
906int gnutls_x509_privkey_export_rsa_raw(gnutls_x509_privkey_t key,
907 gnutls_datum_t * m,
908 gnutls_datum_t * e,
909 gnutls_datum_t * d,
910 gnutls_datum_t * p,
911 gnutls_datum_t * q,
912 gnutls_datum_t * u);
913int gnutls_x509_privkey_export(gnutls_x509_privkey_t key,
914 gnutls_x509_crt_fmt_t format,
915 void *output_data,
916 size_t * output_data_size);
917
918#define GNUTLS_CRL_REASON_UNUSED 128
919#define GNUTLS_CRL_REASON_KEY_COMPROMISE 64
920#define GNUTLS_CRL_REASON_CA_COMPROMISE 32
921#define GNUTLS_CRL_REASON_AFFILIATION_CHANGED 16
922#define GNUTLS_CRL_REASON_SUPERSEEDED 8
923#define GNUTLS_CRL_REASON_CESSATION_OF_OPERATION 4
924#define GNUTLS_CRL_REASON_CERTIFICATE_HOLD 2
925#define GNUTLS_CRL_REASON_PRIVILEGE_WITHDRAWN 1
926#define GNUTLS_CRL_REASON_AA_COMPROMISE 32768
927
928#endif
diff --git a/src/daemon/https/x509/x509_privkey.c b/src/daemon/https/x509/x509_privkey.c
new file mode 100644
index 00000000..f5c64dee
--- /dev/null
+++ b/src/daemon/https/x509/x509_privkey.c
@@ -0,0 +1,1509 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25#include <gnutls_int.h>
26#include <gnutls_datum.h>
27#include <gnutls_global.h>
28#include <gnutls_errors.h>
29#include <gnutls_rsa_export.h>
30#include <gnutls_sig.h>
31#include <common.h>
32#include <gnutls_x509.h>
33#include <x509_b64.h>
34#include <x509.h>
35#include <dn.h>
36#include <mpi.h>
37#include <extensions.h>
38#include <sign.h>
39#include <dsa.h>
40#include <verify.h>
41
42static int _gnutls_asn1_encode_rsa (ASN1_TYPE * c2, mpi_t * params);
43int _gnutls_asn1_encode_dsa (ASN1_TYPE * c2, mpi_t * params);
44
45/* remove this when libgcrypt can handle the PKCS #1 coefficients from
46 * rsa keys
47 */
48#define CALC_COEFF 1
49
50/**
51 * gnutls_x509_privkey_init - This function initializes a gnutls_crl structure
52 * @key: The structure to be initialized
53 *
54 * This function will initialize an private key structure.
55 *
56 * Returns 0 on success.
57 *
58 **/
59int
60gnutls_x509_privkey_init (gnutls_x509_privkey_t * key)
61{
62 *key = gnutls_calloc (1, sizeof (gnutls_x509_privkey_int));
63
64 if (*key)
65 {
66 (*key)->key = ASN1_TYPE_EMPTY;
67 (*key)->pk_algorithm = GNUTLS_PK_UNKNOWN;
68 return 0; /* success */
69 }
70
71 return GNUTLS_E_MEMORY_ERROR;
72}
73
74/**
75 * gnutls_x509_privkey_deinit - This function deinitializes memory used by a gnutls_x509_privkey_t structure
76 * @key: The structure to be initialized
77 *
78 * This function will deinitialize a private key structure.
79 *
80 **/
81void
82gnutls_x509_privkey_deinit (gnutls_x509_privkey_t key)
83{
84 int i;
85
86 if (!key)
87 return;
88
89 for (i = 0; i < key->params_size; i++)
90 {
91 _gnutls_mpi_release (&key->params[i]);
92 }
93
94 asn1_delete_structure (&key->key);
95 gnutls_free (key);
96}
97
98/**
99 * gnutls_x509_privkey_cpy - This function copies a private key
100 * @dst: The destination key, which should be initialized.
101 * @src: The source key
102 *
103 * This function will copy a private key from source to destination key.
104 *
105 **/
106int
107gnutls_x509_privkey_cpy (gnutls_x509_privkey_t dst, gnutls_x509_privkey_t src)
108{
109 int i, ret;
110
111 if (!src || !dst)
112 return GNUTLS_E_INVALID_REQUEST;
113
114 for (i = 0; i < src->params_size; i++)
115 {
116 dst->params[i] = _gnutls_mpi_copy (src->params[i]);
117 if (dst->params[i] == NULL)
118 return GNUTLS_E_MEMORY_ERROR;
119 }
120
121 dst->params_size = src->params_size;
122 dst->pk_algorithm = src->pk_algorithm;
123 dst->crippled = src->crippled;
124
125 if (!src->crippled)
126 {
127 switch (dst->pk_algorithm)
128 {
129 case GNUTLS_PK_RSA:
130 ret = _gnutls_asn1_encode_rsa (&dst->key, dst->params);
131 if (ret < 0)
132 {
133 gnutls_assert ();
134 return ret;
135 }
136 break;
137 default:
138 gnutls_assert ();
139 return GNUTLS_E_INVALID_REQUEST;
140 }
141 }
142
143 return 0;
144}
145
146/* Converts an RSA PKCS#1 key to
147 * an internal structure (gnutls_private_key)
148 */
149ASN1_TYPE
150_gnutls_privkey_decode_pkcs1_rsa_key (const gnutls_datum_t * raw_key,
151 gnutls_x509_privkey_t pkey)
152{
153 int result;
154 ASN1_TYPE pkey_asn;
155
156 if ((result = asn1_create_element (_gnutls_get_gnutls_asn (),
157 "GNUTLS.RSAPrivateKey",
158 &pkey_asn)) != ASN1_SUCCESS)
159 {
160 gnutls_assert ();
161 return NULL;
162 }
163
164 if ((sizeof (pkey->params) / sizeof (mpi_t)) < RSA_PRIVATE_PARAMS)
165 {
166 gnutls_assert ();
167 /* internal error. Increase the mpi_ts in params */
168 return NULL;
169 }
170
171 result = asn1_der_decoding (&pkey_asn, raw_key->data, raw_key->size, NULL);
172 if (result != ASN1_SUCCESS)
173 {
174 gnutls_assert ();
175 goto error;
176 }
177
178 if ((result = _gnutls_x509_read_int (pkey_asn, "modulus", &pkey->params[0]))
179 < 0)
180 {
181 gnutls_assert ();
182 goto error;
183 }
184
185 if ((result = _gnutls_x509_read_int (pkey_asn, "publicExponent",
186 &pkey->params[1])) < 0)
187 {
188 gnutls_assert ();
189 goto error;
190 }
191
192 if ((result = _gnutls_x509_read_int (pkey_asn, "privateExponent",
193 &pkey->params[2])) < 0)
194 {
195 gnutls_assert ();
196 goto error;
197 }
198
199 if ((result = _gnutls_x509_read_int (pkey_asn, "prime1", &pkey->params[3]))
200 < 0)
201 {
202 gnutls_assert ();
203 goto error;
204 }
205
206 if ((result = _gnutls_x509_read_int (pkey_asn, "prime2", &pkey->params[4]))
207 < 0)
208 {
209 gnutls_assert ();
210 goto error;
211 }
212
213#ifdef CALC_COEFF
214 /* Calculate the coefficient. This is because the gcrypt
215 * library is uses the p,q in the reverse order.
216 */
217 pkey->params[5] =
218 _gnutls_mpi_snew (_gnutls_mpi_get_nbits (pkey->params[0]));
219
220 if (pkey->params[5] == NULL)
221 {
222 gnutls_assert ();
223 goto error;
224 }
225
226 _gnutls_mpi_invm (pkey->params[5], pkey->params[3], pkey->params[4]);
227 /* p, q */
228#else
229 if ((result = _gnutls_x509_read_int (pkey_asn, "coefficient",
230 &pkey->params[5])) < 0)
231 {
232 gnutls_assert ();
233 goto error;
234 }
235#endif
236 pkey->params_size = 6;
237
238 return pkey_asn;
239
240error:asn1_delete_structure (&pkey_asn);
241 _gnutls_mpi_release (&pkey->params[0]);
242 _gnutls_mpi_release (&pkey->params[1]);
243 _gnutls_mpi_release (&pkey->params[2]);
244 _gnutls_mpi_release (&pkey->params[3]);
245 _gnutls_mpi_release (&pkey->params[4]);
246 _gnutls_mpi_release (&pkey->params[5]);
247 return NULL;
248
249}
250
251static ASN1_TYPE
252decode_dsa_key (const gnutls_datum_t * raw_key, gnutls_x509_privkey_t pkey)
253{
254 int result;
255 ASN1_TYPE dsa_asn;
256
257 if ((result = asn1_create_element (_gnutls_get_gnutls_asn (),
258 "GNUTLS.DSAPrivateKey",
259 &dsa_asn)) != ASN1_SUCCESS)
260 {
261 gnutls_assert ();
262 return NULL;
263 }
264
265 if ((sizeof (pkey->params) / sizeof (mpi_t)) < DSA_PRIVATE_PARAMS)
266 {
267 gnutls_assert ();
268 /* internal error. Increase the mpi_ts in params */
269 return NULL;
270 }
271
272 result = asn1_der_decoding (&dsa_asn, raw_key->data, raw_key->size, NULL);
273 if (result != ASN1_SUCCESS)
274 {
275 gnutls_assert ();
276 goto error;
277 }
278
279 if ((result = _gnutls_x509_read_int (dsa_asn, "p", &pkey->params[0])) < 0)
280 {
281 gnutls_assert ();
282 goto error;
283 }
284
285 if ((result = _gnutls_x509_read_int (dsa_asn, "q", &pkey->params[1])) < 0)
286 {
287 gnutls_assert ();
288 goto error;
289 }
290
291 if ((result = _gnutls_x509_read_int (dsa_asn, "g", &pkey->params[2])) < 0)
292 {
293 gnutls_assert ();
294 goto error;
295 }
296
297 if ((result = _gnutls_x509_read_int (dsa_asn, "Y", &pkey->params[3])) < 0)
298 {
299 gnutls_assert ();
300 goto error;
301 }
302
303 if ((result =
304 _gnutls_x509_read_int (dsa_asn, "priv", &pkey->params[4])) < 0)
305 {
306 gnutls_assert ();
307 goto error;
308 }
309 pkey->params_size = 5;
310
311 return dsa_asn;
312
313error:asn1_delete_structure (&dsa_asn);
314 _gnutls_mpi_release (&pkey->params[0]);
315 _gnutls_mpi_release (&pkey->params[1]);
316 _gnutls_mpi_release (&pkey->params[2]);
317 _gnutls_mpi_release (&pkey->params[3]);
318 _gnutls_mpi_release (&pkey->params[4]);
319 return NULL;
320
321}
322
323#define PEM_KEY_DSA "DSA PRIVATE KEY"
324#define PEM_KEY_RSA "RSA PRIVATE KEY"
325
326/**
327 * gnutls_x509_privkey_import - This function will import a DER or PEM encoded key
328 * @key: The structure to store the parsed key
329 * @data: The DER or PEM encoded certificate.
330 * @format: One of DER or PEM
331 *
332 * This function will convert the given DER or PEM encoded key
333 * to the native gnutls_x509_privkey_t format. The output will be stored in @key .
334 *
335 * If the key is PEM encoded it should have a header of "RSA PRIVATE KEY", or
336 * "DSA PRIVATE KEY".
337 *
338 * Returns 0 on success.
339 *
340 **/
341int
342gnutls_x509_privkey_import (gnutls_x509_privkey_t key,
343 const gnutls_datum_t * data,
344 gnutls_x509_crt_fmt_t format)
345{
346 int result = 0, need_free = 0;
347 gnutls_datum_t _data;
348
349 if (key == NULL)
350 {
351 gnutls_assert ();
352 return GNUTLS_E_INVALID_REQUEST;
353 }
354
355 _data.data = data->data;
356 _data.size = data->size;
357
358 key->pk_algorithm = GNUTLS_PK_UNKNOWN;
359
360 /* If the Certificate is in PEM format then decode it
361 */
362 if (format == GNUTLS_X509_FMT_PEM)
363 {
364 opaque *out;
365
366 /* Try the first header */
367 result
368 = _gnutls_fbase64_decode (PEM_KEY_RSA, data->data, data->size, &out);
369 key->pk_algorithm = GNUTLS_PK_RSA;
370
371 // TODO rm
372// if (result == GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR)
373// {
374// /* try for the second header */
375// result = _gnutls_fbase64_decode(PEM_KEY_DSA, data->data, data->size,
376// &out);
377// key->pk_algorithm = GNUTLS_PK_DSA;
378//
379// if (result <= 0)
380// {
381// if (result == 0)
382// result = GNUTLS_E_INTERNAL_ERROR;
383// gnutls_assert ();
384// return result;
385// }
386// }
387
388 _data.data = out;
389 _data.size = result;
390
391 need_free = 1;
392 }
393
394 if (key->pk_algorithm == GNUTLS_PK_RSA)
395 {
396 key->key = _gnutls_privkey_decode_pkcs1_rsa_key (&_data, key);
397 if (key->key == NULL)
398 gnutls_assert ();
399 }
400 else
401 {
402 /* Try decoding with both, and accept the one that
403 * succeeds.
404 */
405 key->pk_algorithm = GNUTLS_PK_RSA;
406 key->key = _gnutls_privkey_decode_pkcs1_rsa_key (&_data, key);
407
408 // TODO rm
409// if (key->key == NULL)
410// {
411// key->pk_algorithm = GNUTLS_PK_DSA;
412// key->key = decode_dsa_key(&_data, key);
413// if (key->key == NULL)
414// gnutls_assert();
415// }
416 }
417
418 if (key->key == NULL)
419 {
420 gnutls_assert ();
421 result = GNUTLS_E_ASN1_DER_ERROR;
422 goto cleanup;
423 }
424
425 if (need_free)
426 _gnutls_free_datum (&_data);
427
428 /* The key has now been decoded.
429 */
430
431 return 0;
432
433cleanup:key->pk_algorithm = GNUTLS_PK_UNKNOWN;
434 if (need_free)
435 _gnutls_free_datum (&_data);
436 return result;
437}
438
439#define FREE_RSA_PRIVATE_PARAMS for (i=0;i<RSA_PRIVATE_PARAMS;i++) \
440 _gnutls_mpi_release(&key->params[i])
441#define FREE_DSA_PRIVATE_PARAMS for (i=0;i<DSA_PRIVATE_PARAMS;i++) \
442 _gnutls_mpi_release(&key->params[i])
443
444/**
445 * gnutls_x509_privkey_import_rsa_raw - This function will import a raw RSA key
446 * @key: The structure to store the parsed key
447 * @m: holds the modulus
448 * @e: holds the public exponent
449 * @d: holds the private exponent
450 * @p: holds the first prime (p)
451 * @q: holds the second prime (q)
452 * @u: holds the coefficient
453 *
454 * This function will convert the given RSA raw parameters
455 * to the native gnutls_x509_privkey_t format. The output will be stored in @key.
456 *
457 **/
458int
459gnutls_x509_privkey_import_rsa_raw (gnutls_x509_privkey_t key,
460 const gnutls_datum_t * m,
461 const gnutls_datum_t * e,
462 const gnutls_datum_t * d,
463 const gnutls_datum_t * p,
464 const gnutls_datum_t * q,
465 const gnutls_datum_t * u)
466{
467 int i = 0, ret;
468 size_t siz = 0;
469
470 if (key == NULL)
471 {
472 gnutls_assert ();
473 return GNUTLS_E_INVALID_REQUEST;
474 }
475
476 siz = m->size;
477 if (_gnutls_mpi_scan_nz (&key->params[0], m->data, &siz))
478 {
479 gnutls_assert ();
480 FREE_RSA_PRIVATE_PARAMS;
481 return GNUTLS_E_MPI_SCAN_FAILED;
482 }
483
484 siz = e->size;
485 if (_gnutls_mpi_scan_nz (&key->params[1], e->data, &siz))
486 {
487 gnutls_assert ();
488 FREE_RSA_PRIVATE_PARAMS;
489 return GNUTLS_E_MPI_SCAN_FAILED;
490 }
491
492 siz = d->size;
493 if (_gnutls_mpi_scan_nz (&key->params[2], d->data, &siz))
494 {
495 gnutls_assert ();
496 FREE_RSA_PRIVATE_PARAMS;
497 return GNUTLS_E_MPI_SCAN_FAILED;
498 }
499
500 siz = p->size;
501 if (_gnutls_mpi_scan_nz (&key->params[3], p->data, &siz))
502 {
503 gnutls_assert ();
504 FREE_RSA_PRIVATE_PARAMS;
505 return GNUTLS_E_MPI_SCAN_FAILED;
506 }
507
508 siz = q->size;
509 if (_gnutls_mpi_scan_nz (&key->params[4], q->data, &siz))
510 {
511 gnutls_assert ();
512 FREE_RSA_PRIVATE_PARAMS;
513 return GNUTLS_E_MPI_SCAN_FAILED;
514 }
515
516#ifdef CALC_COEFF
517 key->params[5] = _gnutls_mpi_snew (_gnutls_mpi_get_nbits (key->params[0]));
518
519 if (key->params[5] == NULL)
520 {
521 gnutls_assert ();
522 FREE_RSA_PRIVATE_PARAMS;
523 return GNUTLS_E_MEMORY_ERROR;
524 }
525
526 _gnutls_mpi_invm (key->params[5], key->params[3], key->params[4]);
527#else
528 siz = u->size;
529 if (_gnutls_mpi_scan_nz (&key->params[5], u->data, &siz))
530 {
531 gnutls_assert ();
532 FREE_RSA_PRIVATE_PARAMS;
533 return GNUTLS_E_MPI_SCAN_FAILED;
534 }
535#endif
536
537 if (!key->crippled)
538 {
539 ret = _gnutls_asn1_encode_rsa (&key->key, key->params);
540 if (ret < 0)
541 {
542 gnutls_assert ();
543 FREE_RSA_PRIVATE_PARAMS;
544 return ret;
545 }
546 }
547
548 key->params_size = RSA_PRIVATE_PARAMS;
549 key->pk_algorithm = GNUTLS_PK_RSA;
550
551 return 0;
552
553}
554
555/**
556 * gnutls_x509_privkey_get_pk_algorithm - This function returns the key's PublicKey algorithm
557 * @key: should contain a gnutls_x509_privkey_t structure
558 *
559 * This function will return the public key algorithm of a private
560 * key.
561 *
562 * Returns a member of the gnutls_pk_algorithm_t enumeration on success,
563 * or a negative value on error.
564 *
565 **/
566int
567gnutls_x509_privkey_get_pk_algorithm (gnutls_x509_privkey_t key)
568{
569 if (key == NULL)
570 {
571 gnutls_assert ();
572 return GNUTLS_E_INVALID_REQUEST;
573 }
574
575 return key->pk_algorithm;
576}
577
578/**
579 * gnutls_x509_privkey_export - This function will export the private key
580 * @key: Holds the key
581 * @format: the format of output params. One of PEM or DER.
582 * @output_data: will contain a private key PEM or DER encoded
583 * @output_data_size: holds the size of output_data (and will be
584 * replaced by the actual size of parameters)
585 *
586 * This function will export the private key to a PKCS1 structure for
587 * RSA keys, or an integer sequence for DSA keys. The DSA keys are in
588 * the same format with the parameters used by openssl.
589 *
590 * If the buffer provided is not long enough to hold the output, then
591 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
592 * be returned.
593 *
594 * If the structure is PEM encoded, it will have a header
595 * of "BEGIN RSA PRIVATE KEY".
596 *
597 * Return value: In case of failure a negative value will be
598 * returned, and 0 on success.
599 *
600 **/
601int
602gnutls_x509_privkey_export (gnutls_x509_privkey_t key,
603 gnutls_x509_crt_fmt_t format,
604 void *output_data, size_t * output_data_size)
605{
606 char *msg;
607 int ret;
608
609 if (key == NULL)
610 {
611 gnutls_assert ();
612 return GNUTLS_E_INVALID_REQUEST;
613 }
614
615 if (key->pk_algorithm == GNUTLS_PK_RSA)
616 msg = PEM_KEY_RSA;
617 else
618 msg = NULL;
619
620 if (key->crippled)
621 { /* encode the parameters on the fly.
622 */
623 switch (key->pk_algorithm)
624 {
625 case GNUTLS_PK_RSA:
626 ret = _gnutls_asn1_encode_rsa (&key->key, key->params);
627 if (ret < 0)
628 {
629 gnutls_assert ();
630 return ret;
631 }
632 break;
633 default:
634 gnutls_assert ();
635 return GNUTLS_E_INVALID_REQUEST;
636 }
637 }
638
639 return _gnutls_x509_export_int (key->key, format, msg, output_data,
640 output_data_size);
641}
642
643/**
644 * gnutls_x509_privkey_export_rsa_raw - This function will export the RSA private key
645 * @key: a structure that holds the rsa parameters
646 * @m: will hold the modulus
647 * @e: will hold the public exponent
648 * @d: will hold the private exponent
649 * @p: will hold the first prime (p)
650 * @q: will hold the second prime (q)
651 * @u: will hold the coefficient
652 *
653 * This function will export the RSA private key's parameters found in the given
654 * structure. The new parameters will be allocated using
655 * gnutls_malloc() and will be stored in the appropriate datum.
656 *
657 **/
658int
659gnutls_x509_privkey_export_rsa_raw (gnutls_x509_privkey_t key,
660 gnutls_datum_t * m,
661 gnutls_datum_t * e,
662 gnutls_datum_t * d,
663 gnutls_datum_t * p,
664 gnutls_datum_t * q, gnutls_datum_t * u)
665{
666 int ret;
667 mpi_t coeff = NULL;
668
669 if (key == NULL)
670 {
671 gnutls_assert ();
672 return GNUTLS_E_INVALID_REQUEST;
673 }
674
675 m->data = e->data = d->data = p->data = q->data = u->data = NULL;
676 m->size = e->size = d->size = p->size = q->size = u->size = 0;
677
678 ret = _gnutls_mpi_dprint (m, key->params[0]);
679 if (ret < 0)
680 {
681 gnutls_assert ();
682 goto error;
683 }
684
685 /* E */
686 ret = _gnutls_mpi_dprint (e, key->params[1]);
687 if (ret < 0)
688 {
689 gnutls_assert ();
690 goto error;
691 }
692
693 /* D */
694 ret = _gnutls_mpi_dprint (d, key->params[2]);
695 if (ret < 0)
696 {
697 gnutls_assert ();
698 goto error;
699 }
700
701 /* P */
702 ret = _gnutls_mpi_dprint (p, key->params[3]);
703 if (ret < 0)
704 {
705 gnutls_assert ();
706 goto error;
707 }
708
709 /* Q */
710 ret = _gnutls_mpi_dprint (q, key->params[4]);
711 if (ret < 0)
712 {
713 gnutls_assert ();
714 goto error;
715 }
716
717#ifdef CALC_COEFF
718 coeff = _gnutls_mpi_snew (_gnutls_mpi_get_nbits (key->params[0]));
719
720 if (coeff == NULL)
721 {
722 gnutls_assert ();
723 ret = GNUTLS_E_MEMORY_ERROR;
724 goto error;
725 }
726
727 _gnutls_mpi_invm (coeff, key->params[4], key->params[3]);
728 ret = _gnutls_mpi_dprint (u, coeff);
729 if (ret < 0)
730 {
731 gnutls_assert ();
732 goto error;
733 }
734
735 _gnutls_mpi_release (&coeff);
736#else
737 /* U */
738 ret = _gnutls_mpi_dprint (u, key->params[5]);
739 if (ret < 0)
740 {
741 gnutls_assert ();
742 goto error;
743 }
744#endif
745
746 return 0;
747
748error:_gnutls_free_datum (m);
749 _gnutls_free_datum (d);
750 _gnutls_free_datum (e);
751 _gnutls_free_datum (p);
752 _gnutls_free_datum (q);
753 _gnutls_mpi_release (&coeff);
754
755 return ret;
756}
757
758/**
759 * gnutls_x509_privkey_export_dsa_raw - This function will export the DSA private key
760 * @params: a structure that holds the DSA parameters
761 * @p: will hold the p
762 * @q: will hold the q
763 * @g: will hold the g
764 * @y: will hold the y
765 * @x: will hold the x
766 *
767 * This function will export the DSA private key's parameters found in the given
768 * structure. The new parameters will be allocated using
769 * gnutls_malloc() and will be stored in the appropriate datum.
770 *
771 **/
772int
773gnutls_x509_privkey_export_dsa_raw (gnutls_x509_privkey_t key,
774 gnutls_datum_t * p,
775 gnutls_datum_t * q,
776 gnutls_datum_t * g,
777 gnutls_datum_t * y, gnutls_datum_t * x)
778{
779 int ret;
780
781 if (key == NULL)
782 {
783 gnutls_assert ();
784 return GNUTLS_E_INVALID_REQUEST;
785 }
786
787 /* P */
788 ret = _gnutls_mpi_dprint (p, key->params[0]);
789 if (ret < 0)
790 {
791 gnutls_assert ();
792 return ret;
793 }
794
795 /* Q */
796 ret = _gnutls_mpi_dprint (q, key->params[1]);
797 if (ret < 0)
798 {
799 gnutls_assert ();
800 _gnutls_free_datum (p);
801 return ret;
802 }
803
804 /* G */
805 ret = _gnutls_mpi_dprint (g, key->params[2]);
806 if (ret < 0)
807 {
808 gnutls_assert ();
809 _gnutls_free_datum (p);
810 _gnutls_free_datum (q);
811 return ret;
812 }
813
814 /* Y */
815 ret = _gnutls_mpi_dprint (y, key->params[3]);
816 if (ret < 0)
817 {
818 gnutls_assert ();
819 _gnutls_free_datum (p);
820 _gnutls_free_datum (g);
821 _gnutls_free_datum (q);
822 return ret;
823 }
824
825 /* X */
826 ret = _gnutls_mpi_dprint (x, key->params[4]);
827 if (ret < 0)
828 {
829 gnutls_assert ();
830 _gnutls_free_datum (y);
831 _gnutls_free_datum (p);
832 _gnutls_free_datum (g);
833 _gnutls_free_datum (q);
834 return ret;
835 }
836
837 return 0;
838}
839
840/* Encodes the RSA parameters into an ASN.1 RSA private key structure.
841 */
842static int
843_gnutls_asn1_encode_rsa (ASN1_TYPE * c2, mpi_t * params)
844{
845 int result, i;
846 size_t size[8], total;
847 opaque *m_data, *pube_data, *prie_data;
848 opaque *p1_data, *p2_data, *u_data, *exp1_data, *exp2_data;
849 opaque *all_data = NULL, *p;
850 mpi_t exp1 = NULL, exp2 = NULL, q1 = NULL, p1 = NULL, u = NULL;
851 opaque null = '\0';
852
853 /* Read all the sizes */
854 total = 0;
855 for (i = 0; i < 5; i++)
856 {
857 _gnutls_mpi_print_lz (NULL, &size[i], params[i]);
858 total += size[i];
859 }
860
861 /* Now generate exp1 and exp2
862 */
863 exp1 = _gnutls_mpi_salloc_like (params[0]); /* like modulus */
864 if (exp1 == NULL)
865 {
866 gnutls_assert ();
867 result = GNUTLS_E_MEMORY_ERROR;
868 goto cleanup;
869 }
870
871 exp2 = _gnutls_mpi_salloc_like (params[0]);
872 if (exp2 == NULL)
873 {
874 gnutls_assert ();
875 result = GNUTLS_E_MEMORY_ERROR;
876 goto cleanup;
877 }
878
879 q1 = _gnutls_mpi_salloc_like (params[4]);
880 if (q1 == NULL)
881 {
882 gnutls_assert ();
883 result = GNUTLS_E_MEMORY_ERROR;
884 goto cleanup;
885 }
886
887 p1 = _gnutls_mpi_salloc_like (params[3]);
888 if (p1 == NULL)
889 {
890 gnutls_assert ();
891 result = GNUTLS_E_MEMORY_ERROR;
892 goto cleanup;
893 }
894
895 u = _gnutls_mpi_salloc_like (params[3]);
896 if (u == NULL)
897 {
898 gnutls_assert ();
899 result = GNUTLS_E_MEMORY_ERROR;
900 goto cleanup;
901 }
902
903 _gnutls_mpi_invm (u, params[4], params[3]);
904 /* inverse of q mod p */
905 _gnutls_mpi_print_lz (NULL, &size[5], u);
906 total += size[5];
907
908 _gnutls_mpi_sub_ui (p1, params[3], 1);
909 _gnutls_mpi_sub_ui (q1, params[4], 1);
910
911 _gnutls_mpi_mod (exp1, params[2], p1);
912 _gnutls_mpi_mod (exp2, params[2], q1);
913
914 /* calculate exp's size */
915 _gnutls_mpi_print_lz (NULL, &size[6], exp1);
916 total += size[6];
917
918 _gnutls_mpi_print_lz (NULL, &size[7], exp2);
919 total += size[7];
920
921 /* Encoding phase.
922 * allocate data enough to hold everything
923 */
924 all_data = gnutls_secure_malloc (total);
925 if (all_data == NULL)
926 {
927 gnutls_assert ();
928 result = GNUTLS_E_MEMORY_ERROR;
929 goto cleanup;
930 }
931
932 p = all_data;
933 m_data = p;
934 p += size[0];
935 pube_data = p;
936 p += size[1];
937 prie_data = p;
938 p += size[2];
939 p1_data = p;
940 p += size[3];
941 p2_data = p;
942 p += size[4];
943 u_data = p;
944 p += size[5];
945 exp1_data = p;
946 p += size[6];
947 exp2_data = p;
948
949 _gnutls_mpi_print_lz (m_data, &size[0], params[0]);
950 _gnutls_mpi_print_lz (pube_data, &size[1], params[1]);
951 _gnutls_mpi_print_lz (prie_data, &size[2], params[2]);
952 _gnutls_mpi_print_lz (p1_data, &size[3], params[3]);
953 _gnutls_mpi_print_lz (p2_data, &size[4], params[4]);
954 _gnutls_mpi_print_lz (u_data, &size[5], u);
955 _gnutls_mpi_print_lz (exp1_data, &size[6], exp1);
956 _gnutls_mpi_print_lz (exp2_data, &size[7], exp2);
957
958 /* Ok. Now we have the data. Create the asn1 structures
959 */
960
961 if ((result =
962 asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.RSAPrivateKey",
963 c2)) != ASN1_SUCCESS)
964 {
965 gnutls_assert ();
966 result = _gnutls_asn2err (result);
967 goto cleanup;
968 }
969
970 /* Write PRIME
971 */
972 if ((result = asn1_write_value (*c2, "modulus", m_data, size[0]))
973 != ASN1_SUCCESS)
974 {
975 gnutls_assert ();
976 result = _gnutls_asn2err (result);
977 goto cleanup;
978 }
979
980 if ((result = asn1_write_value (*c2, "publicExponent", pube_data, size[1]))
981 != ASN1_SUCCESS)
982 {
983 gnutls_assert ();
984 result = _gnutls_asn2err (result);
985 goto cleanup;
986 }
987
988 if ((result = asn1_write_value (*c2, "privateExponent", prie_data, size[2]))
989 != ASN1_SUCCESS)
990 {
991 gnutls_assert ();
992 result = _gnutls_asn2err (result);
993 goto cleanup;
994 }
995
996 if ((result = asn1_write_value (*c2, "prime1", p1_data, size[3]))
997 != ASN1_SUCCESS)
998 {
999 gnutls_assert ();
1000 result = _gnutls_asn2err (result);
1001 goto cleanup;
1002 }
1003
1004 if ((result = asn1_write_value (*c2, "prime2", p2_data, size[4]))
1005 != ASN1_SUCCESS)
1006 {
1007 gnutls_assert ();
1008 result = _gnutls_asn2err (result);
1009 goto cleanup;
1010 }
1011
1012 if ((result = asn1_write_value (*c2, "exponent1", exp1_data, size[6]))
1013 != ASN1_SUCCESS)
1014 {
1015 gnutls_assert ();
1016 result = _gnutls_asn2err (result);
1017 goto cleanup;
1018 }
1019
1020 if ((result = asn1_write_value (*c2, "exponent2", exp2_data, size[7]))
1021 != ASN1_SUCCESS)
1022 {
1023 gnutls_assert ();
1024 result = _gnutls_asn2err (result);
1025 goto cleanup;
1026 }
1027
1028 if ((result = asn1_write_value (*c2, "coefficient", u_data, size[5]))
1029 != ASN1_SUCCESS)
1030 {
1031 gnutls_assert ();
1032 result = _gnutls_asn2err (result);
1033 goto cleanup;
1034 }
1035
1036 _gnutls_mpi_release (&exp1);
1037 _gnutls_mpi_release (&exp2);
1038 _gnutls_mpi_release (&q1);
1039 _gnutls_mpi_release (&p1);
1040 _gnutls_mpi_release (&u);
1041 gnutls_free (all_data);
1042
1043 if ((result = asn1_write_value (*c2, "otherPrimeInfos",
1044 NULL, 0)) != ASN1_SUCCESS)
1045 {
1046 gnutls_assert ();
1047 result = _gnutls_asn2err (result);
1048 goto cleanup;
1049 }
1050
1051 if ((result = asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS)
1052 {
1053 gnutls_assert ();
1054 result = _gnutls_asn2err (result);
1055 goto cleanup;
1056 }
1057
1058 return 0;
1059
1060cleanup:_gnutls_mpi_release (&u);
1061 _gnutls_mpi_release (&exp1);
1062 _gnutls_mpi_release (&exp2);
1063 _gnutls_mpi_release (&q1);
1064 _gnutls_mpi_release (&p1);
1065 asn1_delete_structure (c2);
1066 gnutls_free (all_data);
1067
1068 return result;
1069}
1070
1071/* Encodes the DSA parameters into an ASN.1 DSAPrivateKey structure.
1072 */
1073int
1074_gnutls_asn1_encode_dsa (ASN1_TYPE * c2, mpi_t * params)
1075{
1076 int result, i;
1077 size_t size[DSA_PRIVATE_PARAMS], total;
1078 opaque *p_data, *q_data, *g_data, *x_data, *y_data;
1079 opaque *all_data = NULL, *p;
1080 opaque null = '\0';
1081
1082 /* Read all the sizes */
1083 total = 0;
1084 for (i = 0; i < DSA_PRIVATE_PARAMS; i++)
1085 {
1086 _gnutls_mpi_print_lz (NULL, &size[i], params[i]);
1087 total += size[i];
1088 }
1089
1090 /* Encoding phase.
1091 * allocate data enough to hold everything
1092 */
1093 all_data = gnutls_secure_malloc (total);
1094 if (all_data == NULL)
1095 {
1096 gnutls_assert ();
1097 result = GNUTLS_E_MEMORY_ERROR;
1098 goto cleanup;
1099 }
1100
1101 p = all_data;
1102 p_data = p;
1103 p += size[0];
1104 q_data = p;
1105 p += size[1];
1106 g_data = p;
1107 p += size[2];
1108 y_data = p;
1109 p += size[3];
1110 x_data = p;
1111
1112 _gnutls_mpi_print_lz (p_data, &size[0], params[0]);
1113 _gnutls_mpi_print_lz (q_data, &size[1], params[1]);
1114 _gnutls_mpi_print_lz (g_data, &size[2], params[2]);
1115 _gnutls_mpi_print_lz (y_data, &size[3], params[3]);
1116 _gnutls_mpi_print_lz (x_data, &size[4], params[4]);
1117
1118 /* Ok. Now we have the data. Create the asn1 structures
1119 */
1120
1121 if ((result =
1122 asn1_create_element (_gnutls_get_gnutls_asn (), "GNUTLS.DSAPrivateKey",
1123 c2)) != ASN1_SUCCESS)
1124 {
1125 gnutls_assert ();
1126 result = _gnutls_asn2err (result);
1127 goto cleanup;
1128 }
1129
1130 /* Write PRIME
1131 */
1132 if ((result = asn1_write_value (*c2, "p", p_data, size[0])) != ASN1_SUCCESS)
1133 {
1134 gnutls_assert ();
1135 result = _gnutls_asn2err (result);
1136 goto cleanup;
1137 }
1138
1139 if ((result = asn1_write_value (*c2, "q", q_data, size[1])) != ASN1_SUCCESS)
1140 {
1141 gnutls_assert ();
1142 result = _gnutls_asn2err (result);
1143 goto cleanup;
1144 }
1145
1146 if ((result = asn1_write_value (*c2, "g", g_data, size[2])) != ASN1_SUCCESS)
1147 {
1148 gnutls_assert ();
1149 result = _gnutls_asn2err (result);
1150 goto cleanup;
1151 }
1152
1153 if ((result = asn1_write_value (*c2, "Y", y_data, size[3])) != ASN1_SUCCESS)
1154 {
1155 gnutls_assert ();
1156 result = _gnutls_asn2err (result);
1157 goto cleanup;
1158 }
1159
1160 if ((result =
1161 asn1_write_value (*c2, "priv", x_data, size[4])) != ASN1_SUCCESS)
1162 {
1163 gnutls_assert ();
1164 result = _gnutls_asn2err (result);
1165 goto cleanup;
1166 }
1167
1168 gnutls_free (all_data);
1169
1170 if ((result = asn1_write_value (*c2, "version", &null, 1)) != ASN1_SUCCESS)
1171 {
1172 gnutls_assert ();
1173 result = _gnutls_asn2err (result);
1174 goto cleanup;
1175 }
1176
1177 return 0;
1178
1179cleanup:asn1_delete_structure (c2);
1180 gnutls_free (all_data);
1181
1182 return result;
1183}
1184
1185/**
1186 * gnutls_x509_privkey_generate - This function will generate a private key
1187 * @key: should contain a gnutls_x509_privkey_t structure
1188 * @algo: is one of RSA or DSA.
1189 * @bits: the size of the modulus
1190 * @flags: unused for now. Must be 0.
1191 *
1192 * This function will generate a random private key. Note that
1193 * this function must be called on an empty private key.
1194 *
1195 * Returns 0 on success or a negative value on error.
1196 *
1197 **/
1198int
1199gnutls_x509_privkey_generate (gnutls_x509_privkey_t key,
1200 gnutls_pk_algorithm_t algo,
1201 unsigned int bits, unsigned int flags)
1202{
1203 int ret, params_len;
1204 int i;
1205
1206 if (key == NULL)
1207 {
1208 gnutls_assert ();
1209 return GNUTLS_E_INVALID_REQUEST;
1210 }
1211
1212 switch (algo)
1213 {
1214 case GNUTLS_PK_RSA:
1215 ret = _gnutls_rsa_generate_params (key->params, &params_len, bits);
1216 if (ret < 0)
1217 {
1218 gnutls_assert ();
1219 return ret;
1220 }
1221
1222 if (!key->crippled)
1223 {
1224 ret = _gnutls_asn1_encode_rsa (&key->key, key->params);
1225 if (ret < 0)
1226 {
1227 gnutls_assert ();
1228 goto cleanup;
1229 }
1230 }
1231
1232 key->params_size = params_len;
1233 key->pk_algorithm = GNUTLS_PK_RSA;
1234
1235 break;
1236 default:
1237 gnutls_assert ();
1238 return GNUTLS_E_INVALID_REQUEST;
1239 }
1240
1241 return 0;
1242
1243cleanup:key->pk_algorithm = GNUTLS_PK_UNKNOWN;
1244 key->params_size = 0;
1245 for (i = 0; i < params_len; i++)
1246 _gnutls_mpi_release (&key->params[i]);
1247
1248 return ret;
1249}
1250
1251/**
1252 * gnutls_x509_privkey_get_key_id - Return unique ID of the key's parameters
1253 * @key: Holds the key
1254 * @flags: should be 0 for now
1255 * @output_data: will contain the key ID
1256 * @output_data_size: holds the size of output_data (and will be
1257 * replaced by the actual size of parameters)
1258 *
1259 * This function will return a unique ID the depends on the public key
1260 * parameters. This ID can be used in checking whether a certificate
1261 * corresponds to the given key.
1262 *
1263 * If the buffer provided is not long enough to hold the output, then
1264 * *output_data_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
1265 * be returned. The output will normally be a SHA-1 hash output,
1266 * which is 20 bytes.
1267 *
1268 * Return value: In case of failure a negative value will be
1269 * returned, and 0 on success.
1270 *
1271 **/
1272int
1273gnutls_x509_privkey_get_key_id (gnutls_x509_privkey_t key,
1274 unsigned int flags,
1275 unsigned char *output_data,
1276 size_t * output_data_size)
1277{
1278 int result;
1279 GNUTLS_HASH_HANDLE hd;
1280 gnutls_datum_t der = { NULL,
1281 0
1282 };
1283
1284 if (key == NULL || key->crippled)
1285 {
1286 gnutls_assert ();
1287 return GNUTLS_E_INVALID_REQUEST;
1288 }
1289
1290 if (*output_data_size < 20)
1291 {
1292 gnutls_assert ();
1293 *output_data_size = 20;
1294 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1295 }
1296
1297 if (key->pk_algorithm == GNUTLS_PK_RSA)
1298 {
1299 result = _gnutls_x509_write_rsa_params (key->params, key->params_size,
1300 &der);
1301 if (result < 0)
1302 {
1303 gnutls_assert ();
1304 goto cleanup;
1305 }
1306 }
1307 else
1308 return GNUTLS_E_INTERNAL_ERROR;
1309
1310 hd = _gnutls_hash_init (GNUTLS_MAC_SHA1);
1311 if (hd == GNUTLS_HASH_FAILED)
1312 {
1313 gnutls_assert ();
1314 result = GNUTLS_E_INTERNAL_ERROR;
1315 goto cleanup;
1316 }
1317
1318 _gnutls_hash (hd, der.data, der.size);
1319
1320 _gnutls_hash_deinit (hd, output_data);
1321 *output_data_size = 20;
1322
1323 result = 0;
1324
1325cleanup:
1326
1327 _gnutls_free_datum (&der);
1328 return result;
1329}
1330
1331#ifdef ENABLE_PKI
1332
1333/**
1334 * gnutls_x509_privkey_sign_data - This function will sign the given data using the private key params
1335 * @key: Holds the key
1336 * @digest: should be MD5 or SHA1
1337 * @flags: should be 0 for now
1338 * @data: holds the data to be signed
1339 * @signature: will contain the signature
1340 * @signature_size: holds the size of signature (and will be replaced
1341 * by the new size)
1342 *
1343 * This function will sign the given data using a signature algorithm
1344 * supported by the private key. Signature algorithms are always used
1345 * together with a hash functions. Different hash functions may be
1346 * used for the RSA algorithm, but only SHA-1 for the DSA keys.
1347 *
1348 * If the buffer provided is not long enough to hold the output, then
1349 * *signature_size is updated and GNUTLS_E_SHORT_MEMORY_BUFFER will
1350 * be returned.
1351 *
1352 * In case of failure a negative value will be returned, and
1353 * 0 on success.
1354 *
1355 **/
1356int
1357gnutls_x509_privkey_sign_data (gnutls_x509_privkey_t key,
1358 gnutls_digest_algorithm_t digest,
1359 unsigned int flags,
1360 const gnutls_datum_t * data,
1361 void *signature, size_t * signature_size)
1362{
1363 int result;
1364 gnutls_datum_t sig = { NULL, 0 };
1365
1366 if (key == NULL)
1367 {
1368 gnutls_assert ();
1369 return GNUTLS_E_INVALID_REQUEST;
1370 }
1371
1372 result = _gnutls_x509_sign (data, digest, key, &sig);
1373 if (result < 0)
1374 {
1375 gnutls_assert ();
1376 return result;
1377 }
1378
1379 if (*signature_size < sig.size)
1380 {
1381 *signature_size = sig.size;
1382 _gnutls_free_datum (&sig);
1383 return GNUTLS_E_SHORT_MEMORY_BUFFER;
1384 }
1385
1386 *signature_size = sig.size;
1387 memcpy (signature, sig.data, sig.size);
1388
1389 _gnutls_free_datum (&sig);
1390
1391 return 0;
1392}
1393
1394/**
1395 * gnutls_x509_privkey_sign_hash - This function will sign the given data using the private key params
1396 * @key: Holds the key
1397 * @hash: holds the data to be signed
1398 * @signature: will contain newly allocated signature
1399 *
1400 * This function will sign the given hash using the private key.
1401 *
1402 * Return value: In case of failure a negative value will be returned,
1403 * and 0 on success.
1404 **/
1405int
1406gnutls_x509_privkey_sign_hash (gnutls_x509_privkey_t key,
1407 const gnutls_datum_t * hash,
1408 gnutls_datum_t * signature)
1409{
1410 int result;
1411
1412 if (key == NULL)
1413 {
1414 gnutls_assert ();
1415 return GNUTLS_E_INVALID_REQUEST;
1416 }
1417
1418 result = _gnutls_sign (key->pk_algorithm, key->params,
1419 key->params_size, hash, signature);
1420 if (result < 0)
1421 {
1422 gnutls_assert ();
1423 return result;
1424 }
1425
1426 return 0;
1427}
1428
1429/**
1430 * gnutls_x509_privkey_verify_data - This function will verify the given signed data.
1431 * @key: Holds the key
1432 * @flags: should be 0 for now
1433 * @data: holds the data to be signed
1434 * @signature: contains the signature
1435 *
1436 * This function will verify the given signed data, using the parameters in the
1437 * private key.
1438 *
1439 * In case of a verification failure 0 is returned, and
1440 * 1 on success.
1441 *
1442 **/
1443int
1444gnutls_x509_privkey_verify_data (gnutls_x509_privkey_t key,
1445 unsigned int flags,
1446 const gnutls_datum_t * data,
1447 const gnutls_datum_t * signature)
1448{
1449 int result;
1450
1451 if (key == NULL)
1452 {
1453 gnutls_assert ();
1454 return GNUTLS_E_INVALID_REQUEST;
1455 }
1456
1457 result = _gnutls_x509_privkey_verify_signature (data, signature, key);
1458 if (result < 0)
1459 {
1460 gnutls_assert ();
1461 return 0;
1462 }
1463
1464 return result;
1465}
1466
1467/**
1468 * gnutls_x509_privkey_fix - This function will recalculate some parameters of the key.
1469 * @key: Holds the key
1470 *
1471 * This function will recalculate the secondary parameters in a key.
1472 * In RSA keys, this can be the coefficient and exponent1,2.
1473 *
1474 * Return value: In case of failure a negative value will be
1475 * returned, and 0 on success.
1476 *
1477 **/
1478int
1479gnutls_x509_privkey_fix (gnutls_x509_privkey_t key)
1480{
1481 int ret;
1482
1483 if (key == NULL)
1484 {
1485 gnutls_assert ();
1486 return GNUTLS_E_INVALID_REQUEST;
1487 }
1488
1489 if (!key->crippled)
1490 asn1_delete_structure (&key->key);
1491 switch (key->pk_algorithm)
1492 {
1493 case GNUTLS_PK_RSA:
1494 ret = _gnutls_asn1_encode_rsa (&key->key, key->params);
1495 if (ret < 0)
1496 {
1497 gnutls_assert ();
1498 return ret;
1499 }
1500 break;
1501 default:
1502 gnutls_assert ();
1503 return GNUTLS_E_INVALID_REQUEST;
1504 }
1505
1506 return 0;
1507}
1508
1509#endif
diff --git a/src/daemon/https/x509/x509_verify.c b/src/daemon/https/x509/x509_verify.c
new file mode 100644
index 00000000..f01fed9d
--- /dev/null
+++ b/src/daemon/https/x509/x509_verify.c
@@ -0,0 +1,1037 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* All functions which relate to X.509 certificate verification stuff are
26 * included here
27 */
28
29#include <gnutls_int.h>
30#include <gnutls_errors.h>
31#include <gnutls_cert.h>
32#include <libtasn1.h>
33#include <gnutls_global.h>
34#include <gnutls_num.h> /* MAX */
35#include <gnutls_sig.h>
36#include <gnutls_str.h>
37#include <gnutls_datum.h>
38#include <dn.h>
39#include <x509.h>
40#include <mpi.h>
41#include <common.h>
42#include <verify.h>
43
44static int _gnutls_verify_certificate2 (gnutls_x509_crt_t cert,
45 const gnutls_x509_crt_t * trusted_cas,
46 int tcas_size,
47 unsigned int flags,
48 unsigned int *output);
49int _gnutls_x509_verify_signature (const gnutls_datum_t * signed_data,
50 const gnutls_datum_t * signature,
51 gnutls_x509_crt_t issuer);
52
53static
54 int is_crl_issuer (gnutls_x509_crl_t crl, gnutls_x509_crt_t issuer_cert);
55static int _gnutls_verify_crl2 (gnutls_x509_crl_t crl,
56 const gnutls_x509_crt_t * trusted_cas,
57 int tcas_size,
58 unsigned int flags, unsigned int *output);
59
60/* Checks if the issuer of a certificate is a
61 * Certificate Authority, or if the certificate is the same
62 * as the issuer (and therefore it doesn't need to be a CA).
63 *
64 * Returns true or false, if the issuer is a CA,
65 * or not.
66 */
67static int
68check_if_ca (gnutls_x509_crt_t cert,
69 gnutls_x509_crt_t issuer, unsigned int flags)
70{
71 gnutls_datum_t cert_signed_data = { NULL,
72 0
73 };
74 gnutls_datum_t issuer_signed_data = { NULL,
75 0
76 };
77 gnutls_datum_t cert_signature = { NULL,
78 0
79 };
80 gnutls_datum_t issuer_signature = { NULL,
81 0
82 };
83 int result;
84
85 /* Check if the issuer is the same with the
86 * certificate. This is added in order for trusted
87 * certificates to be able to verify themselves.
88 */
89
90 result = _gnutls_x509_get_signed_data (issuer->cert, "tbsCertificate",
91 &issuer_signed_data);
92 if (result < 0)
93 {
94 gnutls_assert ();
95 goto cleanup;
96 }
97
98 result = _gnutls_x509_get_signed_data (cert->cert, "tbsCertificate",
99 &cert_signed_data);
100 if (result < 0)
101 {
102 gnutls_assert ();
103 goto cleanup;
104 }
105
106 result = _gnutls_x509_get_signature (issuer->cert, "signature",
107 &issuer_signature);
108 if (result < 0)
109 {
110 gnutls_assert ();
111 goto cleanup;
112 }
113
114 result =
115 _gnutls_x509_get_signature (cert->cert, "signature", &cert_signature);
116 if (result < 0)
117 {
118 gnutls_assert ();
119 goto cleanup;
120 }
121
122 /* If the subject certificate is the same as the issuer
123 * return true.
124 */
125 if (!(flags & GNUTLS_VERIFY_DO_NOT_ALLOW_SAME))
126 if (cert_signed_data.size == issuer_signed_data.size)
127 {
128 if ((memcmp (cert_signed_data.data, issuer_signed_data.data,
129 cert_signed_data.size) == 0) && (cert_signature.size
130 ==
131 issuer_signature.size)
132 &&
133 (memcmp
134 (cert_signature.data, issuer_signature.data,
135 cert_signature.size) == 0))
136 {
137 result = 1;
138 goto cleanup;
139 }
140 }
141
142 if (gnutls_x509_crt_get_ca_status (issuer, NULL) == 1)
143 {
144 result = 1;
145 goto cleanup;
146 }
147 else
148 gnutls_assert ();
149
150 result = 0;
151
152cleanup:_gnutls_free_datum (&cert_signed_data);
153 _gnutls_free_datum (&issuer_signed_data);
154 _gnutls_free_datum (&cert_signature);
155 _gnutls_free_datum (&issuer_signature);
156 return result;
157}
158
159/* This function checks if 'certs' issuer is 'issuer_cert'.
160 * This does a straight (DER) compare of the issuer/subject fields in
161 * the given certificates.
162 *
163 * Returns 1 if they match and zero if they don't match. Otherwise
164 * a negative value is returned to indicate error.
165 */
166static int
167is_issuer (gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer_cert)
168{
169 gnutls_datum_t dn1 = { NULL,
170 0
171 }, dn2 =
172 {
173 NULL, 0};
174 int ret;
175
176 ret = gnutls_x509_crt_get_raw_issuer_dn (cert, &dn1);
177 if (ret < 0)
178 {
179 gnutls_assert ();
180 goto cleanup;
181 }
182
183 ret = gnutls_x509_crt_get_raw_dn (issuer_cert, &dn2);
184 if (ret < 0)
185 {
186 gnutls_assert ();
187 goto cleanup;
188 }
189
190 ret = _gnutls_x509_compare_raw_dn (&dn1, &dn2);
191
192cleanup:_gnutls_free_datum (&dn1);
193 _gnutls_free_datum (&dn2);
194 return ret;
195
196}
197
198static inline gnutls_x509_crt_t
199find_issuer (gnutls_x509_crt_t cert,
200 const gnutls_x509_crt_t * trusted_cas, int tcas_size)
201{
202 int i;
203
204 /* this is serial search.
205 */
206
207 for (i = 0; i < tcas_size; i++)
208 {
209 if (is_issuer (cert, trusted_cas[i]) == 1)
210 return trusted_cas[i];
211 }
212
213 gnutls_assert ();
214 return NULL;
215}
216
217/*
218 * Verifies the given certificate again a certificate list of
219 * trusted CAs.
220 *
221 * Returns only 0 or 1. If 1 it means that the certificate
222 * was successfuly verified.
223 *
224 * 'flags': an OR of the gnutls_certificate_verify_flags enumeration.
225 *
226 * Output will hold some extra information about the verification
227 * procedure.
228 */
229static int
230_gnutls_verify_certificate2 (gnutls_x509_crt_t cert,
231 const gnutls_x509_crt_t * trusted_cas,
232 int tcas_size,
233 unsigned int flags, unsigned int *output)
234{
235 gnutls_datum_t cert_signed_data = { NULL,
236 0
237 };
238 gnutls_datum_t cert_signature = { NULL,
239 0
240 };
241 gnutls_x509_crt_t issuer;
242 int ret, issuer_version, result;
243
244 if (output)
245 *output = 0;
246
247 if (tcas_size >= 1)
248 issuer = find_issuer (cert, trusted_cas, tcas_size);
249 else
250 {
251 gnutls_assert ();
252 if (output)
253 *output |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
254 return 0;
255 }
256
257 /* issuer is not in trusted certificate
258 * authorities.
259 */
260 if (issuer == NULL)
261 {
262 if (output)
263 *output |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
264 gnutls_assert ();
265 return 0;
266 }
267
268 issuer_version = gnutls_x509_crt_get_version (issuer);
269 if (issuer_version < 0)
270 {
271 gnutls_assert ();
272 return issuer_version;
273 }
274
275 if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN) && !((flags
276 &
277 GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT)
278 && issuer_version == 1))
279 {
280 if (check_if_ca (cert, issuer, flags) == 0)
281 {
282 gnutls_assert ();
283 if (output)
284 *output |= GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID;
285 return 0;
286 }
287 }
288
289 result = _gnutls_x509_get_signed_data (cert->cert, "tbsCertificate",
290 &cert_signed_data);
291 if (result < 0)
292 {
293 gnutls_assert ();
294 goto cleanup;
295 }
296
297 result =
298 _gnutls_x509_get_signature (cert->cert, "signature", &cert_signature);
299 if (result < 0)
300 {
301 gnutls_assert ();
302 goto cleanup;
303 }
304
305 ret = _gnutls_x509_verify_signature (&cert_signed_data, &cert_signature,
306 issuer);
307 if (ret < 0)
308 {
309 gnutls_assert ();
310 }
311 else if (ret == 0)
312 {
313 gnutls_assert ();
314 /* error. ignore it */
315 if (output)
316 *output |= GNUTLS_CERT_INVALID;
317 ret = 0;
318 }
319
320 /* If the certificate is not self signed check if the algorithms
321 * used are secure. If the certificate is self signed it doesn't
322 * really matter.
323 */
324 if (is_issuer (cert, cert) == 0)
325 {
326 int sigalg;
327
328 sigalg = gnutls_x509_crt_get_signature_algorithm (cert);
329
330 if (((sigalg == GNUTLS_SIGN_RSA_MD2) && !(flags
331 &
332 GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2))
333 || ((sigalg == GNUTLS_SIGN_RSA_MD5)
334 && !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5)))
335 {
336 if (output)
337 *output |= GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID;
338 }
339 }
340
341 result = ret;
342
343cleanup:_gnutls_free_datum (&cert_signed_data);
344 _gnutls_free_datum (&cert_signature);
345
346 return result;
347}
348
349/**
350 * gnutls_x509_crt_check_issuer - This function checks if the certificate given has the given issuer
351 * @cert: is the certificate to be checked
352 * @issuer: is the certificate of a possible issuer
353 *
354 * This function will check if the given certificate was issued by the
355 * given issuer. It will return true (1) if the given certificate is issued
356 * by the given issuer, and false (0) if not.
357 *
358 * A negative value is returned in case of an error.
359 *
360 **/
361int
362gnutls_x509_crt_check_issuer (gnutls_x509_crt_t cert,
363 gnutls_x509_crt_t issuer)
364{
365 return is_issuer (cert, issuer);
366}
367
368/* The algorithm used is:
369 * 1. Check last certificate in the chain. If it is not verified return.
370 * 2. Check if any certificates in the chain are revoked. If yes return.
371 * 3. Try to verify the rest of certificates in the chain. If not verified return.
372 * 4. Return 0.
373 *
374 * Note that the return value is an OR of GNUTLS_CERT_* elements.
375 *
376 * This function verifies a X.509 certificate list. The certificate list should
377 * lead to a trusted CA in order to be trusted.
378 */
379static unsigned int
380_gnutls_x509_verify_certificate (const gnutls_x509_crt_t * certificate_list,
381 int clist_size,
382 const gnutls_x509_crt_t * trusted_cas,
383 int tcas_size,
384 const gnutls_x509_crl_t * CRLs,
385 int crls_size, unsigned int flags)
386{
387 int i = 0, ret;
388 unsigned int status = 0, output;
389
390 /* Verify the last certificate in the certificate path
391 * against the trusted CA certificate list.
392 *
393 * If no CAs are present returns CERT_INVALID. Thus works
394 * in self signed etc certificates.
395 */
396 ret = _gnutls_verify_certificate2 (certificate_list[clist_size - 1],
397 trusted_cas, tcas_size, flags, &output);
398
399 if (ret == 0)
400 {
401 /* if the last certificate in the certificate
402 * list is invalid, then the certificate is not
403 * trusted.
404 */
405 gnutls_assert ();
406 status |= output;
407 status |= GNUTLS_CERT_INVALID;
408 return status;
409 }
410
411 /* Check for revoked certificates in the chain
412 */
413#ifdef ENABLE_PKI
414 for (i = 0; i < clist_size; i++)
415 {
416 ret = gnutls_x509_crt_check_revocation (certificate_list[i],
417 CRLs, crls_size);
418 if (ret == 1)
419 { /* revoked */
420 status |= GNUTLS_CERT_REVOKED;
421 status |= GNUTLS_CERT_INVALID;
422 return status;
423 }
424 }
425#endif
426
427 /* Check if the last certificate in the path is self signed.
428 * In that case ignore it (a certificate is trusted only if it
429 * leads to a trusted party by us, not the server's).
430 */
431 if (gnutls_x509_crt_check_issuer (certificate_list[clist_size - 1],
432 certificate_list[clist_size - 1]) > 0
433 && clist_size > 0)
434 {
435 clist_size--;
436 }
437
438 /* Verify the certificate path (chain)
439 */
440 for (i = clist_size - 1; i > 0; i--)
441 {
442 if (i - 1 < 0)
443 break;
444
445 /* note that here we disable this V1 CA flag. So that no version 1
446 * certificates can exist in a supplied chain.
447 */
448 if (!(flags & GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT))
449 flags ^= GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT;
450 if ((ret = _gnutls_verify_certificate2 (certificate_list[i - 1],
451 &certificate_list[i], 1, flags,
452 NULL)) == 0)
453 {
454 status |= GNUTLS_CERT_INVALID;
455 return status;
456 }
457 }
458
459 return 0;
460}
461
462/* Reads the digest information.
463 * we use DER here, although we should use BER. It works fine
464 * anyway.
465 */
466static int
467decode_ber_digest_info (const gnutls_datum_t * info,
468 gnutls_mac_algorithm_t * hash,
469 opaque * digest, int *digest_size)
470{
471 ASN1_TYPE dinfo = ASN1_TYPE_EMPTY;
472 int result;
473 char str[1024];
474 int len;
475
476 if ((result = asn1_create_element (_gnutls_get_gnutls_asn (),
477 "GNUTLS.DigestInfo",
478 &dinfo)) != ASN1_SUCCESS)
479 {
480 gnutls_assert ();
481 return _gnutls_asn2err (result);
482 }
483
484 result = asn1_der_decoding (&dinfo, info->data, info->size, NULL);
485 if (result != ASN1_SUCCESS)
486 {
487 gnutls_assert ();
488 asn1_delete_structure (&dinfo);
489 return _gnutls_asn2err (result);
490 }
491
492 len = sizeof (str) - 1;
493 result = asn1_read_value (dinfo, "digestAlgorithm.algorithm", str, &len);
494 if (result != ASN1_SUCCESS)
495 {
496 gnutls_assert ();
497 asn1_delete_structure (&dinfo);
498 return _gnutls_asn2err (result);
499 }
500
501 *hash = _gnutls_x509_oid2mac_algorithm (str);
502
503 if (*hash == GNUTLS_MAC_UNKNOWN)
504 {
505
506 _gnutls_x509_log ("verify.c: HASH OID: %s\n", str);
507
508 gnutls_assert ();
509 asn1_delete_structure (&dinfo);
510 return GNUTLS_E_UNKNOWN_ALGORITHM;
511 }
512
513 len = sizeof (str) - 1;
514 result = asn1_read_value (dinfo, "digestAlgorithm.parameters", str, &len);
515 /* To avoid permitting garbage in the parameters field, either the
516 parameters field is not present, or it contains 0x05 0x00. */
517 if (!
518 (result == ASN1_ELEMENT_NOT_FOUND
519 || (result == ASN1_SUCCESS && len == 2 && str[0] == 0x05
520 && str[1] == 0x00)))
521 {
522 gnutls_assert ();
523 asn1_delete_structure (&dinfo);
524 return GNUTLS_E_ASN1_GENERIC_ERROR;
525 }
526
527 result = asn1_read_value (dinfo, "digest", digest, digest_size);
528 if (result != ASN1_SUCCESS)
529 {
530 gnutls_assert ();
531 asn1_delete_structure (&dinfo);
532 return _gnutls_asn2err (result);
533 }
534
535 asn1_delete_structure (&dinfo);
536
537 return 0;
538}
539
540/* if hash==MD5 then we do RSA-MD5
541 * if hash==SHA then we do RSA-SHA
542 * params[0] is modulus
543 * params[1] is public key
544 */
545static int
546_pkcs1_rsa_verify_sig (const gnutls_datum_t * text,
547 const gnutls_datum_t * signature,
548 mpi_t * params, int params_len)
549{
550 gnutls_mac_algorithm_t hash = GNUTLS_MAC_UNKNOWN;
551 int ret;
552 opaque digest[MAX_HASH_SIZE], md[MAX_HASH_SIZE];
553 int digest_size;
554 GNUTLS_HASH_HANDLE hd;
555 gnutls_datum_t decrypted;
556
557 ret =
558 _gnutls_pkcs1_rsa_decrypt (&decrypted, signature, params, params_len, 1);
559 if (ret < 0)
560 {
561 gnutls_assert ();
562 return ret;
563 }
564
565 /* decrypted is a BER encoded data of type DigestInfo
566 */
567
568 digest_size = sizeof (digest);
569 if ((ret = decode_ber_digest_info (&decrypted, &hash, digest, &digest_size))
570 != 0)
571 {
572 gnutls_assert ();
573 _gnutls_free_datum (&decrypted);
574 return ret;
575 }
576
577 _gnutls_free_datum (&decrypted);
578
579 if (digest_size != _gnutls_hash_get_algo_len (hash))
580 {
581 gnutls_assert ();
582 return GNUTLS_E_ASN1_GENERIC_ERROR;
583 }
584
585 hd = _gnutls_hash_init (hash);
586 if (hd == NULL)
587 {
588 gnutls_assert ();
589 return GNUTLS_E_HASH_FAILED;
590 }
591
592 _gnutls_hash (hd, text->data, text->size);
593 _gnutls_hash_deinit (hd, md);
594
595 if (memcmp (md, digest, digest_size) != 0)
596 {
597 gnutls_assert ();
598 return GNUTLS_E_PK_SIG_VERIFY_FAILED;
599 }
600
601 return 0;
602}
603
604/* Hashes input data and verifies a DSA signature.
605 */
606static int
607dsa_verify_sig (const gnutls_datum_t * text,
608 const gnutls_datum_t * signature,
609 mpi_t * params, int params_len)
610{
611 int ret;
612 opaque _digest[MAX_HASH_SIZE];
613 gnutls_datum_t digest;
614 GNUTLS_HASH_HANDLE hd;
615
616 hd = _gnutls_hash_init (GNUTLS_MAC_SHA1);
617 if (hd == NULL)
618 {
619 gnutls_assert ();
620 return GNUTLS_E_HASH_FAILED;
621 }
622
623 _gnutls_hash (hd, text->data, text->size);
624 _gnutls_hash_deinit (hd, _digest);
625
626 digest.data = _digest;
627 digest.size = 20;
628
629 ret = _gnutls_dsa_verify (&digest, signature, params, params_len);
630
631 return ret;
632}
633
634/* Verifies the signature data, and returns 0 if not verified,
635 * or 1 otherwise.
636 */
637static int
638verify_sig (const gnutls_datum_t * tbs,
639 const gnutls_datum_t * signature,
640 gnutls_pk_algorithm_t pk,
641 mpi_t * issuer_params, int issuer_params_size)
642{
643
644 switch (pk)
645 {
646 case GNUTLS_PK_RSA:
647
648 if (_pkcs1_rsa_verify_sig
649 (tbs, signature, issuer_params, issuer_params_size) != 0)
650 {
651 gnutls_assert ();
652 return 0;
653 }
654
655 return 1;
656 break;
657
658 default:
659 gnutls_assert ();
660 return GNUTLS_E_INTERNAL_ERROR;
661
662 }
663}
664
665/* verifies if the certificate is properly signed.
666 * returns 0 on failure and 1 on success.
667 *
668 * 'tbs' is the signed data
669 * 'signature' is the signature!
670 */
671int
672_gnutls_x509_verify_signature (const gnutls_datum_t * tbs,
673 const gnutls_datum_t * signature,
674 gnutls_x509_crt_t issuer)
675{
676 mpi_t issuer_params[MAX_PUBLIC_PARAMS_SIZE];
677 int ret, issuer_params_size, i;
678
679 /* Read the MPI parameters from the issuer's certificate.
680 */
681 issuer_params_size = MAX_PUBLIC_PARAMS_SIZE;
682 ret =
683 _gnutls_x509_crt_get_mpis (issuer, issuer_params, &issuer_params_size);
684 if (ret < 0)
685 {
686 gnutls_assert ();
687 return ret;
688 }
689
690 ret = verify_sig (tbs, signature, gnutls_x509_crt_get_pk_algorithm (issuer,
691 NULL),
692 issuer_params, issuer_params_size);
693 if (ret < 0)
694 {
695 gnutls_assert ();
696 }
697
698 /* release all allocated MPIs
699 */
700 for (i = 0; i < issuer_params_size; i++)
701 {
702 _gnutls_mpi_release (&issuer_params[i]);
703 }
704
705 return ret;
706}
707
708/* verifies if the certificate is properly signed.
709 * returns 0 on failure and 1 on success.
710 *
711 * 'tbs' is the signed data
712 * 'signature' is the signature!
713 */
714int
715_gnutls_x509_privkey_verify_signature (const gnutls_datum_t * tbs,
716 const gnutls_datum_t * signature,
717 gnutls_x509_privkey_t issuer)
718{
719 int ret;
720
721 ret = verify_sig (tbs, signature, issuer->pk_algorithm, issuer->params,
722 issuer->params_size);
723 if (ret < 0)
724 {
725 gnutls_assert ();
726 }
727
728 return ret;
729}
730
731/**
732 * gnutls_x509_crt_list_verify - This function verifies the given certificate list
733 * @cert_list: is the certificate list to be verified
734 * @cert_list_length: holds the number of certificate in cert_list
735 * @CA_list: is the CA list which will be used in verification
736 * @CA_list_length: holds the number of CA certificate in CA_list
737 * @CRL_list: holds a list of CRLs.
738 * @CRL_list_length: the length of CRL list.
739 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
740 * @verify: will hold the certificate verification output.
741 *
742 * This function will try to verify the given certificate list and return its status.
743 * Note that expiration and activation dates are not checked
744 * by this function, you should check them using the appropriate functions.
745 *
746 * If no flags are specified (0), this function will use the
747 * basicConstraints (2.5.29.19) PKIX extension. This means that only a certificate
748 * authority is allowed to sign a certificate.
749 *
750 * You must also check the peer's name in order to check if the verified
751 * certificate belongs to the actual peer.
752 *
753 * The certificate verification output will be put in @verify and will be
754 * one or more of the gnutls_certificate_status_t enumerated elements bitwise or'd.
755 * For a more detailed verification status use gnutls_x509_crt_verify() per list
756 * element.
757 *
758 * GNUTLS_CERT_INVALID: the certificate chain is not valid.
759 *
760 * GNUTLS_CERT_REVOKED: a certificate in the chain has been revoked.
761 *
762 * Returns 0 on success and a negative value in case of an error.
763 *
764 **/
765int
766gnutls_x509_crt_list_verify (const gnutls_x509_crt_t * cert_list,
767 int cert_list_length,
768 const gnutls_x509_crt_t * CA_list,
769 int CA_list_length,
770 const gnutls_x509_crl_t * CRL_list,
771 int CRL_list_length,
772 unsigned int flags, unsigned int *verify)
773{
774 if (cert_list == NULL || cert_list_length == 0)
775 return GNUTLS_E_NO_CERTIFICATE_FOUND;
776
777 /* Verify certificate
778 */
779 *verify = _gnutls_x509_verify_certificate (cert_list, cert_list_length,
780 CA_list, CA_list_length,
781 CRL_list, CRL_list_length,
782 flags);
783
784 return 0;
785}
786
787/**
788 * gnutls_x509_crt_verify - This function verifies the given certificate against a given trusted one
789 * @cert: is the certificate to be verified
790 * @CA_list: is one certificate that is considered to be trusted one
791 * @CA_list_length: holds the number of CA certificate in CA_list
792 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
793 * @verify: will hold the certificate verification output.
794 *
795 * This function will try to verify the given certificate and return its status.
796 * The verification output in this functions cannot be GNUTLS_CERT_NOT_VALID.
797 *
798 * Returns 0 on success and a negative value in case of an error.
799 *
800 **/
801int
802gnutls_x509_crt_verify (gnutls_x509_crt_t cert,
803 const gnutls_x509_crt_t * CA_list,
804 int CA_list_length,
805 unsigned int flags, unsigned int *verify)
806{
807 int ret;
808 /* Verify certificate
809 */
810 ret = _gnutls_verify_certificate2 (cert, CA_list, CA_list_length, flags,
811 verify);
812 if (ret < 0)
813 {
814 gnutls_assert ();
815 return ret;
816 }
817
818 return 0;
819}
820
821#ifdef ENABLE_PKI
822
823/**
824 * gnutls_x509_crl_check_issuer - This function checks if the CRL given has the given issuer
825 * @crl: is the CRL to be checked
826 * @issuer: is the certificate of a possible issuer
827 *
828 * This function will check if the given CRL was issued by the
829 * given issuer certificate. It will return true (1) if the given CRL was issued
830 * by the given issuer, and false (0) if not.
831 *
832 * A negative value is returned in case of an error.
833 *
834 **/
835int
836gnutls_x509_crl_check_issuer (gnutls_x509_crl_t cert,
837 gnutls_x509_crt_t issuer)
838{
839 return is_crl_issuer (cert, issuer);
840}
841
842/**
843 * gnutls_x509_crl_verify - This function verifies the given crl against a given trusted one
844 * @crl: is the crl to be verified
845 * @CA_list: is a certificate list that is considered to be trusted one
846 * @CA_list_length: holds the number of CA certificates in CA_list
847 * @flags: Flags that may be used to change the verification algorithm. Use OR of the gnutls_certificate_verify_flags enumerations.
848 * @verify: will hold the crl verification output.
849 *
850 * This function will try to verify the given crl and return its status.
851 * See gnutls_x509_crt_list_verify() for a detailed description of
852 * return values.
853 *
854 * Returns 0 on success and a negative value in case of an error.
855 *
856 **/
857int
858gnutls_x509_crl_verify (gnutls_x509_crl_t crl,
859 const gnutls_x509_crt_t * CA_list,
860 int CA_list_length, unsigned int flags,
861 unsigned int *verify)
862{
863 int ret;
864 /* Verify crl
865 */
866 ret = _gnutls_verify_crl2 (crl, CA_list, CA_list_length, flags, verify);
867 if (ret < 0)
868 {
869 gnutls_assert ();
870 return ret;
871 }
872
873 return 0;
874}
875
876/* The same as above, but here we've got a CRL.
877 */
878static int
879is_crl_issuer (gnutls_x509_crl_t crl, gnutls_x509_crt_t issuer_cert)
880{
881 gnutls_datum_t dn1 = { NULL, 0 }, dn2 =
882 {
883 NULL, 0};
884 int ret;
885
886 ret = _gnutls_x509_crl_get_raw_issuer_dn (crl, &dn1);
887 if (ret < 0)
888 {
889 gnutls_assert ();
890 goto cleanup;
891 }
892
893 ret = gnutls_x509_crt_get_raw_dn (issuer_cert, &dn2);
894 if (ret < 0)
895 {
896 gnutls_assert ();
897 return ret;
898 }
899
900 ret = _gnutls_x509_compare_raw_dn (&dn1, &dn2);
901
902cleanup:
903 _gnutls_free_datum (&dn1);
904 _gnutls_free_datum (&dn2);
905
906 return ret;
907}
908
909static inline gnutls_x509_crt_t
910find_crl_issuer (gnutls_x509_crl_t crl,
911 const gnutls_x509_crt_t * trusted_cas, int tcas_size)
912{
913 int i;
914
915 /* this is serial search.
916 */
917
918 for (i = 0; i < tcas_size; i++)
919 {
920 if (is_crl_issuer (crl, trusted_cas[i]) == 1)
921 return trusted_cas[i];
922 }
923
924 gnutls_assert ();
925 return NULL;
926}
927
928/*
929 * Returns only 0 or 1. If 1 it means that the CRL
930 * was successfuly verified.
931 *
932 * 'flags': an OR of the gnutls_certificate_verify_flags enumeration.
933 *
934 * Output will hold information about the verification
935 * procedure.
936 */
937static int
938_gnutls_verify_crl2 (gnutls_x509_crl_t crl,
939 const gnutls_x509_crt_t * trusted_cas,
940 int tcas_size, unsigned int flags, unsigned int *output)
941{
942 /* CRL is ignored for now */
943 gnutls_datum_t crl_signed_data = { NULL, 0 };
944 gnutls_datum_t crl_signature = { NULL, 0 };
945 gnutls_x509_crt_t issuer;
946 int ret, result;
947
948 if (output)
949 *output = 0;
950
951 if (tcas_size >= 1)
952 issuer = find_crl_issuer (crl, trusted_cas, tcas_size);
953 else
954 {
955 gnutls_assert ();
956 if (output)
957 *output |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
958 return 0;
959 }
960
961 /* issuer is not in trusted certificate
962 * authorities.
963 */
964 if (issuer == NULL)
965 {
966 gnutls_assert ();
967 if (output)
968 *output |= GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_INVALID;
969 return 0;
970 }
971
972 if (!(flags & GNUTLS_VERIFY_DISABLE_CA_SIGN))
973 {
974 if (gnutls_x509_crt_get_ca_status (issuer, NULL) != 1)
975 {
976 gnutls_assert ();
977 if (output)
978 *output |= GNUTLS_CERT_SIGNER_NOT_CA | GNUTLS_CERT_INVALID;
979 return 0;
980 }
981 }
982
983 result =
984 _gnutls_x509_get_signed_data (crl->crl, "tbsCertList", &crl_signed_data);
985 if (result < 0)
986 {
987 gnutls_assert ();
988 goto cleanup;
989 }
990
991 result = _gnutls_x509_get_signature (crl->crl, "signature", &crl_signature);
992 if (result < 0)
993 {
994 gnutls_assert ();
995 goto cleanup;
996 }
997
998 ret =
999 _gnutls_x509_verify_signature (&crl_signed_data, &crl_signature, issuer);
1000 if (ret < 0)
1001 {
1002 gnutls_assert ();
1003 }
1004 else if (ret == 0)
1005 {
1006 gnutls_assert ();
1007 /* error. ignore it */
1008 if (output)
1009 *output |= GNUTLS_CERT_INVALID;
1010 ret = 0;
1011 }
1012
1013 {
1014 int sigalg;
1015
1016 sigalg = gnutls_x509_crl_get_signature_algorithm (crl);
1017
1018 if (((sigalg == GNUTLS_SIGN_RSA_MD2) &&
1019 !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2)) ||
1020 ((sigalg == GNUTLS_SIGN_RSA_MD5) &&
1021 !(flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5)))
1022 {
1023 if (output)
1024 *output |= GNUTLS_CERT_INSECURE_ALGORITHM | GNUTLS_CERT_INVALID;
1025 }
1026 }
1027
1028 result = ret;
1029
1030cleanup:
1031 _gnutls_free_datum (&crl_signed_data);
1032 _gnutls_free_datum (&crl_signature);
1033
1034 return result;
1035}
1036
1037#endif
diff --git a/src/daemon/https/x509/x509_write.c b/src/daemon/https/x509/x509_write.c
new file mode 100644
index 00000000..d9529c33
--- /dev/null
+++ b/src/daemon/https/x509/x509_write.c
@@ -0,0 +1,1094 @@
1/*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation
3 *
4 * Author: Nikos Mavrogiannopoulos
5 *
6 * This file is part of GNUTLS.
7 *
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21 * USA
22 *
23 */
24
25/* This file contains functions to handle X.509 certificate generation.
26 */
27
28#include <gnutls_int.h>
29
30#ifdef ENABLE_PKI
31
32#include <gnutls_datum.h>
33#include <gnutls_global.h>
34#include <gnutls_errors.h>
35#include <common.h>
36#include <gnutls_x509.h>
37#include <x509_b64.h>
38#include <crq.h>
39#include <dn.h>
40#include <mpi.h>
41#include <sign.h>
42#include <extensions.h>
43#include <libtasn1.h>
44
45static void disable_optional_stuff (gnutls_x509_crt_t cert);
46
47/**
48 * gnutls_x509_crt_set_dn_by_oid - This function will set the Certificate request subject's distinguished name
49 * @crt: should contain a gnutls_x509_crt_t structure
50 * @oid: holds an Object Identifier in a null terminated string
51 * @raw_flag: must be 0, or 1 if the data are DER encoded
52 * @name: a pointer to the name
53 * @sizeof_name: holds the size of @name
54 *
55 * This function will set the part of the name of the Certificate subject, specified
56 * by the given OID. The input string should be ASCII or UTF-8 encoded.
57 *
58 * Some helper macros with popular OIDs can be found in gnutls/x509.h
59 * With this function you can only set the known OIDs. You can test
60 * for known OIDs using gnutls_x509_dn_oid_known(). For OIDs that are
61 * not known (by gnutls) you should properly DER encode your data, and
62 * call this function with raw_flag set.
63 *
64 * Returns 0 on success.
65 *
66 **/
67int
68gnutls_x509_crt_set_dn_by_oid (gnutls_x509_crt_t crt, const char *oid,
69 unsigned int raw_flag, const void *name,
70 unsigned int sizeof_name)
71{
72 if (sizeof_name == 0 || name == NULL || crt == NULL)
73 {
74 return GNUTLS_E_INVALID_REQUEST;
75 }
76
77 return _gnutls_x509_set_dn_oid (crt->cert, "tbsCertificate.subject",
78 oid, raw_flag, name, sizeof_name);
79}
80
81/**
82 * gnutls_x509_crt_set_issuer_dn_by_oid - This function will set the Certificate request issuer's distinguished name
83 * @crt: should contain a gnutls_x509_crt_t structure
84 * @oid: holds an Object Identifier in a null terminated string
85 * @raw_flag: must be 0, or 1 if the data are DER encoded
86 * @name: a pointer to the name
87 * @sizeof_name: holds the size of @name
88 *
89 * This function will set the part of the name of the Certificate issuer, specified
90 * by the given OID. The input string should be ASCII or UTF-8 encoded.
91 *
92 * Some helper macros with popular OIDs can be found in gnutls/x509.h
93 * With this function you can only set the known OIDs. You can test
94 * for known OIDs using gnutls_x509_dn_oid_known(). For OIDs that are
95 * not known (by gnutls) you should properly DER encode your data, and
96 * call this function with raw_flag set.
97 *
98 * Normally you do not need to call this function, since the signing
99 * operation will copy the signer's name as the issuer of the certificate.
100 *
101 * Returns 0 on success.
102 *
103 **/
104int
105gnutls_x509_crt_set_issuer_dn_by_oid (gnutls_x509_crt_t crt,
106 const char *oid,
107 unsigned int raw_flag,
108 const void *name,
109 unsigned int sizeof_name)
110{
111 if (sizeof_name == 0 || name == NULL || crt == NULL)
112 {
113 return GNUTLS_E_INVALID_REQUEST;
114 }
115
116 return _gnutls_x509_set_dn_oid (crt->cert, "tbsCertificate.issuer", oid,
117 raw_flag, name, sizeof_name);
118}
119
120/**
121 * gnutls_x509_crt_set_proxy_dn - Set Proxy Certificate subject's distinguished name
122 * @crt: a gnutls_x509_crt_t structure with the new proxy cert
123 * @eecrt: the end entity certificate that will be issuing the proxy
124 * @raw_flag: must be 0, or 1 if the CN is DER encoded
125 * @name: a pointer to the CN name, may be NULL (but MUST then be added later)
126 * @sizeof_name: holds the size of @name
127 *
128 * This function will set the subject in @crt to the end entity's
129 * @eecrt subject name, and add a single Common Name component @name
130 * of size @sizeof_name. This corresponds to the required proxy
131 * certificate naming style. Note that if @name is %NULL, you MUST
132 * set it later by using gnutls_x509_crt_set_dn_by_oid() or similar.
133 *
134 * Returns 0 on success.
135 *
136 **/
137int
138gnutls_x509_crt_set_proxy_dn (gnutls_x509_crt_t crt, gnutls_x509_crt_t eecrt,
139 unsigned int raw_flag, const void *name,
140 unsigned int sizeof_name)
141{
142 int result;
143
144 if (crt == NULL || eecrt == NULL)
145 {
146 return GNUTLS_E_INVALID_REQUEST;
147 }
148
149 result = asn1_copy_node (crt->cert, "tbsCertificate.subject",
150 eecrt->cert, "tbsCertificate.subject");
151 if (result != ASN1_SUCCESS)
152 {
153 gnutls_assert ();
154 return _gnutls_asn2err (result);
155 }
156
157 if (name && sizeof_name)
158 {
159 return _gnutls_x509_set_dn_oid (crt->cert, "tbsCertificate.subject",
160 GNUTLS_OID_X520_COMMON_NAME,
161 raw_flag, name, sizeof_name);
162 }
163
164 return 0;
165}
166
167/**
168 * gnutls_x509_crt_set_version - This function will set the Certificate request version
169 * @crt: should contain a gnutls_x509_crt_t structure
170 * @version: holds the version number. For X.509v1 certificates must be 1.
171 *
172 * This function will set the version of the certificate. This must
173 * be one for X.509 version 1, and so on. Plain certificates without
174 * extensions must have version set to one.
175 *
176 * To create well-formed certificates, you must specify version 3 if
177 * you use any certificate extensions. Extensions are created by
178 * functions such as gnutls_x509_crt_set_subject_alternative_name or
179 * gnutls_x509_crt_set_key_usage.
180 *
181 * Returns 0 on success.
182 *
183 **/
184int
185gnutls_x509_crt_set_version (gnutls_x509_crt_t crt, unsigned int version)
186{
187 int result;
188 unsigned char null = version;
189
190 if (crt == NULL)
191 {
192 gnutls_assert ();
193 return GNUTLS_E_INVALID_REQUEST;
194 }
195
196 if (null > 0)
197 null--;
198
199 result = asn1_write_value (crt->cert, "tbsCertificate.version", &null, 1);
200 if (result != ASN1_SUCCESS)
201 {
202 gnutls_assert ();
203 return _gnutls_asn2err (result);
204 }
205
206 return 0;
207}
208
209/**
210 * gnutls_x509_crt_set_key - This function will associate the Certificate with a key
211 * @crt: should contain a gnutls_x509_crt_t structure
212 * @key: holds a private key
213 *
214 * This function will set the public parameters from the given private key to the
215 * certificate. Only RSA keys are currently supported.
216 *
217 * Returns 0 on success.
218 *
219 **/
220int
221gnutls_x509_crt_set_key (gnutls_x509_crt_t crt, gnutls_x509_privkey_t key)
222{
223 int result;
224
225 if (crt == NULL)
226 {
227 gnutls_assert ();
228 return GNUTLS_E_INVALID_REQUEST;
229 }
230
231 result = _gnutls_x509_encode_and_copy_PKI_params (crt->cert,
232 "tbsCertificate.subjectPublicKeyInfo",
233 key->pk_algorithm,
234 key->params,
235 key->params_size);
236
237 if (result < 0)
238 {
239 gnutls_assert ();
240 return result;
241 }
242
243 return 0;
244}
245
246/**
247 * gnutls_x509_crt_set_crq - This function will associate the Certificate with a request
248 * @crt: should contain a gnutls_x509_crt_t structure
249 * @crq: holds a certificate request
250 *
251 * This function will set the name and public parameters from the given certificate request to the
252 * certificate. Only RSA keys are currently supported.
253 *
254 * Returns 0 on success.
255 *
256 **/
257int
258gnutls_x509_crt_set_crq (gnutls_x509_crt_t crt, gnutls_x509_crq_t crq)
259{
260 int result;
261 int pk_algorithm;
262
263 if (crt == NULL || crq == NULL)
264 {
265 gnutls_assert ();
266 return GNUTLS_E_INVALID_REQUEST;
267 }
268
269 pk_algorithm = gnutls_x509_crq_get_pk_algorithm (crq, NULL);
270
271 result = asn1_copy_node (crt->cert, "tbsCertificate.subject",
272 crq->crq, "certificationRequestInfo.subject");
273 if (result != ASN1_SUCCESS)
274 {
275 gnutls_assert ();
276 return _gnutls_asn2err (result);
277 }
278
279 result =
280 asn1_copy_node (crt->cert, "tbsCertificate.subjectPublicKeyInfo",
281 crq->crq, "certificationRequestInfo.subjectPKInfo");
282 if (result != ASN1_SUCCESS)
283 {
284 gnutls_assert ();
285 return _gnutls_asn2err (result);
286 }
287
288 return 0;
289}
290
291/**
292 * gnutls_x509_crt_set_extension_by_oid - This function will set an arbitrary extension
293 * @crt: should contain a gnutls_x509_crt_t structure
294 * @oid: holds an Object Identified in null terminated string
295 * @buf: a pointer to a DER encoded data
296 * @sizeof_buf: holds the size of @buf
297 * @critical: should be non zero if the extension is to be marked as critical
298 *
299 * This function will set an the extension, by the specified OID, in the certificate.
300 * The extension data should be binary data DER encoded.
301 *
302 * Returns 0 on success and a negative value in case of an error.
303 *
304 **/
305int
306gnutls_x509_crt_set_extension_by_oid (gnutls_x509_crt_t crt,
307 const char *oid, const void *buf,
308 size_t sizeof_buf,
309 unsigned int critical)
310{
311 int result;
312 gnutls_datum_t der_data;
313
314 der_data.data = (void *) buf;
315 der_data.size = sizeof_buf;
316
317 if (crt == NULL)
318 {
319 gnutls_assert ();
320 return GNUTLS_E_INVALID_REQUEST;
321 }
322
323 result = _gnutls_x509_crt_set_extension (crt, oid, &der_data, critical);
324 if (result < 0)
325 {
326 gnutls_assert ();
327 return result;
328 }
329
330 crt->use_extensions = 1;
331
332 return 0;
333
334}
335
336/**
337 * gnutls_x509_crt_set_basic_constraints - This function will set the basicConstraints extension
338 * @crt: should contain a gnutls_x509_crt_t structure
339 * @ca: true(1) or false(0). Depending on the Certificate authority status.
340 * @pathLenConstraint: non-negative values indicate maximum length of path,
341 * and negative values indicate that the pathLenConstraints field should
342 * not be present.
343 *
344 * This function will set the basicConstraints certificate extension.
345 *
346 * Returns 0 on success.
347 *
348 **/
349int
350gnutls_x509_crt_set_basic_constraints (gnutls_x509_crt_t crt,
351 unsigned int ca, int pathLenConstraint)
352{
353 int result;
354 gnutls_datum_t der_data;
355
356 if (crt == NULL)
357 {
358 gnutls_assert ();
359 return GNUTLS_E_INVALID_REQUEST;
360 }
361
362 /* generate the extension.
363 */
364 result = _gnutls_x509_ext_gen_basicConstraints (ca, pathLenConstraint,
365 &der_data);
366 if (result < 0)
367 {
368 gnutls_assert ();
369 return result;
370 }
371
372 result = _gnutls_x509_crt_set_extension (crt, "2.5.29.19", &der_data, 1);
373
374 _gnutls_free_datum (&der_data);
375
376 if (result < 0)
377 {
378 gnutls_assert ();
379 return result;
380 }
381
382 crt->use_extensions = 1;
383
384 return 0;
385}
386
387/**
388 * gnutls_x509_crt_set_ca_status - This function will set the basicConstraints extension
389 * @crt: should contain a gnutls_x509_crt_t structure
390 * @ca: true(1) or false(0). Depending on the Certificate authority status.
391 *
392 * This function will set the basicConstraints certificate extension.
393 * Use gnutls_x509_crt_set_basic_constraints() if you want to control
394 * the pathLenConstraint field too.
395 *
396 * Returns 0 on success.
397 *
398 **/
399int
400gnutls_x509_crt_set_ca_status (gnutls_x509_crt_t crt, unsigned int ca)
401{
402 return gnutls_x509_crt_set_basic_constraints (crt, ca, -1);
403}
404
405/**
406 * gnutls_x509_crt_set_key_usage - This function will set the keyUsage extension
407 * @crt: should contain a gnutls_x509_crt_t structure
408 * @usage: an ORed sequence of the GNUTLS_KEY_* elements.
409 *
410 * This function will set the keyUsage certificate extension.
411 *
412 * Returns 0 on success.
413 *
414 **/
415int
416gnutls_x509_crt_set_key_usage (gnutls_x509_crt_t crt, unsigned int usage)
417{
418 int result;
419 gnutls_datum_t der_data;
420
421 if (crt == NULL)
422 {
423 gnutls_assert ();
424 return GNUTLS_E_INVALID_REQUEST;
425 }
426
427 /* generate the extension.
428 */
429 result = _gnutls_x509_ext_gen_keyUsage ((uint16_t) usage, &der_data);
430 if (result < 0)
431 {
432 gnutls_assert ();
433 return result;
434 }
435
436 result = _gnutls_x509_crt_set_extension (crt, "2.5.29.15", &der_data, 1);
437
438 _gnutls_free_datum (&der_data);
439
440 if (result < 0)
441 {
442 gnutls_assert ();
443 return result;
444 }
445
446 crt->use_extensions = 1;
447
448 return 0;
449}
450
451/**
452 * gnutls_x509_crt_set_subject_alternative_name - This function will set the subject Alternative Name
453 * @crt: should contain a gnutls_x509_crt_t structure
454 * @type: is one of the gnutls_x509_subject_alt_name_t enumerations
455 * @data_string: The data to be set
456 *
457 * This function will set the subject alternative name certificate extension.
458 *
459 * Returns 0 on success.
460 *
461 **/
462int
463gnutls_x509_crt_set_subject_alternative_name (gnutls_x509_crt_t crt,
464 gnutls_x509_subject_alt_name_t
465 type, const char *data_string)
466{
467 int result;
468 gnutls_datum_t der_data;
469 gnutls_datum_t dnsname;
470 unsigned int critical;
471
472 if (crt == NULL)
473 {
474 gnutls_assert ();
475 return GNUTLS_E_INVALID_REQUEST;
476 }
477
478 /* Check if the extension already exists.
479 */
480 result =
481 _gnutls_x509_crt_get_extension (crt, "2.5.29.17", 0, &dnsname, &critical);
482
483 if (result >= 0)
484 _gnutls_free_datum (&dnsname);
485 if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
486 {
487 gnutls_assert ();
488 return GNUTLS_E_INVALID_REQUEST;
489 }
490
491 /* generate the extension.
492 */
493 result =
494 _gnutls_x509_ext_gen_subject_alt_name (type, data_string, &der_data);
495 if (result < 0)
496 {
497 gnutls_assert ();
498 return result;
499 }
500
501 result = _gnutls_x509_crt_set_extension (crt, "2.5.29.17", &der_data, 0);
502
503 _gnutls_free_datum (&der_data);
504
505 if (result < 0)
506 {
507 gnutls_assert ();
508 return result;
509 }
510
511 crt->use_extensions = 1;
512
513 return 0;
514}
515
516/**
517 * gnutls_x509_crt_set_proxy - Set the proxyCertInfo extension
518 * @crt: should contain a gnutls_x509_crt_t structure
519 * @pathLenConstraint: non-negative values indicate maximum length of path,
520 * and negative values indicate that the pathLenConstraints field should
521 * not be present.
522 * @policyLanguage: OID describing the language of @policy.
523 * @policy: opaque byte array with policy language, can be %NULL
524 * @sizeof_policy: size of @policy.
525 *
526 * This function will set the proxyCertInfo extension.
527 *
528 * Returns 0 on success.
529 *
530 **/
531int
532gnutls_x509_crt_set_proxy (gnutls_x509_crt_t crt,
533 int pathLenConstraint,
534 const char *policyLanguage,
535 const char *policy, size_t sizeof_policy)
536{
537 int result;
538 gnutls_datum_t der_data;
539
540 if (crt == NULL)
541 {
542 gnutls_assert ();
543 return GNUTLS_E_INVALID_REQUEST;
544 }
545
546 /* generate the extension.
547 */
548 result = _gnutls_x509_ext_gen_proxyCertInfo (pathLenConstraint,
549 policyLanguage,
550 policy, sizeof_policy,
551 &der_data);
552 if (result < 0)
553 {
554 gnutls_assert ();
555 return result;
556 }
557
558 result = _gnutls_x509_crt_set_extension (crt, "1.3.6.1.5.5.7.1.14",
559 &der_data, 1);
560
561 _gnutls_free_datum (&der_data);
562
563 if (result < 0)
564 {
565 gnutls_assert ();
566 return result;
567 }
568
569 crt->use_extensions = 1;
570
571 return 0;
572}
573
574/**
575 * gnutls_x509_crt_sign2 - This function will sign a certificate with a key
576 * @crt: should contain a gnutls_x509_crt_t structure
577 * @issuer: is the certificate of the certificate issuer
578 * @issuer_key: holds the issuer's private key
579 * @dig: The message digest to use. GNUTLS_DIG_SHA1 is the safe choice unless you know what you're doing.
580 * @flags: must be 0
581 *
582 * This function will sign the certificate with the issuer's private key, and
583 * will copy the issuer's information into the certificate.
584 *
585 * This must be the last step in a certificate generation since all
586 * the previously set parameters are now signed.
587 *
588 * Returns 0 on success.
589 *
590 **/
591int
592gnutls_x509_crt_sign2 (gnutls_x509_crt_t crt, gnutls_x509_crt_t issuer,
593 gnutls_x509_privkey_t issuer_key,
594 gnutls_digest_algorithm_t dig, unsigned int flags)
595{
596 int result;
597
598 if (crt == NULL || issuer == NULL || issuer_key == NULL)
599 {
600 gnutls_assert ();
601 return GNUTLS_E_INVALID_REQUEST;
602 }
603
604 /* disable all the unneeded OPTIONAL fields.
605 */
606 disable_optional_stuff (crt);
607
608 result = _gnutls_x509_pkix_sign (crt->cert, "tbsCertificate",
609 dig, issuer, issuer_key);
610 if (result < 0)
611 {
612 gnutls_assert ();
613 return result;
614 }
615
616 return 0;
617}
618
619/**
620 * gnutls_x509_crt_sign - This function will sign a certificate with a key
621 * @crt: should contain a gnutls_x509_crt_t structure
622 * @issuer: is the certificate of the certificate issuer
623 * @issuer_key: holds the issuer's private key
624 *
625 * This function is the same a gnutls_x509_crt_sign2() with no flags, and
626 * SHA1 as the hash algorithm.
627 *
628 * Returns 0 on success.
629 *
630 **/
631int
632gnutls_x509_crt_sign (gnutls_x509_crt_t crt, gnutls_x509_crt_t issuer,
633 gnutls_x509_privkey_t issuer_key)
634{
635 return gnutls_x509_crt_sign2 (crt, issuer, issuer_key, GNUTLS_DIG_SHA1, 0);
636}
637
638/**
639 * gnutls_x509_crt_set_activation_time - This function will set the Certificate's activation time
640 * @cert: should contain a gnutls_x509_crt_t structure
641 * @act_time: The actual time
642 *
643 * This function will set the time this Certificate was or will be activated.
644 *
645 * Returns 0 on success, or a negative value in case of an error.
646 *
647 **/
648int
649gnutls_x509_crt_set_activation_time (gnutls_x509_crt_t cert, time_t act_time)
650{
651 if (cert == NULL)
652 {
653 gnutls_assert ();
654 return GNUTLS_E_INVALID_REQUEST;
655 }
656
657 return _gnutls_x509_set_time (cert->cert,
658 "tbsCertificate.validity.notBefore",
659 act_time);
660}
661
662/**
663 * gnutls_x509_crt_set_expiration_time - This function will set the Certificate's expiration time
664 * @cert: should contain a gnutls_x509_crt_t structure
665 * @exp_time: The actual time
666 *
667 * This function will set the time this Certificate will expire.
668 *
669 * Returns 0 on success, or a negative value in case of an error.
670 *
671 **/
672int
673gnutls_x509_crt_set_expiration_time (gnutls_x509_crt_t cert, time_t exp_time)
674{
675 if (cert == NULL)
676 {
677 gnutls_assert ();
678 return GNUTLS_E_INVALID_REQUEST;
679 }
680 return _gnutls_x509_set_time (cert->cert,
681 "tbsCertificate.validity.notAfter", exp_time);
682}
683
684/**
685 * gnutls_x509_crt_set_serial - This function will set the certificate's serial number
686 * @cert: should contain a gnutls_x509_crt_t structure
687 * @serial: The serial number
688 * @serial_size: Holds the size of the serial field.
689 *
690 * This function will set the X.509 certificate's serial number.
691 * Serial is not always a 32 or 64bit number. Some CAs use
692 * large serial numbers, thus it may be wise to handle it as something
693 * opaque.
694 *
695 * Returns 0 on success, or a negative value in case of an error.
696 *
697 **/
698int
699gnutls_x509_crt_set_serial (gnutls_x509_crt_t cert, const void *serial,
700 size_t serial_size)
701{
702 int ret;
703
704 if (cert == NULL)
705 {
706 gnutls_assert ();
707 return GNUTLS_E_INVALID_REQUEST;
708 }
709
710 ret =
711 asn1_write_value (cert->cert, "tbsCertificate.serialNumber", serial,
712 serial_size);
713 if (ret != ASN1_SUCCESS)
714 {
715 gnutls_assert ();
716 return _gnutls_asn2err (ret);
717 }
718
719 return 0;
720
721}
722
723/* If OPTIONAL fields have not been initialized then
724 * disable them.
725 */
726static void
727disable_optional_stuff (gnutls_x509_crt_t cert)
728{
729
730 asn1_write_value (cert->cert, "tbsCertificate.issuerUniqueID", NULL, 0);
731
732 asn1_write_value (cert->cert, "tbsCertificate.subjectUniqueID", NULL, 0);
733
734 if (cert->use_extensions == 0)
735 {
736 _gnutls_x509_log ("Disabling X.509 extensions.\n");
737 asn1_write_value (cert->cert, "tbsCertificate.extensions", NULL, 0);
738 }
739
740 return;
741}
742
743/**
744 * gnutls_x509_crt_set_crl_dist_points - This function will set the CRL dist points
745 * @crt: should contain a gnutls_x509_crt_t structure
746 * @type: is one of the gnutls_x509_subject_alt_name_t enumerations
747 * @data_string: The data to be set
748 * @reason_flags: revocation reasons
749 *
750 * This function will set the CRL distribution points certificate extension.
751 *
752 * Returns 0 on success.
753 *
754 **/
755int
756gnutls_x509_crt_set_crl_dist_points (gnutls_x509_crt_t crt,
757 gnutls_x509_subject_alt_name_t
758 type, const void *data_string,
759 unsigned int reason_flags)
760{
761 int result;
762 gnutls_datum_t der_data;
763 gnutls_datum_t oldname;
764 unsigned int critical;
765
766 if (crt == NULL)
767 {
768 gnutls_assert ();
769 return GNUTLS_E_INVALID_REQUEST;
770 }
771
772 /* Check if the extension already exists.
773 */
774 result =
775 _gnutls_x509_crt_get_extension (crt, "2.5.29.31", 0, &oldname, &critical);
776
777 if (result >= 0)
778 _gnutls_free_datum (&oldname);
779 if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
780 {
781 gnutls_assert ();
782 return GNUTLS_E_INVALID_REQUEST;
783 }
784
785 /* generate the extension.
786 */
787 result =
788 _gnutls_x509_ext_gen_crl_dist_points (type, data_string,
789 reason_flags, &der_data);
790 if (result < 0)
791 {
792 gnutls_assert ();
793 return result;
794 }
795
796 result = _gnutls_x509_crt_set_extension (crt, "2.5.29.31", &der_data, 0);
797
798 _gnutls_free_datum (&der_data);
799
800 if (result < 0)
801 {
802 gnutls_assert ();
803 return result;
804 }
805
806 crt->use_extensions = 1;
807
808 return 0;
809}
810
811/**
812 * gnutls_x509_crt_cpy_crl_dist_points - This function will copy the CRL dist points
813 * @dst: should contain a gnutls_x509_crt_t structure
814 * @src: the certificate where the dist points will be copied from
815 *
816 * This function will copy the CRL distribution points certificate
817 * extension, from the source to the destination certificate.
818 * This may be useful to copy from a CA certificate to issued ones.
819 *
820 * Returns 0 on success.
821 *
822 **/
823int
824gnutls_x509_crt_cpy_crl_dist_points (gnutls_x509_crt_t dst,
825 gnutls_x509_crt_t src)
826{
827 int result;
828 gnutls_datum_t der_data;
829 unsigned int critical;
830
831 if (dst == NULL || src == NULL)
832 {
833 gnutls_assert ();
834 return GNUTLS_E_INVALID_REQUEST;
835 }
836
837 /* Check if the extension already exists.
838 */
839 result =
840 _gnutls_x509_crt_get_extension (src, "2.5.29.31", 0, &der_data,
841 &critical);
842 if (result < 0)
843 {
844 gnutls_assert ();
845 return result;
846 }
847
848 result =
849 _gnutls_x509_crt_set_extension (dst, "2.5.29.31", &der_data, critical);
850 _gnutls_free_datum (&der_data);
851
852 if (result < 0)
853 {
854 gnutls_assert ();
855 return result;
856 }
857
858 dst->use_extensions = 1;
859
860 return 0;
861}
862
863/**
864 * gnutls_x509_crt_set_subject_key_id - This function will set the certificate's subject key id
865 * @cert: should contain a gnutls_x509_crt_t structure
866 * @id: The key ID
867 * @id_size: Holds the size of the serial field.
868 *
869 * This function will set the X.509 certificate's subject key ID extension.
870 *
871 * Returns 0 on success, or a negative value in case of an error.
872 *
873 **/
874int
875gnutls_x509_crt_set_subject_key_id (gnutls_x509_crt_t cert,
876 const void *id, size_t id_size)
877{
878 int result;
879 gnutls_datum_t old_id, der_data;
880 unsigned int critical;
881
882 if (cert == NULL)
883 {
884 gnutls_assert ();
885 return GNUTLS_E_INVALID_REQUEST;
886 }
887
888 /* Check if the extension already exists.
889 */
890 result =
891 _gnutls_x509_crt_get_extension (cert, "2.5.29.14", 0, &old_id, &critical);
892
893 if (result >= 0)
894 _gnutls_free_datum (&old_id);
895 if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
896 {
897 gnutls_assert ();
898 return GNUTLS_E_INVALID_REQUEST;
899 }
900
901 /* generate the extension.
902 */
903 result = _gnutls_x509_ext_gen_key_id (id, id_size, &der_data);
904 if (result < 0)
905 {
906 gnutls_assert ();
907 return result;
908 }
909
910 result = _gnutls_x509_crt_set_extension (cert, "2.5.29.14", &der_data, 0);
911
912 _gnutls_free_datum (&der_data);
913
914 if (result < 0)
915 {
916 gnutls_assert ();
917 return result;
918 }
919
920 cert->use_extensions = 1;
921
922 return 0;
923}
924
925/**
926 * gnutls_x509_crt_set_authority_key_id - This function will set the certificate authority's key id
927 * @cert: should contain a gnutls_x509_crt_t structure
928 * @id: The key ID
929 * @id_size: Holds the size of the serial field.
930 *
931 * This function will set the X.509 certificate's authority key ID extension.
932 * Only the keyIdentifier field can be set with this function.
933 *
934 * Returns 0 on success, or a negative value in case of an error.
935 *
936 **/
937int
938gnutls_x509_crt_set_authority_key_id (gnutls_x509_crt_t cert,
939 const void *id, size_t id_size)
940{
941 int result;
942 gnutls_datum_t old_id, der_data;
943 unsigned int critical;
944
945 if (cert == NULL)
946 {
947 gnutls_assert ();
948 return GNUTLS_E_INVALID_REQUEST;
949 }
950
951 /* Check if the extension already exists.
952 */
953 result =
954 _gnutls_x509_crt_get_extension (cert, "2.5.29.35", 0, &old_id, &critical);
955
956 if (result >= 0)
957 _gnutls_free_datum (&old_id);
958 if (result != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
959 {
960 gnutls_assert ();
961 return GNUTLS_E_INVALID_REQUEST;
962 }
963
964 /* generate the extension.
965 */
966 result = _gnutls_x509_ext_gen_auth_key_id (id, id_size, &der_data);
967 if (result < 0)
968 {
969 gnutls_assert ();
970 return result;
971 }
972
973 result = _gnutls_x509_crt_set_extension (cert, "2.5.29.35", &der_data, 0);
974
975 _gnutls_free_datum (&der_data);
976
977 if (result < 0)
978 {
979 gnutls_assert ();
980 return result;
981 }
982
983 cert->use_extensions = 1;
984
985 return 0;
986}
987
988/**
989 * gnutls_x509_crt_set_key_purpose_oid - This function sets the Certificate's key purpose OIDs
990 * @cert: should contain a gnutls_x509_crt_t structure
991 * @oid: a pointer to a null terminated string that holds the OID
992 * @critical: Whether this extension will be critical or not
993 *
994 * This function will set the key purpose OIDs of the Certificate.
995 * These are stored in the Extended Key Usage extension (2.5.29.37)
996 * See the GNUTLS_KP_* definitions for human readable names.
997 *
998 * Subsequent calls to this function will append OIDs to the OID list.
999 *
1000 * On success 0 is returned.
1001 *
1002 **/
1003int
1004gnutls_x509_crt_set_key_purpose_oid (gnutls_x509_crt_t cert,
1005 const void *oid, unsigned int critical)
1006{
1007 int result;
1008 gnutls_datum_t old_id, der_data;
1009 ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
1010
1011 if (cert == NULL)
1012 {
1013 gnutls_assert ();
1014 return GNUTLS_E_INVALID_REQUEST;
1015 }
1016
1017 result = asn1_create_element
1018 (_gnutls_get_pkix (), "PKIX1.ExtKeyUsageSyntax", &c2);
1019 if (result != ASN1_SUCCESS)
1020 {
1021 gnutls_assert ();
1022 return _gnutls_asn2err (result);
1023 }
1024
1025 /* Check if the extension already exists.
1026 */
1027 result =
1028 _gnutls_x509_crt_get_extension (cert, "2.5.29.37", 0, &old_id, NULL);
1029
1030 if (result >= 0)
1031 {
1032 /* decode it.
1033 */
1034 result = asn1_der_decoding (&c2, old_id.data, old_id.size, NULL);
1035 _gnutls_free_datum (&old_id);
1036
1037 if (result != ASN1_SUCCESS)
1038 {
1039 gnutls_assert ();
1040 asn1_delete_structure (&c2);
1041 return _gnutls_asn2err (result);
1042 }
1043
1044 }
1045
1046 /* generate the extension.
1047 */
1048 /* 1. create a new element.
1049 */
1050 result = asn1_write_value (c2, "", "NEW", 1);
1051 if (result != ASN1_SUCCESS)
1052 {
1053 gnutls_assert ();
1054 asn1_delete_structure (&c2);
1055 return _gnutls_asn2err (result);
1056 }
1057
1058 /* 2. Add the OID.
1059 */
1060 result = asn1_write_value (c2, "?LAST", oid, 1);
1061 if (result != ASN1_SUCCESS)
1062 {
1063 gnutls_assert ();
1064 asn1_delete_structure (&c2);
1065 return _gnutls_asn2err (result);
1066 }
1067
1068 result = _gnutls_x509_der_encode (c2, "", &der_data, 0);
1069 asn1_delete_structure (&c2);
1070
1071 if (result != ASN1_SUCCESS)
1072 {
1073 gnutls_assert ();
1074 return _gnutls_asn2err (result);
1075 }
1076
1077 result = _gnutls_x509_crt_set_extension (cert, "2.5.29.37",
1078 &der_data, critical);
1079
1080 _gnutls_free_datum (&der_data);
1081
1082 if (result < 0)
1083 {
1084 gnutls_assert ();
1085 return result;
1086 }
1087
1088 cert->use_extensions = 1;
1089
1090 return 0;
1091
1092}
1093
1094#endif /* ENABLE_PKI */