diff options
Diffstat (limited to 'keyexchange/isakmpd-20041012/regress/x509/x509test.c')
-rw-r--r-- | keyexchange/isakmpd-20041012/regress/x509/x509test.c | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/keyexchange/isakmpd-20041012/regress/x509/x509test.c b/keyexchange/isakmpd-20041012/regress/x509/x509test.c new file mode 100644 index 0000000..25b8bab --- /dev/null +++ b/keyexchange/isakmpd-20041012/regress/x509/x509test.c @@ -0,0 +1,291 @@ +/* $OpenBSD: x509test.c,v 1.22 2003/06/03 14:39:51 ho Exp $ */ +/* $EOM: x509test.c,v 1.9 2000/12/21 15:24:25 ho Exp $ */ + +/* + * Copyright (c) 1998, 1999 Niels Provos. All rights reserved. + * Copyright (c) 1999, 2001 Niklas Hallqvist. All rights reserved. + * Copyright (c) 2001 Håkan Olsson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This code was written under funding by Ericsson Radio Systems. + */ + +/* + * This program takes a certificate generated by ssleay and a key pair + * from rsakeygen. It reads the IP address from certificate.txt and + * includes this as subject alt name extension into the certifcate. + * The result gets written as new certificate that can be used by + * isakmpd. + */ + +#include <sys/param.h> +#include <sys/types.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <ctype.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> + +#include "conf.h" +#include "ipsec_num.h" +#include "isakmp_fld.h" +#include "libcrypto.h" +#include "log.h" +#include "math_mp.h" +#include "x509.h" + +static int x509_check_subjectaltname (u_char *, u_int, X509 *); + +u_int32_t file_sz; + +#if 0 +/* XXX Currently unused. */ +static u_int8_t * +open_file (char *name) +{ + int fd; + struct stat st; + u_int8_t *addr; + + if (stat (name, &st) == -1) + log_fatal ("stat (\"%s\", &st)", name); + file_sz = st.st_size; + fd = open (name, O_RDONLY); + if (fd == -1) + log_fatal ("open (\"%s\", O_RDONLY)", name); + addr = mmap (0, file_sz, PROT_READ | PROT_WRITE, MAP_FILE | MAP_PRIVATE, + fd, 0); + if (addr == MAP_FAILED) + log_fatal ("mmap (0, %d, PROT_READ | PROT_WRITE, MAP_FILE | MAP_PRIVATE," + "%d, 0)", file_sz, fd); + close (fd); + + return addr; +} +#endif + +/* + * Check that a certificate has a subjectAltName and that it matches our ID. + */ +static int +x509_check_subjectaltname (u_char *id, u_int id_len, X509 *scert) +{ + u_int8_t *altname; + u_int32_t altlen; + int type, idtype, ret; + + type = x509_cert_subjectaltname (scert, &altname, &altlen); + if (!type) + { + log_print ("x509_check_subjectaltname: can't access subjectAltName"); + return 0; + } + + /* + * Now that we have the X509 certicate in native form, get the + * subjectAltName extension and verify that it matches our ID. + */ + + /* XXX Get type of ID. */ + idtype = id[0]; + id += ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ; + id_len -= ISAKMP_ID_DATA_OFF - ISAKMP_GEN_SZ; + + ret = 0; + switch (idtype) + { + case IPSEC_ID_IPV4_ADDR: + if (type == X509v3_IP_ADDR) + ret = 1; + break; + case IPSEC_ID_FQDN: + if (type == X509v3_DNS_NAME) + ret = 1; + break; + case IPSEC_ID_USER_FQDN: + if (type == X509v3_RFC_NAME) + ret = 1; + break; + default: + ret = 0; + break; + } + + if (!ret) + { + LOG_DBG ((LOG_CRYPTO, 50, + "x509_check_subjectaltname: " + "our ID type (%d) does not match X509 cert ID type (%d)", + idtype, type)); + return 0; + } + + if (altlen != id_len || memcmp (altname, id, id_len) != 0) + { + LOG_DBG ((LOG_CRYPTO, 50, + "x509_check_subjectaltname: " + "our ID does not match X509 cert ID")); + return 0; + } + + return 1; +} + +int +main (int argc, char *argv[]) +{ + RSA *pub_key, *priv_key; + X509 *cert; + BIO *certfile, *keyfile; + EVP_PKEY *pkey_pub; + u_char ipaddr[6]; + struct in_addr saddr; + char enc[256], dec[256]; + u_int8_t idpayload[8]; + int err, len; + + if (argc < 3 || argc > 4) + { + fprintf (stderr, "usage: x509test private-key certificate ip-address\n"); + exit (1); + } + + /* + * X509_verify will fail, as will all other functions that call + * EVP_get_digest_byname. + */ + + libcrypto_init (); + + printf ("Reading private key %s\n", argv[1]); + keyfile = BIO_new (BIO_s_file ()); + if (BIO_read_filename (keyfile, argv[1]) == -1) + { + perror ("read"); + exit (1); + } +#if SSLEAY_VERSION_NUMBER >= 0x00904100L + priv_key = PEM_read_bio_RSAPrivateKey (keyfile, NULL, NULL, NULL); +#else + priv_key = PEM_read_bio_RSAPrivateKey (keyfile, NULL, NULL); +#endif + BIO_free (keyfile); + if (priv_key == NULL) + { + printf("PEM_read_bio_RSAPrivateKey () failed\n"); + exit (1); + } + + /* Use a certificate created by ssleay. */ + printf ("Reading ssleay created certificate %s\n", argv[2]); + certfile = BIO_new (BIO_s_file ()); + if (BIO_read_filename (certfile, argv[2]) == -1) + { + perror ("read"); + exit (1); + } +#if SSLEAY_VERSION_NUMBER >= 0x00904100L + cert = PEM_read_bio_X509 (certfile, NULL, NULL, NULL); +#else + cert = PEM_read_bio_X509 (certfile, NULL, NULL); +#endif + BIO_free (certfile); + if (cert == NULL) + { + printf("PEM_read_bio_X509 () failed\n"); + exit (1); + } + + pkey_pub = X509_get_pubkey (cert); + /* XXX Violation of the interface? */ + pub_key = pkey_pub->pkey.rsa; + if (pub_key == NULL) + { + exit (1); + } + + printf ("Testing RSA keys: "); + + err = 0; + strlcpy (dec, "Eine kleine Testmeldung", 256); + if ((len = RSA_private_encrypt (strlen (dec), dec, enc, priv_key, + RSA_PKCS1_PADDING)) == -1) + + printf ("SIGN FAILED "); + else + err = RSA_public_decrypt (len, enc, dec, pub_key, RSA_PKCS1_PADDING); + + if (err == -1 || strcmp (dec, "Eine kleine Testmeldung")) + printf ("SIGN/VERIFY FAILED"); + else + printf ("OKAY"); + printf ("\n"); + + + printf ("Validate SIGNED: "); + err = X509_verify (cert, pkey_pub); + printf ("X509 verify: %d ", err); + if (err == -1) + printf ("FAILED "); + else + printf ("OKAY "); + printf ("\n"); + + if (argc == 4) + { + printf ("Verifying extension: "); + if (inet_aton (argv[3], &saddr) == 0) + { + printf ("inet_aton () failed\n"); + exit (1); + } + + saddr.s_addr = htonl (saddr.s_addr); + ipaddr[0] = 0x87; + ipaddr[1] = 0x04; + ipaddr[2] = saddr.s_addr >> 24; + ipaddr[3] = (saddr.s_addr >> 16) & 0xff; + ipaddr[4] = (saddr.s_addr >> 8) & 0xff; + ipaddr[5] = saddr.s_addr & 0xff; + bzero (idpayload, sizeof idpayload); + idpayload[0] = IPSEC_ID_IPV4_ADDR; + bcopy (ipaddr + 2, idpayload + 4, 4); + + if (!x509_check_subjectaltname (idpayload, sizeof idpayload, cert)) + printf("FAILED "); + else + printf("OKAY "); + printf ("\n"); + } + + return 1; +} |