From 9f25490f61c196959accdf8a3a51c93297323b2a Mon Sep 17 00:00:00 2001 From: Carlos Quintana Date: Mon, 18 Oct 2021 11:33:02 +0200 Subject: [PATCH 1/4] Lock global gopenpgp fields --- CHANGELOG.md | 4 ++++ crypto/gopenpgp.go | 9 ++++++++- crypto/time.go | 12 ++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a30504e..866ef16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] +### Fixed +- Protect the global `pgp` variable fields with a lock. + ## [2.2.4] 2021-09-29 ### Fixed - Use the provided `verifyTime` instead of the current time when verifying embedded signatures. diff --git a/crypto/gopenpgp.go b/crypto/gopenpgp.go index c20b5ec..0e599e4 100644 --- a/crypto/gopenpgp.go +++ b/crypto/gopenpgp.go @@ -1,14 +1,21 @@ // Package crypto provides a high-level API for common OpenPGP functionality. package crypto +import "sync" + // GopenPGP is used as a "namespace" for many of the functions in this package. // It is a struct that keeps track of time skew between server and client. type GopenPGP struct { latestServerTime int64 generationOffset int64 + lock *sync.Mutex } -var pgp = GopenPGP{} +var pgp = GopenPGP{ + latestServerTime: 0, + generationOffset: 0, + lock: &sync.Mutex{}, +} // clone returns a clone of the byte slice. Internal function used to make sure // we don't retain a reference to external data. diff --git a/crypto/time.go b/crypto/time.go index 82305a3..a20529b 100644 --- a/crypto/time.go +++ b/crypto/time.go @@ -6,6 +6,9 @@ import ( // UpdateTime updates cached time. func UpdateTime(newTime int64) { + pgp.lock.Lock() + defer pgp.lock.Unlock() + if newTime > pgp.latestServerTime { pgp.latestServerTime = newTime } @@ -13,6 +16,9 @@ func UpdateTime(newTime int64) { // SetKeyGenerationOffset updates the offset when generating keys. func SetKeyGenerationOffset(offset int64) { + pgp.lock.Lock() + defer pgp.lock.Unlock() + pgp.generationOffset = offset } @@ -30,6 +36,9 @@ func GetTime() time.Time { // getNow returns the latest server time. func getNow() time.Time { + pgp.lock.Lock() + defer pgp.lock.Unlock() + if pgp.latestServerTime == 0 { return time.Now() } @@ -44,6 +53,9 @@ func getTimeGenerator() func() time.Time { // getNowKeyGenerationOffset returns the current time with the key generation offset. func getNowKeyGenerationOffset() time.Time { + pgp.lock.Lock() + defer pgp.lock.Unlock() + if pgp.latestServerTime == 0 { return time.Unix(time.Now().Unix()+pgp.generationOffset, 0) } From c406b182bbab97b26b720d7a4c8f4985dfcc4460 Mon Sep 17 00:00:00 2001 From: Carlos Quintana Date: Tue, 19 Oct 2021 08:09:59 +0200 Subject: [PATCH 2/4] Replace Mutex with RWMutex --- crypto/gopenpgp.go | 4 ++-- crypto/time.go | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crypto/gopenpgp.go b/crypto/gopenpgp.go index 0e599e4..2884b31 100644 --- a/crypto/gopenpgp.go +++ b/crypto/gopenpgp.go @@ -8,13 +8,13 @@ import "sync" type GopenPGP struct { latestServerTime int64 generationOffset int64 - lock *sync.Mutex + lock *sync.RWMutex } var pgp = GopenPGP{ latestServerTime: 0, generationOffset: 0, - lock: &sync.Mutex{}, + lock: &sync.RWMutex{}, } // clone returns a clone of the byte slice. Internal function used to make sure diff --git a/crypto/time.go b/crypto/time.go index a20529b..b208d87 100644 --- a/crypto/time.go +++ b/crypto/time.go @@ -36,8 +36,8 @@ func GetTime() time.Time { // getNow returns the latest server time. func getNow() time.Time { - pgp.lock.Lock() - defer pgp.lock.Unlock() + pgp.lock.RLock() + defer pgp.lock.RUnlock() if pgp.latestServerTime == 0 { return time.Now() @@ -53,8 +53,8 @@ func getTimeGenerator() func() time.Time { // getNowKeyGenerationOffset returns the current time with the key generation offset. func getNowKeyGenerationOffset() time.Time { - pgp.lock.Lock() - defer pgp.lock.Unlock() + pgp.lock.RLock() + defer pgp.lock.RUnlock() if pgp.latestServerTime == 0 { return time.Unix(time.Now().Unix()+pgp.generationOffset, 0) From 2118a0e7760f4da9ed225749f43fd40ee690f186 Mon Sep 17 00:00:00 2001 From: Carlos Quintana Date: Tue, 19 Oct 2021 09:06:09 +0200 Subject: [PATCH 3/4] Lint fixes --- crypto/gopenpgp.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/gopenpgp.go b/crypto/gopenpgp.go index 2884b31..d5ae56d 100644 --- a/crypto/gopenpgp.go +++ b/crypto/gopenpgp.go @@ -14,7 +14,7 @@ type GopenPGP struct { var pgp = GopenPGP{ latestServerTime: 0, generationOffset: 0, - lock: &sync.RWMutex{}, + lock: &sync.RWMutex{}, } // clone returns a clone of the byte slice. Internal function used to make sure From 9ca489189aecafeabb5b0631393bc3c72f393436 Mon Sep 17 00:00:00 2001 From: Carlos Quintana Date: Tue, 19 Oct 2021 09:54:29 +0200 Subject: [PATCH 4/4] Upgrade XCode version to 13.0 in Workflows --- .github/workflows/ios.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ios.yml b/.github/workflows/ios.yml index 69cfc01..bccd223 100644 --- a/.github/workflows/ios.yml +++ b/.github/workflows/ios.yml @@ -12,10 +12,10 @@ jobs: runs-on: macos-latest steps: - - name: Set up xcode 12.2 + - name: Set up xcode 13.0 uses: maxim-lobanov/setup-xcode@v1 with: - xcode-version: 12.2 + xcode-version: 13.0 id: xcode - name: Set up Go 1.x