Blob Blame History Raw
From d98aed0cbb25deaa954289e7f870c10edde688dd Mon Sep 17 00:00:00 2001
From: Christina Fu <cfu@redhat.com>
Date: Mon, 18 May 2020 19:14:41 -0400
Subject: [PATCH 1/2] Bug 1794213 Add Directory-based-auth profile for
 SeverSide Keygen

This patch adds caServerKeygen_DirUserCert.cfg, which is a profile using
directory-based authentication for severSide Keygen enrollment.
One is required to set up UserDirEnrollment in CS.cfg.

It also contains some misc cleanup such as removal of unneeded imports
and debugs, as well as perfecting a couple error handling stemmed from
upstream review.

https://bugzilla.redhat.com/show_bug.cgi?id=1794213
(cherry picked from commit 9e2bb93bb435e658a15ab8572a61d6481bb4fed8)
---
 base/ca/shared/conf/CS.cfg                         |   4 +-
 .../profiles/ca/caServerKeygen_DirUserCert.cfg     | 104 +++++++++++++++++++++
 base/kra/src/com/netscape/kra/RecoveryService.java |   2 +-
 .../cms/profile/common/CAEnrollProfile.java        |   2 +
 .../profile/def/ServerKeygenUserKeyDefault.java    |  12 ++-
 .../cms/servlet/connector/ConnectorServlet.java    |   1 -
 .../netscape/cmscore/request/ARequestQueue.java    |   5 +-
 7 files changed, 119 insertions(+), 11 deletions(-)
 create mode 100644 base/ca/shared/profiles/ca/caServerKeygen_DirUserCert.cfg

diff --git a/base/ca/shared/conf/CS.cfg b/base/ca/shared/conf/CS.cfg
index 004efdc..2c50831 100644
--- a/base/ca/shared/conf/CS.cfg
+++ b/base/ca/shared/conf/CS.cfg
@@ -976,7 +976,7 @@ oidmap.pse.oid=2.16.840.1.113730.1.18
 oidmap.subject_info_access.class=netscape.security.extensions.SubjectInfoAccessExtension
 oidmap.subject_info_access.oid=1.3.6.1.5.5.7.1.11
 os.userid=nobody
