security/certverifier/OCSPRequestor.cpp

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "OCSPRequestor.h"
     9 #include "nsIURLParser.h"
    10 #include "nsNSSCallbacks.h"
    11 #include "nsNetCID.h"
    12 #include "nsServiceManagerUtils.h"
    13 #include "pkix/ScopedPtr.h"
    14 #include "secerr.h"
    16 namespace mozilla { namespace psm {
    18 using mozilla::pkix::ScopedPtr;
    20 void
    21 ReleaseHttpServerSession(nsNSSHttpServerSession* httpServerSession)
    22 {
    23   delete httpServerSession;
    24 }
    25 typedef ScopedPtr<nsNSSHttpServerSession, ReleaseHttpServerSession>
    26   ScopedHTTPServerSession;
    28 void
    29 ReleaseHttpRequestSession(nsNSSHttpRequestSession* httpRequestSession)
    30 {
    31   httpRequestSession->Release();
    32 }
    33 typedef ScopedPtr<nsNSSHttpRequestSession, ReleaseHttpRequestSession>
    34   ScopedHTTPRequestSession;
    36 SECItem* DoOCSPRequest(PLArenaPool* arena, const char* url,
    37                        const SECItem* encodedRequest, PRIntervalTime timeout)
    38 {
    39   nsCOMPtr<nsIURLParser> urlParser = do_GetService(NS_STDURLPARSER_CONTRACTID);
    40   if (!urlParser) {
    41     PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0);
    42     return nullptr;
    43   }
    45   uint32_t schemePos;
    46   int32_t schemeLen;
    47   uint32_t authorityPos;
    48   int32_t authorityLen;
    49   uint32_t pathPos;
    50   int32_t pathLen;
    51   nsresult rv = urlParser->ParseURL(url, PL_strlen(url),
    52                                     &schemePos, &schemeLen,
    53                                     &authorityPos, &authorityLen,
    54                                     &pathPos, &pathLen);
    55   if (NS_FAILED(rv)) {
    56     PR_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION, 0);
    57     return nullptr;
    58   }
    59   if (schemeLen < 0 || authorityLen < 0) {
    60     PR_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION, 0);
    61     return nullptr;
    62   }
    63   nsAutoCString scheme(url + schemePos, schemeLen);
    64   if (!scheme.LowerCaseEqualsLiteral("http")) {
    65     // We dont support https:// to avoid loops see Bug 92923
    66     PR_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION, 0);
    67     return nullptr;
    68   }
    70   uint32_t hostnamePos;
    71   int32_t hostnameLen;
    72   int32_t port;
    73   // We do not support urls with user@pass sections in the URL,
    74   // In cas we find them we will ignore and try to connect with
    75   rv = urlParser->ParseAuthority(url + authorityPos, authorityLen,
    76                                  nullptr, nullptr, nullptr, nullptr,
    77                                  &hostnamePos, &hostnameLen, &port);
    78   if (NS_FAILED(rv)) {
    79     PR_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION, 0);
    80     return nullptr;
    81   }
    82   if (hostnameLen < 0) {
    83     PR_SetError(SEC_ERROR_CERT_BAD_ACCESS_LOCATION, 0);
    84     return nullptr;
    85   }
    86   if (port == -1) {
    87     port = 80;
    88   }
    90   nsAutoCString hostname(url + authorityPos + hostnamePos, hostnameLen);
    91   SEC_HTTP_SERVER_SESSION serverSessionPtr = nullptr;
    92   if (nsNSSHttpInterface::createSessionFcn(hostname.BeginReading(), port,
    93                                            &serverSessionPtr) != SECSuccess) {
    94     PR_SetError(SEC_ERROR_NO_MEMORY, 0);
    95     return nullptr;
    96   }
    98   ScopedHTTPServerSession serverSession(
    99     reinterpret_cast<nsNSSHttpServerSession*>(serverSessionPtr));
   100   nsAutoCString path;
   101   if (pathLen > 0) {
   102     path.Assign(url + pathPos, pathLen);
   103   } else {
   104     path.Assign("/");
   105   }
   106   SEC_HTTP_REQUEST_SESSION requestSessionPtr;
   107   if (nsNSSHttpInterface::createFcn(serverSession.get(), "http",
   108                                     path.BeginReading(), "POST",
   109                                     timeout, &requestSessionPtr)
   110         != SECSuccess) {
   111     PR_SetError(SEC_ERROR_NO_MEMORY, 0);
   112     return nullptr;
   113   }
   115   ScopedHTTPRequestSession requestSession(
   116     reinterpret_cast<nsNSSHttpRequestSession*>(requestSessionPtr));
   117   if (nsNSSHttpInterface::setPostDataFcn(requestSession.get(),
   118         reinterpret_cast<char*>(encodedRequest->data), encodedRequest->len,
   119         "application/ocsp-request") != SECSuccess) {
   120     PR_SetError(SEC_ERROR_NO_MEMORY, 0);
   121     return nullptr;
   122   }
   124   uint16_t httpResponseCode;
   125   const char* httpResponseData;
   126   uint32_t httpResponseDataLen = 0; // 0 means any response size is acceptable
   127   if (nsNSSHttpInterface::trySendAndReceiveFcn(requestSession.get(), nullptr,
   128                                                &httpResponseCode, nullptr,
   129                                                nullptr, &httpResponseData,
   130                                                &httpResponseDataLen)
   131         != SECSuccess) {
   132     PR_SetError(SEC_ERROR_OCSP_SERVER_ERROR, 0);
   133     return nullptr;
   134   }
   136   if (httpResponseCode != 200) {
   137     PR_SetError(SEC_ERROR_OCSP_SERVER_ERROR, 0);
   138     return nullptr;
   139   }
   141   SECItem* encodedResponse = SECITEM_AllocItem(arena, nullptr,
   142                                                httpResponseDataLen);
   143   if (!encodedResponse) {
   144     PR_SetError(SEC_ERROR_NO_MEMORY, 0);
   145     return nullptr;
   146   }
   148   memcpy(encodedResponse->data, httpResponseData, httpResponseDataLen);
   149   return encodedResponse;
   150 }
   152 } } // namespace mozilla::psm

mercurial