From c89a5151079b46cfd045ccf783a2ab3d70073f4c Mon Sep 17 00:00:00 2001
From: Joshua Roys <roysjosh@gmail.com>
Date: Fri, 16 Dec 2011 09:34:08 -0500
Subject: [PATCH] Add support for RFC4043 permanent identifiers

---
 .../netscape/cms/profile/def/EnrollDefault.java    |   18 ++++
 pki/base/util/src/CMakeLists.txt                   |    1 +
 .../security/extensions/PermanentIdentifier.java   |   91 ++++++++++++++++++++
 3 files changed, 110 insertions(+), 0 deletions(-)
 create mode 100644 pki/base/util/src/netscape/security/extensions/PermanentIdentifier.java

diff --git a/pki/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java b/pki/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java
index b5afc1c..37ce433 100644
--- a/pki/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java
+++ b/pki/base/common/src/com/netscape/cms/profile/def/EnrollDefault.java
@@ -25,6 +25,7 @@ import java.util.StringTokenizer;
 import java.util.Vector;
 
 import netscape.security.extensions.KerberosName;
+import netscape.security.extensions.PermanentIdentifier;
 import netscape.security.util.DerInputStream;
 import netscape.security.util.DerOutputStream;
 import netscape.security.util.DerValue;
@@ -531,6 +532,23 @@ public abstract class EnrollDefault implements IPolicyDefault, ICertInfoPolicyDe
               // krb5PrincipalName OBJECT IDENTIFIER ::= { krb5 2 }
               return new OtherName(KerberosName.KRB5_PRINCIPAL_NAME,
                        name.toByteArray());
+            } else if (nameValue.startsWith("(PermanentIdentifier)")) {
+              int pos0 = nameValue.indexOf(')');
+              int pos1 = nameValue.indexOf(',');
+              String pi_value, pi_assigner;
+              if (pos1 == -1) {
+                pi_assigner = null;
+                pi_value = nameValue.substring(pos0 + 1).trim();
+              } else {
+                pi_assigner = nameValue.substring(pos0 + 1, pos1).trim();
+                pi_value = nameValue.substring(pos1 + 1).trim();
+              }
+              if (pi_assigner != null && !isValidOID(pi_assigner)) {
+                return null;
+              }
+              ObjectIdentifier pi_assigner_oid = new ObjectIdentifier(pi_assigner);
+              PermanentIdentifier pi = new PermanentIdentifier(pi_value, pi_assigner_oid);
+              return new OtherName(PermanentIdentifier.PERMANENT_IDENTIFIER, pi.toByteArray());
             } else if (nameValue.startsWith("(IA5String)")) {
               int pos0 = nameValue.indexOf(')');
               int pos1 = nameValue.indexOf(',');
diff --git a/pki/base/util/src/CMakeLists.txt b/pki/base/util/src/CMakeLists.txt
index dffa341..dd8049e 100644
--- a/pki/base/util/src/CMakeLists.txt
+++ b/pki/base/util/src/CMakeLists.txt
@@ -210,6 +210,7 @@ set(pki-nsutil_java_SRCS
     netscape/security/extensions/CertificateScopeOfUseExtension.java
     netscape/security/extensions/AuthInfoAccessExtension.java
     netscape/security/extensions/ExtendedKeyUsageExtension.java
+    netscape/security/extensions/PermanentIdentifier.java
     netscape/security/acl/AclImpl.java
     netscape/security/acl/AllPermissionsImpl.java
     netscape/security/acl/PrincipalImpl.java
diff --git a/pki/base/util/src/netscape/security/extensions/PermanentIdentifier.java b/pki/base/util/src/netscape/security/extensions/PermanentIdentifier.java
new file mode 100644
index 0000000..f2f4617
--- /dev/null
+++ b/pki/base/util/src/netscape/security/extensions/PermanentIdentifier.java
@@ -0,0 +1,91 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2011 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package netscape.security.extensions;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import netscape.security.util.DerOutputStream;
+import netscape.security.util.DerValue;
+import netscape.security.util.ObjectIdentifier;
+
+/**
+ * This represents a PermanentIdentifier as defined in
+ * RFC 4043.
+ *
+ *      id-on-permanentIdentifier   OBJECT IDENTIFIER ::= { id-on 3 }
+ *      PermanentIdentifier ::= SEQUENCE {
+ *         identifierValue    UTF8String             OPTIONAL,
+ *                         -- if absent, use a serialNumber attribute,
+ *                         -- if there is such an attribute present
+ *                         -- in the subject DN
+ *         assigner           OBJECT IDENTIFIER      OPTIONAL
+ *                         -- if absent, the assigner is
+ *                         -- the certificate issuer
+ *      }
+ *
+ * @author Joshua Roys
+ * @version $Revision$, $Date$
+ */
+public class PermanentIdentifier {
+
+    public static final int OID[] = { 1, 3, 6, 1, 5, 5, 7, 8, 3 };
+    public static final ObjectIdentifier PERMANENT_IDENTIFIER = new
+        ObjectIdentifier(OID);
+
+    private String m_value = null;
+    private ObjectIdentifier m_assigner = null;
+
+    public PermanentIdentifier(String value, ObjectIdentifier assigner) {
+        m_value = value;
+        m_assigner = assigner;
+    }
+
+    /**
+     * Write the extension to the DerOutputStream.
+     *
+     * @param out the DerOutputStream to write the extension to.
+     * @exception IOException on encoding errors.
+     */
+    public void encode(OutputStream out) throws IOException {
+
+        DerOutputStream seq = new DerOutputStream();
+        DerOutputStream guts = new DerOutputStream();
+
+        if (m_value != null) {
+            guts.putUTF8String(m_value);
+        }
+        if (m_assigner != null) {
+            guts.putOID(m_assigner);
+        }
+
+        seq.write(DerValue.tag_Sequence, guts);
+        out.write(seq.toByteArray());
+    }
+
+    public byte[] toByteArray() throws IOException {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        encode(bos);
+        return bos.toByteArray();
+    }
+
+    public String toString() {
+        return "Permanent Identifier: " + m_value + " Assigner OID: " + m_assigner;
+    }
+}
-- 
1.7.4.1

