LibreSSL, PKCS#11/PKCS#15, & a PIV-Capable FIPS 140-2 Yubikey to run various Smart-Card Cryptographic Operations during Criminal Investigations on OpenBSD



July 10, 2020

As a Criminal Defense Detective and Contractor on Federal CJA-Cases, I must abide by Federal Cryptographic Standards, such as: the Personal Identity Verification of Federal Employees and Contractors (PIV). I have chain-of-custody of uncovered evidence, investigative reports, work-products, affidavits, statements, audio-files, video-files, photographs, etc.

Working on these criminal investigations requires proper and efficient case management as well as compliance to Federal, State and Local laws, regulations and standards governing the handling of confidential files, records, client's data and evidence gathered during the course of an investigation.

Encryption becomes absolutely necessary for the confidentiality and integrity of all digital evidenciary items. The proper cryptographic implementation should keep evidence available for examination and analysis without the risk of spoliation.

While many U.S Military personnel use a smart-card called "CAC-Card - Common Access Card", Federal Employees and Contractors like me, may use another type of PIV-I or PIV-II-Compliant Smart-Card. These smart-cards could either be in the form of an actual ID card or an extra smart-card in addition to an ID card. Source: https://csrc.nist.gov/projects/piv/piv-standards-and-supporting-documentation

Professionals required to abide by the various FIPS Standards and Regulations, HSPD12 and/or HIPAA law, find themselves having to interface with various cryptographic devices and tools. They need to carry a PIV-Compliant smart-card/ID along with an external pin-entry smart-card-reader safe from keylogging. The FIPS-compliant Yubikey uses a usb-port, which makes it a very ubiquitous device to be used from computer to computer without the need for extra card-readers. In addition to a required PIN#, the Yubikey can be configured with a touch-policy depending on what version you are using. A secure operating system such as OpenBSD can be one of the best environments where all these cryptographic operations take place.

As an instructor in the area of cryptography applied to investigations, I teach to members of law enforcement, the military and legal professionals from the private sector on the usage of various Unix-based and GNU/Linux-based cryptographic tools.

In this article, I will cover cryptographic operations done on a smart-card (such as a FIPS 140-2-Compliant-Validated Yubikey) via LibreSSL and PKCS#11/PKCS#15 standards/libraries. This article does NOT cover the safe creation of an Elliptic Curve ECDSA keypair, which can be found in an article published by Sebastian Benoit from the OpenBSD Journal on 02.26.2019. Source: https://undeadly.org/cgi?action=article;sid=20190302235509"

Mr. Benoit's article includes a few pieces of outdated information since the release of OpenBSD 6.7, yet all the steps cited in his article can be followed for the creation of your cryptographic Elliptic Curve ECDSA keypair. Since OpenBSD 6.7 offers the yubico-piv-tool utility natively in its repositories, OpenBSD makes it much easier to interface with the Yubikey during various smart-card cryptographic operations. I do agree with Mr. Benoit that keypairs should not be generated inside the Yubikey itself, but I would also add that keypairs should normally be created on air-gapped machines via an OS running on a CD. A backup of this keypair should then be transferred to a hardware-encrypted drive, such as the ones sold by apricorn.com, which are mostly FIPS-140-Level III-validated devices for those Federal Employees and Contractors who must comply with the laws and standards, or transferred to an encrypted container on a CD or flash drive with Full Disk Encryption (FDE) via BIOCTL/softraid0, which I have published an article about it. Only after a backup setup has been established should you load the keypair created in the air-gapped machine into the Yubikey. Other than that, Mr. Benoit's article is a great reference for those professionals who still need to have their cryptographic keys created and loaded into their smart-cards.

All the various cryptographic operations that I will be demonstrating in this article are done on a OpenBSD machine, which is the most secure and minimalistic general purpose monolithic operating system in the world, not my opinion - it is a fact.

Background and Overview of LibreSSL

https://www.libressl.org

"LibreSSL is a version of the TLS/crypto stack forked from OpenSSL in 2014, with goals of modernizing the codebase, improving security, and applying best practice development processes. Primary development occurs inside the OpenBSD source tree with the usual care the project is known for. LibreSSL is supported financially by the OpenBSD Foundation and the OpenBSD Project."

