OCSP_CERTID *OCSP_cert_id_new (const EVP_MD * dgst, X509_NAME * issuerName, ASN1_BIT_STRING * issuerKey, ASN1_INTEGER * serialNumber) { int nid; unsigned int i; X509_ALGOR *alg; OCSP_CERTID *cid = NULL; unsigned char md[EVP_MAX_MD_SIZE]; if (!(cid = OCSP_CERTID_new ())) goto err; alg = cid->hashAlgorithm; if (alg->algorithm != NULL) ASN1_OBJECT_free (alg->algorithm); if ((nid = EVP_MD_type (dgst)) == NID_undef) { OCSPerr (OCSP_F_OCSP_CERT_ID_NEW, OCSP_R_UNKNOWN_NID); goto err; } if (!(alg->algorithm = OBJ_nid2obj (nid))) goto err; if ((alg->parameter = ASN1_TYPE_new ()) == NULL) goto err; alg->parameter->type = V_ASN1_NULL; if (!X509_NAME_digest (issuerName, dgst, md, &i)) goto digerr; if (!(ASN1_OCTET_STRING_set (cid->issuerNameHash, md, i))) goto err; /* Calculate the issuerKey hash, excluding tag and length */ if (!EVP_Digest (issuerKey->data, issuerKey->length, md, &i, dgst, NULL)) goto err; if (!(ASN1_OCTET_STRING_set (cid->issuerKeyHash, md, i))) goto err; if (serialNumber) { ASN1_INTEGER_free (cid->serialNumber); if (!(cid->serialNumber = ASN1_INTEGER_dup (serialNumber))) goto err; } return cid; digerr: OCSPerr (OCSP_F_OCSP_CERT_ID_NEW, OCSP_R_DIGEST_ERR); err: if (cid) OCSP_CERTID_free (cid); return NULL; }
static void * d2i_ocsp_nonce(void *a, const unsigned char **pp, long length) { ASN1_OCTET_STRING *os, **pos; pos = a; if (!pos || !*pos) os = ASN1_OCTET_STRING_new(); else os = *pos; if (!ASN1_OCTET_STRING_set(os, *pp, length)) goto err; *pp += length; if (pos) *pos = os; return os; err: if (os && (!pos || (*pos != os))) M_ASN1_OCTET_STRING_free(os); OCSPerr(OCSP_F_D2I_OCSP_NONCE, ERR_R_MALLOC_FAILURE); return NULL; }
OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp, OCSP_CERTID *cid, int status, int reason, ASN1_TIME *revtime, ASN1_TIME *thisupd, ASN1_TIME *nextupd) { OCSP_SINGLERESP *single = NULL; OCSP_CERTSTATUS *cs; OCSP_REVOKEDINFO *ri; if(!rsp->tbsResponseData->responses && !(rsp->tbsResponseData->responses = sk_OCSP_SINGLERESP_new_null())) goto err; if (!(single = OCSP_SINGLERESP_new())) goto err; if (!ASN1_TIME_to_generalizedtime(thisupd, &single->thisUpdate)) goto err; if (nextupd && !ASN1_TIME_to_generalizedtime(nextupd, &single->nextUpdate)) goto err; OCSP_CERTID_free(single->certId); if(!(single->certId = OCSP_CERTID_dup(cid))) goto err; cs = single->certStatus; switch(cs->type = status) { case V_OCSP_CERTSTATUS_REVOKED: if (!revtime) { OCSPerr(OCSP_F_OCSP_BASIC_ADD1_STATUS,OCSP_R_NO_REVOKED_TIME); goto err; } if (!(cs->value.revoked = ri = OCSP_REVOKEDINFO_new())) goto err; if (!ASN1_TIME_to_generalizedtime(revtime, &ri->revocationTime)) goto err; if (reason != OCSP_REVOKED_STATUS_NOSTATUS) { if (!(ri->revocationReason = ASN1_ENUMERATED_new())) goto err; if (!(ASN1_ENUMERATED_set(ri->revocationReason, reason))) goto err; } break; case V_OCSP_CERTSTATUS_GOOD: cs->value.good = ASN1_NULL_new(); break; case V_OCSP_CERTSTATUS_UNKNOWN: cs->value.unknown = ASN1_NULL_new(); break; default: goto err; } if (!(sk_OCSP_SINGLERESP_push(rsp->tbsResponseData->responses, single))) goto err; return single; err: OCSP_SINGLERESP_free(single); return NULL; }
EXPORT_C int OCSP_parse_url(char *url, char **phost, char **pport, char **ppath, int *pssl) { char *p, *buf; char *host, *port; /* dup the buffer since we are going to mess with it */ buf = BUF_strdup(url); if (!buf) goto mem_err; *phost = NULL; *pport = NULL; *ppath = NULL; /* Check for initial colon */ p = strchr(buf, ':'); if (!p) goto parse_err; *(p++) = '\0'; if (!strcmp(buf, "http")) { *pssl = 0; port = "80"; } else if (!strcmp(buf, "https")) { *pssl = 1; port = "443"; } else goto parse_err; /* Check for double slash */ if ((p[0] != '/') || (p[1] != '/')) goto parse_err; p += 2; host = p; /* Check for trailing part of path */ p = strchr(p, '/'); if (!p) *ppath = BUF_strdup("/"); else { *ppath = BUF_strdup(p); /* Set start of path to 0 so hostname is valid */ *p = '\0'; } if (!*ppath) goto mem_err; /* Look for optional ':' for port number */ if ((p = strchr(host, ':'))) { *p = 0; port = p + 1; } else { /* Not found: set default port */ if (*pssl) port = "443"; else port = "80"; } *pport = BUF_strdup(port); if (!*pport) goto mem_err; *phost = BUF_strdup(host); if (!*phost) goto mem_err; OPENSSL_free(buf); return 1; mem_err: OCSPerr(OCSP_F_OCSP_PARSE_URL, ERR_R_MALLOC_FAILURE); goto err; parse_err: OCSPerr(OCSP_F_OCSP_PARSE_URL, OCSP_R_ERROR_PARSING_URL); err: if (buf) OPENSSL_free(buf); if (*ppath) OPENSSL_free(*ppath); if (*pport) OPENSSL_free(*pport); if (*phost) OPENSSL_free(*phost); return 0; }
static int parse_http_line1(char *line) { int retcode; char *p, *q, *r; /* Skip to first white space (passed protocol info) */ for(p = line; *p && !isspace((unsigned char)*p); p++) continue; if(!*p) { OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR); return 0; } /* Skip past white space to start of response code */ while(*p && isspace((unsigned char)*p)) p++; if(!*p) { OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR); return 0; } /* Find end of response code: first whitespace after start of code */ for(q = p; *q && !isspace((unsigned char)*q); q++) continue; if(!*q) { OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR); return 0; } /* Set end of response code and start of message */ *q++ = 0; /* Attempt to parse numeric code */ retcode = strtoul(p, &r, 10); if(*r) return 0; /* Skip over any leading white space in message */ while(*q && isspace((unsigned char)*q)) q++; if(*q) { /* Finally zap any trailing white space in message (include * CRLF) */ /* We know q has a non white space character so this is OK */ for(r = q + strlen(q) - 1; isspace((unsigned char)*r); r--) *r = 0; } if(retcode != 200) { OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_ERROR); if(!*q) ERR_add_error_data(2, "Code=", p); else ERR_add_error_data(4, "Code=", p, ",Reason=", q); return 0; } return 1; }