コード例 #1
0
ファイル: SslSocket.cpp プロジェクト: ChugR/qpid-cpp
SslSocket::SslSocket(const std::string& certName, bool clientAuth) :
    nssSocket(0), certname(certName), prototype(0), hostnameVerification(true)
{
    //configure prototype socket:
    prototype = SSL_ImportFD(0, PR_NewTCPSocket());

    if (clientAuth) {
        NSS_CHECK(SSL_OptionSet(prototype, SSL_REQUEST_CERTIFICATE, PR_TRUE));
        NSS_CHECK(SSL_OptionSet(prototype, SSL_REQUIRE_CERTIFICATE, PR_TRUE));
    }
}
コード例 #2
0
ファイル: util.cpp プロジェクト: ChugR/qpid-cpp
void initNSS(const SslOptions& options, bool server)
{
    SslOptions::global = options;
    if (options.certPasswordFile.empty()) {
        PK11_SetPasswordFunc(promptForPassword);
    } else {
        PK11_SetPasswordFunc(readPasswordFromFile);
    }
    NSS_CHECK(NSS_Init(options.certDbPath.c_str()));
    if (options.exportPolicy) {
        NSS_CHECK(NSS_SetExportPolicy());
    } else {
        NSS_CHECK(NSS_SetDomesticPolicy());
    }
    if (server) {
        //use defaults for all args, TODO: may want to make this configurable
        SSL_ConfigServerSessionIDCache(0, 0, 0, 0);
    }

    // disable SSLv2 and SSLv3 versions of the protocol - they are
    // no longer considered secure
    SSLVersionRange drange, srange; // default and supported ranges
    const uint16_t tlsv1 = 0x0301;  // Protocol version for TLSv1.0
    NSS_CHECK(SSL_VersionRangeGetDefault(ssl_variant_stream, &drange));
    NSS_CHECK(SSL_VersionRangeGetSupported(ssl_variant_stream, &srange));
    if (drange.min < tlsv1) {
        drange.min = tlsv1;
        NSS_CHECK(SSL_VersionRangeSetDefault(ssl_variant_stream, &drange));
    }
    if (srange.max > drange.max) {
        drange.max = srange.max;
        NSS_CHECK(SSL_VersionRangeSetDefault(ssl_variant_stream, &drange));
    }
}
コード例 #3
0
ファイル: SslSocket.cpp プロジェクト: KeithLatteri/awips2
void SslSocket::connect(const std::string& host, uint16_t port) const
{
    std::stringstream namestream;
    namestream << host << ":" << port;
    connectname = namestream.str();

    void* arg = SslOptions::global.certName.empty() ? 0 : const_cast<char*>(SslOptions::global.certName.c_str());
    NSS_CHECK(SSL_GetClientAuthDataHook(socket, NSS_GetClientAuthData, arg));
    NSS_CHECK(SSL_SetURL(socket, host.data()));

    char hostBuffer[PR_NETDB_BUF_SIZE];
    PRHostEnt hostEntry;
    PR_CHECK(PR_GetHostByName(host.data(), hostBuffer, PR_NETDB_BUF_SIZE, &hostEntry));
    PRNetAddr address;
    int value = PR_EnumerateHostEnt(0, &hostEntry, port, &address);
    if (value < 0) {
        throw Exception(QPID_MSG("Error getting address for host: " << ErrorString()));
    } else if (value == 0) {
        throw Exception(QPID_MSG("Could not resolve address for host."));
    }
    PR_CHECK(PR_Connect(socket, &address, PR_INTERVAL_NO_TIMEOUT));
}
コード例 #4
0
ファイル: SslSocket.cpp プロジェクト: ChugR/qpid-cpp
int SslSocket::listen(const SocketAddress& sa, int backlog) const
{
    //get certificate and key (is this the correct way?)
    std::string cName( (certname == "") ? "localhost.localdomain" : certname);
    CERTCertificate *cert = PK11_FindCertFromNickname(const_cast<char*>(cName.c_str()), 0);
    if (!cert) throw Exception(QPID_MSG("Failed to load certificate '" << cName << "'"));
    SECKEYPrivateKey *key = PK11_FindKeyByAnyCert(cert, 0);
    if (!key) throw Exception(QPID_MSG("Failed to retrieve private key from certificate"));
    NSS_CHECK(SSL_ConfigSecureServer(prototype, cert, key, NSS_FindCertKEAType(cert)));
    SECKEY_DestroyPrivateKey(key);
    CERT_DestroyCertificate(cert);

    return BSDSocket::listen(sa, backlog);
}
コード例 #5
0
ファイル: SslSocket.cpp プロジェクト: KeithLatteri/awips2
int SslSocket::listen(uint16_t port, int backlog, const std::string& certName, bool clientAuth) const
{
    //configure prototype socket:
    prototype = SSL_ImportFD(0, PR_NewTCPSocket());
    if (clientAuth) {
        NSS_CHECK(SSL_OptionSet(prototype, SSL_REQUEST_CERTIFICATE, PR_TRUE));
        NSS_CHECK(SSL_OptionSet(prototype, SSL_REQUIRE_CERTIFICATE, PR_TRUE));
    }

    //get certificate and key (is this the correct way?)
    CERTCertificate *cert = PK11_FindCertFromNickname(const_cast<char*>(certName.c_str()), 0);
    if (!cert) throw Exception(QPID_MSG("Failed to load certificate '" << certName << "'"));
    SECKEYPrivateKey *key = PK11_FindKeyByAnyCert(cert, 0);
    if (!key) throw Exception(QPID_MSG("Failed to retrieve private key from certificate"));
    NSS_CHECK(SSL_ConfigSecureServer(prototype, cert, key, NSS_FindCertKEAType(cert)));
    SECKEY_DestroyPrivateKey(key);
    CERT_DestroyCertificate(cert);

    //bind and listen
    const int& socket = impl->fd;
    int yes=1;
    QPID_POSIX_CHECK(setsockopt(socket,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)));
    struct sockaddr_in name;
    name.sin_family = AF_INET;
    name.sin_port = htons(port);
    name.sin_addr.s_addr = 0;
    if (::bind(socket, (struct sockaddr*)&name, sizeof(name)) < 0)
        throw Exception(QPID_MSG("Can't bind to port " << port << ": " << strError(errno)));
    if (::listen(socket, backlog) < 0)
        throw Exception(QPID_MSG("Can't listen on port " << port << ": " << strError(errno)));
    
    socklen_t namelen = sizeof(name);
    if (::getsockname(socket, (struct sockaddr*)&name, &namelen) < 0)
        throw QPID_POSIX_ERROR(errno);

    return ntohs(name.sin_port);
}
コード例 #6
0
ファイル: SslSocket.cpp プロジェクト: ChugR/qpid-cpp
void SslSocket::finishConnect(const SocketAddress& addr) const
{
    nssSocket = SSL_ImportFD(0, PR_ImportTCPSocket(fd));

    void* arg;
    // Use the connection's cert-name if it has one; else use global cert-name
    if (certname != "") {
        arg = const_cast<char*>(certname.c_str());
    } else if (SslOptions::global.certName.empty()) {
        arg = 0;
    } else {
        arg = const_cast<char*>(SslOptions::global.certName.c_str());
    }
    NSS_CHECK(SSL_GetClientAuthDataHook(nssSocket, NSS_GetClientAuthData, arg));

    url = addr.getHost();
    if (!hostnameVerification) {
        NSS_CHECK(SSL_BadCertHook(nssSocket, bad_certificate, const_cast<char*>(url.data())));
    }
    NSS_CHECK(SSL_SetURL(nssSocket, url.data()));

    NSS_CHECK(SSL_ResetHandshake(nssSocket, PR_FALSE));
    NSS_CHECK(SSL_ForceHandshake(nssSocket));
}
コード例 #7
0
ファイル: SslSocket.cpp プロジェクト: ChugR/qpid-cpp
/**
 * This form of the constructor is used with the server-side sockets
 * returned from accept. Because we use posix accept rather than
 * PR_Accept, we have to reset the handshake.
 */
SslSocket::SslSocket(int fd, PRFileDesc* model) : BSDSocket(fd), nssSocket(0), prototype(0)
{
    nssSocket = SSL_ImportFD(model, PR_ImportTCPSocket(fd));
    NSS_CHECK(SSL_ResetHandshake(nssSocket, PR_TRUE));
}
コード例 #8
0
ファイル: SslSocket.cpp プロジェクト: KeithLatteri/awips2
/**
 * This form of the constructor is used with the server-side sockets
 * returned from accept. Because we use posix accept rather than
 * PR_Accept, we have to reset the handshake.
 */
SslSocket::SslSocket(IOHandlePrivate* ioph, PRFileDesc* model) : IOHandle(ioph), socket(0), prototype(0)
{ 
    socket = SSL_ImportFD(model, PR_ImportTCPSocket(impl->fd));
    NSS_CHECK(SSL_ResetHandshake(socket, true));
}