LibreSSL is a toolkit that implements TLS network protocols and the cryptographic standards that these protocols require. The openssl utility allows you to use the cryptographic functions of LibreSSL from your Terminal running some type of shell: sh, zsh, ksh, csh, fish, bash, etc.

LibreSSL allows you to generate and manage cryptographic keys, generate digital certificates, encrypt and decrypt files and messages, examine the cryptographic properties of remote systems, test servers, and myriad other cryptographic operations.

Mathematics show that strong cryptographic algorithms are reliably secure. Take for instance how many financial transactions occur on a daily basis over the Internet, ATM Machines and during puchases that require a credit/debit card reader with an Internet connection. A ton of different cipher suites and cryptographic algorithms are behind all of that. Such algorithms are engineered by committees of experts who represent government, academic, and research interests from around the world. Acceptance of a new algorithm is a lengthy and tedious process.

Nonetheless, even after some of these cryptographic algorithms are thoroughly vetted, the softwares that may implement these algorithms may have weaknesses and vulnerabilities. A perfect example of that happened with OpenSSL when the Heartbleed vulnerability was discovered.

Choosing a well-designed and engineered cryptographic software is paramount. LibreSSL became the answer.

The source code is developed upstream by the OpenBSD project and regularly re-packaged for portable use.

LibreSSL includes:

  • - openssl: a utility which provides tools for managing keys and certificates
  • - libcrypto: a library of cryptography fundamentals
  • - libssl: a TLS library, backwards-compatible with OpenSSL
  • - libtls: a new TLS library, designed to make it easier to write foolproof applications.

The OpenBSD team audited the codebase of OpenSSL and decided it was necessary to fork OpenSSL and remove dangerous code. The libressl.org domain was registered on April 11, 2014; the project announced the name on April 22, 2014. In the first week of development, more than 90,000 lines of C code were removed. Unused code was removed, and support for obsolete operating systems was removed.

After 6 years of development, LibreSSL has passed the test of criticism.

In 2020, LibreSSL is the default provider of TLS encryption for OpenBSD and multiple other operating systems.

Professional presentations and papers about OpenSSL can be found at: https://www.libressl.org/papers.html

Mr. Ted Unangst stated the following during a BSD conference in 2014:

"LibreSSL is a fork of the popular OpenSSL crypto and TLS library. TLS is the standard name for the successor to SSL, that other secure transport protocol developed in the 90s. Most notably used for https, but also secure imap/smtp/etc. I'd guess there's far more traffic protected by TLS than any other means. There are several implementations around, but two that dominate, at least in the C universe. OpenSSL is the de facto standard for servers and many clients.

Cryptography in general and TLS in particular are pretty difficult to get right. So a monoculture isn't strictly a bad thing. Put all your eggs in one basket, and then watch that basket very carefully, right? Unfortunately, the OpenSSL basket was being watched somewhat less than very carefully. Yeah, it has bugs, but surely somebody else will fix them. And worst case scenario, since everybody uses the same library, everybody will be affected by the bugs.

Fast forward past a hundred other vulnerabilities to Heartbleed, also known as the worst bug ever, though that title is heavily contested.

What was unusual about Heartbleed? It's a vulnerability, not an exploit, with a name (and a website!). Previously we'd seen The Internet Worm (when there was only one), then Code Red, Blaster, Stuxnet. They all used various exploits, but the vulnerabilities didn't have names. Heartbleed can't even be considered the worst OpenSSL vuln. Previous bugs have resulted in remote code execution. Anybody remember the Slapper worm? That worm exploited an OpenSSL bug (which was apparently titled the SSLv2 client master key buffer overflow) which revealed not only encrypted data or your private key, but also gave up a remote shell on the server, and then it propogated itself."

With a little bit of the history, definitions and background regarding LibreSSL out of the way, let's finally put it to the test.

Requirements

  • - A computer running OpenBSD: preferably a Corebooted and/or Librebooted machine with de-soldered mic, disconnected internal-speakers, no internal webcam, disabled/removed bluetooth, and an Atheros wifi-card.
  • - A FIPS 140-2-Compliant-Validated Yubikey Smart-Card (In case of Federal Employees or Contractors) or Yubikeys 4 or 5 (General Public)
  • - A cryptographic keypair loaded into the Yubikey

