Created
August 20, 2024 09:00
-
-
Save kjunichi/1f6bb2677fe517c3930cc2e04cd89e83 to your computer and use it in GitHub Desktop.
SAMLValidation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.nio.file.Paths; | |
import java.security.Key; | |
import java.security.KeyException; | |
import java.security.PublicKey; | |
import java.security.Signature; | |
import java.security.cert.X509CRL; | |
import java.security.cert.X509Certificate; | |
import java.util.List; | |
import java.util.Iterator; | |
import javax.xml.crypto.AlgorithmMethod; | |
import javax.xml.crypto.KeySelector; | |
import javax.xml.crypto.KeySelectorException; | |
import javax.xml.crypto.KeySelectorResult; | |
import javax.xml.crypto.XMLCryptoContext; | |
import javax.xml.crypto.XMLStructure; | |
import javax.xml.crypto.dsig.SignatureMethod; | |
import javax.xml.crypto.dsig.XMLSignature; | |
import javax.xml.crypto.dsig.XMLSignatureFactory; | |
import javax.xml.crypto.dsig.dom.DOMValidateContext; | |
import javax.xml.crypto.dsig.keyinfo.KeyInfo; | |
import javax.xml.crypto.dsig.keyinfo.KeyValue; | |
import javax.xml.crypto.dsig.keyinfo.X509Data; | |
import javax.xml.parsers.DocumentBuilder; | |
import javax.xml.parsers.DocumentBuilderFactory; | |
import org.w3c.dom.Document; | |
import org.w3c.dom.Element; | |
import org.w3c.dom.NodeList; | |
public class Main { | |
public void execute() throws Exception { | |
System.out.println("start"); | |
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); | |
factory.setNamespaceAware(true); | |
DocumentBuilder builder = factory.newDocumentBuilder(); | |
//Document document = builder.parse(Paths.get("test2.1.xml").toFile()); | |
//Document document = builder.parse(Paths.get("test3.1.xml").toFile()); | |
Document document = builder.parse(Paths.get("test3.xml").toFile()); | |
//document.getDocumentElement().setIdAttributeNS(null, "ID", true); | |
//document.getDocumentElement().setIdAttribute("ID",true); | |
// 署名要素(Signature)の特定 | |
Element sigNode = (Element) document.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature").item(0); | |
String svalue = (String) sigNode.getElementsByTagName("SignatureValue").item(0).getTextContent(); | |
System.out.println("svalue = "+svalue); | |
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM"); | |
//sigNode.setIdAttribute("ID", true); | |
DOMValidateContext valContext = new DOMValidateContext(new RawX509KeySelector(), sigNode); | |
NodeList anl = document.getElementsByTagNameNS("urn:oasis:names:tc:SAML:2.0:assertion", "Assertion"); | |
valContext.setIdAttributeNS((Element)anl.item(0), null, "ID"); | |
System.out.println("valCon"); | |
// unmarshal the XMLSignature | |
XMLSignature signature = fac.unmarshalXMLSignature(valContext); | |
// Validate the XMLSignature (generated above) | |
boolean coreValidity = signature.validate(valContext); | |
System.out.println("coreValidity = "+ coreValidity); | |
if(!coreValidity) { | |
boolean sv = signature.getSignatureValue().validate(valContext); | |
System.out.println("signature validation status: "+sv); | |
Iterator i = signature.getSignedInfo().getReferences().iterator(); | |
for(int j =0;i.hasNext();j++) { | |
System.out.println("j = " +j); | |
boolean refValid = ((javax.xml.crypto.dsig.Reference) i.next()).validate(valContext); | |
System.out.println("ref[]"+j+"] validity status: "+ refValid); | |
} | |
} | |
System.out.println("end"); | |
} | |
public static void main(String[] args) { | |
Main m = new Main(); | |
try { | |
m.execute(); | |
} catch (Exception e) { | |
System.out.println(e); | |
} | |
} | |
private static class KeyValueKeySelector extends KeySelector { | |
public KeySelectorResult select(KeyInfo keyInfo, | |
KeySelector.Purpose purpose, | |
AlgorithmMethod method, | |
XMLCryptoContext context) | |
throws KeySelectorException { | |
if (keyInfo == null) { | |
throw new KeySelectorException("Null KeyInfo object!"); | |
} | |
System.out.println("keyInfo != null"); | |
SignatureMethod sm = (SignatureMethod) method; | |
List<XMLStructure> list = keyInfo.getContent(); | |
for (int i = 0; i < list.size(); i++) { | |
System.out.println("i = "+i); | |
XMLStructure xmlStructure = list.get(i); | |
if (xmlStructure instanceof X509Data) { | |
System.out.println(xmlStructure); | |
for(Object x509Content: ((X509Data)xmlStructure).getContent()) { | |
X509Certificate cert = (X509Certificate)x509Content; | |
System.out.println(cert.getPublicKey().toString()); | |
return new SimpleKeySelectorResult(cert.getPublicKey()); | |
} | |
} | |
if (xmlStructure instanceof KeyValue) { | |
System.out.println("xmlStructure instanceof KeyValue"); | |
PublicKey pk = null; | |
try { | |
pk = ((KeyValue) xmlStructure).getPublicKey(); | |
} catch (KeyException ke) { | |
throw new KeySelectorException(ke); | |
} | |
// make sure algorithm is compatible with method | |
if (algEquals(sm.getAlgorithm(), pk.getAlgorithm())) { | |
return new SimpleKeySelectorResult(pk); | |
} | |
} else { | |
System.out.println(""); | |
} | |
} | |
System.out.println("Dame"); | |
throw new KeySelectorException("No KeyValue element found!"); | |
} | |
static boolean algEquals(String algURI, String algName) { | |
if (algName.equalsIgnoreCase("DSA") && | |
algURI.equalsIgnoreCase("http://www.w3.org/2009/xmldsig11#dsa-sha256")) { | |
return true; | |
} else if (algName.equalsIgnoreCase("RSA") && | |
algURI.equalsIgnoreCase("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256")) { | |
return true; | |
} else { | |
System.out.println("alg Ng"); | |
return false; | |
} | |
} | |
} | |
public static class RawX509KeySelector extends KeySelector { | |
public KeySelectorResult select(KeyInfo keyInfo, | |
KeySelector.Purpose purpose, | |
AlgorithmMethod method, | |
XMLCryptoContext context) | |
throws KeySelectorException { | |
if (keyInfo == null) { | |
throw new KeySelectorException("Null KeyInfo object!"); | |
} | |
// search for X509Data in keyinfo | |
Iterator<?> iter = keyInfo.getContent().iterator(); | |
while (iter.hasNext()) { | |
XMLStructure kiType = (XMLStructure) iter.next(); | |
if (kiType instanceof X509Data) { | |
X509Data xd = (X509Data) kiType; | |
Object[] entries = xd.getContent().toArray(); | |
X509CRL crl = null; | |
// Looking for CRL before finding certificates | |
for (int i = 0; (i < entries.length && crl == null); i++) { | |
if (entries[i] instanceof X509CRL) { | |
crl = (X509CRL) entries[i]; | |
} | |
} | |
Iterator<?> xi = xd.getContent().iterator(); | |
while (xi.hasNext()) { | |
Object o = xi.next(); | |
// skip non-X509Certificate entries | |
if (o instanceof X509Certificate) { | |
if ((purpose != KeySelector.Purpose.VERIFY) && | |
(crl != null) && | |
crl.isRevoked((X509Certificate)o)) { | |
continue; | |
} else { | |
return new SimpleKeySelectorResult | |
(((X509Certificate)o).getPublicKey()); | |
} | |
} | |
} | |
} | |
} | |
throw new KeySelectorException("No X509Certificate found!"); | |
} | |
} | |
private static class SimpleKeySelectorResult implements KeySelectorResult { | |
private PublicKey pk; | |
SimpleKeySelectorResult(PublicKey pk) { | |
this.pk = pk; | |
} | |
public Key getKey() { | |
return pk; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment