summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--prsa.c150
-rw-r--r--util.c3
2 files changed, 110 insertions, 43 deletions
diff --git a/prsa.c b/prsa.c
index 5b2f379..8d4fb92 100644
--- a/prsa.c
+++ b/prsa.c
@@ -63,6 +63,35 @@ const SEC_ASN1Template pem_RSAPrivateKeyTemplate[] = {
{0}
};
+static const SEC_ASN1Template pem_AttributeTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(NSSLOWKEYAttribute) },
+ { SEC_ASN1_OBJECT_ID, offsetof(NSSLOWKEYAttribute, attrType) },
+ { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(NSSLOWKEYAttribute, attrValue),
+ SEC_ASN1_SUB(SEC_AnyTemplate) },
+ { 0 }
+};
+
+static const SEC_ASN1Template pem_SetOfAttributeTemplate[] = {
+ { SEC_ASN1_SET_OF, 0, pem_AttributeTemplate },
+};
+
+const SEC_ASN1Template pem_PrivateKeyInfoTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(NSSLOWKEYPrivateKeyInfo) },
+ { SEC_ASN1_INTEGER,
+ offsetof(NSSLOWKEYPrivateKeyInfo,version) },
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
+ offsetof(NSSLOWKEYPrivateKeyInfo,algorithm),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(NSSLOWKEYPrivateKeyInfo,privateKey) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
+ offsetof(NSSLOWKEYPrivateKeyInfo, attributes),
+ pem_SetOfAttributeTemplate },
+ { 0 }
+};
+
/* Declarations */
SECStatus pem_RSA_Sign(pemLOWKEYPrivateKey * key, unsigned char *output,
unsigned int *outputLen, unsigned int maxOutputLen,
@@ -116,6 +145,79 @@ pem_DestroyPrivateKey(pemLOWKEYPrivateKey * privk)
nss_ZFreeIf(privk);
}
+/* decode and parse the rawkey into the lpk structure */
+static pemLOWKEYPrivateKey *
+pem_getPrivateKey(PLArenaPool *arena, SECItem *rawkey, CK_RV * pError, NSSItem *modulus)
+{
+ pemLOWKEYPrivateKey *lpk = NULL;
+ SECStatus rv = SECFailure;
+ NSSLOWKEYPrivateKeyInfo *pki = NULL;
+ SECItem *keysrc = NULL;
+
+ /* make sure SECOID is initialized - not sure why we have to do this outside of nss_Init */
+ if (SECSuccess != (rv = SECOID_Init())) {
+ *pError = CKR_GENERAL_ERROR;
+ return NULL; /* wha???? */
+ }
+
+ pki = (NSSLOWKEYPrivateKeyInfo*)PORT_ArenaZAlloc(arena,
+ sizeof(NSSLOWKEYPrivateKeyInfo));
+ if(!pki) {
+ *pError = CKR_HOST_MEMORY;
+ goto done;
+ }
+
+ /* let's first see if this is a "raw" RSA private key or an RSA private key in PKCS#8 format */
+ rv = SEC_ASN1DecodeItem(arena, pki, pem_PrivateKeyInfoTemplate, rawkey);
+ if (rv != SECSuccess) {
+ /* not PKCS#8 - assume it's a "raw" RSA private key */
+ keysrc = rawkey;
+ } else if (SECOID_GetAlgorithmTag(&pki->algorithm) == SEC_OID_PKCS1_RSA_ENCRYPTION) {
+ keysrc = &pki->privateKey;
+ } else { /* unsupported */
+ *pError = CKR_FUNCTION_NOT_SUPPORTED;
+ goto done;
+ }
+
+ lpk = (pemLOWKEYPrivateKey *) nss_ZAlloc(NULL,
+ sizeof(pemLOWKEYPrivateKey));
+ if (lpk == NULL) {
+ *pError = CKR_HOST_MEMORY;
+ goto done;
+ }
+
+ lpk->arena = arena;
+ lpk->keyType = pemLOWKEYRSAKey;
+ prepare_low_rsa_priv_key_for_asn1(lpk);
+
+ /* I don't know what this is supposed to accomplish. We free the old
+ modulus data and set it again, making a copy of the new data.
+ But we just allocated a new empty key structure above with
+ nss_ZAlloc. So lpk->u.rsa.modulus.data is NULL and
+ lpk->u.rsa.modulus.len. If the intention is to free the old
+ modulus data, why not just set it to NULL after freeing? Why
+ go through this unnecessary and confusing copying code?
+ */
+ if (modulus) {
+ nss_ZFreeIf(modulus->data);
+ modulus->data = (void *) nss_ZAlloc(NULL, lpk->u.rsa.modulus.len);
+ modulus->size = lpk->u.rsa.modulus.len;
+ nsslibc_memcpy(modulus->data, lpk->u.rsa.modulus.data,
+ lpk->u.rsa.modulus.len);
+ }
+
+ /* decode the private key and any algorithm parameters */
+ rv = SEC_QuickDERDecodeItem(arena, lpk, pem_RSAPrivateKeyTemplate,
+ keysrc);
+
+ if (rv != SECSuccess) {
+ goto done;
+ }
+
+done:
+ return lpk;
+}
+
void
pem_PopulateModulusExponent(pemInternalObject * io)
{
@@ -123,7 +225,7 @@ pem_PopulateModulusExponent(pemInternalObject * io)
const NSSItem *keyType = pem_FetchAttribute(io, CKA_KEY_TYPE);
pemLOWKEYPrivateKey *lpk = NULL;
PLArenaPool *arena;
- SECStatus rv;
+ CK_RV pError = 0;
/* make sure we have the right objects */
if (((const NSSItem *) NULL == classItem) ||
@@ -140,26 +242,12 @@ pem_PopulateModulusExponent(pemInternalObject * io)
return;
}
- lpk = (pemLOWKEYPrivateKey *) nss_ZAlloc(NULL,
- sizeof(pemLOWKEYPrivateKey));
+ lpk = pem_getPrivateKey(arena, io->u.key.key.privateKey, &pError, NULL);
if (lpk == NULL) {
PORT_FreeArena(arena, PR_FALSE);
return;
}
- lpk->arena = arena;
- lpk->keyType = pemLOWKEYRSAKey;
- prepare_low_rsa_priv_key_for_asn1(lpk);
-
- /* decode the private key and any algorithm parameters */
- rv = SEC_QuickDERDecodeItem(arena, lpk, pem_RSAPrivateKeyTemplate,
- io->u.key.key.privateKey);
-
- if (rv != SECSuccess) {
- PORT_FreeArena(arena, PR_FALSE);
- return;
- }
-
nss_ZFreeIf(io->u.key.key.modulus.data);
io->u.key.key.modulus.data =
(void *) nss_ZAlloc(NULL, lpk->u.rsa.modulus.len);
@@ -252,13 +340,6 @@ pem_mdCryptoOperationRSAPriv_Create
pemInternalCryptoOperationRSAPriv *iOperation;
pemLOWKEYPrivateKey *lpk = NULL;
PLArenaPool *arena;
- SECStatus rv;
-
- arena = PORT_NewArena(2048);
- if (!arena) {
- *pError = CKR_HOST_MEMORY;
- return (NSSCKMDCryptoOperation *) NULL;
- }
/* make sure we have the right objects */
if (((const NSSItem *) NULL == classItem) ||
@@ -271,30 +352,15 @@ pem_mdCryptoOperationRSAPriv_Create
return (NSSCKMDCryptoOperation *) NULL;
}
- lpk = (pemLOWKEYPrivateKey *) nss_ZAlloc(NULL,
- sizeof (pemLOWKEYPrivateKey));
- if (lpk == NULL) {
+ arena = PORT_NewArena(2048);
+ if (!arena) {
*pError = CKR_HOST_MEMORY;
return (NSSCKMDCryptoOperation *) NULL;
}
- lpk->arena = arena;
- lpk->keyType = pemLOWKEYRSAKey;
- prepare_low_rsa_priv_key_for_asn1(lpk);
- nss_ZFreeIf(iKey->u.key.key.modulus.data);
- iKey->u.key.key.modulus.data =
- (void *) nss_ZAlloc(NULL, lpk->u.rsa.modulus.len);
- iKey->u.key.key.modulus.size = lpk->u.rsa.modulus.len;
- nsslibc_memcpy(iKey->u.key.key.modulus.data, lpk->u.rsa.modulus.data,
- lpk->u.rsa.modulus.len);
-
- /* decode the private key and any algorithm parameters */
- rv = SEC_QuickDERDecodeItem(arena, lpk, pem_RSAPrivateKeyTemplate,
- iKey->u.key.key.privateKey);
-
- if (rv != SECSuccess) {
+ lpk = pem_getPrivateKey(arena, iKey->u.key.key.privateKey, pError, &iKey->u.key.key.modulus);
+ if (lpk == NULL) {
PORT_FreeArena(arena, PR_FALSE);
- *pError = CKR_HOST_MEMORY;
return (NSSCKMDCryptoOperation *) NULL;
}
diff --git a/util.c b/util.c
index a6ca094..d02ee87 100644
--- a/util.c
+++ b/util.c
@@ -164,7 +164,8 @@ ReadDERFromFile(SECItem *** derlist, char *filename, PRBool ascii,
int key = 0;
while ((asc) && ((body = strstr(asc, "-----BEGIN")) != NULL)) {
key = 0;
- if (strncmp(body, "-----BEGIN RSA PRIVATE KEY", 25) == 0) {
+ if ((strncmp(body, "-----BEGIN RSA PRIVATE KEY", 25) == 0) ||
+ (strncmp(body, "-----BEGIN PRIVATE KEY", 21) == 0)) {
key = 1;
c = body;
body = strchr(body, '\n');