Addition of OTS Token activation procedure

This commit adds an OTS Token activation procedure to IPsec server
implementation. With this implementation, OTS Token is activated
when PKI Auth response message is sent from IPsec server to IPsec
client. The Token expiry time was increased to 7 seconds due to
Kubernetes API dependability that may delay IPsec Auth procedure
in a few seconds, affecting OTS Token validation criterea.

Test plan:
PASS: Full build, system install, bootstrap and unlock DX system w/
      unlocked enabled available status.
PASS: In a DC system with available enabled active status with IPsec
      server being executed from controller-0. Run "ipsec-client
      pxecontroller --opcode 1" in worker-0. Observe that certificates,
      keys and swanctl.conf files are created in worker-0 node. Observe
      that a security association is established between the hosts via
      "sudo swanctl --list-sas" command.
PASS: In a DC system with available enabled active status with IPsec
      server being executed from controller-0. Run "ipsec-client
      pxecontroller --opcode 2" in controller-1. Observe the previously
      created CertificateRequest was deleted and generated a new one for
      controller-1's node. The new certificate is sent to IPsec Client
      and stored with the swanctl rekey command executed sucessfully.

Story: 2010940
Task: 49712

Change-Id: I1c65edf14fd7ae3f47309b35048a805e0306038d
Signed-off-by: Manoel Benedito Neto <Manoel.BeneditoNeto@windriver.com>
This commit is contained in:
Manoel Benedito Neto 2024-03-10 22:12:28 -03:00
parent e378036a0d
commit 56e2d1e2cd
2 changed files with 30 additions and 7 deletions

View File

@ -11,6 +11,10 @@ import string
import time
import threading
from oslo_log import log as logging
LOG = logging.getLogger(__name__)
class State(enum.Enum):
STAGE_1 = 1
@ -64,16 +68,17 @@ class State(enum.Enum):
class Token(object):
VERSION = int(1).to_bytes(1, 'little')
EXPIRY_TIME = 5000
EXPIRY_TIME = 7000
def __init__(self):
self.__nonce = secrets.token_bytes(16) # 128-bit nonce
self.__start_time = int(time.time() * 1000) # 64-bit utc time
self.__creation_time = int(time.time() * 1000) # 64-bit utc time
self.__content = bytearray(self.VERSION + self.__nonce
+ self.__start_time.to_bytes(8, 'little'))
+ self.__creation_time.to_bytes(8, 'little'))
self.__used = False
self.__expired = False
self.__timer = self.__set_timer()
self.__start_time = 0
self.__timer = None
random.shuffle(self.__content)
@ -88,18 +93,32 @@ class Token(object):
def __expire_token(self):
self.__expired = True
self.__timer.cancel()
if self.__timer and self.__timer.is_alive():
self.__timer.cancel()
LOG.info("OTS Token set as expired")
else:
LOG.info("OTS Token expired")
return None
def activate(self):
'''Activate OTS Token timer.'''
self.__start_time = int(time.time() * 1000)
self.__timer = self.__set_timer()
LOG.info("OTS Token activated")
return None
def purge(self):
'''Purge the token.'''
self.__used = True
self.__expired = True
self.__content = bytearray()
self.__expire_token()
LOG.info("OTS Token purged")
return None
def set_as_used(self):
'''Set token as used.'''
self.__used = True
LOG.info("OTS Token set as used")
return None
def get_content(self):
@ -111,7 +130,7 @@ class Token(object):
time and its usage flag.'''
period = int(time.time() * 1000) - self.__start_time
if period >= self.EXPIRY_TIME and not self.__expired:
self.__expired = True
self.__expire_token()
return not (self.__expired or self.__used)

View File

@ -114,9 +114,13 @@ class IPsecConnection(object):
# A readable client socket has data
LOG.debug("Received {!r}".format(data))
self.state = State.get_next_state(self.state)
LOG.debug("Preparing payload")
msg = self._handle_write(data)
sock.sendall(msg)
if self.state == State.STAGE_2:
self.ots_token.activate()
self.state = State.get_next_state(self.state)
elif self.state == State.STAGE_5 or not data:
self.ots_token.purge()