99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * CDDL HEADER START
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * The contents of this file are subject to the terms of the
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Common Development and Distribution License (the "License").
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * You may not use this file except in compliance with the License.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * or http://www.opensolaris.org/os/licensing.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * See the License for the specific language governing permissions
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * and limitations under the License.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * When distributing Covered Code, include this CDDL HEADER in each
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If applicable, add the following below this CDDL HEADER, with the
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * fields enclosed by brackets "[]" replaced with your own identifying
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * information: Portions Copyright [yyyy] [name of copyright owner]
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * CDDL HEADER END
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Use is subject to license terms.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * File: CLIENT.C
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#pragma ident "%Z%%M% %I% %E% SMI"
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <stdio.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <stdlib.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <ctype.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <fcntl.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <poll.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <sys/errno.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <sys/types.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <sys/stat.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <sys/socket.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <netdb.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <netinet/in.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <arpa/inet.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <string.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <unistd.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <libgen.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <kmfapi.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <kmfapiP.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#include <libxml2/libxml/uri.h>
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysextern int errno;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#define OCSP_BUFSIZE 1024
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllystypedef enum {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RESPONSE_OCSP = 1,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RESPONSE_FILE = 2
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys} KMF_RESPONSE_TYPE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys#define TEMP_TEMPLATE "temp.XXXXXX"
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * This function will establish a socket to the host on the specified port.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If succeed, it return a socket descriptor; otherwise, return -1.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic int init_socket(char *host, short port)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys struct sockaddr_in sin;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys struct hostent *hp, hrec;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int sockfd, opt, herrno;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char hostbuf[BUFSIZ];
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sin.sin_family = PF_INET;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sin.sin_port = htons(port);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((hp = gethostbyname_r(host, &hrec, hostbuf,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (hostbuf), &herrno)) == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (-1);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memcpy((char *)&sin.sin_addr, hp->h_addr,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys hp->h_length);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (-1);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys opt = 1;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sizeof (opt)) < 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) close(sockfd);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (-1);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (connect(sockfd, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) close(sockfd);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (-1);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (sockfd);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * This function will connect to host on the port.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * If succeed, return a socket descriptor; otherwise, return 0.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic int
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysconnect_to_server(char *host, short port)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int retry = 1;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int sd = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys while (retry) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((sd = init_socket(host, port)) == -1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (errno == ECONNREFUSED) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys retry = 1;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) sleep(1);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys retry = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys retry = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (sd);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyssend_ocsp_request(int sock, char *reqfile, char *hostname)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int filefd, bytes, n, total = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char buf[OCSP_BUFSIZE];
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys struct stat s;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char req_header[256];
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys static char req_format[] =
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys"POST %s HTTP/1.0\r\n\
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysContent-Type: application/ocsp-request\r\n\
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysContent-Length: %d\r\n\r\n";
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((filefd = open(reqfile, O_RDONLY)) == -1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_OPEN_FILE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* open the request file */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (fstat(filefd, &s) < 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_OPEN_FILE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Send http header */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (hostname != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) snprintf(req_header, 256, req_format, hostname,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys s.st_size);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) snprintf(req_header, 256, req_format, "/", s.st_size);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys bytes = strlen(req_header);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((n = write(sock, req_header, bytes)) < 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_SEND_REQUEST;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto exit;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Send the request content */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys while ((bytes = read(filefd, buf, OCSP_BUFSIZE)) > 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((n = write(sock, buf, bytes)) < 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_SEND_REQUEST;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto exit;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys total += n;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memset(buf, 0, sizeof (buf));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysexit:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) close(filefd);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Perform a write that can handle EINTR.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic int
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyslooping_write(int fd, void *buf, int len)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *p = buf;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int cc, len2 = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (len == 0)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (0);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys do {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys cc = write(fd, p, len);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (cc < 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (errno == EINTR)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys continue;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (cc);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (cc == 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (len2);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys p += cc;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys len2 += cc;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys len -= cc;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } while (len > 0);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (len2);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys/*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * This function will get the response from the server, check the http status
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * line, and write the response content to a file. If this is a OCSP response,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * it will check the content type also.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysget_encoded_response(int sock, KMF_RESPONSE_TYPE resptype, int filefd,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys unsigned int maxsecs)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *buf = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int buflen = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int offset = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int search_offset;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys const int buf_incre = OCSP_BUFSIZE; /* 1 KB at a time */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys const int maxBufSize = 8 * buf_incre; /* 8 KB max */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys const char *CRLF = "\r\n";
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys const char *headerEndMark = "\r\n\r\n";
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys const char *httpprotocol = "HTTP/";
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys const int CRLFlen = strlen(CRLF);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys const int marklen = strlen(headerEndMark);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys const int httplen = strlen(httpprotocol);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *headerEnd = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys boolean_t EOS = B_FALSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys const char *httpcode = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys const char *contenttype = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int contentlength = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int bytes = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *statusLineEnd = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *space = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *nextHeader = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys struct pollfd pfd;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int sock_flag;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int poll_ret;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys boolean_t timeout = B_FALSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* set O_NONBLOCK flag on socket */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((sock_flag = fcntl(sock, F_GETFL, 0)) == -1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_RECV_RESPONSE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sock_flag |= O_NONBLOCK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (fcntl(sock, F_SETFL, sock_flag) == -1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_RECV_RESPONSE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* set up poll */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys pfd.fd = sock;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys pfd.events = POLLIN;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * First read HTTP status line and headers. We will read up to at
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * least the end of the HTTP headers
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys do {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((buflen - offset) < buf_incre) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys buflen += buf_incre;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys buf = realloc(buf, buflen + 1);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (buf == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_MEMORY;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys pfd.revents = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys poll_ret = poll(&pfd, 1, maxsecs * MILLISEC);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (poll_ret == 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys timeout = B_TRUE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (poll_ret < 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_RECV_RESPONSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_RECV_RESPONSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys bytes = read(sock, buf + offset, buf_incre);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (bytes < 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (errno == EWOULDBLOCK) { /* no data this time */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys continue;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_RECV_RESPONSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (bytes == 0) { /* no more data */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys EOS = B_TRUE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else { /* bytes > 0 */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys search_offset = (offset - marklen) > 0 ?
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys offset - marklen : 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys offset += bytes;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *(buf + offset) = '\0'; /* NULL termination */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys headerEnd = strstr((const char *)buf + search_offset,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys headerEndMark);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } while ((!headerEnd) && (EOS == B_FALSE) && (buflen < maxBufSize));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (timeout == B_TRUE) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_RECV_TIMEOUT;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (headerEnd == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* could not find the end of headers */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_HTTP_RESPONSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Parse the HTTP status line, which will look like this:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * "HTTP/1.1 200 OK".
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys statusLineEnd = strstr((const char *)buf, CRLF);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (statusLineEnd == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_HTTP_RESPONSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *statusLineEnd = '\0';
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys space = strchr((const char *)buf, ' ');
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (space == NULL ||
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (strncasecmp((const char *)buf, httpprotocol, httplen) != 0)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_HTTP_RESPONSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Check the HTTP status code. If it is not 200, the HTTP response
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * is not good.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys httpcode = space + 1;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys space = strchr(httpcode, ' ');
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (space == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_HTTP_RESPONSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *space = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (strcmp(httpcode, "200") != 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_HTTP_RESPONSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Parse the HTTP headers in the buffer. Save content-type and
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * content-length only.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys nextHeader = statusLineEnd + CRLFlen;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *headerEnd = '\0'; /* terminate */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys do {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *thisHeaderEnd = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *value = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *colon = strchr(nextHeader, ':');
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (colon == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_HTTP_RESPONSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *colon = '\0';
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys value = colon + 1;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (*value != ' ') {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_HTTP_RESPONSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys value++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys thisHeaderEnd = strstr(value, CRLF);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (thisHeaderEnd != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys *thisHeaderEnd = '\0';
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (strcasecmp(nextHeader, "content-type") == 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys contenttype = value;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (strcasecmp(nextHeader, "content-length") == 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys contentlength = atoi(value);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (thisHeaderEnd != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys nextHeader = thisHeaderEnd + CRLFlen;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys nextHeader = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } while (nextHeader && (nextHeader < (headerEnd + CRLFlen)));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Check the contenttype if this is an OCSP response */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (resptype == KMF_RESPONSE_OCSP) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (contenttype == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_HTTP_RESPONSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (strcasecmp(contenttype,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys "application/ocsp-response") != 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_HTTP_RESPONSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Now we are ready to read the body of the response */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys offset = offset - (int)(headerEnd - (const char *)buf) - marklen;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (offset) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* move all data to the beginning of the buffer */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) memmove(buf, headerEnd + marklen, offset);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* resize buffer to only what's needed to hold the current response */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys buflen = (1 + (offset-1) / buf_incre) * buf_incre;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys while ((EOS == B_FALSE) &&
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ((contentlength == 0) || (offset < contentlength)) &&
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (buflen < maxBufSize)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* we still need to receive more content data */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((buflen - offset) < buf_incre) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys buflen += buf_incre;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys buf = realloc(buf, buflen + 1);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (buf == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_MEMORY;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys pfd.revents = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys poll_ret = poll(&pfd, 1, maxsecs * MILLISEC);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (poll_ret == 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys timeout = B_TRUE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (poll_ret < 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_RECV_RESPONSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (pfd.revents & (POLLERR | POLLHUP | POLLNVAL)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_RECV_RESPONSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys bytes = read(sock, buf + offset, buf_incre);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (bytes < 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (errno == EWOULDBLOCK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys continue;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_RECV_RESPONSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (bytes == 0) { /* no more data */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys EOS = B_TRUE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys offset += bytes;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (timeout == B_TRUE) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_RECV_TIMEOUT;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else if (((contentlength != 0) && (offset < contentlength)) ||
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys offset == 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_HTTP_RESPONSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* write to the file */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (looping_write(filefd, buf, offset) != offset) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_WRITE_FILE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysout:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(buf);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_get_encoded_ocsp_response(KMF_HANDLE_T handle,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys char *reqfile, char *hostname,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int port, char *proxy, int proxy_port, char *respfile,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys unsigned int maxsecs)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int sock, respfd;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char http_hostname[256];
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int final_proxy_port, final_port;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CLEAR_ERROR(handle, ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (hostname == NULL || reqfile == NULL || respfile == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys final_proxy_port = (proxy_port == 0 || proxy_port == -1) ?
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys 80 : proxy_port;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys final_port = (port == 0 || port == -1) ? 80 : port;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Connect to server */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (proxy != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sock = connect_to_server(proxy, final_proxy_port);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sock = connect_to_server(hostname, final_port);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (sock == -1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_CONNECT_SERVER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Send the OCSP request */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (proxy != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) snprintf(http_hostname, sizeof (http_hostname),
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys "http://%s:%d", hostname, final_port);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = send_ocsp_request(sock, reqfile, http_hostname);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = send_ocsp_request(sock, reqfile, NULL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Retrieve the OCSP response */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (maxsecs == 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys maxsecs = 30; /* default poll time limit is 30 seconds */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((respfd = open(respfile, O_CREAT |O_RDWR | O_EXCL, 0600)) == -1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_OPEN_FILE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = get_encoded_response(sock, KMF_RESPONSE_OCSP,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys respfd, maxsecs);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) close(respfd);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysout:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) close(sock);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllyssend_download_request(int sock, char *hostname, int port, boolean_t is_proxy,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *loc)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char url[256];
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char req_header[1024];
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys static char req_format[] =
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys"GET %s HTTP/1.0\r\n\
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysHost: %s:%d\r\n\
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysAccept: */*\r\n\r\n";
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (is_proxy) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) snprintf(url, sizeof (url), "http://%s:%d/%s",
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys hostname, port, loc);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) snprintf(url, sizeof (url), "/%s", loc);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) snprintf(req_header, sizeof (req_header), req_format, url,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys hostname, port);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (write(sock, req_header, strlen(req_header)) < 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_SEND_REQUEST;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysstatic KMF_RETURN
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysdownload_file(char *uri, char *proxy, int proxy_port,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys unsigned int maxsecs, int filefd)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys xmlURIPtr uriptr;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int sock;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys boolean_t is_proxy;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int final_proxy_port;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *hostname = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *path = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int port;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (uri == NULL || filefd == -1)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Parse URI */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys uriptr = xmlParseURI(uri);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (uriptr == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_URI;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (uriptr->scheme == NULL ||
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys strncasecmp(uriptr->scheme, "http", 4) != 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_URI; /* we support http only */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* get the host name */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys hostname = uriptr->server;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (hostname == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_URI;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* get the port number */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys port = uriptr->port;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (port == 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys port = 80;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Get the path */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys path = uriptr->path;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (path == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_URI;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Connect to server */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (proxy != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys final_proxy_port = (proxy_port == 0 || proxy_port == -1) ?
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys 80 : proxy_port;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys is_proxy = B_TRUE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sock = connect_to_server(proxy, final_proxy_port);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys is_proxy = B_FALSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sock = connect_to_server(hostname, port);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (sock == -1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_CONNECT_SERVER;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Send the request */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = send_download_request(sock, hostname, port, is_proxy, path);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Retrieve the response */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = get_encoded_response(sock, KMF_RESPONSE_FILE, filefd,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys maxsecs == 0 ? 30 : maxsecs);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysout:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (uriptr != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys xmlFreeURI(uriptr);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (sock != -1)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) close(sock);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_download_crl(KMF_HANDLE_T handle, char *uri, char *proxy, int proxy_port,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys unsigned int maxsecs, char *crlfile, KMF_ENCODE_FORMAT *pformat)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *filename = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char tempfn[MAXPATHLEN];
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys boolean_t temp_created = B_FALSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys mode_t old_mode;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int fd = -1, tmpfd = -1;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CLEAR_ERROR(handle, ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (uri == NULL || crlfile == NULL || pformat == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((fd = open(crlfile, O_CREAT |O_RDWR | O_EXCL, 0644)) == -1)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_OPEN_FILE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Download the file and save it to a temp file. To make rename()
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * happy, the temp file needs to be created in the same directory as
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * the target file.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((filename = strdup(crlfile)) == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_MEMORY;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) snprintf(tempfn, MAXPATHLEN, "%s/%s", dirname(filename),
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys TEMP_TEMPLATE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys old_mode = umask(077);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys tmpfd = mkstemp(tempfn);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) umask(old_mode);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (tmpfd == -1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_INTERNAL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys temp_created = B_TRUE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = download_file(uri, proxy, proxy_port, maxsecs, tmpfd);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) close(tmpfd);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Check if it is a CRL file and get its format */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (kmf_is_crl_file(handle, tempfn, pformat) != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_CRLFILE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Finally, change the temp filename to the target crlfile */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rename(tempfn, crlfile) == -1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_WRITE_FILE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysout:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (filename != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(filename);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK && temp_created == B_TRUE)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) unlink(tempfn);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (fd != -1)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) close(fd);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_download_cert(KMF_HANDLE_T handle, char *uri, char *proxy, int proxy_port,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys unsigned int maxsecs, char *certfile, KMF_ENCODE_FORMAT *pformat)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *filename = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char tempfn[MAXPATHLEN];
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys boolean_t temp_created = B_FALSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys mode_t old_mode;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int fd = -1, tmpfd = -1;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CLEAR_ERROR(handle, ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (uri == NULL || certfile == NULL || pformat == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((fd = open(certfile, O_CREAT |O_RDWR | O_EXCL, 0644)) == -1)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_OPEN_FILE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Download the file and save it to a temp file. To make rename()
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * happy, the temp file needs to be created in the same directory as
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * the target file.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if ((filename = strdup(certfile)) == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_MEMORY;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) snprintf(tempfn, MAXPATHLEN, "%s/%s", dirname(filename),
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys TEMP_TEMPLATE);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys old_mode = umask(077);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys tmpfd = mkstemp(tempfn);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) umask(old_mode);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (tmpfd == -1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_INTERNAL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys temp_created = B_TRUE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = download_file(uri, proxy, proxy_port, maxsecs, tmpfd);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) close(tmpfd);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Check if it is a Cert file and get its format */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (kmf_is_cert_file(handle, tempfn, pformat) != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_CERTFILE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Finally, change the temp filename to the target filename */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (rename(tempfn, certfile) == -1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_WRITE_FILE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysout:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (filename != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys free(filename);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK && temp_created == B_TRUE)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) unlink(tempfn);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (fd != -1)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) close(fd);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysKMF_RETURN
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllyskmf_get_ocsp_for_cert(KMF_HANDLE_T handle,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_DATA *user_cert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_DATA *ta_cert,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_DATA *response)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys{
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_POLICY_RECORD *policy;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_RETURN ret = KMF_OK;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *hostname = NULL, *host_uri = NULL, *proxyname = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *proxy_port_s = NULL;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int host_port = 0, proxy_port = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char ocsp_reqname[MAXPATHLEN];
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char ocsp_respname[MAXPATHLEN];
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509EXT_AUTHINFOACCESS aia;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys int i;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys boolean_t found = B_FALSE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys KMF_X509EXT_ACCESSDESC *access_info;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys xmlURIPtr uriptr = NULL;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ATTRIBUTE attrlist[10];
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys int numattr = 0;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys CLEAR_ERROR(handle, ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys if (user_cert == NULL || ta_cert == NULL || response == NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_BAD_PARAMETER);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys policy = handle->policy;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Create an OCSP request */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_ISSUER_CERT_DATA_ATTR, ta_cert,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_DATA));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_USER_CERT_DATA_ATTR, user_cert,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys sizeof (KMF_DATA));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr++;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Create temporary files to hold the OCSP request & response data.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) strlcpy(ocsp_reqname, OCSPREQ_TEMPNAME,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sizeof (ocsp_reqname));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (mkstemp(ocsp_reqname) == -1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_INTERNAL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) strlcpy(ocsp_respname, OCSPRESP_TEMPNAME,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys sizeof (ocsp_respname));
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (mkstemp(ocsp_respname) == -1) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (KMF_ERR_INTERNAL);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys kmf_set_attr_at_index(attrlist, numattr,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys KMF_OCSP_REQUEST_FILENAME_ATTR, ocsp_respname,
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys strlen(ocsp_respname));
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys numattr++;
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_create_ocsp_request(handle, numattr, attrlist);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (policy->VAL_OCSP_BASIC.uri_from_cert == 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (policy->VAL_OCSP_BASIC.responderURI == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_OCSP_POLICY;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys host_uri = policy->VAL_OCSP_BASIC.responderURI;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Get the responder URI from certificate
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Authority Information Access
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * thru OID_PKIX_AD_OCSP
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_cert_auth_info_access(user_cert, &aia);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys for (i = 0; i < aia.numberOfAccessDescription; i++) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys access_info = &aia.AccessDesc[i];
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (IsEqualOid(&access_info->AccessMethod,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (KMF_OID *)&KMFOID_PkixAdOcsp)) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys host_uri =
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (char *)access_info->AccessLocation.Data;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys found = B_TRUE;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys break;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (!found) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_OCSP_POLICY;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* Parse the URI string; get the hostname and port */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys uriptr = xmlParseURI(host_uri);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (uriptr == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_URI;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (strncasecmp(uriptr->scheme, "http", 4) != 0) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_URI; /* we support http only */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys hostname = uriptr->server;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (hostname == NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ret = KMF_ERR_BAD_URI;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys host_port = uriptr->port;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (host_port == 0)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys host_port = 80;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /* get the proxy info */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (policy->VAL_OCSP_BASIC.proxy != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys char *last;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys proxyname =
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys strtok_r(policy->VAL_OCSP_BASIC.proxy, ":", &last);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys proxy_port_s = strtok_r(NULL, "\0", &last);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (proxy_port_s != NULL) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys proxy_port = strtol(proxy_port_s, NULL, 0);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys } else {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys proxy_port = 8080; /* default */
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys /*
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * Send the request to an OCSP responder and receive an
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys * OCSP response.
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys */
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_get_encoded_ocsp_response(handle, ocsp_reqname,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys hostname, host_port, proxyname, proxy_port,
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys ocsp_respname, 30);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (ret != KMF_OK) {
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys goto out;
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys }
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
30a5e8fa1253cb33980ee4514743cf683f584b4ewyllys ret = kmf_read_input_file(handle, ocsp_respname, response);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllysout:
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) unlink(ocsp_reqname);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys (void) unlink(ocsp_respname);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys if (uriptr != NULL)
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys xmlFreeURI(uriptr);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys return (ret);
99ebb4ca412cb0a19d77a3899a87c055b9c30fa8wyllys}