From patchwork Thu Aug 15 03:19:32 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "plaisthos (Code Review)" X-Patchwork-Id: 3789 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:77d2:b0:5a1:d4fc:4ac6 with SMTP id r18csp1162524mau; Wed, 14 Aug 2024 20:20:22 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCXiXzvIYSwaqXQJM+/z2hZvPJwQ4NQuFml1qCpBS/YQYgu9ys23/yfHAqk08LU1LwCGhigI6IwHFA6PiP9J/agMJ9L8VsY= X-Google-Smtp-Source: AGHT+IHIQcWD1CNA8i+2dH3VNgeokfVlTulN70AvWMzXavbVg35ji1GSKBmGO6tTw5uC2fi3Xl2y X-Received: by 2002:a17:90b:8c6:b0:2d3:c2a3:2383 with SMTP id 98e67ed59e1d1-2d3c4fb51e1mr1018712a91.0.1723692022124; Wed, 14 Aug 2024 20:20:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1723692022; cv=none; d=google.com; s=arc-20240605; b=WXh1GnfZpdoecKzjP65zVh5s8ch3tpq2qWA/v2uFjcOgehwjaMD03yX+iEsf6jAsd4 Wv4KbZQTeMVZkWxsqPkbg3oz0dim1ZUhn8pcLRt5yWCdH6TPuhy66yM8DgGJVvwPhlmV d+6IN518PPgz+hTRVQICQ8Bw/AsBrTLrY98apScK/af4Xf4wcQ6se1RVC9OW6W/ud21P QGu0IZ1NEVMKvEssEeynCW/GhFRVPtC6bOj+tMpG/PrXfMr2yWJOuM0vbXGpu85qaCJc o8VNg23g6Gn6gtuHM7m5o0O5+Hx1WByVddDfoE0QM2QrkVmZH38/oHCsR3Zlk6UVppeU qM2w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=errors-to:cc:reply-to:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:subject:user-agent :mime-version:message-id:references:auto-submitted:to:date:from :dkim-signature:dkim-signature:dkim-signature; bh=C3foAYzrYtXz2Q5EpV7YYUESYt+4W5UHlHkIBqbZdSI=; fh=U7wEyxtwz2o5+UdevFSA47vNeG9knhWH0KV//QhD5a0=; b=RQ1U1LF4mq3WN9qZ8zwIrk7QXpoVVxVLQiUWHQJESC3EYuA/0zMSNDl215eI4L3onP UTN+Huch37iX1P3mJIugAmYGTinqpX8bVEraPfxiLJsGduN13CyylvPhDeEdlEh47adm PiEJUsBKpCLWo3AsXPp357A5XpDLShnHnvfyEvWuMDRt7et/wqgl0v2vumTkfEFdO8HY 1aREsPx0U7uSMKp4QLxvS7OUZat5S4YUDjqehTSfQRC1KvuQBHPA30Lt/LTKxFemhXQG uyQIWYreHqs2MRDUD/ZWPAV8LFVlgUwrbOwnZWJyRuKodonnA8wJqaA7+LzkgSLzn89R NXuA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=UNlA2x1K; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=SwSd72wR; dkim=neutral (body hash did not verify) header.i=@openvpn.net header.s=google header.b=g214XtZe; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=openvpn.net; dara=fail header.i=@openvpn.net Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 98e67ed59e1d1-2d3ac7e8de4si480894a91.47.2024.08.14.20.20.21 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 14 Aug 2024 20:20:22 -0700 (PDT) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=UNlA2x1K; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=SwSd72wR; dkim=neutral (body hash did not verify) header.i=@openvpn.net header.s=google header.b=g214XtZe; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=openvpn.net; dara=fail header.i=@openvpn.net Received: from [127.0.0.1] (helo=sfs-ml-3.v29.lw.sourceforge.com) by sfs-ml-3.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1seR1i-0007Cy-Vu; Thu, 15 Aug 2024 03:19:50 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-3.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1seR1h-0007Cm-P0 for openvpn-devel@lists.sourceforge.net; Thu, 15 Aug 2024 03:19:49 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Type:Content-Transfer-Encoding:MIME-Version :Message-ID:Reply-To:References:Subject:List-Unsubscribe:List-Id:Cc:To:Date: From:Sender:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:List-Help: List-Subscribe:List-Post:List-Owner:List-Archive; bh=4fhToaU1linTR6mAmioNnMalCRNUa3iMjuO7KAgQNFQ=; b=UNlA2x1K5X/EsqVzmOb5aTW2+l Yftc9ctXfeU4pFyWFij2Mivbg9U/5kPG10n4+s/5Yv3ZpXkmWjvgdLkiEIEHl9yBpv+xwo7N3kVt7 +qdxs62VdwKRQwhcD6kHF50cheaMj2c5ChtO5m2nvznJq9Kw9srRoer596s2Rd2iZYD0=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Type:Content-Transfer-Encoding:MIME-Version:Message-ID:Reply-To: References:Subject:List-Unsubscribe:List-Id:Cc:To:Date:From:Sender:Content-ID :Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To: Resent-Cc:Resent-Message-ID:In-Reply-To:List-Help:List-Subscribe:List-Post: List-Owner:List-Archive; bh=4fhToaU1linTR6mAmioNnMalCRNUa3iMjuO7KAgQNFQ=; b=S wSd72wRq7V+cYd1DfPemsp83PxBo72wo2hnbh8kRf4Uvs3LdmX9bzXZLqh2XCXz5iF3AJbgxGVtun 5rm3j54QfxFqtIxsV7kcy9E4FD/nurHhpmru2wbe1dHlTkY2UQqwcy0ggJuseSbto4fIIDV+8f0Yd X+l7SudlyE6vQGAM=; Received: from mail-wr1-f54.google.com ([209.85.221.54]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.95) id 1seR1Y-0000at-Mi for openvpn-devel@lists.sourceforge.net; Thu, 15 Aug 2024 03:19:42 +0000 Received: by mail-wr1-f54.google.com with SMTP id ffacd0b85a97d-37186c2278bso274800f8f.1 for ; Wed, 14 Aug 2024 20:19:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvpn.net; s=google; t=1723691974; x=1724296774; darn=lists.sourceforge.net; h=user-agent:content-disposition:content-transfer-encoding :mime-version:message-id:reply-to:references:subject :list-unsubscribe:list-id:auto-submitted:cc:to:date:from:from:to:cc :subject:date:message-id:reply-to; bh=4fhToaU1linTR6mAmioNnMalCRNUa3iMjuO7KAgQNFQ=; b=g214XtZeDYWIKNcid8+QaKqm8KMjz6I1dAxfdr+bs66TarptXfOkV3oHaQvNrAvOCM lKMEBUx2NLhiVJRx7FjYCbsyhvtO/vC8XTknXpIIHu2FtR6RMOUeaXBLQD1cwjr85Xlg WlqHBa8nruY3Mk5FMy+Bfp/068wyOoAH9riOsNNR9b391D0ntX9eI2IughfuuVQlj7NF 8dWPFyYQOlMwDYED4VGDCRqvwGssBIRhyAPtSGbwsPG9wrerrpihX370bO+2EbYnvC4x hr6PLN3f9nBLgnoDtD+loRt4OcacOD/OE8MVpGvANeV9XF+4f07TZWtBTbLOxiqA5IOq B5NA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723691974; x=1724296774; h=user-agent:content-disposition:content-transfer-encoding :mime-version:message-id:reply-to:references:subject :list-unsubscribe:list-id:auto-submitted:cc:to:date:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=4fhToaU1linTR6mAmioNnMalCRNUa3iMjuO7KAgQNFQ=; b=lXycJL3yWdfByNxsnCigjKdJeiH0EBIGBPiV8zT88Vw9FXUG9HNoLDbREzWEXWXptr riIyO0eSEXe6/2PND+b+oqiqDeUXnWpyDkXyyH4zJRRaTVwyl3XcDGDmjVm6wOLXZldf Ixr+elV+UN7Jvzv10hUQM4J5RmyPJ3Ghldixm5KSV91PAafH6lLWUsJHrHCnjUY+HLTn PwwFZGa1P1HJ9pqBKM7ZLj21Tnk3XCJLMxPS3sakxYzJnt+EVbfEKWz9tdphfQP5x1+k wY9FTBfMV2Uu+RcbRiYcaotT0jkh0E9boePAWNnwYq709xBuPqvNuzSq9GyXjA0FJxNa ZEOw== X-Gm-Message-State: AOJu0YwyNpvLvNSIc7ZxOoF7OzrpW+c3PoVGg77XxGLhm6P9r43hskPB fudDjXpJygsmFpSbqAqLUeKRTyg/tgZ6RfzPOTR0+OCdw8XWZmhJz7BjO5tBG/ghkVrbcay0hHD y X-Received: by 2002:adf:cc87:0:b0:36b:b08f:64b3 with SMTP id ffacd0b85a97d-37186d72c42mr890318f8f.20.1723691973758; Wed, 14 Aug 2024 20:19:33 -0700 (PDT) Received: from gerrit.openvpn.in (ec2-18-159-0-78.eu-central-1.compute.amazonaws.com. [18.159.0.78]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-37189897175sm471495f8f.83.2024.08.14.20.19.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 14 Aug 2024 20:19:33 -0700 (PDT) From: "selvanair (Code Review)" X-Google-Original-From: "selvanair (Code Review)" X-Gerrit-PatchSet: 1 Date: Thu, 15 Aug 2024 03:19:32 +0000 To: plaisthos , flichtenheld Auto-Submitted: auto-generated X-Gerrit-MessageType: newchange X-Gerrit-Change-Id: I42e17e09a02f01aedadc2b03f9527967f6e1e8ff X-Gerrit-Change-Number: 728 X-Gerrit-Project: openvpn X-Gerrit-ChangeURL: X-Gerrit-Commit: ae0e1e7baaf98e2ecdc1bdc997995c1207162276 References: Message-ID: <288253eeaef2b8fbc200f9d0d890596a2929a061-HTML@gerrit.openvpn.net> MIME-Version: 1.0 User-Agent: Gerrit/3.8.2 X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "util-spamd-1.v13.lw.sourceforge.com", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Attention is currently required from: flichtenheld, plaisthos. Hello plaisthos, flichtenheld, I'd like you to do a code review. Please visit Content analysis details: (-0.2 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: openvpn.net] -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.221.54 listed in wl.mailspike.net] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record 0.0 WEIRD_PORT URI: Uses non-standard port number for HTTP 0.0 HTML_MESSAGE BODY: HTML included in message -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid 0.0 T_KAM_HTML_FONT_INVALID Test for Invalidly Named or Formatted Colors in HTML -0.0 T_SCC_BODY_TEXT_LINE No description available. X-Headers-End: 1seR1Y-0000at-Mi Subject: [Openvpn-devel] [M] Change in openvpn[master]: Protect cached username, password and token on client X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: selva.nair@gmail.com, arne-openvpn@rfc2549.org, openvpn-devel@lists.sourceforge.net, frank@lichtenheld.com Cc: openvpn-devel Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1807422085588060267?= X-GMAIL-MSGID: =?utf-8?q?1807422085588060267?= X-getmail-filter-classifier: gerrit message type newchange Attention is currently required from: flichtenheld, plaisthos. Hello plaisthos, flichtenheld, I'd like you to do a code review. Please visit http://gerrit.openvpn.net/c/openvpn/+/728?usp=email to review the following change. Change subject: Protect cached username, password and token on client ...................................................................... Protect cached username, password and token on client Keep the memory segment containing username and password in "struct user_pass" encrypted. Works only on Windows. Username and auth-token cached by the server are not covered here. Change-Id: I42e17e09a02f01aedadc2b03f9527967f6e1e8ff Signed-off-by: Selva Nair --- M src/openvpn/auth_token.c M src/openvpn/misc.c M src/openvpn/misc.h M src/openvpn/proxy.c M src/openvpn/ssl.c M src/openvpn/ssl_verify.c M src/openvpn/win32.c M src/openvpn/win32.h M tests/unit_tests/openvpn/test_user_pass.c 9 files changed, 140 insertions(+), 8 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/28/728/1 diff --git a/src/openvpn/auth_token.c b/src/openvpn/auth_token.c index 6787ea7..16e1baa 100644 --- a/src/openvpn/auth_token.c +++ b/src/openvpn/auth_token.c @@ -304,6 +304,7 @@ uint8_t b64decoded[USER_PASS_LEN]; int decoded_len = openvpn_base64_decode(up->password + strlen(SESSION_ID_PREFIX), b64decoded, USER_PASS_LEN); + ASSERT(up && !up->protected); /* * Ensure that the decoded data is the size of the diff --git a/src/openvpn/misc.c b/src/openvpn/misc.c index 598fbae..818452a 100644 --- a/src/openvpn/misc.c +++ b/src/openvpn/misc.c @@ -223,6 +223,7 @@ bool password_from_stdin = false; bool response_from_stdin = true; + unprotect_user_pass(up); if (flags & GET_USER_PASS_PREVIOUS_CREDS_FAILED) { msg(M_WARN, "Note: previous '%s' credentials failed", prefix); @@ -479,14 +480,18 @@ secure_memzero(up, sizeof(*up)); up->nocache = nocache; } - /* - * don't show warning if the pass has been replaced by a token: this is an - * artificial "auth-nocache" - */ - else if (!warn_shown) + else { - msg(M_WARN, "WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this"); - warn_shown = true; + protect_user_pass(up); + /* + * don't show warning if the pass has been replaced by a token: this is an + * artificial "auth-nocache" + */ + if (!warn_shown) + { + msg(M_WARN, "WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this"); + warn_shown = true; + } } } @@ -495,6 +500,7 @@ { if (strlen(token)) { + unprotect_user_pass(tk); strncpynt(tk->password, token, USER_PASS_LEN); tk->token_defined = true; @@ -505,6 +511,7 @@ { tk->defined = true; } + protect_user_pass(tk); } } @@ -513,6 +520,7 @@ { if (strlen(username)) { + unprotect_user_pass(tk); /* Clear the username before decoding to ensure no old material is left * and also allow decoding to not use all space to ensure the last byte is * always 0 */ @@ -523,6 +531,7 @@ { msg(D_PUSH, "Error decoding auth-token-username"); } + protect_user_pass(tk); } } @@ -779,3 +788,29 @@ return combined_path; } + +void +protect_user_pass(struct user_pass *up) +{ + if (up->protected) + { + return; + } +#ifdef _WIN32 + size_t len = offsetof(struct user_pass, pad) - offsetof(struct user_pass, username); + up->protected = protect_buffer_win32(up->username, len); +#endif +} + +void +unprotect_user_pass(struct user_pass *up) +{ + if (!up->protected) + { + return; + } +#ifdef _WIN32 + size_t len = offsetof(struct user_pass, pad) - offsetof(struct user_pass, username); + up->protected = !unprotect_buffer_win32(up->username, len); +#endif +} diff --git a/src/openvpn/misc.h b/src/openvpn/misc.h index 963f3e6..4d7e4d7 100644 --- a/src/openvpn/misc.h +++ b/src/openvpn/misc.h @@ -60,6 +60,7 @@ * use this second bool to track if the token (password) is defined */ bool token_defined; bool nocache; + bool protected; /* max length of username/password */ #ifdef ENABLE_PKCS11 @@ -70,6 +71,7 @@ /* Note that username and password are expected to be null-terminated */ char username[USER_PASS_LEN]; char password[USER_PASS_LEN]; + char pad; /* used by protect_user_pass() to determine boundary */ }; #ifdef ENABLE_MANAGEMENT @@ -207,6 +209,19 @@ struct buffer prepend_dir(const char *dir, const char *path, struct gc_arena *gc); +/** + * Encrypt username and password buffers in user_pass + */ +void +protect_user_pass(struct user_pass *up); + +/** + * Decrypt username and password buffers in user_pass + */ +void +unprotect_user_pass(struct user_pass *up); + + #define _STRINGIFY(S) #S /* *INDENT-OFF* - uncrustify need to ignore this macro */ #define MAC_FMT _STRINGIFY(%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx) diff --git a/src/openvpn/proxy.c b/src/openvpn/proxy.c index eddacc9..404ea08 100644 --- a/src/openvpn/proxy.c +++ b/src/openvpn/proxy.c @@ -291,13 +291,14 @@ UP_TYPE_PROXY, flags); static_proxy_user_pass.nocache = p->options.nocache; + protect_user_pass(&static_proxy_user_pass); } /* * Using cached credentials */ p->queried_creds = true; - p->up = static_proxy_user_pass; + p->up = static_proxy_user_pass; /* this is a copy of protected memory */ } #if 0 @@ -668,6 +669,7 @@ { clear_user_pass_http(); } + unprotect_user_pass(&p->up); } /* are we being called again after getting the digest server nonce in the previous transaction? */ diff --git a/src/openvpn/ssl.c b/src/openvpn/ssl.c index 14c38cf..c2c9c29 100644 --- a/src/openvpn/ssl.c +++ b/src/openvpn/ssl.c @@ -243,6 +243,7 @@ void pem_password_setup(const char *auth_file) { + unprotect_user_pass(&passbuf); if (!strlen(passbuf.password)) { get_user_pass(&passbuf, auth_file, UP_TYPE_PRIVATE_KEY, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_PASSWORD_ONLY); @@ -256,6 +257,7 @@ { /* prompt for password even if --askpass wasn't specified */ pem_password_setup(NULL); + ASSERT(!passbuf.protected); strncpynt(buf, passbuf.password, size); purge_user_pass(&passbuf, false); @@ -295,6 +297,7 @@ if (!auth_user_pass.defined && !auth_token.defined) { + unprotect_user_pass(&auth_user_pass); #ifdef ENABLE_MANAGEMENT if (auth_challenge) /* dynamic challenge/response */ { @@ -2094,6 +2097,7 @@ { up = &auth_token; } + unprotect_user_pass(up); if (!write_string(buf, up->username, -1)) { @@ -2106,8 +2110,11 @@ /* save username for auth-token which may get pushed later */ if (session->opt->pull && up != &auth_token) { + unprotect_user_pass(&auth_token); strncpynt(auth_token.username, up->username, USER_PASS_LEN); + protect_user_pass(&auth_token); } + protect_user_pass(up); /* respect auth-nocache */ purge_user_pass(&auth_user_pass, false); } diff --git a/src/openvpn/ssl_verify.c b/src/openvpn/ssl_verify.c index 0b0e2c3..74b2775 100644 --- a/src/openvpn/ssl_verify.c +++ b/src/openvpn/ssl_verify.c @@ -1594,6 +1594,8 @@ { struct key_state *ks = &session->key[KS_PRIMARY]; /* primary key */ + ASSERT(up && !up->protected); + #ifdef ENABLE_MANAGEMENT int man_def_auth = KMDA_UNDEF; diff --git a/src/openvpn/win32.c b/src/openvpn/win32.c index 72496fa..86556a8 100644 --- a/src/openvpn/win32.c +++ b/src/openvpn/win32.c @@ -1658,4 +1658,40 @@ return wcsnicmp(system_dir, plugin_path, wcslen(system_dir)) == 0; } +bool +protect_buffer_win32(char *buf, size_t len) +{ + bool ret; + if (len % CRYPTPROTECTMEMORY_BLOCK_SIZE) + { + msg(M_NONFATAL, "Error: Unable to encrypt memory: buffer size not a multiple of %d", + CRYPTPROTECTMEMORY_BLOCK_SIZE); + return false; + } + ret = CryptProtectMemory(buf, len, CRYPTPROTECTMEMORY_SAME_PROCESS); + if (!ret) + { + msg(M_NONFATAL | M_ERRNO, "Failed to encrypt memory."); + } + return ret; +} + +bool +unprotect_buffer_win32(char *buf, size_t len) +{ + bool ret; + if (len % CRYPTPROTECTMEMORY_BLOCK_SIZE) + { + msg(M_NONFATAL, "Error: Unable to decrypt memory: buffer size not a multiple of %d", + CRYPTPROTECTMEMORY_BLOCK_SIZE); + return false; + } + ret = CryptUnprotectMemory(buf, len, CRYPTPROTECTMEMORY_SAME_PROCESS); + if (!ret) + { + msg(M_FATAL | M_ERRNO, "Failed to decrypt memory."); + } + return ret; +} + #endif /* ifdef _WIN32 */ diff --git a/src/openvpn/win32.h b/src/openvpn/win32.h index ffad6d9..081beeb 100644 --- a/src/openvpn/win32.h +++ b/src/openvpn/win32.h @@ -351,5 +351,27 @@ bool plugin_in_trusted_dir(const WCHAR *plugin_path); +/** + * Encrypt a region of memory using CryptProtectMemory() + * with access restricted to the current process. + * + * - buf pointer to the memory + * - len number of bytes to encrypt -- must be a multiple of + * CRYPTPROTECTMEMORY_BLOCK_SIZE = 16 + */ +bool +protect_buffer_win32(char *buf, size_t len); + +/** + * Decrypt a previously encrypted region of memory using CryptUnProtectMemory() + * with access restricted to the current process. + * + * - buf pointer to the memory + * - len number of bytes to encrypt -- must be a multiple of + * CRYPTPROTECTMEMORY_BLOCK_SIZE = 16 + */ +bool +unprotect_buffer_win32(char *buf, size_t len); + #endif /* ifndef OPENVPN_WIN32_H */ #endif /* ifdef _WIN32 */ diff --git a/tests/unit_tests/openvpn/test_user_pass.c b/tests/unit_tests/openvpn/test_user_pass.c index de60291..4dc4b83 100644 --- a/tests/unit_tests/openvpn/test_user_pass.c +++ b/tests/unit_tests/openvpn/test_user_pass.c @@ -83,6 +83,18 @@ return 0; } +bool +protect_buffer_win32(char *buf, size_t len) +{ + return true; +} + +bool +unprotect_buffer_win32(char *buf, size_t len) +{ + return true; +} + /* tooling */ static void reset_user_pass(struct user_pass *up)