NOTE-1: FIPS series of Yubikeys meet Authenticator Assurance Level-3 (AA3) as specified in NIST SP-800-63B.
NOTE-2: Smart-card functionality based on the PIV-II interface as specified in NIST SP-800-73 has been possible through Yubikey smart-cards for several years now. A FIPS 140-2-Validated Yubikey becomes a viable option for Federal Agencies, Federal Employees and Contractors who need to be in compliance with the various cryptographic requirements, standards and Federal laws.

Required Packages

  • LibreSSL, opensc, yubico-piv-tool, yubikey-manager, ykpers, pcsc-tools, pinentry, PKCS-library-suite (pkcs11-tool, pkcs15-tool, pkcs15-crypt), which are all available natively on the OpenBSD repositories.

Initial Commands and System Configuration

This article will NOT cover GUI/frontend tools. The steps below will cover commands executed in a shell (in my case "zsh") running on a Terminal Emulator (in my case "ST" - the Suckless Terminal from suckless.org) for conducting cryptographic operations during a criminal investigation. Note: Since we will run all the cryptographic operations via the Terminal, it is advisable that you make pinentry your default program, instead of its counterparts, such as: pinentry-gnome or pinentry-gtk; even better uninstall the -gnome/-gtk variants, and pinentry (curses) will be the default one.

I really dislike GUI tools, they normally pack a lot of different functionality into one large monolithic program, while still hindering the investigator's ability to have power, control and flexibility during the forensic process. Piping and redirection also becomes an impossible situation via GUI frontend tools. Although working via a Physical Terminal dates back to over half a century from the 1960s and the days of the teletypewriter, working via an Emulated Terminal has not become archaic at all during criminal and forensic investigations, it has rather become even more dependable, fast, reliable, lightweight on OS resources and super efficient specially during times when an Investigator's only option is to access a remote shell on a headless server. The Unix philosophy of working via simple-suckless-non-bloated tools that do one job well remains true during 2020 and for centuries to come. OpenBSD never stopped following this philosophy and remains the most pure UNIX-like Operating System.

On the other side of the spectrum, there are those investigators who could not live or work without GUI solutions. Gladly, I am not part of that spectrum and I love living and working in a shell running on a Terminal Emulator for all my mundane tasks and professional work.

0 - Installation of packages:

$ doas pkg_add opensc pcsc-tools yubico-piv-tool yubikey-manager ykpers pinentry 

1 - Testing LibreSSL & probing the Yubikey:

$ openssl version -a

The output of the previous command should show whether you have LibreSSL installed in your system, its version and other info.

1.1 - After than you can run a simple libressl command to retrieve TLS Certificate information from a webserver, in this case openbsd.org:

$ openssl s_client -connect openbsd.org:443 | less

The output of the previous command should display the digital certificate chain, info on the encryption ciphers, info regarding the TLS session itself, etc.

1.2 - Let's now test whether your smart-card reader is working and whether your Yubikey is functioning properly:

First check if the pcscd (PCSC daemon) is listening and enabled:

$ doas rcctl ls started

If pcscd is not shown, then run the following commands to enable it and start it, then run the previous command again:

  • $ doas rcctl enable pcscd
  • $ doas rcctl start pcscd
  • $ doas rcctl ls started

Now check if your Yubikey can be read as a smart-card:

  • $ opensc-tool -a
  • $ ykinfo -V
  • $ pkcs11-tool -I

1.3 - Find out details about which slots are currently in use, the digital certificates that have been loaded, and cryptographic keys that are currently present in your Yubikey:

  • $ yubico-piv-tool -a status
  • $ pkcs11-tool -L

You can probe your Yubikey for further information regarding its present state by issuing the following command:

$ pcsc_scan

1.4 - Let's now configure a relevant setting that will allow OpenSSH to read your Yubikey via the PKCS11Provider feature, so you can authenticate to various remote systems and servers as well as have interoperability with the PIV-II Cryptographic Standard via opensc and PKCS libraries:

Open the SSH configuration file on your OpenBSD machine using your preferred text editor, in my case "vi", root privileges are required

$ doas vi /etc/ssh/ssh_config

Add the following line at the very bottom of your ssh config file, save and close the file

PKCS11Provider /usr/local/lib/pkcs11/opensc-pkcs11.so