-profile.list=caCMCserverCert,caCMCECserverCert,caCMCECsubsystemCert,caCMCsubsystemCert,caCMCauditSigningCert,caCMCcaCert,caCMCocspCert,caCMCkraTransportCert,caCMCkraStorageCert,caServerKeygen_UserCert,caUserCert,caECUserCert,caUserSMIMEcapCert,caDualCert,caDirBasedDualCert,AdminCert,ECAdminCert,caSignedLogCert,caTPSCert,caRARouterCert,caRouterCert,caServerCert,caECServerCert,caSubsystemCert,caECSubsystemCert,caOtherCert,caCACert,caCMCcaCert,caCrossSignedCACert,caInstallCACert,caRACert,caOCSPCert,caStorageCert,caTransportCert,caDirPinUserCert,caECDirPinUserCert,caDirUserCert,caECDirUserCert,caAgentServerCert,caECAgentServerCert,caAgentFileSigning,caCMCUserCert,caCMCECUserCert,caFullCMCUserCert,caECFullCMCUserCert,caFullCMCUserSignedCert,caECFullCMCUserSignedCert,caFullCMCSharedTokenCert,caECFullCMCSharedTokenCert,caSimpleCMCUserCert,caECSimpleCMCUserCert,caTokenDeviceKeyEnrollment,caTokenUserEncryptionKeyEnrollment,caTokenUserSigningKeyEnrollment,caTempTokenDeviceKeyEnrollment,caTempTokenUserEncryptionKeyEnrollment,caTempTokenUserSigningKeyEnrollment,caAdminCert,caECAdminCert,caInternalAuthServerCert,caECInternalAuthServerCert,caInternalAuthTransportCert,caInternalAuthDRMstorageCert,caInternalAuthSubsystemCert,caECInternalAuthSubsystemCert,caInternalAuthOCSPCert,caInternalAuthAuditSigningCert,DomainController,caDualRAuserCert,caRAagentCert,caRAserverCert,caUUIDdeviceCert,caSSLClientSelfRenewal,caDirUserRenewal,caManualRenewal,caTokenMSLoginEnrollment,caTokenUserSigningKeyRenewal,caTokenUserEncryptionKeyRenewal,caTokenUserAuthKeyRenewal,caJarSigningCert,caIPAserviceCert,caEncUserCert,caSigningUserCert,caTokenUserDelegateAuthKeyEnrollment,caTokenUserDelegateSigningKeyEnrollment
+profile.list=caCMCserverCert,caCMCECserverCert,caCMCECsubsystemCert,caCMCsubsystemCert,caCMCauditSigningCert,caCMCcaCert,caCMCocspCert,caCMCkraTransportCert,caCMCkraStorageCert,caServerKeygen_UserCert,caServerKeygen_DirUserCert,caUserCert,caECUserCert,caUserSMIMEcapCert,caDualCert,caDirBasedDualCert,AdminCert,ECAdminCert,caSignedLogCert,caTPSCert,caRARouterCert,caRouterCert,caServerCert,caECServerCert,caSubsystemCert,caECSubsystemCert,caOtherCert,caCACert,caCMCcaCert,caCrossSignedCACert,caInstallCACert,caRACert,caOCSPCert,caStorageCert,caTransportCert,caDirPinUserCert,caECDirPinUserCert,caDirUserCert,caECDirUserCert,caAgentServerCert,caECAgentServerCert,caAgentFileSigning,caCMCUserCert,caCMCECUserCert,caFullCMCUserCert,caECFullCMCUserCert,caFullCMCUserSignedCert,caECFullCMCUserSignedCert,caFullCMCSharedTokenCert,caECFullCMCSharedTokenCert,caSimpleCMCUserCert,caECSimpleCMCUserCert,caTokenDeviceKeyEnrollment,caTokenUserEncryptionKeyEnrollment,caTokenUserSigningKeyEnrollment,caTempTokenDeviceKeyEnrollment,caTempTokenUserEncryptionKeyEnrollment,caTempTokenUserSigningKeyEnrollment,caAdminCert,caECAdminCert,caInternalAuthServerCert,caECInternalAuthServerCert,caInternalAuthTransportCert,caInternalAuthDRMstorageCert,caInternalAuthSubsystemCert,caECInternalAuthSubsystemCert,caInternalAuthOCSPCert,caInternalAuthAuditSigningCert,DomainController,caDualRAuserCert,caRAagentCert,caRAserverCert,caUUIDdeviceCert,caSSLClientSelfRenewal,caDirUserRenewal,caManualRenewal,caTokenMSLoginEnrollment,caTokenUserSigningKeyRenewal,caTokenUserEncryptionKeyRenewal,caTokenUserAuthKeyRenewal,caJarSigningCert,caIPAserviceCert,caEncUserCert,caSigningUserCert,caTokenUserDelegateAuthKeyEnrollment,caTokenUserDelegateSigningKeyEnrollment
 profile.caUUIDdeviceCert.class_id=caEnrollImpl
 profile.caUUIDdeviceCert.config=[PKI_INSTANCE_PATH]/[PKI_SUBSYSTEM_TYPE]/profiles/ca/caUUIDdeviceCert.cfg
 profile.caManualRenewal.class_id=caEnrollImpl
@@ -1133,6 +1133,8 @@ profile.caTransportCert.class_id=caEnrollImpl
 profile.caTransportCert.config=[PKI_INSTANCE_PATH]/[PKI_SUBSYSTEM_TYPE]/profiles/ca/caTransportCert.cfg
 profile.caServerKeygen_UserCert.class_id=caEnrollImpl
 profile.caServerKeygen_UserCert.config=[PKI_INSTANCE_PATH]/[PKI_SUBSYSTEM_TYPE]/profiles/ca/caServerKeygen_UserCert.cfg
