001/**
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003 *
004 * Copyright (c) 2008 Sun Microsystems Inc. All Rights Reserved
005 *
006 * The contents of this file are subject to the terms
007 * of the Common Development and Distribution License
008 * (the License). You may not use this file except in
009 * compliance with the License.
010 *
011 * You can obtain a copy of the License at
012 * https://opensso.dev.java.net/public/CDDLv1.0.html or
013 * opensso/legal/CDDLv1.0.txt
014 * See the License for the specific language governing
015 * permission and limitations under the License.
016 *
017 * When distributing Covered Code, include this CDDL
018 * Header Notice in each file and include the License file
019 * at opensso/legal/CDDLv1.0.txt.
020 * If applicable, add the following below the CDDL Header,
021 * with the fields enclosed by brackets [] replaced by
022 * your own identifying information:
023 * "Portions Copyrighted [year] [name of copyright owner]"
024 *
025 * $Id: NameIDMapping.java,v 1.6 2009/11/20 21:41:16 exu Exp $
026 *
027 */
028
029/*
030 * Portions Copyrighted 2013 ForgeRock, Inc.
031 */
032
033package com.sun.identity.saml2.profile;
034
035import java.security.PrivateKey;
036import java.security.cert.X509Certificate;
037import java.util.Date;
038import java.util.Iterator;
039import java.util.List;
040import java.util.Map;
041import javax.xml.soap.SOAPException;
042import javax.xml.soap.SOAPMessage;
043
044import org.w3c.dom.Element;
045
046import com.sun.identity.plugin.session.SessionException;
047import com.sun.identity.plugin.session.SessionManager;
048import com.sun.identity.plugin.session.SessionProvider;
049import com.sun.identity.saml.xmlsig.KeyProvider;
050import com.sun.identity.saml2.assertion.AssertionFactory;
051import com.sun.identity.saml2.assertion.EncryptedID;
052import com.sun.identity.saml2.assertion.Issuer;
053import com.sun.identity.saml2.assertion.NameID;
054import com.sun.identity.saml2.common.AccountUtils;
055import com.sun.identity.saml2.common.NameIDInfo;
056import com.sun.identity.saml2.common.SAML2Constants;
057import com.sun.identity.saml2.common.SAML2Exception;
058import com.sun.identity.saml2.common.SAML2SDKUtils;
059import com.sun.identity.saml2.common.SAML2Utils;
060import com.sun.identity.saml2.jaxb.entityconfig.BaseConfigType;
061import com.sun.identity.saml2.jaxb.metadata.IDPSSODescriptorElement;
062import com.sun.identity.saml2.jaxb.metadata.NameIDMappingServiceElement;
063import com.sun.identity.saml2.jaxb.metadata.RoleDescriptorType;
064import com.sun.identity.saml2.jaxb.metadata.SPSSODescriptorElement;
065import com.sun.identity.saml2.key.EncInfo;
066import com.sun.identity.saml2.key.KeyUtil;
067import com.sun.identity.saml2.meta.SAML2MetaException;
068import com.sun.identity.saml2.meta.SAML2MetaManager;
069import com.sun.identity.saml2.plugins.IDPAccountMapper;
070import com.sun.identity.saml2.protocol.NameIDMappingRequest;
071import com.sun.identity.saml2.protocol.NameIDMappingResponse;
072import com.sun.identity.saml2.protocol.NameIDPolicy;
073import com.sun.identity.saml2.protocol.ProtocolFactory;
074import com.sun.identity.saml2.protocol.Status;
075
076import com.sun.identity.shared.xml.XMLUtils;
077
078/**
079 * This class provides methods to send or process
080 * <code>NameIDMappingRequest</code>.
081 *
082 * @supported.api
083 */
084
085public class NameIDMapping {
086    static ProtocolFactory pf = ProtocolFactory.getInstance();
087    static AssertionFactory af = AssertionFactory.getInstance();
088    static SAML2MetaManager metaManager = null;
089    static KeyProvider keyProvider = KeyUtil.getKeyProviderInstance(); 
090
091    static SessionProvider sessionProvider = null;
092    
093    static {
094        try {
095            metaManager= new SAML2MetaManager();
096            sessionProvider = SessionManager.getProvider();
097        } catch (SAML2MetaException se) {
098            SAML2Utils.debug.error(SAML2Utils.bundle.getString(
099                "errorMetaManager"), se);
100        } catch (SessionException sessE) {
101            SAML2Utils.debug.error("Error retrieving session provider.", sessE);
102        }
103    }
104    
105    /**
106     * Parses the request parameters and builds the NameIDMappingRequest to
107     * sent to remote identity provider.
108     *
109     * @param session user session.
110     * @param realm the realm of hosted entity
111     * @param spEntityID entity ID of hosted service provider
112     * @param idpEntityID entity ID of remote idendity provider
113     * @param targetSPEntityID entity ID of target entity ID of service
114     *     provider
115     * @param targetNameIDFormat format of target Name ID
116     * @param paramsMap Map of all other parameters
117     *
118     * @return the <code>NameIDMappingResponse</code>
119     * @throws SAML2Exception if error initiating request to remote entity.
120     *
121     * @supported.api
122     */
123    public static NameIDMappingResponse initiateNameIDMappingRequest(
124        Object session, String realm, String spEntityID, String idpEntityID,
125        String targetSPEntityID, String targetNameIDFormat,
126        Map paramsMap) throws SAML2Exception {
127            
128        if (spEntityID == null) {
129            throw new SAML2Exception(
130                SAML2Utils.bundle.getString("nullSPEntityID"));
131        }
132                
133        if (idpEntityID == null)  {
134            throw new SAML2Exception(
135                SAML2Utils.bundle.getString("nullIDPEntityID"));
136        }
137
138        String userID = null;
139
140        try {
141            userID = sessionProvider.getPrincipalName(session);
142        } catch (SessionException e) {
143            if (SAML2Utils.debug.messageEnabled()) {
144                SAML2Utils.debug.message(
145                    "NameIDMapping.createNameIDMappingRequest: ", e);
146            }
147        }
148
149        if (userID == null) {
150            throw new SAML2Exception(
151                SAML2Utils.bundle.getString("invalidSSOToken"));
152        }
153        
154        if (SAML2Utils.debug.messageEnabled()) {
155            SAML2Utils.debug.message(
156                "NameIDMapping.initiateNameMappingRequest:" +
157                " IDP EntityID is : " + idpEntityID);
158            SAML2Utils.debug.message(
159                "NameIDMapping.initiateNameMappingRequest:" +
160                " SP HOST EntityID is : " + spEntityID); 
161            SAML2Utils.debug.message(
162                "NameIDMapping.initiateNameMappingRequest:" +
163                " target SP EntityID is : " + targetSPEntityID); 
164        }
165        
166        try {
167            // nameIDMappingService
168            String binding = 
169                SAML2Utils.getParameter(paramsMap, SAML2Constants.BINDING); 
170            if (binding == null) {
171                binding = SAML2Constants.SOAP;
172            } else if (!binding.equals(SAML2Constants.SOAP)) {
173                throw new SAML2Exception(
174                    SAML2Utils.bundle.getString("nimServiceBindingUnsupport"));
175            }
176
177            String nimURL = SAML2Utils.getParameter(paramsMap,
178                "nimURL");
179            if (nimURL == null) {
180                NameIDMappingServiceElement nameIDMappingService =
181                    getNameIDMappingService(realm, idpEntityID, binding);
182
183                if (nameIDMappingService != null) {
184                    nimURL = nameIDMappingService.getLocation();
185                }
186            }
187            if (SAML2Utils.debug.messageEnabled()) {
188                SAML2Utils.debug.message(
189                    "NameIDMapping.initiateNameMappingRequest:" +
190                    " nimURL" + nimURL);
191            }
192
193            if (nimURL == null) {
194                throw new SAML2Exception(
195                    SAML2Utils.bundle.getString("nimServiceNotFound"));
196            }
197
198            NameIDMappingRequest nimRequest = createNameIDMappingRequest(
199                userID, realm, spEntityID, idpEntityID, nimURL,
200                targetSPEntityID, targetNameIDFormat);
201
202            signNIMRequest(nimRequest, realm, spEntityID, false);
203
204            BaseConfigType config = metaManager.getIDPSSOConfig(realm,
205                idpEntityID);
206
207            nimURL = SAML2SDKUtils.fillInBasicAuthInfo(config, nimURL);
208
209            return doNIMBySOAP(nimRequest.toXMLString(true,true), nimURL, 
210                realm, spEntityID);
211
212        } catch (SAML2MetaException sme) {
213            throw new SAML2Exception(
214                SAML2Utils.bundle.getString("metaDataError"));            
215        }
216    }
217    
218    public static NameIDMappingResponse processNameIDMappingRequest(
219        NameIDMappingRequest nimRequest, String realm, String idpEntityID)
220        throws SAML2Exception {
221
222        NameIDMappingResponse nimResponse = null;
223        String spEntityID = nimRequest.getIssuer().getValue();
224        if (spEntityID == null)  {
225            throw new SAML2Exception(
226                SAML2Utils.bundle.getString("nullSPEntityID"));
227        }
228
229        String responseID = SAML2Utils.generateID();
230        if (responseID == null) {
231            SAML2Utils.debug.error(
232                SAML2Utils.bundle.getString("failedToGenResponseID"));
233        }
234        nimResponse = pf.createNameIDMappingResponse();
235        nimResponse.setID(responseID);
236        nimResponse.setInResponseTo(nimRequest.getID());
237        nimResponse.setVersion(SAML2Constants.VERSION_2_0);
238        nimResponse.setIssueInstant(new Date());
239        nimResponse.setIssuer(SAML2Utils.createIssuer(idpEntityID)); 
240
241        SAML2Utils.verifyRequestIssuer(realm, idpEntityID,
242            nimRequest.getIssuer(), nimRequest.getID());
243
244
245        NameIDPolicy nameIDPolicy = nimRequest.getNameIDPolicy();
246        String targetSPEntityID = nameIDPolicy.getSPNameQualifier();
247        String format = nameIDPolicy.getFormat();
248
249        Status status = null;
250
251        if ((format != null) && (format.length() != 0) &&
252            (!format.equals(SAML2Constants.PERSISTENT)) &&
253            (!format.equals(SAML2Constants.UNSPECIFIED))) {
254
255            nimResponse.setNameID(nimRequest.getNameID());
256            nimResponse.setEncryptedID(nimRequest.getEncryptedID());
257            status = SAML2Utils.generateStatus(
258            SAML2Constants.INVALID_NAME_ID_POLICY,
259                 SAML2Utils.bundle.getString("targetNameIDFormatUnsupported"));
260        } else if ((targetSPEntityID == null) ||
261            (targetSPEntityID.length() == 0) ||
262            targetSPEntityID.equals(spEntityID)) {
263
264            nimResponse.setNameID(nimRequest.getNameID());
265            nimResponse.setEncryptedID(nimRequest.getEncryptedID());
266            status = SAML2Utils.generateStatus(
267                SAML2Constants.INVALID_NAME_ID_POLICY,
268                SAML2Utils.bundle.getString("targetNameIDNoChange"));
269        } else {
270            // check if source SP has account fed
271            // if yes then get nameid of targetSP
272            IDPAccountMapper idpAcctMapper = SAML2Utils.getIDPAccountMapper(
273                realm, idpEntityID);
274
275            NameID nameID = getNameID(nimRequest, realm, idpEntityID);
276            String userID = idpAcctMapper.getIdentity(nameID, idpEntityID,
277                spEntityID, realm);
278            NameIDInfo targetNameIDInfo = null;
279            if (userID != null) {
280                targetNameIDInfo = AccountUtils.getAccountFederation(userID,
281                    idpEntityID, targetSPEntityID);
282            }
283            if (targetNameIDInfo == null) {
284                nimResponse.setNameID(nimRequest.getNameID());
285                nimResponse.setEncryptedID(nimRequest.getEncryptedID());
286                status = SAML2Utils.generateStatus(
287                    SAML2Constants.INVALID_NAME_ID_POLICY,
288                    SAML2Utils.bundle.getString("targetNameIDNotFound"));
289            } else {
290                NameID targetSPNameID = targetNameIDInfo.getNameID();
291                if (SAML2Utils.debug.messageEnabled()) {
292                    SAML2Utils.debug.message(
293                        "NameIDMapping.processNameIDMappingRequest: " +
294                        "User ID = " + userID + ", name ID = " +
295                        targetSPNameID.toXMLString(true,true));
296                }
297
298                nimResponse.setEncryptedID(getEncryptedID(targetSPNameID,
299                    realm, spEntityID, SAML2Constants.SP_ROLE));
300                status = SAML2Utils.generateStatus(
301                    SAML2Constants.SUCCESS, null);
302            }
303        }
304
305        nimResponse.setStatus(status);
306        signNIMResponse(nimResponse, realm, idpEntityID, false);
307
308        return nimResponse;
309    }
310    
311    static private NameIDMappingRequest createNameIDMappingRequest(
312        String userID, String realm, String spEntityID, String idpEntityID,
313        String destination, String targetSPEntityID, String targetNameIDFormat)
314        throws SAML2Exception {
315
316        if (SAML2Utils.debug.messageEnabled()) {
317            SAML2Utils.debug.message(
318                "NameIDMapping.createNameIDMappingRequest: User ID : " +
319                userID);
320        }
321        
322        NameIDMappingRequest nimRequest = pf.createNameIDMappingRequest();
323        
324        nimRequest.setID(SAML2Utils.generateID());
325        nimRequest.setVersion(SAML2Constants.VERSION_2_0);
326        nimRequest.setDestination(XMLUtils.escapeSpecialCharacters(
327            destination));
328        nimRequest.setIssuer(SAML2Utils.createIssuer(spEntityID));
329        nimRequest.setIssueInstant(new Date());
330
331        setNameIDForNIMRequest(nimRequest, realm, spEntityID, idpEntityID,
332            targetSPEntityID, targetNameIDFormat, userID);
333        return nimRequest;
334    }
335
336    static private NameIDMappingResponse doNIMBySOAP(
337        String nimRequestXMLString, String nimURL, String realm,
338        String spEntityID) throws SAML2Exception {
339
340        if (SAML2Utils.debug.messageEnabled()) {
341            SAML2Utils.debug.message("NameIDMapping.doNIMBySOAP: " +
342                "NIMRequestXMLString : " + nimRequestXMLString);
343            SAML2Utils.debug.message("NameIDMapping.doNIMBySOAP: " +
344                "NIMRedirectURL : " + nimURL);
345        }
346        
347        SOAPMessage resMsg = null;
348        try {
349            resMsg = SAML2Utils.sendSOAPMessage(nimRequestXMLString, nimURL,
350                true);
351        } catch (SOAPException se) {
352            SAML2Utils.debug.error("NameIDMapping.doNIMBySOAP: ", se);
353            throw new SAML2Exception(SAML2Utils.bundle.getString(
354                "invalidSOAPMessge"));
355        }
356
357        Element nimRespElem = SAML2Utils.getSamlpElement(resMsg,
358            SAML2Constants.NAME_ID_MAPPING_RESPONSE);
359        NameIDMappingResponse nimResponse = 
360             pf.createNameIDMappingResponse(nimRespElem);
361        
362        if (SAML2Utils.debug.messageEnabled()) {
363            SAML2Utils.debug.message("NameIDMapping.doNIMBySOAP: " +
364                "NameIDMappingResponse without SOAP envelope:\n" +
365                nimResponse.toXMLString(true,true));
366        }
367
368
369        String idpEntityID = nimResponse.getIssuer().getValue();
370        Issuer resIssuer = nimResponse.getIssuer();
371        String requestId = nimResponse.getInResponseTo();
372        SAML2Utils.verifyResponseIssuer(realm, spEntityID, resIssuer,
373            requestId);
374                    
375        if (!verifyNIMResponse(nimResponse, realm, idpEntityID)) {
376            throw new SAML2Exception(
377                SAML2Utils.bundle.getString("invalidSignInResponse"));
378        }
379
380        return nimResponse;
381    }
382
383    static private void setNameIDForNIMRequest(NameIDMappingRequest nimRequest,
384        String realm, String spEntityID, String idpEntityID,
385        String targetSPEntityID, String targetNameIDFormat, String userID)
386        throws SAML2Exception {
387
388        if (SAML2Utils.debug.messageEnabled()) {
389            SAML2Utils.debug.message("NameIDMapping.setNameIDForNIMRequest: " +
390                "user ID = " + userID);
391        }
392
393        NameID nameID = AssertionFactory.getInstance().createNameID();
394        NameIDInfo info = AccountUtils.getAccountFederation(userID, spEntityID,
395            idpEntityID);
396        nameID.setValue(info.getNameIDValue());
397        nameID.setFormat(info.getFormat());
398        nameID.setNameQualifier(idpEntityID);
399        nameID.setSPNameQualifier(spEntityID);
400
401        NameIDPolicy nameIDPolicy =
402            ProtocolFactory.getInstance().createNameIDPolicy();
403        nameIDPolicy.setSPNameQualifier(targetSPEntityID);
404        nameIDPolicy.setFormat(targetNameIDFormat);
405        nimRequest.setNameIDPolicy(nameIDPolicy);
406
407        boolean needEncryptIt = SAML2Utils.getWantNameIDEncrypted(realm,
408            idpEntityID, SAML2Constants.IDP_ROLE);
409        if (!needEncryptIt) {
410            if (SAML2Utils.debug.messageEnabled()) {
411                SAML2Utils.debug.message(
412                    "NameIDMapping.setNameIDForNIMRequest: "  +
413                    "NamID doesn't need to be encrypted.");
414            }
415            nimRequest.setNameID(nameID);
416            return;
417        }
418        
419        EncryptedID encryptedID = getEncryptedID(nameID, realm, idpEntityID,
420            SAML2Constants.IDP_ROLE);
421
422        nimRequest.setEncryptedID(encryptedID);
423    }    
424
425    /**
426     * Returns first NameIDMappingService matching specified binding in an
427     * entity under the realm.
428     *
429     * @param realm The realm under which the entity resides.
430     * @param entityId ID of the entity to be retrieved.
431     * @param binding bind type need to has to be matched.
432     * @return <code>ManageNameIDServiceElement</code> for the entity or null
433     * @throws SAML2MetaException if unable to retrieve the first identity
434     *     provider's SSO configuration.
435     * @throws SessionException invalid or expired single-sign-on session
436     */
437    static public NameIDMappingServiceElement getNameIDMappingService(
438        String realm, String entityId, String binding)
439        throws SAML2MetaException {
440
441
442        IDPSSODescriptorElement idpSSODesc = metaManager.getIDPSSODescriptor(
443            realm, entityId);
444        if (idpSSODesc == null) {
445            SAML2Utils.debug.error(SAML2Utils.bundle.getString("noIDPEntry"));
446            return null;
447        }
448
449        List list = idpSSODesc.getNameIDMappingService();
450
451        NameIDMappingServiceElement nimService = null;
452        if ((list != null) && !list.isEmpty()) {
453            if (binding == null) {
454                return (NameIDMappingServiceElement)list.get(0);
455            }
456            Iterator it = list.iterator();
457            while (it.hasNext()) {
458                nimService = (NameIDMappingServiceElement)it.next();  
459                if (binding.equalsIgnoreCase(nimService.getBinding())) {
460                    return nimService;
461                }
462            }
463        }
464        return null;
465    }
466        
467    static EncryptedID getEncryptedID(NameID nameID, String realm,
468        String entityID, String role) throws SAML2Exception {
469
470        RoleDescriptorType roled = null;
471
472        if (role.equals(SAML2Constants.SP_ROLE)) {
473            roled = metaManager.getSPSSODescriptor(realm, entityID);
474        } else {
475            roled = metaManager.getIDPSSODescriptor(realm, entityID);
476        }
477
478        EncInfo encInfo = KeyUtil.getEncInfo(roled, entityID, role);
479        
480        if (encInfo == null) {
481            throw new SAML2Exception(
482                SAML2Utils.bundle.getString("UnableToFindEncryptKeyInfo"));
483        }
484        
485        EncryptedID encryptedID = nameID.encrypt(encInfo.getWrappingKey(), 
486            encInfo.getDataEncAlgorithm(), encInfo.getDataEncStrength(),
487            entityID);
488
489        return encryptedID;
490    }    
491
492    private static void signNIMRequest(NameIDMappingRequest nimRequest, 
493        String realm, String spEntityID, boolean includeCert)
494        throws SAML2Exception {
495
496        String alias = SAML2Utils.getSigningCertAlias(realm, spEntityID,
497            SAML2Constants.SP_ROLE);
498        
499        if (SAML2Utils.debug.messageEnabled()) {
500            SAML2Utils.debug.message("NameIDMapping.signNIMRequest: " +
501                "Cert Alias is : " + alias);
502            SAML2Utils.debug.message("NameIDMapping.signNIMRequest: " +
503                "NIMRequest before sign : " +
504                nimRequest.toXMLString(true, true));
505        }
506        PrivateKey signingKey = keyProvider.getPrivateKey(alias);
507        X509Certificate signingCert = null;
508        if (includeCert) {
509            signingCert = keyProvider.getX509Certificate(alias);
510        }
511        
512        if (signingKey != null) {
513            nimRequest.sign(signingKey, signingCert);
514        } else {
515            throw new SAML2Exception(
516                SAML2Utils.bundle.getString("missingSigningCertAlias"));
517        }
518        
519        if (SAML2Utils.debug.messageEnabled()) {
520            SAML2Utils.debug.message("NameIDMapping.signNIMRequest: " +
521                "NIMRequest after sign : " +
522                nimRequest.toXMLString(true, true));
523        }
524    }
525
526    private static boolean verifyNIMRequest(NameIDMappingRequest nimRequest, 
527        String realm, String spEntityID) throws SAML2Exception {
528
529        SPSSODescriptorElement spSSODesc =
530            metaManager.getSPSSODescriptor(realm, spEntityID);
531        X509Certificate signingCert = KeyUtil.getVerificationCert(spSSODesc,
532            spEntityID, SAML2Constants.SP_ROLE);
533
534        if (signingCert != null) {
535            boolean valid = nimRequest.isSignatureValid(signingCert);
536            if (SAML2Utils.debug.messageEnabled()) {
537                SAML2Utils.debug.message("NameIDMapping:verifyNIMRequest: " +
538                "Signature is : " + valid);
539            }
540            return valid;
541        } else {
542            throw new SAML2Exception(
543                SAML2Utils.bundle.getString("missingSigningCertAlias"));
544        }
545    }
546
547    static void signNIMResponse(NameIDMappingResponse nimResponse,
548        String realm, String idpEntityID, boolean includeCert)
549        throws SAML2Exception {
550
551        String alias = SAML2Utils.getSigningCertAlias(realm, idpEntityID,
552            SAML2Constants.IDP_ROLE);
553        if (SAML2Utils.debug.messageEnabled()) {
554            SAML2Utils.debug.message("NameIDMapping.signNIMResponse: " +
555                realm);
556            SAML2Utils.debug.message("NameIDMapping.signNIMResponse: " +
557                idpEntityID);
558            SAML2Utils.debug.message("NameIDMapping.signNIMResponse: " +
559                alias);
560
561        }
562
563        String encryptedKeyPass =
564                SAML2Utils.getSigningCertEncryptedKeyPass(realm, idpEntityID, SAML2Constants.IDP_ROLE);
565        PrivateKey signingKey;
566        if (encryptedKeyPass == null || encryptedKeyPass.isEmpty()) {
567            signingKey = keyProvider.getPrivateKey(alias);
568        } else {
569            signingKey = keyProvider.getPrivateKey(alias, encryptedKeyPass);
570        }
571        X509Certificate signingCert = null;
572        if (includeCert) {
573            signingCert = keyProvider.getX509Certificate(alias);
574        }
575
576        if (signingKey != null) {
577            nimResponse.sign(signingKey, signingCert); 
578        } else {
579            SAML2Utils.debug.error("NameIDMapping.signNIMResponse: " +
580                "Incorrect configuration for Signing Certificate.");
581            throw new SAML2Exception(
582                SAML2Utils.bundle.getString("metaDataError"));
583        }
584
585    }
586
587    private static boolean verifyNIMResponse(NameIDMappingResponse nimResponse,
588        String realm, String idpEntityID) throws SAML2Exception {
589
590        IDPSSODescriptorElement idpSSODesc = metaManager.getIDPSSODescriptor(
591            realm, idpEntityID);
592        X509Certificate signingCert = KeyUtil.getVerificationCert(idpSSODesc,
593            idpEntityID, SAML2Constants.IDP_ROLE);
594        
595        if (signingCert != null) {
596            boolean valid = nimResponse.isSignatureValid(signingCert);
597            if (SAML2Utils.debug.messageEnabled()) {
598                SAML2Utils.debug.message("NameIDMapping.verifyNIMResponse: " +
599                    "Signature is : " + valid);
600            }
601            return valid;
602        } else {
603            throw new SAML2Exception(
604                SAML2Utils.bundle.getString("missingSigningCertAlias"));
605        }
606    }
607
608    private static NameID getNameID(NameIDMappingRequest nimRequest,
609        String realm, String idpEntityID){
610
611        NameID nameID = nimRequest.getNameID();
612        if (nameID == null) {
613            String alias = SAML2Utils.getSigningCertAlias(realm, idpEntityID, SAML2Constants.IDP_ROLE);
614            String encryptedKeyPass =
615                    SAML2Utils.getSigningCertEncryptedKeyPass(realm, idpEntityID, SAML2Constants.IDP_ROLE);
616            PrivateKey signingKey;
617            if (encryptedKeyPass == null || encryptedKeyPass.isEmpty()) {
618                signingKey = keyProvider.getPrivateKey(alias);
619            } else {
620                signingKey = keyProvider.getPrivateKey(alias, encryptedKeyPass);
621            }
622
623            EncryptedID encryptedID = nimRequest.getEncryptedID();
624            try {
625                nameID = encryptedID.decrypt(signingKey);
626            } catch (SAML2Exception ex) {
627                if (SAML2Utils.debug.messageEnabled()) {
628                    SAML2Utils.debug.message("NameIDMapping.getNameID:", ex);
629                }
630                return null;
631            }
632        }
633
634        if (!SAML2Utils.isPersistentNameID(nameID)) {
635            return null;
636        }
637
638        return nameID;
639    }
640}