From now on when you issue an ssh command that requires access to your private key, ssh will send the request via the PKCS#11 interface to communicate with your Yubikey and demand your PIN input and "yubikey-touch". Storing private keys on a smart-card, like the Yubikey, becomes much safer than storing it in your local hard drive. The other advantage of that is that your private key can never be extracted from your Yubikey or Smart-Card. Once a private key is loaded into the card, it stays there. The only key you can extract from your smart-card or Yubikey is your public-key.

1.5 You can now use OpenSSH to interact with your Yubikey:

Displaying your SSH public-key is as easy as issuing the following command

$ doas ssh-keygen -D /usr/local/lib/pkcs11/opensc-pkcs11.so

You can also redirect the output of the previous command into a file for further examination

$ doas ssh-keygen -D /usr/local/lib/pkcs11/opensc-pkcs11.so >> my-ssh-pub-key.asc

You can then probe the generated file above for its SSH public certificate/key Fingerprint and redirect the output into another file:

$ doas ssh-keygen -lf my-ssh-pub-key.asc >> my-ssh-pub-key-fpr.txt

The previous command is essential for those times when you want to compare and verify the authenticity of a server's public-key fingerprint with a corresponding one present in your smart-card or Yubikey. This cryptographic process prevents a possible Man-In-The-Middle Attack.

NOTE: None of the steps from 1.2-1.5 would be possible unless you had first created your cryptographic keypair and loaded them into your Yubikey. Following the recommendations set forth on this article and on the article published by Mr. Benoit would be a prudent thing to do.

2 - Extracting further information from your Yubikey and redirecting its output into files:

With the Yubikey inserted into your OpenBSD machine, run the following command

$ pkcs15-tool --read-public-key 01

On the previous command I chose probing the Yubikey from its Slot#01, also known as Slot 9a. I found out which Slot I was using after the command I had previously run on Step 1.3. Your case may vary, depending on how you loaded your keypair into your Yubikey, the keys could have gone to Slot#02, also known as Slot 9c. Run Step 1.3 again if necessary.

I can now run the previous command again and redirect its output to a file, which will contain my PIV-Public-Key

$ pkcs15-tool --read-public-key 01 >> my-piv-pub-key.asc

Now it's time to obtain the Public Digital Certificate, which is present in my Yubikey during the process when my keypair was loaded into it. Let's redirect the output of the following command into a file.

$ yubico-piv-tool -a read-certificate -s 9a >> my-x509-pub-certificate.pem

By convention, public digital certificates should be saved with .pem extension. Since we now have the public certificate as a file, we can then further examine its cryptographic properties by running the following command

$ openssl x509 -noout -text -in my-x509-pub-certificate.pem | less

Encryption, Decryption, Hashing and Digital Signatures via LibreSSL, PKCS#11 & PKCS#15-libraries using a Yubikey:

The X-509, PKCS#11 & PKCS#15 cryptographic standards, and the PIV-II Protocol generates encryption and digital signatures of binary files that contain no metadata. Thus, the hashing algorithm during encryption, decryption and signing must always be specified.

If you work for the U.S Military, the U.S Federal Government or for a Big Multi-National Corporation, your cryptographic keypair will be generated respecting a certain Public Key Infrastructure (PKI).

PKI Security will involve a Root Certificate Authority, which is normally kept offline, and sometimes valid for up to 30+ years. Below, Root CA's are the Intermediate CAs, which are normally online and carry a shorter validity. The Root CA can revoke Intermediate CAs. A Root CA compromise is a huge catastrophic crisis-event. Such compromise would be an immeasurable cyber and physical threat.

3 - Generating hash values of all RAW photographs obtained by a CSI Investigator/Forensic Photographer from his/her Nikon DSLR during a crime-scene investigation. The command below will use LibreSSL, but other methods and command utilities could also be utilized:

$ openssl dgst -sha256 *.NEF >> criminal-case-1234-photo-hashes-sha256.txt

Command above will issue a sha256 hash value for each RAW photograph contained in the current working directory that has all the crime-scene photographs. The command's output will then be redirected into a .txt file that can later be digitally signed with the Investigator's cryptographic-private-key contained in his/her smart-card or Yubikey.

3.1 - Detached Digital Signatures:

This cryptographic method of signing any type of digital criminal investigation report involves the creation of a separate binary-file containing the Investigator's signature. This method is called a "Detached Digital Signature" because the signature does not behave the same way as an ASCII-armored/Clearsigned-Signature as is the case with OpenPGP, where the ASCII-signature is embbeded into the criminal report/file itself. By the way, ASCII-armored signatures has its applicabilities and is also useful in many different situations.

