XML Digitial Security - Hmac_SHA1 - digital-signature

I need to create a digest value for the below input
<u:Timestamp u:Id="_0" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<u:Created>2015-07-28T13:35:54Z</u:Created>
<u:Expires>2015-07-28T13:40:49Z</u:Expires>
</u:Timestamp>
so am passing the above value as a doc obj to the below code
public static void main(String[] args) throws Exception {
// Create a DOM XMLSignatureFactory that will be used to generate the
// enveloped signature
XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
SecretKey signingKey = new SecretKeySpec("welcome1".getBytes(), "HMAC");
// Create a Reference to the enveloped document (in this case we are
// signing the whole document, so a URI of "" signifies that) and
// also specify the SHA1 digest algorithm and the ENVELOPED Transform.
Reference ref = fac.newReference
("#_0", fac.newDigestMethod(DigestMethod.SHA1, null),
Collections.singletonList
(fac.newTransform
("http://www.w3.org/2001/10/xml-exc-c14n#", (TransformParameterSpec) null)),
null, null);
// Create the SignedInfo
SignedInfo si = fac.newSignedInfo
(fac.newCanonicalizationMethod
(CanonicalizationMethod.EXCLUSIVE,
(C14NMethodParameterSpec) null),
fac.newSignatureMethod(SignatureMethod.HMAC_SHA1, null),
Collections.singletonList(ref));
// Instantiate the document to be signed
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc =
dbf.newDocumentBuilder().parse(new FileInputStream("C:/Users/Signed_Encryp/timestamp.txt"));
// Create a DOMSignContext and specify the DSA PrivateKey and
// location of the resulting XMLSignature's parent element
DOMSignContext dsc = new DOMSignContext
(signingKey, doc.getDocumentElement());
// Create the XMLSignature (but don't sign it yet)
XMLSignature signature = fac.newXMLSignature(si, null);
// Marshal, generate (and sign) the enveloped signature
signature.sign(dsc);
// output the resulting document
OutputStream os;
if (args.length > 1) {
os = new FileOutputStream(args[1]);
} else {
os = System.out;
}
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.transform(new DOMSource(doc), new StreamResult(os));
}
which returning me a result as
<u:Timestamp xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" u:Id="_0">
<u:Created>2015-07-28T13:35:54Z</u:Created>
<u:Expires>2015-07-28T13:40:49Z</u:Expires>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#hmac-sha1"/>
<ds:Reference URI="#_0">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>1X/3X+yCdJc0x3n8guQnlCFvX+s=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>R4ZrHvlvyGvvQYpojZWPgUgRRSw=</ds:SignatureValue>
</ds:Signature>
</u:Timestamp>
here am not confident that digest value is created using the input am passed, also signature is created inside the timestamp tag , is there any option available to create signature tag after the timestamp tag.
Please help

To check if the signature is over the data, simply change the data and use the same key. If the HMAC value changes then the hash clearly is over the data. When changing back it should return to the old value. Note that this is true for HMAC-SHA1, it may not be the case for all primitives (e.g. RSA-PSS).
Alternatively, if you're up to it, you can perform the canonicalization yourself and manually calculate the signature. Or try another implementation.
If u:Timestamp is the root element then you cannot put anything next to it, as XML only has a single root element. You have yourself indicated that the signature is placed at doc.getDocumentElement(). You can however create a detached signature. Now you know how it is called, you should be able to search for it.

Related

How to restrict/write a validation code just for impex?

