Back to index

opendkim  2.6.4
Defines | Functions | Variables
dkim-test.c File Reference
#include "build-config.h"
#include <sys/param.h>
#include <sys/types.h>
#include <arpa/nameser.h>
#include <netinet/in.h>
#include <assert.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <resolv.h>
#include <errno.h>
#include <openssl/bio.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include "dkim-internal.h"
#include "dkim-types.h"
#include "dkim-keys.h"
#include "dkim-util.h"
#include "dkim-test.h"
#include "dkim-strl.h"

Go to the source code of this file.

Defines

#define TESTTTL   300
#define MAXPACKET   8192

Functions

DKIM_STAT dkim_get_key __P ((DKIM *, DKIM_SIGINFO *, _Bool))
int dkim_test_dns_put (DKIM *dkim, int class, int type, int prec, u_char *name, u_char *data)
size_t dkim_test_dns_get (DKIM *dkim, u_char *buf, size_t buflen)
int dkim_test_key (DKIM_LIB *lib, char *selector, char *domain, char *key, size_t keylen, int *dnssec, char *err, size_t errlen)
int dkim_test_adsp (DKIM_LIB *lib, const char *domain, dkim_policy_t *presult, int *presult2, char *err, size_t errlen)

Variables

static char dkim_test_c_id [] = "@(#)$Id: dkim-test.c,v 1.16.10.1 2010/10/27 21:43:08 cm-msk Exp $"

Define Documentation

#define MAXPACKET   8192

Definition at line 45 of file dkim-test.c.

#define TESTTTL   300

Definition at line 44 of file dkim-test.c.


Function Documentation

DKIM_STAT dkim_get_key __P ( (DKIM *, DKIM_SIGINFO *, _Bool)  )
int dkim_test_adsp ( DKIM_LIB *  lib,
const char *  domain,
dkim_policy_t presult,
int *  presult2,
char *  err,
size_t  errlen 
)

Definition at line 509 of file dkim-test.c.

