[ create a new paste ] login | about

Link: http://codepad.org/aBIMTr0D    [ raw code | fork ]

C, pasted on Apr 6:
package com.shephertz.app42.paas.customcode.sample;


import javax.xml.crypto.*;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.crypto.dsig.keyinfo.*;

import java.io.FileInputStream;
import java.security.*;
import java.util.Iterator;
import java.util.List;

import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

//http://stackoverflow.com/questions/20877563/how-to-validate-windows-phone-in-app-purchase-with-java-on-server-side
//http://stackoverflow.com/questions/11985618/how-do-we-verify-windows-8-in-app-billing-receipt-on-the-server-side
//https://social.msdn.microsoft.com/forums/windowsapps/en-US/853f0713-b6e5-44c3-8131-aad136b81374/inapp-purchase-serverside-receipt-verification
//https://msdn.microsoft.com/library/windows/apps/jj206949(v=vs.105).aspx
//http://webservices20.blogspot.com/2013/06/validating-windows-mobile-app-store.html
  
 

public class SecurityWindowsPhone 
{
	
	public static boolean VerifyPurchase(String signedData) throws Exception
	{
		//Instantiate the document to be validated
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        Document doc = dbf.newDocumentBuilder().parse(new FileInputStream(signedData));

        // Find Signature element
        NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
        if (nl.getLength() == 0) 
        {
        	Log.Sev1("Windows Phone. Cannot find Signature element.");
            return false;
        }

        // Create a DOM XMLSignatureFactory that will be used to unmarshal the
        // document containing the XMLSignature
        XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");

        // Create a DOMValidateContext and specify a KeyValue KeySelector
        // and document context
          DOMValidateContext valContext = new DOMValidateContext(new KeyValueKeySelector(), nl.item(0));

        // unmarshal the XMLSignature
        XMLSignature signature = fac.unmarshalXMLSignature(valContext);

        // Validate the XMLSignature (generated above)
        boolean coreValidity = signature.validate(valContext);

        // Check core validation status
        if (coreValidity == false) 
        {
            Log.Sev1("Signature failed core validation");            
            boolean sv = signature.getSignatureValue().validate(valContext);
            Log.Sev1("signature validation status: " + sv);
            
            // check the validation status of each Reference
            Iterator i = signature.getSignedInfo().getReferences().iterator();
            for (int j=0; i.hasNext(); j++) 
            {
                boolean refValid = ((Reference) i.next()).validate(valContext);
                Log.Sev1("ref["+j+"] validity status: " + refValid);
            }
        } 
        else
        {
        	return true;
        }
        
        return false;
	}
		
    private static class KeyValueKeySelector extends KeySelector 
    {
        public KeySelectorResult select(KeyInfo keyInfo, KeySelector.Purpose purpose, AlgorithmMethod method, XMLCryptoContext context)
        {
            if (keyInfo == null) 
            {
            	Log.Sev1("Null KeyInfo object!");
                return null;
            }
            
            SignatureMethod sm = (SignatureMethod) method;   
            
            List list = keyInfo.getContent();
            
            for (int i = 0; i < list.size(); i++) 
            {
                XMLStructure xmlStructure = (XMLStructure) list.get(i);
                if (xmlStructure instanceof KeyValue) 
                {
                    PublicKey pk = null;
                    try 
                    {
                        pk = ((KeyValue)xmlStructure).getPublicKey();
                    } 
                    catch (KeyException ke)
                    {
                    	Log.Sev1("KeyException");
                        return null;
                    }
                    // make sure algorithm is compatible with method
                    if (algEquals(sm.getAlgorithm(), pk.getAlgorithm())) 
                    {
                        return new SimpleKeySelectorResult(pk);
                    }
                }
            }            
            
            Log.Sev1("No KeyValue element found!");
            return null;
        }

        //@@@FIXME: this should also work for key types other than DSA/RSA
        static boolean algEquals(String algURI, String algName)
        {
            if (algName.equalsIgnoreCase("DSA") && algURI.equalsIgnoreCase(SignatureMethod.DSA_SHA1)) 
            {
                return true;
            } 
            else if (algName.equalsIgnoreCase("RSA") && algURI.equalsIgnoreCase(SignatureMethod.RSA_SHA1))
            {
                return true;
            } 
            else 
            {
                return false;
            }
        }
	}

    private static class SimpleKeySelectorResult implements KeySelectorResult 
    {
        private PublicKey pk;
        
        SimpleKeySelectorResult(PublicKey pk)
        {
            this.pk = pk;
        }

        public Key getKey() 
        {
        	return pk; 
        }
    }    
}


Create a new paste based on this one


Comments: