### DNS Record Setup and Verification Source: https://context7.com/trusteddomainproject/opendkim/llms.txt Examples for publishing DKIM public keys in DNS zone files and verifying them with dig. ```bash # DNS zone file entry for example.com mail._domainkey.example.com. IN TXT ( "v=DKIM1; k=rsa; " "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA" "1Z4FJEMHjJDuBmt25zvYFVejlARZGt1L8f0s1+rLxIPY" "kfCogQi+Y8oLEg9vvEKnLx9aogZzuNt6j4Sty3LgXxaI" "wHnMqk0LldbA/mh3wLZb16Wc6btXHON0o3uDipxqGK2i" "RLTvcgAnNDegseOS+i0aJEnNSl663ywRBp/QKezhUC7c" "nbqR/H8dz8pEOjeawNN3nexdHGsk+RaafYvCFvU+70CQ" "ORcsk+mxb74SwGT2CGHWxVywQA9yrV+sYkJpxaufZLo6" "xp0Z7RZmbf1eGlCAdhkEy+KYQpQkw2Cdl7iKIK4+17gr" "+XZOrfFLJ5IwpVK/a19m3BLxADf0Kh3oZwIDAQAB" ) # Verify DNS record is published dig -t txt mail._domainkey.example.com # Add test mode flag during initial deployment mail._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; t=y; p=MIIBIj..." ``` -------------------------------- ### Basic OpenDKIM Configuration Source: https://context7.com/trusteddomainproject/opendkim/llms.txt Standard configuration for a single-domain OpenDKIM setup. ```ini Domain example.com Selector mail KeyFile /etc/opendkim/keys/mail.private # Socket for MTA communication Socket inet:8891@localhost # Operating mode: s=sign, v=verify Mode sv # Canonicalization: relaxed/relaxed is most forgiving Canonicalization relaxed/relaxed # Signature algorithm SignatureAlgorithm rsa-sha256 # Hosts to sign for (internal hosts) InternalHosts /etc/opendkim/trusted-hosts # Enable logging Syslog yes SyslogSuccess yes LogWhy yes # Drop privileges UserID opendkim:opendkim # PID file PidFile /var/run/opendkim/opendkim.pid ``` -------------------------------- ### Initialize OpenDKIM Library Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/overview.html Call this once when the application starts to initialize the library. The returned handle can be reused across multiple messages and threads. ```c lib = dkim_init(...); ``` -------------------------------- ### dkim_dns_set_query_start Function Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/dkim_dns_set_query_start.html This function declares the callback to be used by a libopendkim instance when it needs to start a DNS query. By default, a stub function that calls the standard UNIX resolver library is set. ```APIDOC ## dkim_dns_set_query_start() ### Description Declares the function to be used by a libopendkim instance when it needs to start a DNS query. By default, a stub function that calls the standard UNIX resolver library is set. The function will be passed the following arguments: 1. An opaque DNS service handle as previously specified by a call to [dkim_dns_set_query_service()](dkim_dns_set_query_service.html) 2. The DNS query type (e.g., ns_t_txt or the older T_TXT) 3. A NULL-terminated string containing the name to be queried 4. The address of a buffer into which the result should be written 5. The length of that buffer 6. The address of a void * that should be updated to contain an opaque handle for the started query The function is expected to return one of the following: * DKIM_DNS_SUCCESS -- query was successfully initiated * DKIM_DNS_ERROR -- an error occurred ### Method void ### Endpoint N/A (This is a library function, not an API endpoint) ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example N/A ### Response #### Success Response (200) N/A #### Response Example N/A ### Notes * Asynchronous key lookups can also be accomplished using [dkim_set_key_lookup()](dkim_set_key_lookup.html). ``` -------------------------------- ### Manage OpenDKIM Milter Service Source: https://context7.com/trusteddomainproject/opendkim/llms.txt Commands to start and manage the OpenDKIM milter service for MTA integration. ```bash # Start opendkim with command line options opendkim -p inet:8891@localhost -d example.com -k /etc/opendkim/keys/mail.private -s mail # Start with configuration file opendkim -x /etc/opendkim/opendkim.conf # Test mode - process a file without connecting to MTA opendkim -t /path/to/test-message.eml # Run in foreground for debugging opendkim -f -x /etc/opendkim/opendkim.conf # Run with verbose logging opendkim -v -x /etc/opendkim/opendkim.conf ``` -------------------------------- ### Declare DNS Resolver Initialization Function Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/dkim_dns_set_close.html Declares the function to be used by a libopendkim instance when it needs to initialize a DNS resolver. A stub function initializing the standard system resolver is set by default. This function is called implicitly if no service handle is stored and a query is ready to start. ```c #include int dkim_dns_set_init( DKIM_LIB *libopendkim, int (*func)(void **) ); ``` -------------------------------- ### dkim_libversion() - Get Library Version Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/dkim_libversion.html Retrieves the version of the OpenDKIM library that the application was linked against. The version is returned as a 32-bit integer. ```APIDOC ## dkim_libversion() ### Description Returns the version of the library against which an application was linked. The version is encoded as a four-octet integer, with the octets representing (from highest-order to lowest-order) the release number, the major version number, the minor version number, and the patch level. ### Method N/A (C function) ### Endpoint N/A (C function) ### Parameters None. ### Request Example N/A ### Response #### Success Response - **return value** (uint32_t) - The encoded library version. #### Response Example ```c uint32_t version = dkim_libversion(); // version will contain the encoded library version ``` ``` -------------------------------- ### dkim_getsiglist - Get Signature Information Source: https://context7.com/trusteddomainproject/opendkim/llms.txt Retrieves the list of signatures found in a message during verification. ```APIDOC ## dkim_getsiglist - Get Signature Information ### Description Retrieves the list of signatures found in a message during verification. ### Method (Not applicable - C function) ### Endpoint (Not applicable - C function) ### Parameters (Not applicable - C function parameters are shown in the code example) ### Request Example ```c #include DKIM *dkim; DKIM_STAT status; DKIM_SIGINFO **sigs; int nsigs; /* Get list of signatures after dkim_eoh() */ status = dkim_getsiglist(dkim, &sigs, &nsigs); if (status == DKIM_STAT_OK) { printf("Found %d signature(s)\n", nsigs); for (int i = 0; i < nsigs; i++) { unsigned char *domain = dkim_sig_getdomain(sigs[i]); unsigned char *selector = dkim_sig_getselector(sigs[i]); int flags = dkim_sig_getflags(sigs[i]); printf("Signature %d: domain=%s, selector=%s\n", i + 1, domain, selector); if (flags & DKIM_SIGFLAG_PASSED) { printf(" Status: PASSED\n"); } else if (flags & DKIM_SIGFLAG_PROCESSED) { int error = dkim_sig_geterror(sigs[i]); printf(" Status: FAILED (%s)\n", dkim_sig_geterrorstr(error)); } } } ``` ### Response #### Success Response (DKIM_STAT_OK) - **sigs** (DKIM_SIGINFO **) - A pointer to an array of signature information structures. - **nsigs** (int *) - A pointer to an integer storing the number of signatures found. #### Response Example ``` Found 1 signature(s) Signature 1: domain=example.com, selector=selector Status: PASSED ``` ``` -------------------------------- ### dkim_getsighdr - Get Generated Signature Header Source: https://context7.com/trusteddomainproject/opendkim/llms.txt After signing, retrieves the generated DKIM-Signature header to be added to the message. ```APIDOC ## dkim_getsighdr - Get Generated Signature Header ### Description After signing, retrieves the generated DKIM-Signature header to be added to the message. ### Method (Not applicable - C function) ### Endpoint (Not applicable - C function) ### Parameters (Not applicable - C function parameters are shown in the code example) ### Request Example ```c #include DKIM *dkim; DKIM_STAT status; unsigned char signature[4096]; /* Get the signature header after dkim_eom() */ status = dkim_getsighdr(dkim, signature, sizeof(signature), strlen("DKIM-Signature: ")); if (status == DKIM_STAT_OK) { printf("DKIM-Signature: %s\n", signature); /* * Output example: * DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=example.com; * s=selector; t=1704110400; * h=from:to:subject:date:message-id; * bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=; * b=AuUoFEfDxTDkHlLXSZEpZj79LICEps6eda7W3deTVFOk4yAUoqO... */ } ``` ### Response #### Success Response (DKIM_STAT_OK) - **signature** (unsigned char array) - The generated DKIM-Signature header. #### Response Example ``` DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=example.com; s=selector; t=1704110400; h=from:to:subject:date:message-id; bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=; b=AuUoFEfDxTDkHlLXSZEpZj79LICEps6eda7W3deTVFOk4yAUoqO... ``` ``` -------------------------------- ### Sign an Email Message in C Source: https://context7.com/trusteddomainproject/opendkim/llms.txt Demonstrates the full workflow for signing an email message using the OpenDKIM C library. Requires proper initialization and cleanup of the DKIM library handle. ```c #include #include #include int sign_message(const char *privatekey, const char *selector, const char *domain, const char *message) { DKIM_LIB *lib; DKIM *dkim; DKIM_STAT status; unsigned char sighdr[4096]; /* Initialize library */ lib = dkim_init(NULL, NULL); if (lib == NULL) { fprintf(stderr, "dkim_init() failed\n"); return -1; } /* Create signing handle */ dkim = dkim_sign(lib, "test-msg", NULL, (dkim_sigkey_t)privatekey, (unsigned char *)selector, (unsigned char *)domain, DKIM_CANON_RELAXED, DKIM_CANON_RELAXED, DKIM_SIGN_RSASHA256, -1, &status); if (dkim == NULL) { fprintf(stderr, "dkim_sign() failed: %s\n", dkim_getresultstr(status)); dkim_close(lib); return -1; } /* Process headers (find blank line separator) */ const char *body = strstr(message, "\r\n\r\n"); if (body == NULL) body = strstr(message, "\n\n"); const char *hdr_start = message; const char *hdr_end; while (hdr_start < body) { hdr_end = strstr(hdr_start, "\r\n"); if (hdr_end == NULL) hdr_end = strchr(hdr_start, '\n'); if (hdr_end == NULL || hdr_end >= body) break; status = dkim_header(dkim, (u_char *)hdr_start, hdr_end - hdr_start); if (status != DKIM_STAT_OK) { fprintf(stderr, "dkim_header() failed\n"); dkim_free(dkim); dkim_close(lib); return -1; } hdr_start = hdr_end + (hdr_end[1] == '\n' ? 2 : 1); } /* End of headers */ status = dkim_eoh(dkim); if (status != DKIM_STAT_OK) { fprintf(stderr, "dkim_eoh() failed\n"); dkim_free(dkim); dkim_close(lib); return -1; } /* Process body */ body = body + (body[1] == '\n' ? 4 : 2); /* Skip blank line */ status = dkim_body(dkim, (u_char *)body, strlen(body)); if (status != DKIM_STAT_OK) { fprintf(stderr, "dkim_body() failed\n"); dkim_free(dkim); dkim_close(lib); return -1; } /* End of message - generate signature */ status = dkim_eom(dkim, NULL); if (status != DKIM_STAT_OK) { fprintf(stderr, "dkim_eom() failed: %s\n", dkim_getresultstr(status)); dkim_free(dkim); dkim_close(lib); return -1; } /* Get the signature header */ status = dkim_getsighdr(dkim, sighdr, sizeof(sighdr), strlen("DKIM-Signature: ")); if (status == DKIM_STAT_OK) { printf("DKIM-Signature: %s\n", sighdr); } /* Cleanup */ dkim_free(dkim); dkim_close(lib); return 0; } ``` -------------------------------- ### MTA Integration for Sendmail and Postfix Source: https://context7.com/trusteddomainproject/opendkim/llms.txt Configuration snippets to connect OpenDKIM as a milter to Sendmail or Postfix. ```ini # Sendmail: Add to sendmail.mc INPUT_MAIL_FILTER(`opendkim', `S=inet:8891@localhost') # Postfix: Add to main.cf smtpd_milters = inet:localhost:8891 non_smtpd_milters = inet:localhost:8891 milter_default_action = accept ``` -------------------------------- ### Get DKIM Signature Header Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/overview.html Compute and retrieve the base64-encoded signature for the message. The entire signature header field is generated and returned. ```c stat = dkim_getsighdr(dkim, ...); ``` -------------------------------- ### dkim_init Source: https://context7.com/trusteddomainproject/opendkim/llms.txt Initializes the DKIM library and returns a handle required for all subsequent operations. ```APIDOC ## dkim_init ### Description Creates a new instantiation of the DKIM service for signing or verifying messages. Returns a library handle that must be passed to all subsequent operations. ### Parameters - **malloc_func** (function pointer) - Optional - Custom memory allocation function. - **free_func** (function pointer) - Optional - Custom memory free function. ### Response - **DKIM_LIB*** (handle) - A pointer to the initialized library structure or NULL on failure. ``` -------------------------------- ### dkim_dns_set_init Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/dkim_dns_set_close.html Configures the function used by libopendkim to initialize a DNS resolver. ```APIDOC ## dkim_dns_set_init ### Description Declares the function to be used by a libopendkim instance when it needs to initialize a DNS resolver. By default, a stub function that initializes the standard system resolver is set. ### Parameters - **libopendkim** (DKIM_LIB*) - Required - The library instantiation handle, returned by dkim_init(). - **func** (int (*)(void **)) - Required - A pointer to a function that should be used to instantiate a DNS resolver. ### Return Values - **DKIM_DNS_SUCCESS** - Successful operation - **DKIM_DNS_ERROR** - An error occurred ``` -------------------------------- ### dkim_init() - Initialize DKIM Service Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/dkim_init.html Initializes a new instance of the DKIM service. This function is used to set up the DKIM library for either signing or verifying email messages. It allows for the specification of custom memory allocation and deallocation functions. ```APIDOC ## dkim_init() ### Description Creates a new instantiation of the DKIM service, for signing or verifying Internet messages. This function is called when setting up the application. The handle it returns is used when generating per-message handles for signing and verifying, and is used to declare optional alternate memory allocate and free functions. ### Method N/A (C function) ### Endpoint N/A (C function) ### Parameters #### Arguments - **mallocf** (void *(\*mallocf)(void *closure, size_t nbytes)) - Optional - Alternate memory allocation function. It must take two parameters: a void pointer which is the memory closure specified in calls to [dkim_sign()](dkim_sign.html) or [dkim_verify()](dkim_verify.html), and the number of bytes to be allocated. This allows memory allocations for a specific message to be made within the same closure. - **freef** (void (*freef)(void *closure, void *p)) - Optional - Alternate memory release function. It must take two parameters: a void pointer which is the memory closure specified in calls to [dkim_sign()](dkim_sign.html) or [dkim_verify()](dkim_verify.html), and the pointer to memory to be released. This allows memory allocations for a specific message to be made within the same closure. ### Request Example N/A (C function) ### Response #### Success Response - **DKIM_LIB*** - On success, a pointer to the created [DKIM_LIB](dkim_lib.html) handle is returned. #### Failure Response - **NULL** - On failure, NULL is returned. Generally this means a memory allocation failure. ### Notes - The handle returned by this function is passed to [dkim_sign()](dkim_sign.html) and [dkim_verify()](dkim_verify.html). ``` -------------------------------- ### dkim_getsighdr - Get Generated Signature Header Source: https://context7.com/trusteddomainproject/opendkim/llms.txt After signing and calling dkim_eom(), this function retrieves the generated DKIM-Signature header. Ensure sufficient buffer size is provided. ```c #include DKIM *dkim; DKIM_STAT status; unsigned char signature[4096]; /* Get the signature header after dkim_eom() */ status = dkim_getsighdr(dkim, signature, sizeof(signature), strlen("DKIM-Signature: ")); if (status == DKIM_STAT_OK) { printf("DKIM-Signature: %s\n", signature); /* * Output example: * DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=example.com; * s=selector; t=1704110400; * h=from:to:subject:date:message-id; * bh=2jUSOH9NhtVGCQWNr9BrIAPreKQjO6Sn7XIkfJVOzv8=; * b=AuUoFEfDxTDkHlLXSZEpZj79LICEps6eda7W3deTVFOk4yAUoqO... */ } ``` -------------------------------- ### Initialize DKIM Service - C Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/dkim_init.html Call dkim_init() when setting up the application to create a DKIM service handle. This handle is used for per-message operations and can optionally specify alternate memory allocation functions. ```c #include DKIM_LIB *dkim_init( void *(\*mallocf)(void *closure, size_t nbytes), void (*freef)(void *closure, void *p) ); ``` -------------------------------- ### Get DKIM Signature Selector Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/dkim_sig_getselector.html Use dkim_sig_getselector() to retrieve the selector name from a DKIM signature handle. This function can be called after the signature information handles have been initialized. ```c #include const char * dkim_sig_getselector( [DKIM_SIGINFO](dkim_siginfo.html) *sig ); ``` -------------------------------- ### Retrieve DKIM Signature Context Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/dkim_sig_getcontext.html Use dkim_sig_getcontext() to get the user-defined context pointer for a DKIM signature. This function is callable from within a prescreen callback if one is defined. ```c #include void * dkim_sig_getcontext( DKIM_SIGINFO *sig ); ``` -------------------------------- ### dkim_dns_init() - Initialize DNS Resolver Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/dkim_dns_init.html Initializes the DNS resolver for the OpenDKIM library. This function can be called at any time and ensures the DNS resolver is ready for lookups. ```APIDOC ## dkim_dns_init() ### Description Initializes the DNS resolver to be used by the library. This is automatically called if the resolver has not yet been initialized and the library needs to perform a DNS lookup. ### Method N/A (C function) ### Endpoint N/A (C function) ### Parameters #### Arguments - **libopendkim** (DKIM_LIB*) - The library instantiation handle, returned by dkim_init(). ### Request Example N/A (C function) ### Response #### Return Values - **DKIM_DNS_SUCCESS** (int) - successful operation - **DKIM_DNS_INVALID** (int) - already initialized - **DKIM_DNS_ERROR** (int) - an error occurred #### Response Example N/A (C function) ``` -------------------------------- ### dkim_getsiglist - Get Signature Information Source: https://context7.com/trusteddomainproject/opendkim/llms.txt Retrieves a list of signatures found in a message during verification after dkim_eoh() has been called. Iterates through the list to access domain, selector, and status flags for each signature. ```c #include DKIM *dkim; DKIM_STAT status; DKIM_SIGINFO **sigs; int nsigs; /* Get list of signatures after dkim_eoh() */ status = dkim_getsiglist(dkim, &sigs, &nsigs); if (status == DKIM_STAT_OK) { printf("Found %d signature(s)\n", nsigs); for (int i = 0; i < nsigs; i++) { unsigned char *domain = dkim_sig_getdomain(sigs[i]); unsigned char *selector = dkim_sig_getselector(sigs[i]); int flags = dkim_sig_getflags(sigs[i]); printf("Signature %d: domain=%s, selector=%s\n", i + 1, domain, selector); if (flags & DKIM_SIGFLAG_PASSED) { printf(" Status: PASSED\n"); } else if (flags & DKIM_SIGFLAG_PROCESSED) { int error = dkim_sig_geterror(sigs[i]); printf(" Status: FAILED (%s)\n", dkim_sig_geterrorstr(error)); } } } ``` -------------------------------- ### Initialize OpenDKIM Library Source: https://context7.com/trusteddomainproject/opendkim/llms.txt Initializes the DKIM library, optionally with custom memory allocators. The returned handle is required for subsequent operations. Ensure to call dkim_close() when done. ```c #include /* Initialize the DKIM library with default memory allocators */ DKIM_LIB *lib = dkim_init(NULL, NULL); if (lib == NULL) { fprintf(stderr, "dkim_init() failed\n"); exit(1); } /* Or with custom memory allocators */ void *my_malloc(void *closure, size_t nbytes) { return malloc(nbytes); } void my_free(void *closure, void *p) { free(p); } DKIM_LIB *lib = dkim_init(my_malloc, my_free); /* When done, shut down the library */ dkim_close(lib); ``` -------------------------------- ### Retrieve SSL Error Buffer from DKIM Signature Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/dkim_sig_getsslbuf.html Use dkim_sig_getsslbuf() to get the SSL error string after the cryptographic phase of signature processing. It returns NULL if no error message was recorded. ```c #include const char * dkim_sig_getsslbuf( DKIM_SIGINFO *sig ); ``` -------------------------------- ### Load Private Key for Signing - C Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/dkim_privkey_load.html Use dkim_privkey_load() to load and prepare a private key for signing. This function is called after dkim_sign() and before dkim_eom() if explicit loading is desired. The crypto library's strictness may affect key parsing. ```c #include DKIM_STAT dkim_privkey_load( DKIM *dkim ); ``` -------------------------------- ### Multi-Domain OpenDKIM Configuration Source: https://context7.com/trusteddomainproject/opendkim/llms.txt Configuration files for managing multiple domains with separate keys and signing tables. ```ini # /etc/opendkim/opendkim.conf KeyTable /etc/opendkim/key.table SigningTable refile:/etc/opendkim/signing.table ExternalIgnoreList /etc/opendkim/trusted-hosts InternalHosts /etc/opendkim/trusted-hosts Socket inet:8891@localhost Mode sv Canonicalization relaxed/relaxed Syslog yes UserID opendkim:opendkim ``` ```ini # /etc/opendkim/key.table # Format: keyname domain:selector:keyfile example example.com:mail:/etc/opendkim/keys/example.private example-net example.net:default:/etc/opendkim/keys/example-net.private subdomain sub.example.com:mail:/etc/opendkim/keys/sub.private ``` ```ini # /etc/opendkim/signing.table # Format: pattern keyname (supports wildcards with refile:) *@example.com example *@example.net example-net *@sub.example.com subdomain ``` ```ini # /etc/opendkim/trusted-hosts 127.0.0.1 ::1 localhost 192.168.1.0/24 mail.example.com ``` -------------------------------- ### dkim_set_signer() Function Signature Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/dkim_set_signer.html Specifies the signer to be included in the signature being generated. This will cause the "i=" tag to be added to the signature when it gets generated. Called at any time prior to signature generation. ```c #include DKIM_STAT dkim_set_signer( DKIM *dkim, const unsigned char *signer); ``` -------------------------------- ### Create DKIM Signing Handle Source: https://context7.com/trusteddomainproject/opendkim/llms.txt Creates a handle for signing messages. Requires a library handle, message ID, private key, selector, domain, canonicalization methods, signing algorithm, and body signing option. The status is returned via a pointer. ```c #include DKIM_LIB *lib; DKIM *dkim; DKIM_STAT status; /* Private key in PEM format */ const char *privatekey = "-----BEGIN RSA PRIVATE KEY-----\n" "MIICXgIBAAJBALb...(key data)... "" "-----END RSA PRIVATE KEY-----\n"; /* Create a signing handle */ dkim = dkim_sign(lib, /* library handle */ "msg-id-12345", /* message ID for logging */ NULL, /* memory closure */ (dkim_sigkey_t)privatekey, /* private key */ (unsigned char *)"selector", /* DNS selector */ (unsigned char *)"example.com", /* signing domain */ DKIM_CANON_RELAXED, /* header canonicalization */ DKIM_CANON_SIMPLE, /* body canonicalization */ DKIM_SIGN_RSASHA256, /* signing algorithm */ -1, /* sign entire body */ &status); /* status return */ if (dkim == NULL) { fprintf(stderr, "dkim_sign() failed: %s\n", dkim_getresultstr(status)); exit(1); } ``` -------------------------------- ### Retrieve DNS Query Name with dkim_qi_getname() Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/dkim_qi_getname.html Use dkim_qi_getname() to get the DNS name from a DKIM_QUERYINFO handle. This function can be called any time after query information is returned by dkim_sig_getqueries(). It returns NULL if no name can be determined. ```c #include const char * dkim_qi_getname( DKIM_QUERYINFO *query ); ``` -------------------------------- ### dkim_privkey_load() Function Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/dkim_privkey_load.html This function attempts to load and prepare a private key for signing. It is called after dkim_sign() and before dkim_eom() if explicit loading is desired. ```APIDOC ## dkim_privkey_load() ### Description Attempts to load and prepare a private key for signing. This operation is implicitly performed by dkim_eom() if not called explicitly beforehand. ### Method N/A (C function) ### Endpoint N/A (C function) ### Parameters #### Arguments - **dkim** ([DKIM](dkim.html) *) - Message-specific handle, returned by [dkim_sign()](dkim_sign.html). ### Return Values - DKIM_STAT_OK: Indicates the key was successfully parsed and loaded by the crypto library. - DKIM_STAT_NORESOURCE: Indicates the key could not be parsed. ### Notes - This library relies on an external cryptography library for hashing and signing operations. The strictness of key parsing can vary between these libraries, and this library responds to the error codes passed up from them. ### Example ```c #include DKIM_STAT status = dkim_privkey_load(dkim_handle); ``` ``` -------------------------------- ### Verify DNS Key Records with opendkim-testkey Source: https://context7.com/trusteddomainproject/opendkim/llms.txt Validates that a private key matches the public key published in DNS. ```bash # Test key for domain and selector opendkim-testkey -d example.com -s mail # Test with specific private key file opendkim-testkey -d example.com -s mail -k /etc/opendkim/keys/mail.private # Verbose output showing DNS query details opendkim-testkey -vvv -d example.com -s mail ``` -------------------------------- ### void dkim_dns_set_query_waitreply() Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/dkim_dns_set_query_waitreply.html Declares the function to be used by a libopendkim instance when it needs to wait on a DNS query already in progress. ```APIDOC ## void dkim_dns_set_query_waitreply() ### Description Declares the function to be used by a libopendkim instance when it needs to wait on a DNS query already in progress. By default, a stub function is set as the standard UNIX resolver library is not asynchronous. ### Parameters - **libopendkim** (DKIM_LIB *) - Required - The library instantiation handle, returned by dkim_init(). - **func** (int (*)(void *, void *, struct timeval *, size_t *, int *, int *)) - Required - A pointer to a function that should be used to wait on active DNS queries. ### Callback Function Arguments 1. **dns_service_handle** (void *) - Opaque DNS service handle. 2. **query_handle** (void *) - Handle for a previously initiated DNS query. 3. **timeout** (struct timeval *) - Pointer to a structure stipulating a timeout. 4. **reply_len** (size_t *) - Pointer to receive the length of the reply. 5. **error_code** (int *) - Pointer to receive an error code. 6. **dnssec_status** (int *) - Pointer to receive a DKIM_DNSSEC constant. ### Return Values The callback function is expected to return: - DKIM_DNS_SUCCESS: A reply is available. - DKIM_DNS_EXPIRED: The query expired. - DKIM_DNS_ERROR: An I/O error occurred. - DKIM_DNS_NOREPLY: The specified timeout expired. ``` -------------------------------- ### dkim_verify() Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/dkim_verify.html Initializes a new DKIM handle for verifying a signed message. ```APIDOC ## dkim_verify() ### Description Creates a new handle for verifying a (possibly) signed message. ### Parameters #### Arguments - **libhandle** (DKIM_LIB*) - Required - DKIM library instance handle, returned by an earlier call to dkim_init(). - **id** (const char*) - Required - An opaque, printable string for identifying this message, suitable for use in logging or debug output. - **memclosure** (void*) - Required - Opaque memory closure, passed directly to the caller-provided malloc() and/or free() replacement functions. - **statp** (DKIM_STAT*) - Required - Pointer to a DKIM_STAT object which receives the completion status of this operation. ### Response - **Success** (DKIM*) - A pointer to the created DKIM handle. - **Failure** (NULL) - Returns NULL and updates the value of statp to indicate the cause of the problem. ``` -------------------------------- ### dkim_dns_set_query_service() Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/dkim_dns_set_query_service.html Specifies an opaque handle referring to the DNS service to be used by libopendkim. This handle will be passed to the DNS functions declared using dkim_dns_set_query_start(), dkim_dns_set_query_cancel(), and dkim_dns_set_query_waitreply(). ```APIDOC ## dkim_dns_set_query_service() ### Description Specifies an opaque handle referring to the DNS service to be used by libopendkim. This handle will be passed to the DNS functions declared using dkim_dns_set_query_start(), dkim_dns_set_query_cancel(), and dkim_dns_set_query_waitreply(). ### Method void ### Endpoint N/A (C function) ### Parameters #### Arguments - **libopendkim** (DKIM_LIB *) - The library instantiation handle, returned by dkim_init(). - **service** (void *) - An opaque handle referring to the DNS service to be used. ### Return Values * None. ### Notes * Asynchronous key lookups can also be accomplished using dkim_set_key_lookup(). ``` -------------------------------- ### Create DKIM Verification Handle Source: https://context7.com/trusteddomainproject/opendkim/llms.txt Creates a handle for verifying DKIM signatures in incoming messages. Requires a library handle and a message ID for logging. The status is returned via a pointer. ```c #include DKIM_LIB *lib; DKIM *dkim; DKIM_STAT status; /* Create a verification handle */ dkim = dkim_verify(lib, /* library handle */ "msg-id-67890", /* message ID for logging */ NULL, /* memory closure */ &status); /* status return */ if (dkim == NULL) { fprintf(stderr, "dkim_verify() failed: %s\n", dkim_getresultstr(status)); exit(1); } ``` -------------------------------- ### dkim_dns_nslist() Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/dkim_dns_nslist.html Defines the set of nameservers to be used by the resolver. ```APIDOC ## dkim_dns_nslist() ### Description Defines the set of nameservers to be used by the resolver. This function is most useful prior to performing DNS operations such as verification. ### Parameters - **libopendkim** (DKIM_LIB*) - Required - The library instantiation handle, returned by dkim_init(). - **nslist** (const char*) - Required - A null-terminated string containing a comma-separated list of nameserver IP addresses. ### Response - **DKIM_DNS_SUCCESS** - Successful operation. - **DKIM_DNS_ERROR** - An error occurred. ``` -------------------------------- ### Set user context for DKIM handle Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/dkim_set_user_context.html Defines an opaque pointer to be passed to DNS callbacks. This is primarily useful during verification operations. ```c #include DKIM_STAT dkim_set_user_context( DKIM *dkim, void *ctx); ); ``` -------------------------------- ### Generate DKIM Keys with opendkim-genkey Source: https://context7.com/trusteddomainproject/opendkim/llms.txt Utility for generating private keys and corresponding DNS TXT records. Use the -s flag to define the selector and -d for the domain. ```bash # Generate a 2048-bit key with selector "mail" for domain example.com opendkim-genkey -b 2048 -d example.com -s mail # Output files: mail.private (private key), mail.txt (DNS TXT record) # Generate key with test mode flag (for initial testing) opendkim-genkey -t -d example.com -s mail # Generate key restricted to email signing only opendkim-genkey -r -d example.com -s mail # Generate key in specific directory opendkim-genkey -D /etc/opendkim/keys -d example.com -s mail # Generated DNS record (mail.txt) example: # mail._domainkey IN TXT ( "v=DKIM1; k=rsa; " # "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..." ) ``` -------------------------------- ### Define Nameservers for DNS Resolver - C Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/dkim_dns_nslist.html Use dkim_dns_nslist() to specify a comma-separated list of IP addresses for nameservers. This is useful before performing DNS operations, such as during verification in dkim_eoh(). ```c #include DKIM_STAT dkim_dns_nslist( DKIM_LIB *libopendkim, const char * nslist ); ``` -------------------------------- ### dkim_options - Set/Get Library Options Source: https://context7.com/trusteddomainproject/opendkim/llms.txt Configures library behavior such as timeouts, canonicalization defaults, and feature flags. ```APIDOC ## dkim_options - Set/Get Library Options ### Description Configures library behavior such as timeouts, canonicalization defaults, and feature flags. ### Method (Not applicable - C function) ### Endpoint (Not applicable - C function) ### Parameters (Not applicable - C function parameters are shown in the code example) ### Request Example ```c #include DKIM_LIB *lib; DKIM_STAT status; unsigned int flags; unsigned int timeout; /* Get current flags */ status = dkim_options(lib, DKIM_OP_GETOPT, DKIM_OPTS_FLAGS, &flags, sizeof(flags)); /* Enable caching and temporary files for debugging */ flags = DKIM_LIBFLAGS_CACHE | DKIM_LIBFLAGS_TMPFILES; status = dkim_options(lib, DKIM_OP_SETOPT, DKIM_OPTS_FLAGS, &flags, sizeof(flags)); /* Set DNS timeout to 30 seconds */ timeout = 30; status = dkim_options(lib, DKIM_OP_SETOPT, DKIM_OPTS_TIMEOUT, &timeout, sizeof(timeout)); /* Specify headers that must be signed */ const char *mustbesigned[] = { "from", "to", "subject", NULL }; status = dkim_options(lib, DKIM_OP_SETOPT, DKIM_OPTS_MUSTBESIGNED, mustbesigned, sizeof(mustbesigned)); ``` ### Response #### Success Response (DKIM_STAT_OK) (Not applicable - function returns status code) #### Response Example (Status codes are returned, not structured responses) ``` -------------------------------- ### dkim_options - Set/Get Library Options Source: https://context7.com/trusteddomainproject/opendkim/llms.txt Configures library behavior such as timeouts, canonicalization defaults, and feature flags. Options can be set or retrieved using DKIM_OP_SETOPT and DKIM_OP_GETOPT respectively. ```c #include DKIM_LIB *lib; DKIM_STAT status; unsigned int flags; unsigned int timeout; /* Get current flags */ status = dkim_options(lib, DKIM_OP_GETOPT, DKIM_OPTS_FLAGS, &flags, sizeof(flags)); /* Enable caching and temporary files for debugging */ flags = DKIM_LIBFLAGS_CACHE | DKIM_LIBFLAGS_TMPFILES; status = dkim_options(lib, DKIM_OP_SETOPT, DKIM_OPTS_FLAGS, &flags, sizeof(flags)); /* Set DNS timeout to 30 seconds */ timeout = 30; status = dkim_options(lib, DKIM_OP_SETOPT, DKIM_OPTS_TIMEOUT, &timeout, sizeof(timeout)); /* Specify headers that must be signed */ const char *mustbesigned[] = { "from", "to", "subject", NULL }; status = dkim_options(lib, DKIM_OP_SETOPT, DKIM_OPTS_MUSTBESIGNED, mustbesigned, sizeof(mustbesigned)); ``` -------------------------------- ### Free Signing Handle Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/overview.html Free resources associated with a specific signing message handle. This should be called after obtaining the signature. ```c stat = dkim_free(dkim); ``` -------------------------------- ### Utility Functions Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/index.html Utility functions for retrieving information, checking syntax, and managing library options. ```APIDOC ## DKIM Utility Functions ### dkim_getid() **Description**: Retrieve "id" string from handle. ### dkim_get_msgdate() **Description**: Attempt to parse the Date: header field of a message and return its UNIX time_t conversion as a 64-bit unsigned integer. ### dkim_get_sigsubstring() **Description**: Retrieve a minimal signature substring for matching results to signatures. ### dkim_key_syntax() **Description**: Check the syntax of a key record. ### dkim_mail_parse() **Description**: Parse a message header field, e.g. From:, to get user and domain. ### dkim_mail_parse_multi() **Description**: Parse a message header field, e.g. To: or Cc:, to get users and domains. ### dkim_options() **Description**: Get or set library options. ### dkim_qi_getname() **Description**: Retrieve the DNS name from a DKIM_QUERYINFO handle. ### dkim_qi_gettype() **Description**: Retrieve the DNS resource record type from a DKIM_QUERYINFO handle. ### dkim_sig_gethashes() **Description**: Retrieve computed hashes related to a signature. ### dkim_sig_gettagvalue() **Description**: Retrieve arbitrary tags and values from signatures and keys. ### dkim_sig_syntax() **Description**: Check the syntax of a signature. ``` -------------------------------- ### OpenDKIM Library Administration Functions Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/index.html Functions for initializing, managing, and closing the OpenDKIM service, as well as retrieving library information and statistics. ```APIDOC ## OpenDKIM Library Administration Functions ### Description Functions for initializing, managing, and closing the OpenDKIM service, as well as retrieving library information and statistics. ### Functions #### Initialize and Terminate - **dkim_init()**: Initialize an instance of the DKIM service. - **dkim_close()**: Terminate an instance of the DKIM service. #### Cache Management - **dkim_flush_cache()**: Flush the key cache. - **dkim_getcachestats()**: Retrieve caching statistics. #### Error and Mode Handling - **dkim_geterror()**: Retrieve the most recent internal error message associated with a DKIM handle. - **dkim_getmode()**: Return the mode (signing or verifying) of a DKIM handle. #### Context and Signer Retrieval - **dkim_get_signer()**: Retrieve the current message signer (if any). - **dkim_get_user_context()**: Retrieve a specific user context pointer for a sign or verify operation previously set by a call to dkim_set_user_context(). #### Library Information and Features - **dkim_libfeature()**: Test for availability of a particular feature in the library. - **dkim_libversion()**: Retrieve the version of libopendkim against which the application is linked. - **dkim_ssl_version()**: Retrieve the OpenSSL version used when the library was compiled. #### Callback and Lookup Configuration - **dkim_set_dns_callback()**: Request a call back into the main program from time to time while waiting for DNS results. - **dkim_set_final()**: Provide a function to perform final signature analysis and/or re-ordering during verifications. - **dkim_set_key_lookup()**: Provide a function to perform key lookups, replacing the internal implementation. Includes support for asynchronous operation. - **dkim_set_prescreen()**: Provide a function to perform signature prescreening and/or re-ordering during verifications. - **dkim_set_signature_handle()**: Provide a function to allocate a user-side signature description structure and return a pointer to it. - **dkim_set_signature_handle_free()**: Provide a function to deallocate a user-side signature description structure. - **dkim_set_signature_tagvalues()**: Provide a function to receive signature-specific tags and values for user-side analysis. - **dkim_set_user_context()**: Set a specific user context pointer for a sign or verify operation which will be passed to user callbacks. ``` -------------------------------- ### Register a DNS callback function Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/dkim_set_dns_callback.html Defines a function to be called periodically during DNS resolution, useful for timeout-sensitive applications. ```c #include DKIM_STAT dkim_set_dns_callback( DKIM_LIB *libopendkim, void (*func)(const void *context), unsigned int interval); ); ``` -------------------------------- ### dkim_dns_set_nslist() Function Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/dkim_dns_set_nslist.html Declares the function to be used by a libopendkim instance when it needs to replace the set of nameservers used by a DNS resolver. By default, a stub function that configures the standard system resolver (when supported) is set. ```APIDOC ## dkim_dns_set_nslist() ### Description Declares the function to be used by a libopendkim instance when it needs to replace the set of nameservers used by a DNS resolver. By default, a stub function that configures the standard system resolver (when supported) is set. ### Method C Function ### Endpoint N/A (Library Function) ### Parameters #### Arguments - **libopendkim** (*DKIM_LIB*) - The library instantiation handle, returned by [dkim_init()](dkim_init.html). - **func** (int (*)(void *, const char *)) - A pointer to a function that should be used to change the list of nameservers to be queried by the DNS resolver. ### Request Example N/A (C Function) ### Response #### Return Values - **DKIM_DNS_SUCCESS** (int) - successful operation - **DKIM_DNS_ERROR** (int) - an error occurred ``` -------------------------------- ### Add Body Chunk for Signing Source: https://github.com/trusteddomainproject/opendkim/blob/master/libopendkim/docs/overview.html Pass a chunk of the message body to libopendkim for signature computation. Repeat this call for each body chunk. ```c stat = dkim_body(dkim, ...); ```