+profile.caServerKeygen_DirUserCert.class_id=caEnrollImpl
+profile.caServerKeygen_DirUserCert.config=[PKI_INSTANCE_PATH]/[PKI_SUBSYSTEM_TYPE]/profiles/ca/caServerKeygen_DirUserCert.cfg
 profile.caUserCert.class_id=caEnrollImpl
 profile.caUserCert.config=[PKI_INSTANCE_PATH]/[PKI_SUBSYSTEM_TYPE]/profiles/ca/caUserCert.cfg
 profile.caECUserCert.class_id=caEnrollImpl
diff --git a/base/ca/shared/profiles/ca/caServerKeygen_DirUserCert.cfg b/base/ca/shared/profiles/ca/caServerKeygen_DirUserCert.cfg
new file mode 100644
index 0000000..ea1acfb
--- /dev/null
+++ b/base/ca/shared/profiles/ca/caServerKeygen_DirUserCert.cfg
@@ -0,0 +1,104 @@
+desc=This certificate profile is for enrolling user certificates using server-side Key generation with Directory-based authentication.
+visible=true
+enable=true
+enableBy=admin
+name=Directory-authenticated User Dual-Use Certificate Enrollment using server-side Key generation
+auth.instance_id=UserDirEnrollment
+input.list=i1,i2,i3
+input.i1.class_id=serverKeygenInputImpl
+input.i2.class_id=subjectNameInputImpl
+input.i3.class_id=submitterInfoInputImpl
+output.list=o1
+output.o1.class_id=pkcs12OutputImpl
+policyset.list=userCertSet
+policyset.userCertSet.list=1,10,2,3,4,5,6,7,8,9
+policyset.userCertSet.1.constraint.class_id=subjectNameConstraintImpl
+policyset.userCertSet.1.constraint.name=Subject Name Constraint
+policyset.userCertSet.1.constraint.params.pattern=UID=.*
+policyset.userCertSet.1.constraint.params.accept=true
+policyset.userCertSet.1.default.class_id=userSubjectNameDefaultImpl
+policyset.userCertSet.1.default.name=Subject Name Default
+policyset.userCertSet.1.default.params.name=
+policyset.userCertSet.10.constraint.class_id=renewGracePeriodConstraintImpl
+policyset.userCertSet.10.constraint.name=Renewal Grace Period Constraint
+policyset.userCertSet.10.constraint.params.renewal.graceBefore=30
+policyset.userCertSet.10.constraint.params.renewal.graceAfter=30
+policyset.userCertSet.10.default.class_id=noDefaultImpl
+policyset.userCertSet.10.default.name=No Default
+policyset.userCertSet.2.constraint.class_id=validityConstraintImpl
+policyset.userCertSet.2.constraint.name=Validity Constraint
+policyset.userCertSet.2.constraint.params.range=365
+policyset.userCertSet.2.constraint.params.notBeforeCheck=false
+policyset.userCertSet.2.constraint.params.notAfterCheck=false
+policyset.userCertSet.2.default.class_id=validityDefaultImpl
+policyset.userCertSet.2.default.name=Validity Default
+policyset.userCertSet.2.default.params.range=180
+policyset.userCertSet.2.default.params.startTime=0
+policyset.userCertSet.3.constraint.class_id=keyConstraintImpl
+policyset.userCertSet.3.constraint.name=Key Constraint
+policyset.userCertSet.3.constraint.params.keyType=-
+policyset.userCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096,nistp256,nistp384,nistp521
+policyset.userCertSet.3.default.class_id=serverKeygenUserKeyDefaultImpl
+policyset.userCertSet.3.default.name=Server-Side Keygen Default
+policyset.userCertSet.3.default.params.keyType=RSA
+policyset.userCertSet.3.default.params.keySize=2048
+policyset.userCertSet.3.default.params.enableArchival=true
+policyset.userCertSet.4.constraint.class_id=noConstraintImpl
+policyset.userCertSet.4.constraint.name=No Constraint
+policyset.userCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
+policyset.userCertSet.4.default.name=Authority Key Identifier Default
+policyset.userCertSet.5.constraint.class_id=noConstraintImpl
+policyset.userCertSet.5.constraint.name=No Constraint
+policyset.userCertSet.5.default.class_id=authInfoAccessExtDefaultImpl
+policyset.userCertSet.5.default.name=AIA Extension Default
+policyset.userCertSet.5.default.params.authInfoAccessADEnable_0=true
+policyset.userCertSet.5.default.params.authInfoAccessADLocationType_0=URIName
+policyset.userCertSet.5.default.params.authInfoAccessADLocation_0=
+policyset.userCertSet.5.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
+policyset.userCertSet.5.default.params.authInfoAccessCritical=false
+policyset.userCertSet.5.default.params.authInfoAccessNumADs=1
+policyset.userCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
+policyset.userCertSet.6.constraint.name=Key Usage Extension Constraint
+policyset.userCertSet.6.constraint.params.keyUsageCritical=true
+policyset.userCertSet.6.constraint.params.keyUsageDigitalSignature=true
+policyset.userCertSet.6.constraint.params.keyUsageNonRepudiation=true
+policyset.userCertSet.6.constraint.params.keyUsageDataEncipherment=false
+policyset.userCertSet.6.constraint.params.keyUsageKeyEncipherment=true
+policyset.userCertSet.6.constraint.params.keyUsageKeyAgreement=false
+policyset.userCertSet.6.constraint.params.keyUsageKeyCertSign=false
+policyset.userCertSet.6.constraint.params.keyUsageCrlSign=false
+policyset.userCertSet.6.constraint.params.keyUsageEncipherOnly=false
+policyset.userCertSet.6.constraint.params.keyUsageDecipherOnly=false
+policyset.userCertSet.6.default.class_id=keyUsageExtDefaultImpl
+policyset.userCertSet.6.default.name=Key Usage Default
+policyset.userCertSet.6.default.params.keyUsageCritical=true
+policyset.userCertSet.6.default.params.keyUsageDigitalSignature=true
+policyset.userCertSet.6.default.params.keyUsageNonRepudiation=true
+policyset.userCertSet.6.default.params.keyUsageDataEncipherment=false
+policyset.userCertSet.6.default.params.keyUsageKeyEncipherment=true
+policyset.userCertSet.6.default.params.keyUsageKeyAgreement=false
+policyset.userCertSet.6.default.params.keyUsageKeyCertSign=false
+policyset.userCertSet.6.default.params.keyUsageCrlSign=false
+policyset.userCertSet.6.default.params.keyUsageEncipherOnly=false
+policyset.userCertSet.6.default.params.keyUsageDecipherOnly=false
+policyset.userCertSet.7.constraint.class_id=noConstraintImpl
+policyset.userCertSet.7.constraint.name=No Constraint
+policyset.userCertSet.7.default.class_id=extendedKeyUsageExtDefaultImpl
+policyset.userCertSet.7.default.name=Extended Key Usage Extension Default
+policyset.userCertSet.7.default.params.exKeyUsageCritical=false
+policyset.userCertSet.7.default.params.exKeyUsageOIDs=1.3.6.1.5.5.7.3.2,1.3.6.1.5.5.7.3.4
+policyset.userCertSet.8.constraint.class_id=noConstraintImpl
+policyset.userCertSet.8.constraint.name=No Constraint
+policyset.userCertSet.8.default.class_id=subjectAltNameExtDefaultImpl
+policyset.userCertSet.8.default.name=Subject Alt Name Constraint
+policyset.userCertSet.8.default.params.subjAltNameExtCritical=false
+policyset.userCertSet.8.default.params.subjAltExtType_0=RFC822Name
+policyset.userCertSet.8.default.params.subjAltExtPattern_0=$request.requestor_email$
+policyset.userCertSet.8.default.params.subjAltExtGNEnable_0=true
+policyset.userCertSet.8.default.params.subjAltNameNumGNs=1
+policyset.userCertSet.9.constraint.class_id=signingAlgConstraintImpl
+policyset.userCertSet.9.constraint.name=No Constraint
+policyset.userCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,SHA1withEC,SHA256withEC,SHA384withRSA,SHA384withEC,SHA512withEC,SHA256withRSA/PSS,SHA384withRSA/PSS,SHA512withRSA/PSS
+policyset.userCertSet.9.default.class_id=signingAlgDefaultImpl
+policyset.userCertSet.9.default.name=Signing Alg
+policyset.userCertSet.9.default.params.signingAlg=-
diff --git a/base/kra/src/com/netscape/kra/RecoveryService.java b/base/kra/src/com/netscape/kra/RecoveryService.java
index c5229ea..529cb57 100644
--- a/base/kra/src/com/netscape/kra/RecoveryService.java
+++ b/base/kra/src/com/netscape/kra/RecoveryService.java
@@ -637,7 +637,7 @@ public class RecoveryService implements IService {
                     pass,
                     /* NSS has a bug that causes any AES CBC encryption
                      * to use AES-256, but AlgorithmID contains chosen
-                     * alg.  To avoid mismatch, use AES_128_CBC. */
+                     * alg.  To avoid mismatch, use AES_256_CBC. */
                     EncryptionAlgorithm.AES_256_CBC,
                     0 /* iterations (use default) */,
                     priKey);
