Esempio n. 1
0
static char*
pop3pushtls(Pop *pop)
{
	int fd;
	uchar digest[SHA1dlen];
	TLSconn conn;

	memset(&conn, 0, sizeof conn);
	// conn.trace = pop3log;
	fd = tlsClient(pop->fd, &conn);
	if(fd < 0)
		return "tls error";
	if(conn.cert==nil || conn.certlen <= 0){
		close(fd);
		return "server did not provide TLS certificate";
	}
	sha1(conn.cert, conn.certlen, digest, nil);
	if(!pop->thumb || !okThumbprint(digest, pop->thumb)){
		fmtinstall('H', encodefmt);
		close(fd);
		free(conn.cert);
		fprint(2, "upas/fs pop3: server certificate %.*H not recognized\n", SHA1dlen, digest);
		return "bad server certificate";
	}
	free(conn.cert);
	close(pop->fd);
	pop->fd = fd;
	pop->encrypted = 1;
	Binit(&pop->bin, pop->fd, OREAD);
	Binit(&pop->bout, pop->fd, OWRITE);
	return nil;
}
Esempio n. 2
0
static int
starttls(Imap *imap, TLSconn *connp)
{
    int sfd;
    uchar digest[SHA1dlen];

    fmtinstall('H', encodefmt);
    memset(connp, 0, sizeof *connp);
    sfd = tlsClient(imap->fd, connp);
    if(sfd < 0) {
        werrstr("tlsClient: %r");
        return -1;
    }
    if(connp->cert==nil || connp->certlen <= 0) {
        close(sfd);
        werrstr("server did not provide TLS certificate");
        return -1;
    }
    sha1(connp->cert, connp->certlen, digest, nil);
    /*
     * don't do this any more.  our local it people are rotating their
     * certificates faster than we can keep up.
     */
    if(0 && (!imap->thumb || !okThumbprint(digest, imap->thumb))) {
        close(sfd);
        werrstr("server certificate %.*H not recognized",
                SHA1dlen, digest);
        return -1;
    }
    close(imap->fd);
    imap->fd = sfd;
    return sfd;
}
Esempio n. 3
0
static void
loadThumbprints(char *file, Thumbprint *table, Thumbprint *crltab)
{
	Thumbprint *entry;
	Biobuf *bin;
	char *line, *field[50];
	uchar sum[SHA1dlen];
	int i;

	bin = Bopen(file, OREAD);
	if(bin == nil)
		return;
	for(; (line = Brdstr(bin, '\n', 1)) != 0; free(line)){
		if(tokenize(line, field, nelem(field)) < 2)
			continue;
		if(strcmp(field[0], "#include") == 0){
			loadThumbprints(field[1], table, crltab);
			continue;
		}
		if(strcmp(field[0], "x509") != 0 || strncmp(field[1], "sha1=", strlen("sha1=")) != 0)
			continue;
		field[1] += strlen("sha1=");
		dec16(sum, sizeof(sum), field[1], strlen(field[1]));
		if(crltab && okThumbprint(sum, crltab))
			continue;
		entry = (Thumbprint*)emalloc(sizeof(*entry));
		memcpy(entry->sha1, sum, SHA1dlen);
		i = ((sum[0]<<8) + sum[1]) & (ThumbTab-1);
		entry->next = table[i].next;
		table[i].next = entry;
	}
	Bterm(bin);
}
Esempio n. 4
0
static char *
ckthumbs(TLSconn *c)
{
	Thumbprint *goodcerts;
	char *h, *err;
	uchar hash[SHA1dlen];

	err = nil;
	goodcerts = initThumbprints(smtpthumbs, smtpexclthumbs);
	if (goodcerts == nil) {
		if (!okunksecure)
			syslog(0, "smtp", "bad thumbprints in %s", smtpthumbs);
		return Giveup;		/* how to recover? TLS is started */
	}

	/* compute sha1 hash of remote's certificate, see if we know it */
	sha1(c->cert, c->certlen, hash, nil);
	if (!okThumbprint(hash, goodcerts) && !okunksecure) {
		h = malloc(2*sizeof hash + 1);
		if (h != nil) {
			enc16(h, 2*sizeof hash + 1, hash, sizeof hash);
			syslog(0, "smtp", "remote cert. has bad thumbprint: "
				"x509 sha1=%s server=%q", h, ddomain);
			free(h);
		}
		err = Giveup;		/* how to recover? TLS is started */
	}
	freeThumbprints(goodcerts);
	return err;
}
Esempio n. 5
0
static char *
wraptls(void)
{
	TLSconn *c;
	Thumbprint *goodcerts;
	char *h, *err;
	int fd;
	uchar hash[SHA1dlen];

	goodcerts = nil;
	err = Giveup;
	c = mallocz(sizeof(*c), 1);
	if (c == nil)
		return err;

	fd = tlsClient(Bfildes(&bout), c);
	if (fd < 0) {
		syslog(0, "smtp", "tlsClient to %q: %r", ddomain);
		goto Out;
	}
	Bterm(&bout);
	Binit(&bout, fd, OWRITE);
	fd = dup(fd, Bfildes(&bin));
	Bterm(&bin);
	Binit(&bin, fd, OREAD);

	goodcerts = initThumbprints(smtpthumbs, smtpexclthumbs);
	if (goodcerts == nil) {
		syslog(0, "smtp", "bad thumbprints in %s", smtpthumbs);
		goto Out;
	}
	/* compute sha1 hash of remote's certificate, see if we know it */
	sha1(c->cert, c->certlen, hash, nil);
	if (!okThumbprint(hash, goodcerts)) {
		/* TODO? if not excluded, add hash to thumb list */
		h = malloc(2*sizeof hash + 1);
		if (h == nil)
			goto Out;
		enc16(h, 2*sizeof hash + 1, hash, sizeof hash);
		syslog(0, "smtp", "remote cert. has bad thumbprint: x509 sha1=%s server=%q",
			h, ddomain);
		free(h);
		goto Out;
	}
	syslog(0, "smtp", "started TLS to %q", ddomain);
	err = nil;
Out:
	if(goodcerts != nil)
		freeThumbprints(goodcerts);
	free(c->cert);
	free(c->sessionID);
	free(c);
	return err;
}