From 72d149a8bda9ab560e9419a7f7046cf982081c33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Grubbstr=C3=B6m=20=28Grubba=29?= <grubba@grubba.org> Date: Sun, 23 Feb 2014 20:31:47 +0100 Subject: [PATCH] Standards.PKCS.CSR: Added CRI and sign_cri(). --- lib/modules/Standards.pmod/PKCS.pmod/CSR.pmod | 101 +++++++++++++++++- .../Standards.pmod/PKCS.pmod/Certificate.pmod | 20 +++- 2 files changed, 117 insertions(+), 4 deletions(-) diff --git a/lib/modules/Standards.pmod/PKCS.pmod/CSR.pmod b/lib/modules/Standards.pmod/PKCS.pmod/CSR.pmod index 6082aa3fc9..0d01690602 100644 --- a/lib/modules/Standards.pmod/PKCS.pmod/CSR.pmod +++ b/lib/modules/Standards.pmod/PKCS.pmod/CSR.pmod @@ -1,4 +1,4 @@ -//! Handling of Certificate Signing Requests (PKCS-10, RFC 2986) +//! Handling of Certificate Signing Requests (PKCS-10, RFC 2314, RFC 2986) #pike __REAL_VERSION__ // #pragma strict_types @@ -17,6 +17,105 @@ class CRIAttributes // FIXME: Mark as deprecated! constant CSR_Attributes = CRIAttributes; +//! CertificationRequestInfo +//! +//! This is the data that is signed by @[sign_cri()]. +class CRI +{ + inherit Sequence; + + //! + void `version=(int v) + { + der = UNDEFINED; + if (v != 1) { + error("Only version 1 is supported.\n"); + } + elements[0] = Integer(v-1); + } + int `version() + { + return elements[0]->value + 1; + } + + //! Certificate subject. + void `subject=(Sequence i) + { + der = UNDEFINED; + elements[1] = i; + } + Sequence `subject() + { + return elements[1]; + } + + //! Public key information. + void `keyinfo=(Sequence ki) + { + der = UNDEFINED; + elements[2] = ki; + } + Sequence `keyinfo() + { + return elements[2]; + } + + //! Subject attributes. + void `attributes=(Set|CRIAttributes attrs) + { + der = UNDEFINED; + if ((attrs->type_name != "SET") && + (attrs->type_name != "CONSTRUCTED")) { + error("Invalid attributes: %O.\n", attrs->type_name); + } + if ((attrs->get_cls() != 2) || attrs->get_tag() || attrs->raw) { + attrs = CRIAttributes(attrs->elements); + } + elements[3] = attrs; + } + CRIAttributes `attributes() + { + return elements[3]; + } + + protected void create(Sequence|void asn1) + { + if (asn1) { + if ((asn1->type_name != "SEQUENCE") || + (sizeof(asn1->elements) != 4) || + (asn1[0]->type_name != "INTEGER") || + asn1[0]->value) { + error("Invalid CRI."); + } + elements = asn1->elements; + attributes = elements[3]; + } else { + elements = ({ + Integer(0), // version (v1) + Null, // subject + Null, // subjectPKInfo + CRIAttributes(({})), // attributes + }); + } + } +} + +//! Sign a @[CRI] to generate a Certificate Signing Request. +//! +//! @param cri +//! CertificationRequestInfo to sign. +//! +//! @param sign +//! Signature to use. Must have a private key set that matches +//! the public key in the keyinfo in @[cri]. +//! +//! @param hash +//! Hash algorithm to use for the signature. +Sequence sign_cri(CRI cri, Crypto.Sign sign, Crypto.Hash hash) +{ + return Standards.PKCS.Signature.sign(cri, sign, hash); +} + //! Build a Certificate Signing Request. //! //! @param sign diff --git a/lib/modules/Standards.pmod/PKCS.pmod/Certificate.pmod b/lib/modules/Standards.pmod/PKCS.pmod/Certificate.pmod index d5fe16355d..4df7f0c5ca 100644 --- a/lib/modules/Standards.pmod/PKCS.pmod/Certificate.pmod +++ b/lib/modules/Standards.pmod/PKCS.pmod/Certificate.pmod @@ -315,24 +315,38 @@ class Attribute { inherit Sequence; - void create(mapping(string:object) types, string type, - array(object) v) + protected void create(mapping(string:object) types, string type, + array(object) v) { if (!types[type]) error( "Unknown attribute type '%s'\n", type); ::create( ({ types[type], Set(v) }) ); } + protected variant void create(array(Object) elements) + { + if (sizeof(elements) != 2) + error("Invalid attribute encoding.\n"); + ::create(elements); + } } class Attributes { inherit Set; - void create(mapping(string:object) types, mapping(string:array(object)) m) + protected void create(mapping(string:object) types, + mapping(string:array(object)) m) { ::create(map(indices(m), lambda(string field, mapping m, mapping t) { return Attribute(t, field, m[field]); }, m, types)); } + protected variant void create(array(Object) elements) + { + ::create(map(elements, + lambda(object e) { + return Attribute(e->elements); + })); + } } -- GitLab