Commit 0e99f0e4 authored by Daiki Ueno's avatar Daiki Ueno

From 193777aedc558c56bb6501ba8e2134668ee5697b Mon Sep 17 00:00:00 2001

Bug 1162897, util: add minimal PKCS#11 URI parser, r=rrelyea
parent 02db64a6
......@@ -11,6 +11,7 @@
#include "cert.h"
#include "keyhi.h"
#include "pk11pub.h"
#include "pkcs11uri.h"
struct ScopedDelete {
void operator()(CERTCertificate* cert) { CERT_DestroyCertificate(cert); }
......@@ -32,6 +33,7 @@ struct ScopedDelete {
void operator()(SECKEYPrivateKeyList* list) {
SECKEY_DestroyPrivateKeyList(list);
}
void operator()(PK11URI* uri) { PK11URI_DestroyURI(uri); }
};
template <class T>
......@@ -59,6 +61,7 @@ SCOPED(SECItem);
SCOPED(SECKEYPublicKey);
SCOPED(SECKEYPrivateKey);
SCOPED(SECKEYPrivateKeyList);
SCOPED(PK11URI);
#undef SCOPED
......
......@@ -9,6 +9,7 @@ MODULE = nss
CPPSRCS = \
util_utf8_unittest.cc \
util_b64_unittest.cc \
util_pkcs11uri_unittest.cc \
$(NULL)
INCLUDES += \
......
......@@ -13,6 +13,7 @@
'sources': [
'util_utf8_unittest.cc',
'util_b64_unittest.cc',
'util_pkcs11uri_unittest.cc',
'<(DEPTH)/gtests/common/gtests.cc',
],
'dependencies': [
......
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <climits>
#include <memory>
#include "pkcs11uri.h"
#include "gtest/gtest.h"
#include "scoped_ptrs.h"
namespace nss_test {
class PK11URITest : public ::testing::Test {
public:
bool TestCreate(const PK11URIAttribute *pattrs, size_t num_pattrs,
const PK11URIAttribute *qattrs, size_t num_qattrs) {
ScopedPK11URI tmp(
PK11URI_CreateURI(pattrs, num_pattrs, qattrs, num_qattrs));
return tmp != nullptr;
}
void TestCreateRetrieve(const PK11URIAttribute *pattrs, size_t num_pattrs,
const PK11URIAttribute *qattrs, size_t num_qattrs) {
ScopedPK11URI tmp(
PK11URI_CreateURI(pattrs, num_pattrs, qattrs, num_qattrs));
ASSERT_TRUE(tmp);
size_t i;
for (i = 0; i < num_pattrs; i++) {
const char *value = PK11URI_GetPathAttribute(tmp.get(), pattrs[i].name);
ASSERT_TRUE(value);
ASSERT_EQ(std::string(value), std::string(pattrs[i].value));
}
for (i = 0; i < num_qattrs; i++) {
const char *value = PK11URI_GetQueryAttribute(tmp.get(), qattrs[i].name);
ASSERT_TRUE(value);
ASSERT_EQ(std::string(value), std::string(qattrs[i].value));
}
}
void TestCreateFormat(const PK11URIAttribute *pattrs, size_t num_pattrs,
const PK11URIAttribute *qattrs, size_t num_qattrs,
const std::string &formatted) {
ScopedPK11URI tmp(
PK11URI_CreateURI(pattrs, num_pattrs, qattrs, num_qattrs));
ASSERT_TRUE(tmp);
char *out = PK11URI_FormatURI(nullptr, tmp.get());
ASSERT_TRUE(out);
ASSERT_EQ(std::string(out), formatted);
PORT_Free(out);
}
bool TestParse(const std::string &str) {
ScopedPK11URI tmp(PK11URI_ParseURI(str.c_str()));
return tmp != nullptr;
}
void TestParseRetrieve(const std::string &str, const PK11URIAttribute *pattrs,
size_t num_pattrs, const PK11URIAttribute *qattrs,
size_t num_qattrs) {
ScopedPK11URI tmp(PK11URI_ParseURI(str.c_str()));
ASSERT_TRUE(tmp);
size_t i;
for (i = 0; i < num_pattrs; i++) {
const char *value = PK11URI_GetPathAttribute(tmp.get(), pattrs[i].name);
ASSERT_TRUE(value);
ASSERT_EQ(std::string(value), std::string(pattrs[i].value));
}
for (i = 0; i < num_qattrs; i++) {
const char *value = PK11URI_GetQueryAttribute(tmp.get(), qattrs[i].name);
ASSERT_TRUE(value);
ASSERT_EQ(std::string(value), std::string(qattrs[i].value));
}
}
void TestParseFormat(const std::string &str, const std::string &formatted) {
ScopedPK11URI tmp(PK11URI_ParseURI(str.c_str()));
ASSERT_TRUE(tmp);
char *out = PK11URI_FormatURI(nullptr, tmp.get());
ASSERT_TRUE(out);
ASSERT_EQ(std::string(out), formatted);
PORT_Free(out);
}
protected:
};
const PK11URIAttribute pattrs[] = {
{"token", "aaa"}, {"manufacturer", "bbb"}, {"vendor", "ccc"}};
const PK11URIAttribute qattrs[] = {{"pin-source", "|grep foo /etc/passwd"},
{"pin-value", "secret"},
{"vendor", "ddd"}};
const PK11URIAttribute pattrs_invalid[] = {{"token", "aaa"},
{"manufacturer", "bbb"},
{"vendor", "ccc"},
{"$%*&", "invalid"},
{"", "empty"}};
const PK11URIAttribute qattrs_invalid[] = {
{"pin-source", "|grep foo /etc/passwd"},
{"pin-value", "secret"},
{"vendor", "ddd"},
{"$%*&", "invalid"},
{"", "empty"}};
TEST_F(PK11URITest, CreateTest) {
EXPECT_TRUE(
TestCreate(pattrs, PR_ARRAY_SIZE(pattrs), qattrs, PR_ARRAY_SIZE(qattrs)));
EXPECT_FALSE(TestCreate(pattrs_invalid, PR_ARRAY_SIZE(pattrs_invalid), qattrs,
PR_ARRAY_SIZE(qattrs)));
EXPECT_FALSE(TestCreate(pattrs, PR_ARRAY_SIZE(pattrs), qattrs_invalid,
PR_ARRAY_SIZE(qattrs_invalid)));
EXPECT_FALSE(TestCreate(pattrs_invalid, PR_ARRAY_SIZE(pattrs_invalid),
qattrs_invalid, PR_ARRAY_SIZE(qattrs_invalid)));
}
TEST_F(PK11URITest, CreateRetrieveTest) {
TestCreateRetrieve(pattrs, PR_ARRAY_SIZE(pattrs), qattrs,
PR_ARRAY_SIZE(qattrs));
}
TEST_F(PK11URITest, CreateFormatTest) {
TestCreateFormat(pattrs, PR_ARRAY_SIZE(pattrs), qattrs, PR_ARRAY_SIZE(qattrs),
"pkcs11:token=aaa;manufacturer=bbb;vendor=ccc?pin-source=|"
"grep%20foo%20/etc/passwd&pin-value=secret&vendor=ddd");
}
TEST_F(PK11URITest, ParseTest) {
EXPECT_FALSE(TestParse("pkcs11:token=aaa;token=bbb"));
EXPECT_FALSE(TestParse("pkcs11:dup=aaa;dup=bbb"));
EXPECT_FALSE(TestParse("pkcs11:?pin-value=aaa&pin-value=bbb"));
EXPECT_FALSE(TestParse("pkcs11:=empty"));
EXPECT_FALSE(TestParse("pkcs11:token=%2;manufacturer=aaa"));
}
TEST_F(PK11URITest, ParseRetrieveTest) {
TestParseRetrieve(
"pkcs11:token=aaa;manufacturer=bbb;vendor=ccc?pin-source=|"
"grep%20foo%20/etc/passwd&pin-value=secret&vendor=ddd",
pattrs, PR_ARRAY_SIZE(pattrs), qattrs, PR_ARRAY_SIZE(qattrs));
}
TEST_F(PK11URITest, ParseFormatTest) {
TestParseFormat("pkcs11:", "pkcs11:");
TestParseFormat("pkcs11:token=aaa", "pkcs11:token=aaa");
TestParseFormat("pkcs11:token=aaa;manufacturer=bbb",
"pkcs11:token=aaa;manufacturer=bbb");
TestParseFormat("pkcs11:manufacturer=bbb;token=aaa",
"pkcs11:token=aaa;manufacturer=bbb");
TestParseFormat("pkcs11:manufacturer=bbb;token=aaa;vendor2=ddd;vendor1=ccc",
"pkcs11:token=aaa;manufacturer=bbb;vendor1=ccc;vendor2=ddd");
TestParseFormat("pkcs11:?pin-value=secret", "pkcs11:?pin-value=secret");
TestParseFormat("pkcs11:?dup=aaa&dup=bbb", "pkcs11:?dup=aaa&dup=bbb");
TestParseFormat(
"pkcs11:?pin-source=|grep%20foo%20/etc/passwd&pin-value=secret",
"pkcs11:?pin-source=|grep%20foo%20/etc/passwd&pin-value=secret");
TestParseFormat("pkcs11:token=aaa?pin-value=secret",
"pkcs11:token=aaa?pin-value=secret");
}
} // namespace nss_test
......@@ -30,6 +30,7 @@
'pkcs11p.h',
'pkcs11t.h',
'pkcs11u.h',
'pkcs11uri.h',
'pkcs1sig.h',
'portreg.h',
'secasn1.h',
......
......@@ -41,6 +41,7 @@ EXPORTS = \
utilrename.h \
utilpars.h \
utilparst.h \
pkcs11uri.h \
$(NULL)
PRIVATE_EXPORTS = \
......@@ -76,6 +77,7 @@ CSRCS = \
utf8.c \
utilmod.c \
utilpars.c \
pkcs11uri.c \
$(NULL)
MODULE = nss
......
......@@ -296,3 +296,14 @@ SEC_ASN1DecoderSetMaximumElementSize;
;+ local:
;+ *;
;+};
;+NSSUTIL_3.31 { # NSS Utilities 3.31 release
;+ global:
PK11URI_CreateURI;
PK11URI_ParseURI;
PK11URI_FormatURI;
PK11URI_DestroyURI;
PK11URI_GetPathAttribute;
PK11URI_GetQueryAttribute;
;+ local:
;+ *;
;+};
This diff is collapsed.
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef _PKCS11URI_H_
#define _PKCS11URI_H_ 1
#include "seccomon.h"
/* Path attributes defined in RFC7512. */
#define PK11URI_PATTR_TOKEN "token"
#define PK11URI_PATTR_MANUFACTURER "manufacturer"
#define PK11URI_PATTR_SERIAL "serial"
#define PK11URI_PATTR_MODEL "model"
#define PK11URI_PATTR_LIBRARY_MANUFACTURER "library-manufacturer"
#define PK11URI_PATTR_LIBRARY_DESCRIPTION "library-description"
#define PK11URI_PATTR_LIBRARY_VERSION "library-version"
#define PK11URI_PATTR_OBJECT "object"
#define PK11URI_PATTR_TYPE "type"
#define PK11URI_PATTR_ID "id"
#define PK11URI_PATTR_SLOT_MANUFACTURER "slot-manufacturer"
#define PK11URI_PATTR_SLOT_DESCRIPTION "slot-description"
#define PK11URI_PATTR_SLOT_ID "slot-id"
/* Query attributes defined in RFC7512. */
#define PK11URI_QATTR_PIN_SOURCE "pin-source"
#define PK11URI_QATTR_PIN_VALUE "pin-value"
#define PK11URI_QATTR_MODULE_NAME "module-name"
#define PK11URI_QATTR_MODULE_PATH "module-path"
SEC_BEGIN_PROTOS
/* A PK11URI object is an immutable structure that holds path and
* query attributes of a PKCS#11 URI. */
struct PK11URIStr;
typedef struct PK11URIStr PK11URI;
struct PK11URIAttributeStr {
const char *name;
const char *value;
};
typedef struct PK11URIAttributeStr PK11URIAttribute;
/* Create a new PK11URI object from a set of attributes. */
extern PK11URI *PK11URI_CreateURI(const PK11URIAttribute *pattrs,
size_t num_pattrs,
const PK11URIAttribute *qattrs,
size_t num_qattrs);
/* Parse PKCS#11 URI and return a new PK11URI object. */
extern PK11URI *PK11URI_ParseURI(const char *string);
/* Format a PK11URI object to a string. */
extern char *PK11URI_FormatURI(PLArenaPool *arena, PK11URI *uri);
/* Destroy a PK11URI object. */
extern void PK11URI_DestroyURI(PK11URI *uri);
/* Retrieve a path attribute with the given name. */
extern const char *PK11URI_GetPathAttribute(PK11URI *uri, const char *name);
/* Retrieve a query attribute with the given name. */
extern const char *PK11URI_GetQueryAttribute(PK11URI *uri, const char *name);
SEC_END_PROTOS
#endif /* _PKCS11URI_H_ */
......@@ -21,6 +21,7 @@
'nssrwlk.c',
'oidstring.c',
'pkcs1sig.c',
'pkcs11uri.c',
'portreg.c',
'quickder.c',
'secalgid.c',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment