diff --git a/lib/modules/Standards.pmod/PKCS.pmod/CSR.pmod b/lib/modules/Standards.pmod/PKCS.pmod/CSR.pmod new file mode 100644 index 0000000000000000000000000000000000000000..db91e6953b743ac6e70da2ec453561c7363ded3f --- /dev/null +++ b/lib/modules/Standards.pmod/PKCS.pmod/CSR.pmod @@ -0,0 +1,29 @@ +/* csr.pmod + * + * Handlig of Certifikate Signing Requests (PKCS-10) + */ + +import asn1.encode; + +class Attributes +{ + inherit certificate.attribute_set; + constant cls = 2; + constant tag = 0; +} + +object build_csr(object rsafoo, object name, + mapping(string:object) attributes) +{ + object info = asn1_sequence(asn1_integer(0), name, + rsa.build_rsa_public_key(rsafoo), + Attributes(identifiers.attribute_ids, + attributes)); + return asn1_sequence(info, + asn1_sequence( + identifiers.rsa_md5_id, asn1_null()), + asn1_bitstring(rsafoo->sign(info->der(), Crypto.md5) + ->digits(256))); +} + + diff --git a/lib/modules/Standards.pmod/PKCS.pmod/Certificate.pmod b/lib/modules/Standards.pmod/PKCS.pmod/Certificate.pmod new file mode 100644 index 0000000000000000000000000000000000000000..86244d63575b4730cdcd14ce04a2828efb7da9f2 --- /dev/null +++ b/lib/modules/Standards.pmod/PKCS.pmod/Certificate.pmod @@ -0,0 +1,170 @@ +/* certificate.pmod + * + * Handle pkcs-6 and pkcs-10 certificates and certificate requests. + * + */ + +/* ASN.1 structures: + +CertificationRequestInfo ::= SEQUENCE { + version Version, + subject Name, + subjectPublicKeyInfo SubjectPublicKeyInfo, + attributes [0] IMPLICIT Attributes } + +Version ::= INTEGER + +Attributes ::= SET OF Attribute + +-- From the last section of PKCS-9. Is this used??? +Attribute ::= SEQUENCE { + attribyteType ::= OBJECT IDENTIFIER, + attributeValue ::= SET OF ANY } + +CertificationRequest ::= SEQUENCE { + certificationRequestInfo CertificationRequestInfo, + signatureAlgorithm SignatureAlgorithmIdentifier, + signature Signature } + +SignatureAlgorithmIdentifier ::= AlgorithmIdentifier + +Signature ::= BIT STRING + +CertificationRequest ::= SEQUENCE { + certificationRequestInfo CertificationRequestInfo, + signatureAlgorithm SignatureAlgorithmIdentifier, + signature Signature } + +SignatureAlgorithmIdentifier ::= AlgorithmIdentifier + +Signature ::= BIT STRING + +ExtendedCertificateOrCertificate ::= CHOICE { + certificate Certificate, -- X.509 + extendedCertificate [0] IMPLICIT ExtendedCertificate + +ExtendedCertificateInfo ::= SEQUENCE { + version Version, + certificate Certificate, + attributes Attributes } + +Version ::= INTEGER + +ExtendedCertificate ::= SEQUENCE { + extendedCertificateInfo ExtendedCertificateInfo, + signatureAlgorithm SignatureAlgorithmIdentifier, + signature Signature } + +SignatureAlgorithmIdentifier ::= AlgorithmIdentifier + +Signature ::= BIT STRING + +CertificateInfo ::= SEQUENCE { + version [0] Version DEFAULT v1988, + serialNumber CertificateSerialNumber, + signature AlgorithmIdentifier, + issuer Name, + validity Validity, + subject Name, + subjectPublicKeyInfo SubjectPublicKeyInfo } + +Version ::= INTEGER { v1988(0) } + +CertificateSerialNumber ::= INTEGER + +Validity ::= SEQUENCE { + notBefore UTCTime, + notAfter UTCTime } + +SubjectPublicKeyInfo ::= SEQUENCE { + algorithm AlgorithmIdentifier, + subjectPublicKey BIT STRING } + +AlgorithmIdentifier ::= SEQUENCE { + algorithm OBJECT IDENTIFIER, + parameters ANY DEFINED BY ALGORITHM OPTIONAL } + +Certificate ::= SEQUENCE { + certificateInfo CertificateInfo, + signatureAlgorithm AlgorithmIdentifier, + signature BIT STRING } + +Name ::= CHOICE { + RDNSequence } + +RDNSequence ::= SEQUENCE OF RelativeDistinguishedName + +RelativeDistinguishedName ::= + SET OF AttributeValueAssertion + +AttributeValueAssertion ::= SEQUENCE { + AttributeType, + AttributeValue } + +AttributeType ::= OBJECT IDENTIFIER + +AttributeValue ::= ANY + +RSAPublicKey ::= SEQUENCE { + modulus INTEGER, -- n + publicExponent INTEGER -- e } + +RSAPrivateKey ::= SEQUENCE { + version Version, + modulus INTEGER, -- n + publicExponent INTEGER, -- e + privateExponent INTEGER, -- d + prime1 INTEGER, -- p + prime2 INTEGER, -- q + exponent1 INTEGER, -- d mod (p-1) + exponent2 INTEGER, -- d mod (q-1) + coefficient INTEGER -- (inverse of q) mod p } + +Version ::= INTEGER + +*/ + +import asn1.encode; +import identifiers; + +class AttributeValueAssertion +{ + import asn1.encode; + inherit asn1_sequence; + void create(mapping(string:object) types, + string type, + object value) + { + if (!types[type]) + throw( ({ sprintf("AttributeValueAssertion: " + "Unknown attribute type '%s'\n", + type), backtrace() }) ); + ::create(types[type], value); + } +} + +/* RelativeDistinguishedName */ +class attribute_set +{ + import asn1.encode; + inherit asn1_set; + + void create(mapping(string:object) types, mapping(string:object) pairs) + { + ::create(@ Array.map(indices(pairs), + lambda(string s, mapping m, mapping t) + { + return AttributeValueAssertion(t, s, m[s]); + }, + pairs, types)); + } +} + +object build_distinguished_name(mapping(string:object) ... args) +{ + return asn1_sequence(@Array.map(args, lambda(mapping rdn) + { + return attribute_set( + identifiers.name_ids, rdn); + } )); +} diff --git a/lib/modules/Standards.pmod/PKCS.pmod/Identifiers.pmod b/lib/modules/Standards.pmod/PKCS.pmod/Identifiers.pmod new file mode 100644 index 0000000000000000000000000000000000000000..4edee6b793a3dd4e7ee908afe5f54ff0697f0702 --- /dev/null +++ b/lib/modules/Standards.pmod/PKCS.pmod/Identifiers.pmod @@ -0,0 +1,98 @@ +/* identifiers.pmod + * + * Object identifiers */ + +/* Attributes (from http://leangen.uninett.no:29659/~hta/ietf/oid/2.5.4.html): + + 2.5.4.0 - id-at-objectClass + 2.5.4.1 - id-at-aliasedEntryName + 2.5.4.2 - id-at-knowldgeinformation + 2.5.4.3 - id-at-commonName + 2.5.4.4 - id-at-surname + 2.5.4.5 - id-at-serialNumber + 2.5.4.6 - id-at-countryName + 2.5.4.7 - id-at-localityName (1 more) + 2.5.4.8 - id-at-stateOrProvinceName (1 more) + 2.5.4.9 - id-at-streetAddress (1 more) + 2.5.4.10 - id-at-organizationName (1 more) + 2.5.4.11 - id-at-organizationalUnitName (1 more) + 2.5.4.12 - id-at-title + 2.5.4.13 - id-at-description + 2.5.4.14 - id-at-searchGuide + 2.5.4.15 - id-at-businessCategory + 2.5.4.16 - id-at-postalAddress (1 more) + 2.5.4.17 - id-at-postalCode (1 more) + 2.5.4.18 - id-at-postOfficeBox (1 more) + 2.5.4.19 - id-at-physicalDeliveryOfficeName (1 more) + 2.5.4.20 - id-at-telephoneNumber (1 more) + 2.5.4.21 - id-at-telexNumber (1 more) + 2.5.4.22 - id-at-teletexTerminalIdentifier (1 more) + 2.5.4.23 - id-at-facsimileTelephoneNumber (1 more) + 2.5.4.24 - id-at-x121Address + 2.5.4.25 - id-at-internationalISDNNumber (1 more) + 2.5.4.26 - id-at-registeredAddress + 2.5.4.27 - id-at-destinationIndicator + 2.5.4.28 - id-at-preferredDeliveryMethod + 2.5.4.29 - id-at-presentationAddress + 2.5.4.30 - id-at-supportedApplicationContext + 2.5.4.31 - id-at-member + 2.5.4.32 - id-at-owner + 2.5.4.33 - id-at-roleOccupant + 2.5.4.34 - id-at-seeAlso + 2.5.4.35 - id-at-userPassword + 2.5.4.36 - id-at-userCertificate + 2.5.4.37 - id-at-cACertificate + + 2.5.4.38 - id-at-authorityRevocationList + 2.5.4.39 - id-at-certificateRevocationList + 2.5.4.40 - id-at-crossCertificatePair + 2.5.4.41 - id-at-name + 2.5.4.42 - id-at-givenName + 2.5.4.43 - id-at-initials + 2.5.4.44 - id-at-generationQualifier + 2.5.4.45 - id-at-uniqueIdentifier + 2.5.4.46 - id-at-dnQualifier + 2.5.4.47 - id-at-enhancedSearchGuide + 2.5.4.48 - id-at-protocolInformation + 2.5.4.49 - id-at-distinguishedName + 2.5.4.50 - id-at-uniqueMember + 2.5.4.51 - id-at-houseIdentifier + 2.5.4.52 - id-at-supportedAlgorithms + 2.5.4.53 - id-at-deltaRevocationList +*/ + +import asn1.encode; + +object pkcs_id = asn1_identifier(1, 2, 840, 113549, 1); +object pkcs_1_id = pkcs_id->append(1); +object pkcs_9_id = pkcs_id->append(9); + +object rsa_id = pkcs_1_id->append(1); +object rsa_md5_id = pkcs_1_id->append(4); + +/* Object Identifiers used in X509 distinguished names */ + +object attributeType_id = asn1_identifier(2, 5, 4); + +mapping name_ids = +([ + /* layman.asc says "commonUnitName". Typo? */ + "commonName" : attributeType_id->append(3), /* printable string */ + "countryName" : attributeType_id->append(6), /* printable string */ + "localityName" : attributeType_id->append(7), /* printable string */ + "organizationName" : attributeType_id->append(10) /* printable string */ + ]); + +mapping attribute_ids = +([ + "emailAddress" : pkcs_9_id->append(1), /* IA5String */ + "unstructuredName" : pkcs_9_id->append(2), /* IA5String */ + "contentType" : pkcs_9_id->append(3), /* Identifier */ + "messageDigest" : pkcs_9_id->append(4), /* Octet string */ + "signingTime" : pkcs_9_id->append(5), /* UTCTime */ + "countersignature" : pkcs_9_id->append(6), /* SignerInfo */ + "challengePassword" : pkcs_9_id->append(7), /* Printable | T61 + | Universal */ + "unstructuredAddress" : pkcs_9_id->append(8), /* Printable | T61 */ + "extendedCertificateAttributes" : pkcs_9_id->append(0) /* Attributes */ + ]); diff --git a/lib/modules/Standards.pmod/PKCS.pmod/RSA.pmod b/lib/modules/Standards.pmod/PKCS.pmod/RSA.pmod new file mode 100644 index 0000000000000000000000000000000000000000..d2580144a1b4bed816d06440996a740fbbedbfd2 --- /dev/null +++ b/lib/modules/Standards.pmod/PKCS.pmod/RSA.pmod @@ -0,0 +1,55 @@ +/* rsa.pmod + * + * rsa operations and types as described in PKCS-1 */ + +#if 0 +#define WERROR werror +#else +#define WERROR(x) +#endif + +import asn1.encode; + +/* Create a DER-coded RSAPrivateKey structure */ +string rsa_private_key(object rsa) +{ + return asn1_sequence(@ Array.map( + ({ 0, rsa->n, rsa->e, rsa->d, rsa->p, rsa->q, + rsa->d % (rsa->p - 1), rsa->d, (rsa->q -1), + rsa->q->invert(rsa->p) % rsa->p + }), + asn1_integer))->der(); +} + +/* Decode a coded RSAPrivateKey structure */ +object parse_private_key(string key) +{ + WERROR(sprintf("rsa->parse_private_key: '%s'\n", key)); + array a = asn1.decode(key)->get_asn1(); + + WERROR(sprintf("rsa->parse_private_key: asn1 = %O\n", a)); + if (!a + || (a[0] != "SEQUENCE") + || (sizeof(a[1]) != 10) + || (sizeof(column(a[1], 0) - ({ "INTEGER" }))) + || a[1][0][1]) + return 0; + + object rsa = Crypto.rsa(); + rsa->set_public_key(a[1][1][1], a[1][2][1]); + rsa->set_private_key(a[1][3][1], column(a[1][4..], 1)); + return rsa; +} + +object build_rsa_public_key(object rsa) +{ + return asn1_sequence( + asn1_sequence( + identifiers.rsa_id, asn1_null()), + asn1_bitstring(asn1_sequence( + asn1_integer(rsa->n), asn1_integer(rsa->e))->der())); +} + + + + diff --git a/lib/modules/Crypto/pkcs.pmod b/lib/modules/Standards.pmod/PKCS.pmod/Signature.pmod similarity index 83% rename from lib/modules/Crypto/pkcs.pmod rename to lib/modules/Standards.pmod/PKCS.pmod/Signature.pmod index 46cda906e0aceceed941a3f292b8f57e8d36bc91..1e68f34e764473c26e89e9683c6354f0f8f586e0 100644 --- a/lib/modules/Crypto/pkcs.pmod +++ b/lib/modules/Standards.pmod/PKCS.pmod/Signature.pmod @@ -1,6 +1,5 @@ -/* pkcs.pmod +/* signature.pmod * - * Miscellaneous functions needed for pkcs operation. */ /* Construct a PKCS-1 digestinfo */