{
       DKIM_STAT stat;
       dkim_policy_t pcode = DKIM_POLICY_DEFAULT;
       DKIM *dkim;

       assert(lib != NULL);
       assert(presult != NULL);
       assert(presult2 != NULL);

       dkim = dkim_verify(lib, (u_char *) "test", NULL, &stat);
       if (dkim == NULL)
       {
              if (err != NULL)
                     strlcpy(err, dkim_getresultstr(stat), errlen);
              return -1;
       }

       dkim->dkim_mode = DKIM_MODE_VERIFY;
       dkim->dkim_domain = (u_char *) domain;
       dkim->dkim_sigcount = 0;

       stat = dkim_policy(dkim, &pcode, NULL, NULL);
       if (stat != DKIM_STAT_OK)
       {
              if (err != NULL)
              {
                     const char *errstr;

                     errstr = dkim_geterror(dkim);
                     if (errstr != NULL)
                     {
                            strlcpy(err, errstr, errlen);
                     }
                     else
                     {
                            strlcpy(err, dkim_getresultstr(stat),
                                    errlen);
                     }
              }

              dkim->dkim_domain = NULL;
              (void) dkim_free(dkim);

              return -1;
       }

       *presult = pcode;
       *presult2 = dkim_getpresult(dkim);

       dkim->dkim_domain = NULL;
       (void) dkim_free(dkim);

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

size_t dkim_test_dns_get ( DKIM *  dkim,
u_char *  buf,
size_t  buflen 
)

Definition at line 127 of file dkim-test.c.

{
       int n;
       int len;
       uint32_t testttl;
       struct dkim_test_dns_data *td;
       u_char *cp;
       u_char *p;
       u_char *end;
       u_char answer[MAXPACKET];
       HEADER hdr;

       td = dkim->dkim_dnstesth;
       if (td == NULL)
              return -1;

       dkim->dkim_dnstesth = td->dns_next;

       /* encode the reply */
       memset(&hdr, '\0', sizeof hdr);
       hdr.qdcount = htons(1);
       hdr.rcode = (td->dns_reply == NULL ? NXDOMAIN : NOERROR);
       hdr.ancount = (td->dns_reply == NULL ? htons(0) : htons(1));

       memcpy(answer, &hdr, sizeof hdr);

       cp = answer + HFIXEDSZ;
       end = answer + sizeof answer;

       /* repeat the question */
       n = dn_comp((char *) td->dns_query, cp, end - cp, NULL, NULL);
       if (n < 0)
       {
              DKIM_FREE(dkim, td);
              return -1;
       }
       cp += n;
       if (end - cp < 2 * sizeof(uint16_t))
       {
              DKIM_FREE(dkim, td);
              return -1;
       }

       PUTSHORT(td->dns_type, cp);
       PUTSHORT(td->dns_class, cp);

       /* short-circuit? */
       if (hdr.rcode == NXDOMAIN)
       {
              DKIM_FREE(dkim, td);

              memcpy(buf, answer, buflen);

              return cp - answer;
       }

       /* the answer starts out the same way */
       n = dn_comp((char *) td->dns_query, cp, end - cp, NULL, NULL);
       if (n < 0)
       {
              DKIM_FREE(dkim, td);
              return -1;
       }
       cp += n;

       if (end - cp < 2 * sizeof(uint16_t) + sizeof(uint32_t))
       {
              DKIM_FREE(dkim, td);
              return -1;
       }

       PUTSHORT(td->dns_type, cp);
       PUTSHORT(td->dns_class, cp);

       testttl = htonl(TESTTTL);
       PUTLONG(testttl, cp);

       switch (td->dns_type)
       {
         case T_TXT:
              /* figure out how many bytes we need total */
              n = strlen((char *) td->dns_reply);
              len = n + n / 255 + 1;
              if (end - cp < len + sizeof(uint16_t))
              {
                     DKIM_FREE(dkim, td);
                     return -1;
              }
              PUTSHORT(len, cp);

              /* write the buffer, inserting length bytes as needed */
              len = 0;
              p = td->dns_reply;
              while (n > 0)
              {
                     if (len == 0)
                     {
                            len = MIN(255, n);
                            *cp++ = len;
                     }
                     *cp++ = *p++;
                     n--;
                     len--;
              }
              break;

         case T_MX:
              if (end - cp < sizeof(uint16_t))
              {
                     DKIM_FREE(dkim, td);
                     return -1;
              }
              PUTSHORT(td->dns_prec, cp);
              n = dn_comp((char *) td->dns_reply, cp, end - cp, NULL, NULL);
              if (n < 0)
              {
                     DKIM_FREE(dkim, td);
                     return -1;
              }

              cp += n;
              break;

         default:
              DKIM_FREE(dkim, td);
              return -1;
       }

       DKIM_FREE(dkim, td);

       memcpy(buf, answer, buflen);

       return cp - answer;
}

Here is the caller graph for this function:

int dkim_test_dns_put ( DKIM *  dkim,
int  class,
int  type,
int  prec,
u_char *  name,
u_char *  data 
)

Definition at line 67 of file dkim-test.c.

{
       struct dkim_test_dns_data *td;

       assert(dkim != NULL);
       assert(name != NULL);

       td = (struct dkim_test_dns_data *) DKIM_MALLOC(dkim, sizeof *td);
       if (td == NULL)
              return -1;

       td->dns_class = class;
       td->dns_type = type;
       td->dns_prec = prec;

       td->dns_query = dkim_strdup(dkim, name, 0);
       if (td->dns_query == NULL)
       {
              DKIM_FREE(dkim, td);
              return -1;
       }

       if (data != NULL)
       {
              td->dns_reply = dkim_strdup(dkim, data, 0);
              if (td->dns_reply == NULL)
              {
                     DKIM_FREE(dkim, td->dns_query);
                     DKIM_FREE(dkim, td);
                     return -1;
              }
       }

       td->dns_next = NULL;

       if (dkim->dkim_dnstesth == NULL)
              dkim->dkim_dnstesth = td;
       else
              dkim->dkim_dnstestt->dns_next = td;

       dkim->dkim_dnstestt = td;

       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int dkim_test_key ( DKIM_LIB *  lib,
char *  selector,
char *  domain,
char *  key,
size_t  keylen,
int *  dnssec,
char *  err,
size_t  errlen 
)

Definition at line 283 of file dkim-test.c.

{
       int status = 0;
       DKIM_STAT stat;
       DKIM *dkim;
       DKIM_SIGINFO *sig;
#ifdef USE_GNUTLS
       gnutls_datum_t keybuf;
       gnutls_datum_t outkey;
#else /* USE_GNUTLS */
       BIO *keybuf;
       BIO *outkey;
#endif /* USE_GNUTLS */
       void *ptr;
       struct dkim_rsa *rsa;
       char buf[BUFRSZ];

       assert(lib != NULL);
       assert(selector != NULL);
       assert(domain != NULL);

       dkim = dkim_verify(lib, (u_char *) "test", NULL, &stat);
       if (dkim == NULL)
       {
              if (err != NULL)
                     strlcpy(err, dkim_getresultstr(stat), errlen);
              return -1;
       }

       snprintf(buf, sizeof buf, "v=1; d=%s; s=%s; h=x; b=x; a=x",
                domain, selector);

       stat = dkim_process_set(dkim, DKIM_SETTYPE_SIGNATURE, (u_char *) buf,
                               strlen(buf), NULL, FALSE, NULL);
       if (stat != DKIM_STAT_OK)
       {
              strlcpy(err, "syntax error on input", errlen);
              (void) dkim_free(dkim);
              return -1;
       }

       dkim->dkim_sigcount = 1;

       stat = dkim_siglist_setup(dkim);
       if (stat != DKIM_STAT_OK)
       {
              (void) dkim_free(dkim);
              return -1;
       }

       sig = dkim->dkim_siglist[0];

       dkim->dkim_user = dkim_strdup(dkim, (u_char *) "nobody", 0);
       if (dkim->dkim_user == NULL)
       {
              (void) dkim_free(dkim);
              return -1;
       }

       stat = dkim_get_key(dkim, sig, TRUE);
       if (stat != DKIM_STAT_OK)
       {
              if (err != NULL)
              {
                     const char *errstr;

                     errstr = dkim_geterror(dkim);
                     if (errstr != NULL)
                     {
                            strlcpy(err, errstr, errlen);
                     }
                     else
                     {
                            strlcpy(err, dkim_getresultstr(stat),
                                    errlen);
                     }
              }

              (void) dkim_free(dkim);
              return -1;
       }

       if (dnssec != NULL)
              *dnssec = dkim_sig_getdnssec(sig);

       if (key != NULL)
       {
              rsa = DKIM_MALLOC(dkim, sizeof(struct dkim_rsa));
              if (rsa == NULL)
              {
#ifndef USE_GNUTLS
                     BIO_free(keybuf);
#endif /* ! USE_GNUTLS */
                     (void) dkim_free(dkim);
                     if (err != NULL)
                     {
                            snprintf(err, errlen,
                                     "unable to allocate %zu byte(s)",
                                     sizeof(struct dkim_rsa));
                     }
                     return -1;
              }
              memset(rsa, '\0', sizeof(struct dkim_rsa));

#ifdef USE_GNUTLS
              keybuf.data = key;
              keybuf.size = keylen;
#else /* USE_GNUTLS */
              keybuf = BIO_new_mem_buf(key, keylen);
              if (keybuf == NULL)
              {
                     if (err != NULL)
                     {
                            strlcpy(err, "BIO_new_mem_buf() failed",
                                    errlen);
                     }

                     (void) dkim_free(dkim);
                     return -1;
              }
#endif /* USE_GNUTLS */

              sig->sig_signature = (void *) rsa;
              sig->sig_keytype = DKIM_KEYTYPE_RSA;

#ifdef USE_GNUTLS
              if (err != NULL)
                     strlcpy(err, "function not implemented", errlen);

              (void) dkim_free(dkim);
              return -1;
#else /* USE_GNUTLS */
              rsa->rsa_pkey = PEM_read_bio_PrivateKey(keybuf, NULL,
                                                      NULL, NULL);
              if (rsa->rsa_pkey == NULL)
              {
                     BIO_free(keybuf);
                     (void) dkim_free(dkim);
                     if (err != NULL)
                     {
                            strlcpy(err,
                                    "PEM_read_bio_PrivateKey() failed",
                                    errlen);
                     }
                     return -1;
              }

              rsa->rsa_rsa = EVP_PKEY_get1_RSA(rsa->rsa_pkey);
              if (rsa->rsa_rsa == NULL)
              {
                     BIO_free(keybuf);
                     (void) dkim_free(dkim);
                     if (err != NULL)
                     {
                            strlcpy(err, "EVP_PKEY_get1_RSA() failed",
                                    errlen);
                     }
                     return -1;
              }
       
              rsa->rsa_keysize = RSA_size(rsa->rsa_rsa);
              rsa->rsa_pad = RSA_PKCS1_PADDING;

              outkey = BIO_new(BIO_s_mem());
              if (outkey == NULL)
              {
                     BIO_free(keybuf);
                     (void) dkim_free(dkim);
                     if (err != NULL)
                            strlcpy(err, "BIO_new() failed", errlen);
                     return -1;
              }

              status = i2d_RSA_PUBKEY_bio(outkey, rsa->rsa_rsa);
              if (status == 0)
              {
                     BIO_free(keybuf);
                     BIO_free(outkey);
                     (void) dkim_free(dkim);
                     if (err != NULL)
                     {
                            strlcpy(err, "i2d_RSA_PUBKEY_bio() failed",
                                       errlen);
                     }
                     return -1;
              }

              (void) BIO_get_mem_data(outkey, &ptr);

              if (BIO_number_written(outkey) == sig->sig_keylen)
                     status = memcmp(ptr, sig->sig_key, sig->sig_keylen);
              else
                     status = 1;

              if (status != 0)
                     strlcpy(err, "keys do not match", errlen);

              BIO_free(keybuf);
              BIO_free(outkey);
#endif /* USE_GNUTLS */
       }

       (void) dkim_free(dkim);

       return (status == 0 ? 0 : 1);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

char dkim_test_c_id[] = "@(#)$Id: dkim-test.c,v 1.16.10.1 2010/10/27 21:43:08 cm-msk Exp $" [static]

Definition at line 9 of file dkim-test.c.