| 1 |  |  | 
            
  
    | 2 |  |  | 
            
  
    | 3 |  |  | 
            
  
    | 4 |  |  | 
            
  
    | 5 |  |  | 
            
  
    | 6 |  |  | 
            
  
    | 7 |  |  | 
            
  
    | 8 |  |  | 
            
  
    | 9 |  |  | 
            
  
    | 10 |  |  | 
            
  
    | 11 |  |  | 
            
  
    | 12 |  |  | 
            
  
    | 13 |  |  | 
            
  
    | 14 |  |  | 
            
  
    | 15 |  |  | 
            
  
    | 16 |  | package org.kuali.student.security.util; | 
            
  
    | 17 |  |  | 
            
  
    | 18 |  | import java.io.IOException; | 
            
  
    | 19 |  | import java.net.URL; | 
            
  
    | 20 |  | import java.security.KeyStore; | 
            
  
    | 21 |  | import java.security.KeyStoreException; | 
            
  
    | 22 |  | import java.security.NoSuchAlgorithmException; | 
            
  
    | 23 |  | import java.security.PrivateKey; | 
            
  
    | 24 |  | import java.security.PublicKey; | 
            
  
    | 25 |  | import java.security.UnrecoverableKeyException; | 
            
  
    | 26 |  | import java.security.cert.CertificateException; | 
            
  
    | 27 |  | import java.security.cert.X509Certificate; | 
            
  
    | 28 |  | import java.util.Arrays; | 
            
  
    | 29 |  | import java.util.Date; | 
            
  
    | 30 |  | import java.util.Map; | 
            
  
    | 31 |  |  | 
            
  
    | 32 |  | import javax.xml.parsers.DocumentBuilder; | 
            
  
    | 33 |  | import javax.xml.parsers.DocumentBuilderFactory; | 
            
  
    | 34 |  | import javax.xml.parsers.ParserConfigurationException; | 
            
  
    | 35 |  | import javax.xml.transform.TransformerException; | 
            
  
    | 36 |  |  | 
            
  
    | 37 |  | import org.apache.xml.security.exceptions.XMLSecurityException; | 
            
  
    | 38 |  | import org.apache.xml.security.keys.KeyInfo; | 
            
  
    | 39 |  | import org.apache.xml.security.signature.XMLSignature; | 
            
  
    | 40 |  | import org.apache.xml.security.signature.XMLSignatureException; | 
            
  
    | 41 |  | import org.apache.xml.security.transforms.Transforms; | 
            
  
    | 42 |  | import org.apache.xml.security.utils.Constants; | 
            
  
    | 43 |  | import org.apache.xpath.XPathAPI; | 
            
  
    | 44 |  | import org.opensaml.SAMLAssertion; | 
            
  
    | 45 |  | import org.opensaml.SAMLAttribute; | 
            
  
    | 46 |  | import org.opensaml.SAMLAttributeStatement; | 
            
  
    | 47 |  | import org.opensaml.SAMLAuthenticationStatement; | 
            
  
    | 48 |  | import org.opensaml.SAMLException; | 
            
  
    | 49 |  | import org.opensaml.SAMLNameIdentifier; | 
            
  
    | 50 |  | import org.opensaml.SAMLSubject; | 
            
  
    | 51 |  | import org.w3c.dom.DOMException; | 
            
  
    | 52 |  | import org.w3c.dom.Document; | 
            
  
    | 53 |  | import org.w3c.dom.Element; | 
            
  
    | 54 |  | import org.w3c.dom.Node; | 
            
  
    | 55 |  | import org.w3c.dom.NodeList; | 
            
  
    | 56 |  |  | 
            
  
    | 57 |  |  | 
            
  
    | 58 |  |  | 
            
  
    | 59 |  |  | 
            
  
    | 60 |  | @author | 
            
  
    | 61 |  |  | 
            
  
    | 62 |  |  | 
               
        |  |  | 
           
           |  | 11.1% | Uncovered Elements: 112 (126) | Complexity: 25 | Complexity Density: 0.26 |  | 
  
  
    | 63 |  | public class SamlUtils { | 
            
  
    | 64 |  |  | 
               
        |  |  | 
           
           |  | 100% | Uncovered Elements: 0 (1) | Complexity: 1 | Complexity Density: 1 |  | 
  
  
    | 65 | 1 |  static {... | 
            
  
    | 66 | 1 | org.apache.xml.security.Init.init(); | 
            
  
    | 67 |  | } | 
            
  
    | 68 |  |  | 
            
  
    | 69 |  |  | 
            
  
    | 70 |  | private static String keystoreType; | 
            
  
    | 71 |  | private static String keystoreFile; | 
            
  
    | 72 |  | private static String keystorePass; | 
            
  
    | 73 |  | private static String privateKeyAlias; | 
            
  
    | 74 |  | private static String privateKeyPass; | 
            
  
    | 75 |  | private static String certificateAlias; | 
            
  
    | 76 |  |  | 
            
  
    | 77 |  | private static ThreadLocal<Map<String,String>> samlPropertiesHolder = new ThreadLocal<Map<String,String>>(); | 
            
  
    | 78 |  |  | 
               
        |  |  | 
           
           |  | 0% | Uncovered Elements: 32 (32) | Complexity: 1 | Complexity Density: 0.03 |  | 
  
  
    | 79 | 0 |  public static SAMLAssertion createAssertion() throws SAMLException, CloneNotSupportedException{... | 
            
  
    | 80 |  |  | 
            
  
    | 81 | 0 | String user = getSamlProperties().get("user"); | 
            
  
    | 82 | 0 | String pgt = getSamlProperties().get("proxyGrantingTicket"); | 
            
  
    | 83 | 0 | String proxies = getSamlProperties().get("proxies"); | 
            
  
    | 84 | 0 | String issuer = getSamlProperties().get("samlIssuerForUser"); | 
            
  
    | 85 | 0 | String nameQualifier = getSamlProperties().get("samlIssuerForUser"); | 
            
  
    | 86 |  |  | 
            
  
    | 87 | 0 | SAMLAssertion assertion = new SAMLAssertion(); | 
            
  
    | 88 | 0 | assertion.setIssuer(issuer); | 
            
  
    | 89 |  |  | 
            
  
    | 90 |  |  | 
            
  
    | 91 | 0 | SAMLNameIdentifier nameId = new SAMLNameIdentifier(user, nameQualifier, ""); | 
            
  
    | 92 | 0 | String[] confirmationMethods = {SAMLSubject.CONF_SENDER_VOUCHES}; | 
            
  
    | 93 | 0 | SAMLSubject subject = new SAMLSubject(); | 
            
  
    | 94 | 0 | subject.setNameIdentifier(nameId); | 
            
  
    | 95 | 0 | subject.setConfirmationMethods(Arrays.asList(confirmationMethods)); | 
            
  
    | 96 |  |  | 
            
  
    | 97 |  |  | 
            
  
    | 98 | 0 | SAMLAuthenticationStatement authStmt = new SAMLAuthenticationStatement(); | 
            
  
    | 99 | 0 | authStmt.setAuthInstant(new Date()); | 
            
  
    | 100 | 0 | authStmt.setAuthMethod(SAMLAuthenticationStatement.AuthenticationMethod_Password); | 
            
  
    | 101 | 0 | authStmt.setSubject(subject); | 
            
  
    | 102 |  |  | 
            
  
    | 103 |  |  | 
            
  
    | 104 | 0 | SAMLAttributeStatement attrStatement = new SAMLAttributeStatement(); | 
            
  
    | 105 | 0 | SAMLAttribute attr1 = new SAMLAttribute(); | 
            
  
    | 106 | 0 | attr1.setName("proxyGrantingTicket"); | 
            
  
    | 107 | 0 | attr1.setNamespace("http://student.kuali.org/wsdl/security/saml"); | 
            
  
    | 108 |  |  | 
            
  
    | 109 | 0 | SAMLAttribute attr2 = new SAMLAttribute(); | 
            
  
    | 110 | 0 | attr2.setName("proxies"); | 
            
  
    | 111 | 0 | attr2.setNamespace("http://student.kuali.org/wsdl/security/saml"); | 
            
  
    | 112 |  |  | 
            
  
    | 113 | 0 | attr1.addValue(pgt); | 
            
  
    | 114 | 0 | attr2.addValue(proxies); | 
            
  
    | 115 |  |  | 
            
  
    | 116 | 0 | attrStatement.addAttribute(attr1); | 
            
  
    | 117 | 0 | attrStatement.addAttribute(attr2); | 
            
  
    | 118 |  |  | 
            
  
    | 119 | 0 | SAMLSubject subjectInAttr = (SAMLSubject)subject.clone(); | 
            
  
    | 120 | 0 | attrStatement.setSubject(subjectInAttr); | 
            
  
    | 121 |  |  | 
            
  
    | 122 |  |  | 
            
  
    | 123 | 0 | assertion.addStatement(authStmt); | 
            
  
    | 124 | 0 | assertion.addStatement(attrStatement); | 
            
  
    | 125 |  |  | 
            
  
    | 126 | 0 | return assertion; | 
            
  
    | 127 |  | } | 
            
  
    | 128 |  |  | 
               
        |  |  | 
           
           |  | 0% | Uncovered Elements: 1 (1) | Complexity: 1 | Complexity Density: 1 |  | 
  
  
    | 129 | 0 |  public static void setSamlProperties(Map<String, String> samlProperties){... | 
            
  
    | 130 |  |  | 
            
  
    | 131 | 0 | SamlUtils.samlPropertiesHolder.set(samlProperties); | 
            
  
    | 132 |  | } | 
            
  
    | 133 |  |  | 
               
        |  |  | 
           
           |  | 0% | Uncovered Elements: 1 (1) | Complexity: 1 | Complexity Density: 1 |  | 
  
  
    | 134 | 0 |  public static Map<String, String> getSamlProperties() {... | 
            
  
    | 135 |  |  | 
            
  
    | 136 | 0 | return SamlUtils.samlPropertiesHolder.get(); | 
            
  
    | 137 |  | } | 
            
  
    | 138 |  |  | 
               
        |  |  | 
           
           |  | 0% | Uncovered Elements: 25 (25) | Complexity: 1 | Complexity Density: 0.04 |  | 
  
  
    | 139 | 0 |  public static Document signAssertion(SAMLAssertion assertion) throws XMLSecurityException, KeyStoreException, ... | 
            
  
    | 140 |  | NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException, | 
            
  
    | 141 |  | ParserConfigurationException, DOMException, SAMLException { | 
            
  
    | 142 | 0 | Constants.setSignatureSpecNSprefix("ds"); | 
            
  
    | 143 |  |  | 
            
  
    | 144 | 0 | ClassLoader classLoader = SamlUtils.class.getClassLoader(); | 
            
  
    | 145 | 0 | URL url = classLoader.getResource(keystoreFile); | 
            
  
    | 146 |  |  | 
            
  
    | 147 |  |  | 
            
  
    | 148 | 0 | KeyStore ks = KeyStore.getInstance(keystoreType); | 
            
  
    | 149 | 0 | ks.load(url.openStream(), keystorePass.toCharArray()); | 
            
  
    | 150 |  |  | 
            
  
    | 151 |  |  | 
            
  
    | 152 | 0 | PrivateKey privateKey = (PrivateKey) ks.getKey(privateKeyAlias, privateKeyPass.toCharArray()); | 
            
  
    | 153 |  |  | 
            
  
    | 154 | 0 | DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); | 
            
  
    | 155 |  |  | 
            
  
    | 156 |  |  | 
            
  
    | 157 | 0 | dbf.setNamespaceAware(true); | 
            
  
    | 158 |  |  | 
            
  
    | 159 | 0 | DocumentBuilder db = dbf.newDocumentBuilder(); | 
            
  
    | 160 | 0 | Document doc = db.newDocument(); | 
            
  
    | 161 |  |  | 
            
  
    | 162 | 0 | Element root = doc.createElementNS("http://student.kuali.org", "ks:KSSecureToken"); | 
            
  
    | 163 | 0 | root.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:ks", "http://student.kuali.org"); | 
            
  
    | 164 |  |  | 
            
  
    | 165 | 0 | doc.appendChild(root); | 
            
  
    | 166 |  |  | 
            
  
    | 167 | 0 | root.appendChild(assertion.toDOM(doc)); | 
            
  
    | 168 |  |  | 
            
  
    | 169 | 0 | XMLSignature sig = new XMLSignature(doc, null, XMLSignature.ALGO_ID_SIGNATURE_RSA); | 
            
  
    | 170 |  |  | 
            
  
    | 171 |  |  | 
            
  
    | 172 |  |  | 
            
  
    | 173 |  |  | 
            
  
    | 174 |  |  | 
            
  
    | 175 |  |  | 
            
  
    | 176 |  |  | 
            
  
    | 177 |  |  | 
            
  
    | 178 |  |  | 
            
  
    | 179 | 0 | root.appendChild(sig.getElement()); | 
            
  
    | 180 |  |  | 
            
  
    | 181 |  |  | 
            
  
    | 182 | 0 | Transforms transforms = new Transforms(doc); | 
            
  
    | 183 |  |  | 
            
  
    | 184 |  |  | 
            
  
    | 185 |  |  | 
            
  
    | 186 | 0 | transforms.addTransform(Transforms.TRANSFORM_ENVELOPED_SIGNATURE); | 
            
  
    | 187 |  |  | 
            
  
    | 188 |  |  | 
            
  
    | 189 |  |  | 
            
  
    | 190 | 0 | transforms.addTransform(Transforms.TRANSFORM_C14N_WITH_COMMENTS); | 
            
  
    | 191 |  |  | 
            
  
    | 192 | 0 | sig.addDocument("", transforms, Constants.ALGO_ID_DIGEST_SHA1); | 
            
  
    | 193 |  |  | 
            
  
    | 194 |  |  | 
            
  
    | 195 |  |  | 
            
  
    | 196 | 0 | X509Certificate cert = (X509Certificate) ks.getCertificate(certificateAlias); | 
            
  
    | 197 |  |  | 
            
  
    | 198 | 0 | sig.addKeyInfo(cert); | 
            
  
    | 199 | 0 | sig.addKeyInfo(cert.getPublicKey()); | 
            
  
    | 200 |  |  | 
            
  
    | 201 | 0 | sig.sign(privateKey); | 
            
  
    | 202 |  |  | 
            
  
    | 203 | 0 | return doc; | 
            
  
    | 204 |  | } | 
            
  
    | 205 |  |  | 
               
        |  |  | 
           
           |  | 0% | Uncovered Elements: 36 (36) | Complexity: 8 | Complexity Density: 0.33 |  | 
  
  
    | 206 | 0 |  public static SAMLAssertion unsignAssertion(Document doc) throws TransformerException, XMLSecurityException, SAMLException {... | 
            
  
    | 207 | 0 | boolean validSig = false; | 
            
  
    | 208 | 0 | Element nscontext = doc.createElementNS(null, "namespaceContext"); | 
            
  
    | 209 | 0 | nscontext.setAttributeNS(Constants.NamespaceSpecNS, "xmlns:ds", Constants.SignatureSpecNS); | 
            
  
    | 210 |  |  | 
            
  
    | 211 | 0 | Element sigElement = (Element) XPathAPI.selectSingleNode(doc, "//ds:Signature[1]", nscontext); | 
            
  
    | 212 |  |  | 
            
  
    | 213 | 0 | XMLSignature signature = new XMLSignature(sigElement, null); | 
            
  
    | 214 |  |  | 
            
  
    | 215 | 0 | KeyInfo ki = signature.getKeyInfo(); | 
            
  
    | 216 |  |  | 
            
  
    | 217 | 0 | if (ki != null) { | 
            
  
    | 218 | 0 | X509Certificate cert = ki.getX509Certificate(); | 
            
  
    | 219 |  |  | 
            
  
    | 220 | 0 | if (cert != null) { | 
            
  
    | 221 | 0 | validSig = signature.checkSignatureValue(cert); | 
            
  
    | 222 |  |  | 
            
  
    | 223 |  | } else { | 
            
  
    | 224 | 0 | PublicKey pk = ki.getPublicKey(); | 
            
  
    | 225 |  |  | 
            
  
    | 226 | 0 | if (pk != null) { | 
            
  
    | 227 | 0 | validSig = signature.checkSignatureValue(pk); | 
            
  
    | 228 |  |  | 
            
  
    | 229 |  | } else { | 
            
  
    | 230 | 0 | throw new XMLSignatureException("Could not find a certificate or a public key in the message, can't check the signature"); | 
            
  
    | 231 |  | } | 
            
  
    | 232 |  | } | 
            
  
    | 233 |  | } else { | 
            
  
    | 234 | 0 | throw new XMLSignatureException("Could not find a KeyInfo element in message"); | 
            
  
    | 235 |  | } | 
            
  
    | 236 |  |  | 
            
  
    | 237 |  |  | 
            
  
    | 238 | 0 | if(validSig){ | 
            
  
    | 239 | 0 | NodeList nodeList = doc.getDocumentElement().getChildNodes(); | 
            
  
    | 240 | 0 | Node childNode = null; | 
            
  
    | 241 |  |  | 
            
  
    | 242 | 0 | for(int i=0; i < nodeList.getLength(); i++){ | 
            
  
    | 243 | 0 | childNode = nodeList.item(i); | 
            
  
    | 244 | 0 | if((childNode.getNodeName().equals("Assertion")) && (childNode.getNodeType() == Node.ELEMENT_NODE)){ | 
            
  
    | 245 | 0 | SAMLAssertion assertion = new SAMLAssertion((Element)childNode); | 
            
  
    | 246 | 0 | return assertion; | 
            
  
    | 247 |  | } | 
            
  
    | 248 |  | } | 
            
  
    | 249 |  | } | 
            
  
    | 250 |  |  | 
            
  
    | 251 | 0 | throw new XMLSignatureException("The message signature was invalid"); | 
            
  
    | 252 |  | } | 
            
  
    | 253 |  |  | 
            
  
    | 254 |  |  | 
            
  
    | 255 |  | @return | 
            
  
    | 256 |  |  | 
               
        |  |  | 
           
           |  | 0% | Uncovered Elements: 1 (1) | Complexity: 1 | Complexity Density: 1 |  | 
  
  
    | 257 | 0 |  public String getKeystoreType() {... | 
            
  
    | 258 | 0 | return keystoreType; | 
            
  
    | 259 |  | } | 
            
  
    | 260 |  |  | 
            
  
    | 261 |  |  | 
            
  
    | 262 |  | @param | 
            
  
    | 263 |  |  | 
               
        |  |  | 
           
           |  | 100% | Uncovered Elements: 0 (1) | Complexity: 1 | Complexity Density: 1 |  | 
  
  
    | 264 | 1 |  public void setKeystoreType(String keystoreType) {... | 
            
  
    | 265 | 1 | SamlUtils.keystoreType = keystoreType; | 
            
  
    | 266 |  | } | 
            
  
    | 267 |  |  | 
            
  
    | 268 |  |  | 
            
  
    | 269 |  | @return | 
            
  
    | 270 |  |  | 
               
        |  |  | 
           
           |  | 0% | Uncovered Elements: 1 (1) | Complexity: 1 | Complexity Density: 1 |  | 
  
  
    | 271 | 0 |  public String getKeystoreFile() {... | 
            
  
    | 272 | 0 | return keystoreFile; | 
            
  
    | 273 |  | } | 
            
  
    | 274 |  |  | 
            
  
    | 275 |  |  | 
            
  
    | 276 |  | @param | 
            
  
    | 277 |  |  | 
               
        |  |  | 
           
           |  | 100% | Uncovered Elements: 0 (1) | Complexity: 1 | Complexity Density: 1 |  | 
  
  
    | 278 | 1 |  public void setKeystoreFile(String keystoreFile) {... | 
            
  
    | 279 | 1 | SamlUtils.keystoreFile = keystoreFile; | 
            
  
    | 280 |  | } | 
            
  
    | 281 |  |  | 
            
  
    | 282 |  |  | 
            
  
    | 283 |  | @return | 
            
  
    | 284 |  |  | 
               
        |  |  | 
           
           |  | 0% | Uncovered Elements: 1 (1) | Complexity: 1 | Complexity Density: 1 |  | 
  
  
    | 285 | 0 |  public String getKeystorePass() {... | 
            
  
    | 286 | 0 | return keystorePass; | 
            
  
    | 287 |  | } | 
            
  
    | 288 |  |  | 
            
  
    | 289 |  |  | 
            
  
    | 290 |  | @param | 
            
  
    | 291 |  |  | 
               
        |  |  | 
           
           |  | 100% | Uncovered Elements: 0 (1) | Complexity: 1 | Complexity Density: 1 |  | 
  
  
    | 292 | 1 |  public void setKeystorePass(String keystorePass) {... | 
            
  
    | 293 | 1 | SamlUtils.keystorePass = keystorePass; | 
            
  
    | 294 |  | } | 
            
  
    | 295 |  |  | 
            
  
    | 296 |  |  | 
            
  
    | 297 |  | @return | 
            
  
    | 298 |  |  | 
               
        |  |  | 
           
           |  | 0% | Uncovered Elements: 1 (1) | Complexity: 1 | Complexity Density: 1 |  | 
  
  
    | 299 | 0 |  public String getPrivateKeyAlias() {... | 
            
  
    | 300 | 0 | return privateKeyAlias; | 
            
  
    | 301 |  | } | 
            
  
    | 302 |  |  | 
            
  
    | 303 |  |  | 
            
  
    | 304 |  | @param | 
            
  
    | 305 |  |  | 
               
        |  |  | 
           
           |  | 100% | Uncovered Elements: 0 (1) | Complexity: 1 | Complexity Density: 1 |  | 
  
  
    | 306 | 1 |  public void setPrivateKeyAlias(String privateKeyAlias) {... | 
            
  
    | 307 | 1 | SamlUtils.privateKeyAlias = privateKeyAlias; | 
            
  
    | 308 |  | } | 
            
  
    | 309 |  |  | 
            
  
    | 310 |  |  | 
            
  
    | 311 |  | @return | 
            
  
    | 312 |  |  | 
               
        |  |  | 
           
           |  | 0% | Uncovered Elements: 1 (1) | Complexity: 1 | Complexity Density: 1 |  | 
  
  
    | 313 | 0 |  public String getPrivateKeyPass() {... | 
            
  
    | 314 | 0 | return privateKeyPass; | 
            
  
    | 315 |  | } | 
            
  
    | 316 |  |  | 
            
  
    | 317 |  |  | 
            
  
    | 318 |  | @param | 
            
  
    | 319 |  |  | 
               
        |  |  | 
           
           |  | 100% | Uncovered Elements: 0 (1) | Complexity: 1 | Complexity Density: 1 |  | 
  
  
    | 320 | 1 |  public void setPrivateKeyPass(String privateKeyPass) {... | 
            
  
    | 321 | 1 | SamlUtils.privateKeyPass = privateKeyPass; | 
            
  
    | 322 |  | } | 
            
  
    | 323 |  |  | 
            
  
    | 324 |  |  | 
            
  
    | 325 |  | @return | 
            
  
    | 326 |  |  | 
               
        |  |  | 
           
           |  | 0% | Uncovered Elements: 1 (1) | Complexity: 1 | Complexity Density: 1 |  | 
  
  
    | 327 | 0 |  public String getCertificateAlias() {... | 
            
  
    | 328 | 0 | return certificateAlias; | 
            
  
    | 329 |  | } | 
            
  
    | 330 |  |  | 
            
  
    | 331 |  |  | 
            
  
    | 332 |  | @param | 
            
  
    | 333 |  |  | 
               
        |  |  | 
           
           |  | 100% | Uncovered Elements: 0 (1) | Complexity: 1 | Complexity Density: 1 |  | 
  
  
    | 334 | 1 |  public void setCertificateAlias(String certificateAlias) {... | 
            
  
    | 335 | 1 | SamlUtils.certificateAlias = certificateAlias; | 
            
  
    | 336 |  | } | 
            
  
    | 337 |  | } |