Skip to content

Commit 8876f7b

Browse files
committed
softhsm2-util: support import certificate
The softhsm2-util already support importing keys, why not also import certificates? Useful for test scripts that require both keys and certificates. Add --import-type <type> parameter, depreciate the --aes parameter. Signed-off-by: Alon Bar-Lev <[email protected]>
1 parent 3593859 commit 8876f7b

5 files changed

+298
-29
lines changed

src/bin/util/softhsm2-util-botan.cpp

+48
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
#include <botan/bigint.h>
4848
#include <botan/der_enc.h>
4949
#include <botan/oids.h>
50+
#include <botan/x509cert.h>
51+
#include <botan/x509_dn.h>
5052

5153
// Init Botan
5254
void crypto_init()
@@ -833,4 +835,50 @@ void crypto_free_eddsa(eddsa_key_material_t* keyMat)
833835
if (keyMat->bigA) free(keyMat->bigA);
834836
free(keyMat);
835837
}
838+
839+
// Import a key pair from given path
840+
int crypto_import_certificate
841+
(
842+
CK_SESSION_HANDLE hSession,
843+
char* filePath,
844+
char* label,
845+
char* objID,
846+
size_t objIDLen
847+
)
848+
{
849+
Botan::X509_Certificate cert(filePath);
850+
std::vector<uint8_t> blob = cert.BER_encode();
851+
std::vector<uint8_t> name = cert.subject_dn().BER_encode();
852+
std::vector<uint8_t> issuer = cert.issuer_dn().BER_encode();
853+
std::vector<uint8_t> serial = cert.serial_number();
854+
855+
CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
856+
CK_CERTIFICATE_TYPE certType = CKC_X_509;
857+
CK_BBOOL ckTrue = CK_TRUE, ckFalse = CK_FALSE, ckToken = CK_TRUE;
858+
CK_ATTRIBUTE certTemplate[] = {
859+
{ CKA_CLASS, &certClass, sizeof(certClass) },
860+
{ CKA_CERTIFICATE_TYPE, &certType, sizeof(certType) },
861+
{ CKA_LABEL, label, strlen(label) },
862+
{ CKA_ID, objID, objIDLen },
863+
{ CKA_TOKEN, &ckToken, sizeof(ckToken) },
864+
{ CKA_PRIVATE, &ckFalse, sizeof(ckTrue) },
865+
{ CKA_VALUE, &*blob.begin(), (CK_ULONG)blob.size() },
866+
{ CKA_SUBJECT, &*name.begin(), (CK_ULONG)name.size() },
867+
{ CKA_ISSUER, &*issuer.begin(), (CK_ULONG)issuer.size() },
868+
{ CKA_SERIAL_NUMBER, &*serial.begin(), (CK_ULONG)serial.size() }
869+
};
870+
871+
CK_OBJECT_HANDLE hCert;
872+
CK_RV rv = p11->C_CreateObject(hSession, certTemplate, 10, &hCert);
873+
if (rv != CKR_OK)
874+
{
875+
fprintf(stderr, "ERROR: Could not save the certificate in the token.\n");
876+
return 1;
877+
}
878+
879+
printf("The certificate has been imported.\n");
880+
881+
return 0;
882+
}
883+
836884
#endif

src/bin/util/softhsm2-util-ossl.cpp

+81
Original file line numberDiff line numberDiff line change
@@ -990,4 +990,85 @@ void crypto_free_eddsa(eddsa_key_material_t* keyMat)
990990
free(keyMat);
991991
}
992992