In a Forensic Environment, detached digital signatures can be applied when the Lead Detective may be required to also obtain the digital signature of his/her supervisor. In this case, the criminal investigation report or forensic work-product will contain two detached-digital-signatures, which in return will create a stronger case for the cryptographic integrity of a criminal report, as well as strongly establish non-repudiation where the authenticity of the report can be validated and verified by the signature of the Lead Detective and the signature of his/her Supervisor:

Signature of the Lead Detective

$ pkcs11-tool -s -m SHA256-RSA-PKCS -i criminal-case-1234-photo-hashes-sha256.txt 
-o criminal-case-1234-photo-hashes-sha256.txt.detective.sig

Signature of the Supervisor

$ pkcs11-tool -s -m SHA256-RSA-PKCS -i criminal-case-1234-photo-hashes-sha256.txt 
-o criminal-case-1234-photo-hashes-sha256.txt.supervisor.sig

NOTE1: The previous commands will require that both the Lead Detective and Supervisor use their own assigned PIV-II-Compliant Yubikeys and type their PINs# and touch their yubikeys following the PIV-II Cryptographic Standard. Two different binary-signatures will have been generated at the end of this cryptographic procedure.

NOTE2: Multiple detached digital signatures from different professionals working on the same case and signing the same report/document ensures stronger guarantees regarding the integrity of a report/document as well as reduces the chances of spoliation of evidence in case of compromised cryptographic private keys and/or during possible malicious changes in the original report done by only one of the parties involved in the signing of the report or work-product during a criminal investigation.

NOTE3: Multiple detached digital signatures create more accountability, supervison and better overall case management. This is no different than how most Police Reports across America are generated. Most Police Reports contain the signature of the responding/arresting officer and the signature of a supervisor; however, their handwritten signatures and most electronic ones signed by these officers do not carry the cryptographic-mathematical properties found in a PIV-II-Capable ID-Smart-Card or FIPS-Validated Yubikey.

3.2 - Verifying whether the Detective's and His Supervisor's Digital Signatures are authentic, as well as cryptographically determining the integrity of criminal report via LibreSSL:

First Verification - you will need three files: the Detective's PIV-public-key, his/her signature file and the original txt file.

$ openssl dgst -sha256 -verify my-piv-pub-key.asc -signature criminal-case-1234-photo-hashes-sha256.txt.detective.sig 
criminal-case-1234-photo-hashes-sha256.txt

Second Verification - you will need three files: the Supervisor's PIV-public-key, his/her signature file and the original txt file.

NOTE: When I use the expression "PIV-public-key", it does not mean that the key itself is a PIV key, these keys are actually RSA, ECDSA, or some other type. The only reason I call them PIV-public-key is to avoid the assumption that these keys are derived from the OpenPGP standard.

$ openssl dgst -sha256 -verify supervisor-piv-pub-key.asc -signature criminal-case-1234-photo-hashes-sha256.txt.supervisor.sig 
criminal-case-1234-photo-hashes-sha256.txt

3.3 - Using LibreSSL to encrypt files.

Currently, you can only encrypt/decrypt files that are 256 bytes in size, which is the same size of the sha256 hash algorithm. Anything larger than 256-bytes will not be supported by LibreSSL, Yubikey and PKCS#11 combo. Thus, only small messages/files can be encrypted/decrypted using this type PIV-II protocol:

The following demonstrates the encryption of a random generated .txt file via the PIV-II cryptographic protocol containing an Investigator's RSA PIV-public-key. It is important to note that you only need someone's public-key to encrypt anything you want:

$ openssl rsautl -encrypt -inkey my-piv-pub-key.asc -pubin -in plainfile.txt -out encryptedfile.bin

The previous example will generate an encrypted-binary-file with no metadata associated to it.

3.4 - Using the pkcs11-tool utility to decrypt the previous binary file. Decrypting a file, on the other hand, will require the Investigator's access to his/her private key, which could be accomplished by perfoming a cryptographic operation via the PIV-II protocol. The PIN# and "yubikey-touch" will be required.

$ pkcs11-tool --decrypt -i encryptedfile.bin -m RSA-PKCS

