diff --git a/pages/help/0.php b/pages/help/0.php index 010b33c..17c41c5 100644 --- a/pages/help/0.php +++ b/pages/help/0.php @@ -19,7 +19,6 @@
=_("Following are several tips you may find useful.")?>
CERTIFICATE RETRIEVAL - - -STATUS OF THIS MEMO - - This document is an Internet-Draft and is subject to all provisions of - Section 10 of RFC2026.. - -INTRODUCTION - - The CERTIFICATE RETRIEVAL Service is a TCP transaction based query/response - server, running on port xxxxx, that provides directory service for internet - users to automate the task of retrieving certificates based on email - addresses or hostnames. - - This service, together with a corresponding database of X.509 certificates - can be used to automate security in conjunction with the 802.1x protocol - for authentication and encryption, webmail services, and email in general - that employ s/mime to encrypt replies to authors could request a certificate - via the service rather then requiring the user to supply it up front, so as - long as you know the email address and they have signed up for a certificate - the message can be encrypted. - - This method of distributing client certificates isn't intended for extremely - sensitive material, but merely to protect day to day emails that are currently - being sent as clear text. The security risk in this method isn't more likely - to succeed then signing an email and distributing the certificate in that - manner. - -PROTOCOL - - To access the CERTIFICATE RETRIEVAL service: - - Connect to the service host on TCP service port xxxxx - (decimal). - - Send a single "command line", ending with(ASCII CR and - LF). - - Receive information in response to the command line. The server - closes its connection as soon as the output is finished. - - Extention to Service: - - This service could be extended to relay services that worked inline - with Certificate Authorities to cache responses and verify the - certificates were still valid using OCSP services. Using the relay - method it would be easier to include additional Certificate - Authorities, instead of issuing client software updates every time a - new Certificate Authority commenced operations, or alternatively - ceased to operate. - - Due to political concerns more then technical issues relay services - should be run by impartial parties that don't have a vested interest - in competing with other Certificate Authorities so no user would be - disadvantaged. - -SECURITY ISSUES - - Spam: - - Obviously this would open a potential method for spammers to validate - their spam lists, and sending encrypted spam which may bypass current - spam filters. This system to an extent mimics the PGP Key Exchange - service, unlike the PGP Key Exchange there will be no effort to allow - searching apart from exact email or hostnames. At time of writting - there are no documented attempts to exploit the PGP Key Exchange for - the purposes of spam. Certificate Authorities should offer a way for - their users to opt out of this method of distributing public - certificates. - - Transfer: - - Due to the nature of X.509 it would be highly improbable that the - certificates could be compromised if they passed via a compromised - relay, or as the information is passed via any communications medium. - After the certificate is received issuer, CRL and OCSP checks should - be performed by client software as per normal with any certificate - received by other methods. - -SIMILAR SERVICES - - LDAP: - - LDAP can already be used in a method similar to described in this - document, however a simpler approach to security through an extremely - simple, efficient method of distributing without the need for bulky libs - and wrappers would help adoption and help increase security in general. - - PGP Key Exchange: - - Has much more extended capabilities although the concept is basically - the same, an easy method of distributing public keys. - - OCSP/CRL: - - Much simpler services only responding to requests about validity of - a certificate presented to them, will not respond with a copy of the - certificate. - -COMMAND LINES AND REPLIES - - A command line is normally a single name specification. Note that - the specification formats will evolve with time; the best way to - obtain the most recent documentation on name specifications is to - give the server a command line consisting of "? " (that is, a - question-mark alone as the name specification). The response from - the server will list all possible formats that can be used. - The responses are currently intended to be machine-readable; the - information is not meant to be passed back directly to a human user. The - following three examples illustrate the use of the service as of February - 2004. - - --------------------------------------------------------------------- - - Command line: ? - Response: - - Please enter an email address or hostname, such as "www.cacert.org". - - --------------------------------------------------------------------- - - Command line: myisp.com - Response: - No valid certificate available. - - --------------------------------------------------------------------- - - Command line: www.cacert.org - Response: - -----BEGIN CERTIFICATE----- - MIIFiTCCA3GgAwIBAgICAjYwDQYJKoZIhvcNAQEEBQAweTEQMA4GA1UEChMHUm9v - dCBDQTEeMBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlD - QSBDZXJ0IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0 - QGNhY2VydC5vcmcwHhcNMDMwNDAyMDAzNzU2WhcNMDUwNDAxMDAzNzU2WjCBmjEL - MAkGA1UEBhMCQVUxDDAKBgNVBAgTA05TVzEPMA0GA1UEBxMGU3lkbmV5MRAwDgYD - VQQKEwdDQSBDZXJ0MR4wHAYDVQQLExVTZXJ2ZXIgQWRtaW5pc3RyYXRpb24xFzAV - BgNVBAMTDnd3dy5jYWNlcnQub3JnMSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNh - Y2VydC5vcmcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMWKlVe5/cfDZiPq - WZTUGvgLA4dbvj/cBJXZgkz6aIvKuBhZ+cXob/xc6tkL20NdXZIW6WIzaGk6SU0a - vu6grLlHumwuXrFGPNRb8HyRQrvWzgD73Est+CDfLo+Omq55UjDDH0TZoAMV3L0N - Gb/S7YZeYHNcUzAHcXTE1//LyS8bAgMBAAGjggF7MIIBdzAMBgNVHRMBAf8EAjAA - MCoGA1UdJQQjMCEGCCsGAQUFBwMBBglghkgBhvhCBAEGCisGAQQBgjcKAwMwCwYD - VR0PBAQDAgUgMB0GA1UdDgQWBBTN0mx8ONpAgO9SaMf5KcKmDjFgDjCBowYDVR0j - BIGbMIGYgBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9v - dCBDQTEeMBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlD - QSBDZXJ0IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0 - QGNhY2VydC5vcmeCAQAwEQYJYIZIAYb4QgEBBAQDAgZAMFYGCWCGSAGG+EIBDQRJ - FkdUbyBnZXQgeW91ciBvd24gY2VydGlmaWNhdGUgZm9yIEZSRUUgaGVhZCBvdmVy - IHRvIGh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzANBgkqhkiG9w0BAQQFAAOCAgEAc7vb - l/zrCweRmHo8dQw7fpvX4KibbpZ5fXT9c1tn+oIUxV1erDI3r5YW6Cha8XIDhMxJ - tKPXdyAkrzEt3SrQrFy/KndMCjS1ypic2g/IhUjnB7FnH7Jc3RF+w3GX6OO38XtQ - ydcQk2qD125W7Kl6cgSXjauVz2AyjetHi0jA+SRcmnlIRafKLEDPsnc/1A6CFd4C - e8J+mrSA4FPOwf1ezAEJAlsBNiM2oIcfbWjrUR/dfaBrGweBQS/mgXxSXJWJnFQI - wNE47X3ibISAgT74p/zqdVoYBQEXe0LDNsmFU6eqc8OyLEKW3BIgfQxtGxKCLCsA - G/TjfjxGRhi1FlX9ZPvuWGfV0ks0gMa/VDM7V37LMhVViyTHNTmKuHsOa7UAz/5x - qJo/ruLuCfGF9Z8jfj0197J0LMQSr09YQ/JSDJE6IFE59/6ju7+Py+2NDRsiqo+/ - qi/4SGbXakOXqJv92NHLqD/jdq8D8RIPggQ2RGG7aNQ5bpmnZk6KEJH9jD50LAs1 - kU+KI/v8o94ZBz+MDhNgJpwT5R/Vvnri2iT9mIysfpCuZCZC6KJKN8rXT031ocmx - CJyaTBopnpnHwGu238IAMSpq9nPibhCb0OlqMVHdid9qPr8iZDWVhgmgDasigS5Y - lzsrd9lRVDVN5HITUCFG3Qr5xx7ltSouj/dkykg= - -----END CERTIFICATE----- - - --------------------------------------------------------------------- - -EXAMPLE CODE - - --------------------------------------------------------------------- - -/* - Copyright Jeremey Barrett 2004 for CAcert.org - You may create derivative works, as long as this copyright notice remains at the top -*/ - -/* - Example finger daemon that can return certificates from a database. - Currently only tested on debian stable. - use the following command to build program - gcc -o cacert-finger cacert-finger.c -I/usr/include/mysql -L/usr/lib \ - -lmysqlclient -lz -DUSE_MYSQL -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <fcntl.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/select.h> -#include <netinet/in.h> - -#ifdef USE_MYSQL -#include <mysql.h> -#endif - -#ifdef USE_MYSQL -static MYSQL mysql_db; -#endif - -#define DEFAULT_PORT 79 - -#define EMAIL_QUERY "select CRT from certs where `EMAIL`='%s' and \ - `revoked`='0000-00-00 00:00:00'" -#define DOMAIN_QUERY "select CRT from domaincerts where \ - `revoked`='0000-00-00 00:00:00' and `CN`='%s'" -#define WILD_DOMAIN_QUERY "select CRT from domaincerts where \ - `revoked`='0000-00-00 00:00:00' and (`CN`='%s' OR `CN`='%s')" - -void err_exit(void) - { - perror(""); - exit(1); - } - - -#ifdef USE_MYSQL -void do_mysql(int client_fd, char *query) - { - MYSQL_RES *res; - MYSQL_ROW row; - char *cert; - - if(!(mysql_real_connect(&mysql_db, "host", "username", "password", - "database", 0, "/var/run/mysqld/mysqld.sock", 0) != NULL)) - { - printf(mysql_error(&mysql_db)); - exit(1); - } - - if(mysql_real_query(&mysql_db, query, strlen(query))) - goto _err_return; - - res = mysql_store_result(&mysql_db); - if(mysql_num_rows(res) > 0) - { - row = mysql_fetch_row(res); - - if(!row[0]) - goto _free_res_return; - - cert = strstr(row[0], "-----BEGIN CERTIFICATE"); - if(cert) { - char *response; - int response_len = strlen(cert)+2; - - response = (char *)calloc(1, response_len+1); - if(!response) - goto _free_res_return; - memcpy(response, cert, response_len-2); - response[response_len-2] = '\r'; - response[response_len-1] = '\n'; - - /* should be checked for errors, more writing */ - write(client_fd, response, response_len); - - free(response); - } } - - _free_res_return: - mysql_free_result(res); - - _err_return: - mysql_close(&mysql_db); - } -#endif - - -int read_line(int fd, char *buf, int size) - { - int n = 0; - int t = 0; - char *p; - char *q; - - for(; t < size; ) { - n = read(fd, buf+t, size-t); - if(n < 0) { - switch(errno) { - case EINTR: - continue; - - default: - return -1; - } - } - - if(n == 0) { - return t; - } - - if(t) - p = buf+t-1; - else - p = buf; - - for(; *p && *p != '\n' && *p != '\r'; p++); - - if(*p) { - *p = 0; - t = p-buf; - return t; - } - - t += n; - } - - return -1; - } - - -int handle_request(int fd) - { - char *buf; - int buf_size; - int len; - int i; - int email_query = 0; - char query[4096]; /* ugly */ - char *email = NULL; - char *domain = NULL; - char *wildcard = NULL; - - buf_size = 2048; - - buf = (char *)calloc(1, buf_size); - if(!buf) - return -1; - - if((len = read_line(fd, buf, buf_size-1)) <= 0) - goto _free_return; - - memset(buf+len, 0, buf_size-len); - - if(strchr(buf, '@')) { - email_query = 1; - email = buf; - } - else { - char *p; - char *q; - - p = strchr(buf, '.'); - if(p) { - q = strchr(p+1, '.'); - if(q) { - wildcard = (char *)calloc(1, strlen(p)+2); - if(wildcard) { - *wildcard = '*'; - memcpy(wildcard+1, p, strlen(p)); - } - } - } - - domain = buf; - } - - memset(query, 0, sizeof(query)); - - if(email_query) { - snprintf(query, sizeof(query)-2, EMAIL_QUERY, email); - } - else { - if(wildcard && strcmp(wildcard, domain)) - snprintf(query, sizeof(query)-2, WILD_DOMAIN_QUERY, domain, wildcard); - else - snprintf(query, sizeof(query)-2, DOMAIN_QUERY, domain); - - if(wildcard) - free(wildcard); - } - - - /* go and do MySQL stuff here */ - -#ifdef USE_MYSQL - do_mysql(fd, query); -#else - strcat(query, "\n"); - write(fd, query, strlen(query)); -#endif - - - _free_return: - free(buf); - return 0; - } - - -int main(int argc, char **argv) - { - struct sockaddr_in server_sock; - struct sockaddr_in client_sock; - int client_addr_size; - int server_fd = -1; - int client_fd = -1; - int pid; - - /* take command line args, e.g. -p <port>, later */ - - if ((pid=fork()) < 0) - { - perror ("Fork failed"); - exit(errno); - - - } - - if (pid) - { - exit(0); - } - - server_fd = socket(PF_INET, SOCK_STREAM, 0); - if(server_fd < 0) - err_exit(); - - memset(&server_sock, 0, sizeof(server_sock)); - - server_sock.sin_family = AF_INET; - server_sock.sin_addr.s_addr = INADDR_ANY; - server_sock.sin_port = htons(DEFAULT_PORT); - - if(bind(server_fd, (struct sockaddr *)&server_sock, - sizeof(struct sockaddr_in)) < 0) - err_exit(); - - if(listen(server_fd, 64) < 0) - err_exit(); - - setgid(65534); - setuid(65534); - - for(;;) { - memset(&client_sock, 0, sizeof(client_sock)); - client_addr_size = sizeof(client_sock); - - client_fd = accept(server_fd, - (struct sockaddr *)&client_sock, &client_addr_size); - if(client_fd < 0) - err_exit(); - - if(handle_request(client_fd) < 0) - break; - - close(client_fd); - client_fd = -1; - } - - if(client_fd >= 0) - close(client_fd); - - close(server_fd); - - exit(0); - }