I want to know if it is a way to trigger my Validation Code just for impex. What I mean is that my Code should validate a new Product created through Impex (not through backoffice). Here is my Code:
#Override
public void onValidate(final Object o, final InterceptorContext ctx) throws InterceptorException
if (o instanceof ProductModel)
{
final ProductModel product = (ProductModel) o;
if (ctx.isNew(product))
{
final String manufacturerName = enumerationService.getEnumerationName(product.getManufacturerName()); // if ManufacturerName is Null enumerationService throw "Parameter plainEnum must not be null!"
final String code = product.getCode().toString();
final String manufacturerProductId = product.getManufacturerProductId();
final int a = productLookupService.getProduct(code, manufacturerName, manufacturerProductId);
switch (a)
{
case 1:
throw new InterceptorException("Product already in ProductLookup");
case 2:
throw new InterceptorException(
"There are more than one product with the same " + code + " number in ProductLookup !");
default:
}
}
}
My Problem is that in BackOffice when I create a new Product I don´t have manufacturerName and manufacturerProductId fields.
Thanks! and sorry if I said something wrong, I am new in this :)
You said that "In BackOffice when i create a new Product i don´t have manufacturerName and manufacturerProductId fields".
This can also be the case for Impex. Most probably the impex you are using is specifying those two attributes now and that is why there is no problem.
If you want, you can make this two attributes mandatory and then nobody will be able to create a product without specifying the manufacturerName ad the manufacturerProductId.
I also believe that the backOffice will update to also include these two attributes during creation since they are mandatory.
You can specify that an attribute is mandatory in your {extensionName}-items.xml(under your type definition) using the optional flag like below:
<attribute qualifier="manufacturerProductId" type="String">
<persistence type="property"/>
<modifiers optional="false"/>
</attribute>
If these two attributes are not mandatory, you have to consider the case when a product will be created without having them(like your current backOffice situation).
However your Interceptor should take into consideration both cases (when you have these attributes specified during creation and when you don't)
Because of this you can edit your code to verify whether this two attributes are null or not before using them. You can add this right before trying to get the manufacturerName:
if (product.getManufacturerName() == null || product.getManufacturerProductId() == null) {
return;
}

Monotouch - Error setting AVAssetWriterInput - unrecognized selector sent to instance

When I try to set the audio configuration writer input I'm getting an error:
-[__NSCFNumber length]: unrecognized selector sent to instance 0xbcdab0
My code:
NSObject[] values = new NSObject[]
{
NSNumber.FromFloat(44100.0f),
NSNumber.FromInt32((int)MonoTouch.AudioToolbox.AudioFormatType.MPEG4AAC),
NSNumber.FromInt32(2),
NSNumber.FromInt32((int)AVAudioQuality.Medium)
};
//Set up the NSObject Array of keys that will be combined with the values to make the NSDictionary
NSObject[] keys = new NSObject[]
{
AVAudioSettings.AVSampleRateKey,
AVAudioSettings.AVFormatIDKey,
AVAudioSettings.AVNumberOfChannelsKey,
AVAudioSettings.AVChannelLayoutKey
};
//Set Settings with the Values and Keys to create the NSDictionary
NSDictionary audiosettings = NSDictionary.FromObjectsAndKeys (values, keys);
writeraudioInput = new AVAssetWriterInput (AVMediaType.Audio, audiosettings);
Seems like you're setting key to AVChannelLayoutKey and value to type of AVAudioQuality. They're no corresponding to each other. AVChannelLayoutKey's value should contant struct of AudioChannelLayout.
Comment both last key and last values. Or fill and pass AudioChannelLayout structure.
You are using the loosely typed NSDictionary-based API.
You could avoid these errors in the future if you use the other constructor that takes an AudioSettings parameter, which conveniently provides intellisense for you.

SignedXml.CheckSignature(key) always throws error

I am new to C#.NET programming. With help of online references, I have written the code below to verify signature of a SAML assertion (generated by a server API).
My Env:
VS 2010 Ver4.0
Win XP SP3
SAML Assertion token looks something like this:*
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Version="2.0" ID="idGYEv...USb8GfnqF" IssueInstant="2012-12-05T14:13:39.00Z">
<saml:Issuer Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">http://noszti...xyz.com</saml:Issuer>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>uDeAjOE/iCa6Pfz5oOjaOMtAQe4=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>IGjZX...LaEMzA=</SignatureValue>
<KeyInfo>
<X509Data>
<X509Certificate>MIIE...cg6A==</X509Certificate>
<X509SubjectName>emailAddress=xmlsec#aleksey.com,CN=Aleksey Sanin,OU=Test Root Certificate,O=XML Security Library (http://www.aleksey.com/xmlsec),ST=California,C=US</X509SubjectName>
</X509Data>
</KeyInfo>
</Signature>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">admin</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData NotOnOrAfter="2012-12-05T14:19:39.00Z" Recipient=""/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2012-12-05T14:13:39.00Z" NotOnOrAfter="2012-12-05T14:19:39.00Z">
<saml:AudienceRestriction>
<saml:Audience/>
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2012-12-05T14:13:39.00Z">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
</saml:Assertion>
My code snippet to verify signature:
//Load the SAMLAssertionToken in XML Document
XmlDocument xDoc = new XmlDocument();
xDoc.PreserveWhitespace = false;
xDoc.LoadXml(SAMLAssertionToken); //SAMLAssertionToken above
//Retrieve the public key from certificate available to end user
X509Certificate2 X509Cert = new X509Certificate2("D:/Schemas/X509Certificate.cer");
RSACryptoServiceProvider rsaKey = (RSACryptoServiceProvider)X509Cert.PublicKey.Key;
//Signature Verification Starts. Find the Signature element
XmlNamespaceManager xMan = new XmlNamespaceManager(xDoc.NameTable);
xMan.AddNamespace("ns", "urn:oasis:names:tc:SAML:2.0:assertion");
xMan.AddNamespace("ns1", "http://www.w3.org/2000/09/xmldsig#");
XmlElement SigElm = (XmlElement)xDoc.SelectSingleNode("//ns:Assertion//ns1:Signature", xMan);
//Create SignedXml object and load signature for verification
SignedXml sig = new SignedXml(xDoc);
sig.LoadXml(SigElm);
bool verified = sig.CheckSignature(rsaKey);
if (verified)
{
Console.WriteLine("Signature verified successfully");
}
else
{
Console.WriteLine("Signature not valid");
}
On running the code, it throws an error "SignatureDescription could not be created for the signature algorithm supplied."
on line: bool verified = sig.CheckSignature(rsaKey);
On debugging, Signature is correctly assigned to SigElm.
Note: the certificate retrieved from "X509Certificate.cer" is exactly the same as that displayed in element of the signature (in SAML Assertion). So it looks like a valid and matching certificate. The certificate in SAML assertion token is signed with a private key; so I am using the public key from "X509Certificate.cer" (certificate available to end users) to verify the signature (in SAML assertion).
I also tried to verify the signature using:
bool verified = sig.CheckSignature(X509Cert, true);
but it throws the same error.
I tried few approaches (using online references for this error) but unable to figure out the problem.
Pls advise...

Programmatically obtain Storage Space Allocation - Lists

I am tasked with writing a report that pulls data out of a the "Storage Space Allocation" section within various SharePoint sites. I am able to screen scrape the general "Document Libraries" values by performing a general GET call, but I cannot programmatically obtain the "Lists" values. When I navigate to the SharePoint site (*/_layouts/storman.aspx) "Document Libraries" is the default selection. I think I need to send a POST call in order to change it to "Lists" [then I can scrape the values]. Creating the appropriate POST call is becomine a hassle because SharePoint does not seem to recognize my key/value pair (or maybe I'm not supplying all of the necessary parameters?).
I tried this code, but no luck - only the "Document Libraries" data is returned.
using (System.Net.WebClient client = new System.Net.WebClient() { UseDefaultCredentials = true })
{
NameValueCollection myQueryStringCollection = new NameValueCollection();
myQueryStringCollection.Add(queryParameterName, queryParameterValue);
client.QueryString = myQueryStringCollection;
return client.DownloadString(url);
}
I also tried this (alongside other ideas):
private static string GetWebResponse(string url, NameValueCollection parameters)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.UseDefaultCredentials = true;
httpWebRequest.ContentType = "application/x-www-form-urlencoded";
httpWebRequest.Method = "POST";
var sb = new StringBuilder();
foreach (var key in parameters.AllKeys)
sb.Append(key + "=" + parameters[key] + "&");
sb.Length = sb.Length - 1;
byte[] requestBytes = Encoding.UTF8.GetBytes(sb.ToString());
httpWebRequest.ContentLength = requestBytes.Length;
using (var requestStream = httpWebRequest.GetRequestStream())
{
requestStream.Write(requestBytes, 0, requestBytes.Length);
requestStream.Close();
}
Task<WebResponse> responseTask = Task.Factory.FromAsync<WebResponse>(httpWebRequest.BeginGetResponse, httpWebRequest.EndGetResponse, null);
using (var responseStream = responseTask.Result.GetResponseStream())
{
var reader = new StreamReader(responseStream);
return reader.ReadToEnd();
}
}
Viewing the source code of the _layouts/storman.aspx page, I can see the name/value pair i need to send is ct100$PlaceHolderMain$m_filterDropdown and Lists respectively. I determined this by this view source code:
<select name="ctl00$PlaceHolderMain$m_filterDropdown" id="ctl00_PlaceHolderMain_m_filterDropdown" class="ms-viewselect">
<option selected="selected" value="Document Libraries">Document Libraries</option>
<option value="Documents">Documents</option>
<option value="Lists">Lists</option>
<option value="Recycle Bin">Recycle Bin</option>
</select>
Any ideas on how to get the List values from this page?
I finally figured this out...
I have to send every name/value query parameter pair that SharePoint is expecting. To complicate matters, I must first perform a GET request in order to obtain the __REQUESTDIGEST, __VIEWSTATE, __EVENTVALIDATION values that SharePoint is expecting. Also, all parameters must be UrlEncoded when I send them back to SharePoint.

Unboundid LDAP domain attributes

I need to evaluate an user's password expiration time against an Active Directory.
I'm using Android and Unboundid sdk. I can successfully connect to server using this code
final SocketFactory _socket_factory;
final SSLUtil _ssl_util = new SSLUtil(new TrustAllTrustManager());
try {
_socket_factory = _ssl_util.createSSLSocketFactory();
}
catch (Exception e) {
Log.e(LOG_TAG, "*** Unable to initialize ssl", e);
return null;
}
LDAPConnectionOptions _ldap_connection_options = new LDAPConnectionOptions();
_ldap_connection_options.setAutoReconnect(true);
_ldap_connection_options.setConnectTimeoutMillis(30000);
_ldap_connection_options.setFollowReferrals(false);
_ldap_connection_options.setMaxMessageSize(1024*1024);
LDAPConnection _ldap_connection = new LDAPConnection(_socket_factory, _ldap_connection_options, _host, _port);
BindRequest _bind_request = new SimpleBindRequest(_username, _password);
BindResult _bind_result = _ldap_connection.bind(_bind_request);
I retreive user attributes using a search
Filter _filter = Filter.create("(userPrincipalName=lorenzoff)");
SearchRequest _search_request = new SearchRequest(_server._base_dn, SearchScope.SUB, _filter);
But how can I read the domain's attribute 'maxPwdAge'? I can see it in among the domain attributes...
I need it to evaluate the remaining days until user's password expires.
I had the same issue and found a solution. the idea is simple you have to access the base DN and get that attribute:
SearchRequest _search_request = new SearchRequest(_server._base_dn,
SearchScope.BASE, "(objectClass=*)","maxPwdAge");
with this you should get the result with that attribute, if you get SearchRequest.ALL_USER_ATTRIBUTES you will have all the attributes shown on your screenshot.
That attribute is common for all users, the next thing you need to do is to search your specific user as you where doing before an get the attribute pwdLastSet, as you would expect it has the timestamp of the last time the user changed his password.
now is simple, you need to find the expiration date with the last time the user change it, and the password age
hope it helps
If maxPwdAge is an "operational" attribute, it must be explicitly requested as part of your search request. "User" attributes are returned (as permissions permit), but "operational" attributes must be explicitly requested. To request maxPwdAge create your request as follows:
SearchRequest _search_request = new SearchRequest(_server._base_dn,
SearchScope.SUB, _filter,"maxPwdAge");
The SeachRequest constructor actually accepts a variable length list of attribute types also:
SearchRequest _search_request = new SearchRequest(_server._base_dn,
SearchScope.SUB,_filter,"maxPwdAge","minPwdAge",
SearchRequest.ALL_USER_ATTRIBUTES);
requests maxPwdAge, minPwdAge, and all other user attributes. To request all operational attributes, use SearchRequest.ALL_OPERATIONAL_ATTRIBUTES.

Resources