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 */