Using LibreSSL for RFC-3161 Compliant Timestamp Protocol (TSP)

Timestamping is a formal standard defined in RFC-3161, which describes the format of a timestamp request and response.

Digital signatures strongly bind an authorized criminal investigator to the integrity of a file containing a forensic acquisition result, an official work-product or investigative report and/or a top-secret document. Authentication of intellectual property is also a good example.

In many cases, it is very relevant to strongly bind an Investigator's document/report to a specific point in time. This can be achieved by using an independent timestamping service.

LibreSSL can be utilized to create and send timestamp requests and also used to verify responses.

4 - The example below will demonstrate how to create a RFC-3161 Timestamp Request (TSQ) with a PEM X-509 Certificate Authority PKI-Compliant Protocol using the amazing LibreSSL toolkit:

$ openssl ts -query -data criminal-case-1234-work-product.txt -no_nonce -sha256 -out criminal-case-1234-work-product.txt.tsq 
-cert

The timestamp request issued above contains a hash of the ...work-product.txt file. The actual file is never sent to the timestamping server. This is important from an information security perspective. The server is only trusted with timestamp information, not the contents of the file being timestamped.

4.1 - The generated request can then be sent to a timestamping service using the curl utility available on OpenBSD and the output redirected into a .tsr file:

$ curl -s -H "Content-Type: application/timestamp-query" --data-binary "@criminal-case-1234-work-product.txt.tsq" 
https://freetsa.org/tsr > criminal-case-1234-work-product.txt.tsr

If the timestamping server accepts the request above, it returns a RFC-3161-compliant timestamp.

4.2 - Using LibreSSL to view the contents returned by the timestamping server.

$ openssl ts -reply -in criminal-case-1234-work-product.txt.tsr -text

A copy of the criminal-case-1234-work-product.txt.tsr file provides proof that the acquisition results existed at a specific point in time.

4.3 - Using LibreSSL and the curl utility to verify the validity of a timestamp service. This is normally conducted by legal adversaries or by the criminal investigator working on a case and having to demostrate his/her forensic procedures:

First, it is necessary to download the timestamping service's CA certificate. It can be fetched manually using the curl utility:

$ curl http://freetsa.org/files/cacert.pem > cacert.pem

Assuming that both the CA and TSA certificates are available to LibreSSL and valid, the independent third party can then validate the timestamp by issuing the following command via LibreSSL:

$ openssl ts -verify -in criminal-case-1234-work-product.txt.tsr -queryfile criminal-case-1234-work-product.txt.tsq 
-CAfile cacert.pem

In the command above, the timestamp query (tsq) and the timestamp response (tsr) are both provided. In this example, the file containing the timestamp server's CA certificate is also specified.

If the third-party timestamp is valid, it will display a message, such as: (Verification: OK), indicating that the file has not been modified since the specified time. This a safeguard against evidence spoliation.

Final Remarks:

In the article above, I have covered some of the commands and tasks that I normally run on my OpenBSD-detective-workstation during some of my criminal investigations.

The use of OpenBSD, LibreSSL, OpenSSH, PKCS#11/15 cryptographic libraries, and a FIPS-Compliant Yubikey and/or PIV-II-Compliant Smart Card make all of the cryptographic operations cited above possible and forensically sound.

The world of cryptography can be relatively complex and robust. The correct implementation of cryptographic standards and protocols is vital for the advancement of criminal investigations. Professionals across America and around the World will continue to be challenged and required to study, learn and use digital cryptography during their work and careers.

Whether you are a law-enforcement officer or a criminal defense investigator, federal agent, military-personnel, civil-service and/or private-sector legal professional, or a concerned citizen that values privacy, confidentiality and security, OpenBSD is a viable and solid option. Departmental policies and procedures must be checked first, and an approval from your department is necessary before you can engage in any type of encryption involving governmental records. If you are a private attorney or private investigator, check your state and local laws first; if none exist, you can create your own internal policy and benefit from encryption regardless.

I have given workshops and training regarding Cryptography Applied to Investigations to various professionals, including: Police Precinct Commanders, Homicide Detectives, Forensic Investigators, Bomb Squad Supervisors, Military Personnel, and Defense Attorneys.

For more information regarding Cryptography Applied to Investigations, Operating Systems that I recommend or to attend a workshop/seminar check: Cyber SWAT


back to Blog