Exemple #1
0
//! Save the fact that the user has manually accepted a certificate.
void PersistAcceptanceForCertificate(ConfirmationDialogData *confinfo)
{
	unsigned char tmphash[SHA_DIGEST_LENGTH];
    if (X509_pubkey_digest(confinfo->err_cert, EVP_sha1(), tmphash, NULL) != 0) {
        std::string hexhash = bin2hex(tmphash, SHA_DIGEST_LENGTH);
        std::string regpath = std::string(REGKEYBASE "\\AllowedCerts\\").append(hexhash);
        HKEY hkeyAllowed;
        if (RegCreateKeyEx(HKEY_CURRENT_USER, regpath.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_READ, NULL, &hkeyAllowed, NULL) == ERROR_SUCCESS) {
            DOUT(("stundlg: Saving acceptance for persisted certificate.\n"));

            char buf[256];
            X509_NAME_oneline(X509_get_subject_name(confinfo->err_cert), buf, sizeof(buf));
            RegSetValueEx(hkeyAllowed, "SubjectName", 0, REG_SZ, reinterpret_cast<const BYTE*>(buf), static_cast<DWORD>(strlen(buf) + 1));

            RegCloseKey(hkeyAllowed);
        }
    }
}
Exemple #2
0
static int
tls_keypair_pubkey_hash(struct tls_keypair *keypair, char **hash)
{
	BIO *membio = NULL;
	X509 *cert = NULL;
	char d[EVP_MAX_MD_SIZE], *dhex = NULL;
	int dlen, rv = -1;

	*hash = NULL;

	if ((membio = BIO_new_mem_buf(keypair->cert_mem,
	    keypair->cert_len)) == NULL)
		goto err;
	if ((cert = PEM_read_bio_X509_AUX(membio, NULL, tls_password_cb,
	    NULL)) == NULL)
		goto err;

	if (X509_pubkey_digest(cert, EVP_sha256(), d, &dlen) != 1)
		goto err;

	if (tls_hex_string(d, dlen, &dhex, NULL) != 0)
		goto err;

	if (asprintf(hash, "SHA256:%s", dhex) == -1) {
		*hash = NULL;
		goto err;
	}

	rv = 0;

 err:
	free(dhex);
	X509_free(cert);
	BIO_free(membio);

	return (rv);
}
Exemple #3
0
/*!
 * \param confinfo Pointer to structure containing identity of certificate.
 * \return Returns true if the connection should be allowed without prompting.
 *        Otherwise the user should be asked whether to allow it.
 *
 * \sa ConfirmCertificateDialog
 */
bool CheckAllowCertificate(ConfirmationDialogData *confinfo)
{
    DOUT(("stundlg: CheckAllowCertificate called\n"));

    // OpenSSL will sometimes call the certificate verification routine 
    // multiple times when establishing a connection, but we should not
    // prompt the user to confirm the same connection multiple times.
    if (confinfo->stunnel->bCertificateAccepted) {
        DOUT(("stundlg: Returning acceptance since this stunnel object has already been authorized.\n"));
        return true;
    }

#if 0
    // If you trust OpenSSL's pre-verification step, then accept it.
    if (confinfo->preverify_ok) {
        DOUT(("stundlg: Returning acceptance since certificate preverification was ok.\n"));
        return true;
    }
#endif


#if 1
    // Check the registry setting that forces us to accept all certificates.
    // This is a pretty insecure mode since it allows anything.
    do {
        HKEY hkeySettings;
        if (RegCreateKeyEx(HKEY_CURRENT_USER, REGKEYBASE, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_READ, NULL, &hkeySettings, NULL) != ERROR_SUCCESS) {
            break;
        }
        DWORD dwType;
        char buffer[512];
        DWORD dwBufferSize = sizeof(buffer);
        bool AlwaysAllowAnyCert = false;
        if (RegQueryValueEx(hkeySettings, "AlwaysAllowAnyCert", NULL, &dwType, (LPBYTE) buffer, &dwBufferSize) == ERROR_SUCCESS && (dwType == REG_DWORD)) {
            AlwaysAllowAnyCert = (*reinterpret_cast<DWORD*>(buffer) != 0);
        } else {
            *reinterpret_cast<DWORD*>(buffer) = (AlwaysAllowAnyCert ? 1 : 0);

            RegSetValueEx(hkeySettings, "AlwaysAllowAnyCert", 0, REG_DWORD, 
                reinterpret_cast<const BYTE *>(buffer), sizeof(DWORD) );
        }
        RegCloseKey(hkeySettings);
        if (AlwaysAllowAnyCert) {
            DOUT(("stundlg: Returning acceptance since the AlwaysAllowAnyCert mode is enabled.\n"));
            return true;
        }
    } while (0);
#endif

    // Check the registry to see if the user has explicitly accepted this 
    // certificate in the past.
	unsigned char tmphash[SHA_DIGEST_LENGTH];
    if (X509_pubkey_digest(confinfo->err_cert, EVP_sha1(), tmphash, NULL) != 0) {
        std::string hexhash = bin2hex(tmphash, SHA_DIGEST_LENGTH);
        std::string regpath = std::string(REGKEYBASE "\\AllowedCerts\\").append(hexhash);
        HKEY hkeyAllowed;
        if (RegOpenKeyEx(HKEY_CURRENT_USER, regpath.c_str(), 0, KEY_READ, &hkeyAllowed) == ERROR_SUCCESS) {
            DOUT(("stundlg: Returning acceptance for persisted certificate.\n"));
            RegCloseKey(hkeyAllowed);
            return true;
        }
    }

    return false;           // don't know, so prompt the user about what to do.
}