993+
// Import a key pair from given path
994+
int crypto_import_certificate
995+
(
996+
CK_SESSION_HANDLE hSession,
997+
char* filePath,
998+
char* label,
999+
char* objID,
1000+
size_t objIDLen
1001+
)
1002+
{
1003+
BIO* in = NULL;
1004+
1005+
if (!(in = BIO_new_file(filePath, "rb")))
1006+
{
1007+
fprintf(stderr, "ERROR: Could open the PKCS#8 file: %s\n", filePath);
1008+
return 1;
1009+
}
1010+
1011+
X509* x509 = PEM_read_bio_X509(in, NULL, NULL, NULL);
1012+
BIO_free(in);
1013+
1014+
if (!x509)
1015+
{
1016+
fprintf(stderr, "ERROR: Could not read the certificate file.\n");
1017+
return 1;
1018+
}
1019+
1020+
int blobSize = i2d_X509(x509, NULL);
1021+
CK_BYTE_PTR blob = (CK_BYTE_PTR)malloc(blobSize);
1022+
CK_BYTE_PTR p;
1023+
p = blob;
1024+
blobSize = i2d_X509(x509, &p);
1025+
1026+
int nameSize = i2d_X509_NAME(X509_get_subject_name(x509), NULL);
1027+
CK_BYTE_PTR name = (CK_BYTE_PTR)malloc(nameSize);
1028+
p = name;
1029+
nameSize = i2d_X509_NAME(X509_get_subject_name(x509), &p);
1030+
1031+
int issuerSize = i2d_X509_NAME(X509_get_issuer_name(x509), NULL);
1032+
CK_BYTE_PTR issuer = (CK_BYTE_PTR)malloc(issuerSize);
1033+
p = issuer;
1034+
issuerSize = i2d_X509_NAME(X509_get_issuer_name(x509), &p);
1035+
1036+
int serialSize = i2d_ASN1_INTEGER(X509_get_serialNumber(x509), NULL);
1037+
CK_BYTE_PTR serial = (CK_BYTE_PTR)malloc(serialSize);
1038+
p = serial;
1039+
serialSize = i2d_ASN1_INTEGER(X509_get_serialNumber(x509), &p);
1040+
1041+
CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
1042+
CK_CERTIFICATE_TYPE certType = CKC_X_509;
1043+
CK_BBOOL ckTrue = CK_TRUE, ckFalse = CK_FALSE, ckToken = CK_TRUE;
1044+
CK_ATTRIBUTE certTemplate[] = {
1045+
{ CKA_CLASS, &certClass, sizeof(certClass) },
1046+
{ CKA_CERTIFICATE_TYPE, &certType, sizeof(certType) },
1047+
{ CKA_LABEL, label, strlen(label) },
1048+
{ CKA_ID, objID, objIDLen },
1049+
{ CKA_TOKEN, &ckToken, sizeof(ckToken) },
1050+
{ CKA_PRIVATE, &ckFalse, sizeof(ckTrue) },
1051+
{ CKA_VALUE, blob, (CK_ULONG)blobSize },
1052+
{ CKA_SUBJECT, name, (CK_ULONG)nameSize },
1053+
{ CKA_ISSUER, issuer, (CK_ULONG)issuerSize },
1054+
{ CKA_SERIAL_NUMBER, serial, (CK_ULONG)serialSize }
1055+
};
1056+
1057+
CK_OBJECT_HANDLE hCert;
1058+
CK_RV rv = p11->C_CreateObject(hSession, certTemplate, 10, &hCert);
1059+
free(issuer);
1060+
free(name);
1061+
free(blob);
1062+
X509_free(x509);
1063+
if (rv != CKR_OK)
1064+
{
1065+
fprintf(stderr, "ERROR: Could not save the certificate in the token.\n");
1066+
return 1;
1067+
}
1068+
1069+
printf("The certificate has been imported.\n");
1070+
1071+
return 0;
1072+
}
1073+
9931074
#endif

src/bin/util/softhsm2-util.1

+21-17
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,23 @@ softhsm2-util \- support tool for libsofthsm2
1717
.PP
1818
.B softhsm2-util \-\-import
1919
.I path
20+
.RB [ \-\-import-type
21+
.IR type ]
22+
\\
23+
.ti +0.7i
2024
.RB [ \-\-file-pin
2125
.IR PIN ]
2226
.B \-\-token
2327
.I label
28+
.RB [ \-\-pin
29+
.I PIN]
30+
.B [\-\-no\-public\-key]
2431
\\
2532
.ti +0.7i
26-
.RB [ \-\-pin
27-
.I PIN
28-
.B \-\-no\-public\-key]
2933
.B \-\-label
3034
.I text
3135
.B \-\-id
3236
.I hex
33-
.PP
34-
.B softhsm2-util \-\-import
35-
.I path
36-
.B \-\-aes
37-
.B \-\-token
38-
.I label
39-
\\
40-
.ti +0.7i
4137
.RB [ \-\-pin
4238
.I PIN]
4339
.B \-\-label
@@ -122,11 +118,11 @@ Any content in token will be erased.
122118
Show the help information.
123119
.TP
124120
.B \-\-import \fIpath\fR
125-
Import a key pair from the given
121+
Import an object from the given
126122
.IR path .
127-
The file must be in PKCS#8-format.
128123
.br
129124
Use with
125+
.BR \-\-import-type,
130126
.BR \-\-slot
131127
or
132128
.BR \-\-token
@@ -138,10 +134,6 @@ or
138134
.BR \-\-label ,
139135
and
140136
.BR \-\-id .
141-
.br
142-
Can also be used with
143-
.BR \-\-aes
144-
to use file as is and import it as AES.
145137
.TP
146138
.B \-\-init-token
147139
Initialize the token at a given slot, token label or token serial.
@@ -173,8 +165,20 @@ Display all the available slots and their current status.
173165
Show the version info.
174166
.SH OPTIONS
175167
.TP
168+
.B \-\-import-type \fItype\fR
169+
Import object type, \fItype\fR may be one of:
170+
.RS
171+
.IP keypair\ [default]
172+
The file must be in PKCS#8 PEM format.
173+
.IP aes
174+
The file must be in binary format.
175+
.IP cert
176+
The file must be in X509 PEM format.
177+
.RE
178+
.TP
176179
.B \-\-aes
177180
Used to tell import to use file as is and import it as AES.
181+
Deprecated, use \fI--import-type aes\fR instead.
178182
.TP
179183
.B \-\-file-pin \fIPIN\fR
180184
The

0 commit comments

Comments
 (0)