diff --git a/base/server/cms/src/com/netscape/cms/profile/common/CAEnrollProfile.java b/base/server/cms/src/com/netscape/cms/profile/common/CAEnrollProfile.java
index f8b547d..b0dd773 100644
--- a/base/server/cms/src/com/netscape/cms/profile/common/CAEnrollProfile.java
+++ b/base/server/cms/src/com/netscape/cms/profile/common/CAEnrollProfile.java
@@ -156,6 +156,8 @@ public class CAEnrollProfile extends EnrollProfile {
                 if (kraConnector == null) {
                     String message = "KRA connector not configured";
                     CMS.debug(method + message);
+
+                    throw new EProfileException(message);
                 } else {
                     CMS.debug(method + "request");
                     kraConnector.send(request);
diff --git a/base/server/cms/src/com/netscape/cms/profile/def/ServerKeygenUserKeyDefault.java b/base/server/cms/src/com/netscape/cms/profile/def/ServerKeygenUserKeyDefault.java
index b1eb58e..3c4e3d0 100644
--- a/base/server/cms/src/com/netscape/cms/profile/def/ServerKeygenUserKeyDefault.java
+++ b/base/server/cms/src/com/netscape/cms/profile/def/ServerKeygenUserKeyDefault.java
@@ -20,7 +20,6 @@ package com.netscape.cms.profile.def;
 import java.io.ByteArrayInputStream;
 import java.math.BigInteger;
 import java.security.interfaces.DSAParams;
-import java.util.Enumeration;
 import java.util.Locale;
 import java.util.Vector;
 import java.security.KeyPair;
@@ -271,6 +270,7 @@ public class ServerKeygenUserKeyDefault extends EnrollDefault {
         CertificateX509Key certKey = null;
         String method = "ServerKeygenUserKeyDefault: populate: ";
         CMS.debug(method + "begins");
+        String errmsg = "";
 
         // trigger serverSide keygen enrollment
         try {
@@ -439,8 +439,9 @@ public class ServerKeygenUserKeyDefault extends EnrollDefault {
                     pubKeyStr = TEMP_PUBKEY_RSA_4096;
                     break;
                 default:
-                    CMS.debug("ServerKeygenUserKeyDefault: populate: unsupported keySize: " + keySize);
-                    break;
+                    errmsg = "unsupported keySize: " + keySize;
+                    CMS.debug("ServerKeygenUserKeyDefault: populate: " + errmsg);
+                    throw new EProfileException(errmsg);
               }
             } else {
               switch (curveName) {
@@ -454,8 +455,9 @@ public class ServerKeygenUserKeyDefault extends EnrollDefault {
                     pubKeyStr = TEMP_PUBKEY_EC_NISTP521;
                     break;
                 default:
-                    CMS.debug("ServerKeygenUserKeyDefault: populate: unsupported cureveName: " + curveName);
-                    break;
+                    errmsg = "unsupported curveName: " + curveName;
+                    CMS.debug("ServerKeygenUserKeyDefault: populate: " + errmsg);
+                    throw new EProfileException(errmsg);
               }
             }
             byte[] certKeyData = CryptoUtil.base64Decode(pubKeyStr);
diff --git a/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java b/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java
index fb9ed65..0e72559 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/connector/ConnectorServlet.java
@@ -28,7 +28,6 @@ import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
 import java.util.Enumeration;
-import java.util.Hashtable;
 
 import javax.servlet.ServletConfig;
 import javax.servlet.ServletException;
diff --git a/base/server/cmscore/src/com/netscape/cmscore/request/ARequestQueue.java b/base/server/cmscore/src/com/netscape/cmscore/request/ARequestQueue.java
index 24c2f77..3941fa0 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/request/ARequestQueue.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/request/ARequestQueue.java
@@ -568,12 +568,11 @@ public abstract class ARequestQueue
 
         // by default, write request to LDAP
         if (delayLDAPCommit == null || !delayLDAPCommit.equals("true")) {
-            CMS.debug("ARequestQueue: updateRequest(): delayLDAPCommit is false");
+            // CMS.debug("ARequestQueue: updateRequest(): delayLDAPCommit is false");
             // TODO: use a state flag to determine whether to call
             // addRequest or modifyRequest (see newRequest as well)
             modifyRequest(r);
-        }  else //: delay the write to ldap
-            CMS.debug("ARequestQueue: updateRequest(): delayLDAPCommit is true");
+        }
     }
 
     // PRIVATE functions
-- 
1.8.3.1


From b12e75b4314c9d017763130683b99008d7fc22ca Mon Sep 17 00:00:00 2001
From: jmagne <jmagne@redhat.com>
Date: Mon, 18 May 2020 20:35:31 -0400
Subject: [PATCH 2/2] Additional fix Bug# 1710109 - add RSA PSS support. (#414)

Remove minor log message which was causing problems.
Fix a typo in the pkispawn code that detects PSS signing algorithms.

Co-authored-by: Jack Magne <jmagne@test.host.com>
(cherry picked from commit f30d2a26d6484cd85415b338fd721efc6499a937)
---
 base/server/python/pki/server/deployment/pkihelper.py  | 2 +-
 base/util/src/netscape/security/x509/X509CertInfo.java | 6 ------
 2 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/base/server/python/pki/server/deployment/pkihelper.py b/base/server/python/pki/server/deployment/pkihelper.py
index 8c7ef51..214c9ae 100644
--- a/base/server/python/pki/server/deployment/pkihelper.py
+++ b/base/server/python/pki/server/deployment/pkihelper.py
@@ -4596,7 +4596,7 @@ class ConfigClient:
         if ('pki_subsystem_signing_algorithm' in self.mdict):
             if ('RSA' in self.mdict['pki_subsystem_signing_algorithm'] and
                 'PSS' not in self.mdict['pki_subsystem_signing_algorithm']):
-                self.mdict[''] = \
+                self.mdict['pki_subsystem_signing_algorithm'] = \
                     self.mdict['pki_subsystem_signing_algorithm'] + '/PSS'
                     
 
diff --git a/base/util/src/netscape/security/x509/X509CertInfo.java b/base/util/src/netscape/security/x509/X509CertInfo.java
index 93377f4..083ec41 100644
--- a/base/util/src/netscape/security/x509/X509CertInfo.java
+++ b/base/util/src/netscape/security/x509/X509CertInfo.java
@@ -34,9 +34,6 @@ import netscape.security.util.DerInputStream;
 import netscape.security.util.DerOutputStream;
 import netscape.security.util.DerValue;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 /**
  * The X509CertInfo class represents X.509 certificate information.
  *
@@ -75,8 +72,6 @@ public class X509CertInfo implements CertAttrSet, Serializable {
      * get, set, delete methods of Certificate, x509 type.
      */
 
-     private static Logger logger = LoggerFactory.getLogger(X509CertInfo.class);
-
     public static final String IDENT = "x509.info";
     // Certificate attribute names
     public static final String NAME = "info";
@@ -621,7 +616,6 @@ public class X509CertInfo implements CertAttrSet, Serializable {
                 return (serialNum.get(attrName.getSuffix()));
             }
         case (ATTR_ALGORITHM):
-            logger.warn("X509CertInfo.get(alg): " + this.toString());
             if (attrName.getSuffix() == null) {
                 return (algId);
             } else {
-- 
1.8.3.1