Thursday, 17 August 2017

NPE in getUnmarshallerFactory() in OpenSAML 3

If you are getting NullPointerException when trying to get unmarshaller factory in OpenSAML 3, means most likely OpenSAML 3 has not been initialized. I was calling OpenSAML 3 methods in my unit test suite which gave me the below error. Call (InitializationService/initialize) to initialize the library. My main program does the initialization, so I do not get error when running, but unit test does not invoke that code path.
lein test :only com.concur.saml.saml-test/saml-response

ERROR in (saml-response) (XMLObjectProviderRegistrySupport.java:126)
Uncaught exception, not in assertion.
expected: nil
  actual: java.lang.NullPointerException: null
 at org.opensaml.core.xml.config.XMLObjectProviderRegistrySupport.getUnmarshallerFactory (XMLObjectProviderRegistrySupport.java:126)
    com.concur.saml.core$get_response.invokeStatic (core.clj:253)
    com.concur.saml.core$get_response.invoke (core.clj:249)
    com.concur.saml.saml_test$fn__7679.invokeStatic (saml_test.clj:22)
    com.concur.saml.saml_test/fn (saml_test.clj:19)
 ...
    user$eval85$fn__136.invoke (form-init5596096413821124374.clj:1)
    clojure.lang.AFn.applyToHelper (AFn.java:156)
    clojure.lang.AFn.applyTo (AFn.java:144)
    clojure.core$apply.invokeStatic (core.clj:648)
...
    clojure.lang.AFn.applyToHelper (AFn.java:156)
    clojure.lang.Var.applyTo (Var.java:700)
    clojure.main.main (main.java:37)

Ran 1 tests containing 1 assertions.
0 failures, 1 errors.
Tests failed.

Wednesday, 31 May 2017

Slide - SAML, Variants, Functors, Monads and Exceptions

A presentation I gave at work (SAP Concur) on SAML, using variants and exception handling in Clojure, functors, applicative functors and monads in Haskell and how Maybe and Either monads short circuits during exception and such. Removed some internal code and links.


The variant C code can be downloaded from Github.
Download this slide from Github.

Friday, 12 May 2017

BlackBerry Passport MicroSDXC Card Support

BlackBerry Passport supports microSD cards upto 128GB. microSDXC cards can also be used with it. However, BlackBerry 10 recognises only FAT formatted external partitions and these cards comes mostly with ExFAT. So the device will show that the media card is not supported and is downloading drivers, but it will fail with an error. To fix this, erase the card and choose FAT as the partition format. Then the OS will recognise the microSDXC card.

Monday, 8 May 2017

Get RSA PublicKey from XML Key Format

Here is a script (prototype) in Groovy to get RSA PublicKey from XML public key. You might encounter such XML keys, say during .NET interop.
import javax.xml.parsers.DocumentBuilder
import javax.xml.parsers.DocumentBuilderFactory
import org.w3c.dom.Document
import java.nio.charset.StandardCharsets
import java.security.spec.RSAPublicKeySpec
import java.security.KeyFactory
import java.security.PublicKey

def rsaPubXML = "ANxn+vSe8nIdRSy0gHkGoJQnUIIJ3WfOV7hsSk9An9LRafuZXYUMB6H5RxtWFm72f7nPKlg2N5kpqk+oEuhPx4IrnXIqnN5vwu4Sbc/w8rjE3XxcGsgXUams3wgiBJ0r1/lLCd6a61xRGtj4+Vae+Ps3mz/TdGUkDf80dVek9b9VAQAB"
def docBuilderFactory = DocumentBuilderFactory.newInstance()
def docBuilder = docBuilderFactory.newDocumentBuilder()

def b64Decode(enc) {
    Base64.getDecoder().decode(enc)
}

Document xmlDoc = docBuilder.parse(new ByteArrayInputStream(rsaPubXML.getBytes(StandardCharsets.UTF_8)))

def modulus = xmlDoc.getElementsByTagName("Modulus").item(0).textContent
def exponent = xmlDoc.getElementsByTagName("Exponent").item(0).textContent
println "modulus: ${modulus}\nexponent: ${exponent}"

RSAPublicKeySpec keySpec = new RSAPublicKeySpec(new BigInteger(b64Decode(modulus)), new BigInteger(b64Decode(exponent)));
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey key = keyFactory.generatePublic(keySpec);

println "key: ${key}"
This gives the following output.
modulus: ANxn+vSe8nIdRSy0gHkGoJQnUIIJ3WfOV7hsSk9An9LRafuZXYUMB6H5RxtWFm72f7nPKlg2N5kpqk+oEuhPx4IrnXIqnN5vwu4Sbc/w8rjE3XxcGsgXUams3wgiBJ0r1/lLCd6a61xRGtj4+Vae+Ps3mz/TdGUkDf80dVek9b9V
exponent: AQAB
key: Sun RSA public key, 1024 bits
  modulus: 154774478177095248394968828543369801032226937226535865231262824893513573019304152154974259955740337204606655133945162319470662684517274530901497375379716962851415879364453962123395223899051919634994929603613704222239797911292193776910691509004328773391280872757318122152217457361921195935350223751896771182421
  public exponent: 65537
Note that the modulus must be a positive integer. If you are working with other JVM languages and are getting a negative integer value, specify the signum as 1 in the BigInteger(1, b64Decode(modulus)) function call. The exponent must always be 65537 as of now because that is the largest Fermat's Prime known today.

Sunday, 30 April 2017

Base64 macOS App Release

Released v1.0 of Base64 macOS app. It is a simple app for encoding and decoding base64 texts. It will encode texts as we type or paste. This program does not access any files or network and works offline. It is sandboxed as well.

Encode screen

Decode screen

Source code at GitHub. For downloads, check the release folder.

Saturday, 29 April 2017

Working with AppKit Delegates

Delegates are responders that acts to events that occurs in a program. AppKit delegates often work with Cocoa UI events. Here we will see two examples of handling events, one for NSTextField and another for NSTextView in conjunction with Interface Builder, rather than programatically.

1. Create a macOS Cocoa project from Xcode which will generate an AppDelegate and a ViewController as usual.
2. We will make the ViewController as the delegate to respond to events. For that we need to declare that the ViewController adopts the formal protocol defined by the delegates.
@interface ViewController : NSViewController<NSTextViewDelegate, NSTextFieldDelegate> {
3. Choose the Main.storyboard and choose the View Controller Scene, drag and drop Text View and Text Field components.
4. Choose the Text View from the Document Outline of the View Controller Scene, option click, and in the popup, connect the delegate outlet to the View Controller. Same for Text Field.

5. Now, in the ViewController.h header, declare two IBOutlets which will connect the components in the storyboard to the code.
@interface ViewController : NSViewController<NSTextViewDelegate, NSTextFieldDelegate> {
    IBOutlet NSTextView *textView;
    IBOutlet NSTextField *textField;
}
Since these interface builder outlets are not connected yet, the radio box is in unchecked state.
6. Go back to the interface builder (the storyboard file), choose Text View, option click, drag and connect the New Referencing Outlet to View Controller which brings the above IBOutlets. Choose textView to make the connection. Do the same for Text Field, but here we should choose textField as the referencing outlet.


7. Back to code, open ViewController.m implementation file and implement any of the delegated methods.
#pragma mark - delegates

/* NSTextView */
- (void)textDidChange:(NSNotification *)notification {
    NSLog(@"text did change");
    textView = [notification object];
    NSLog(@"string: %@", [textView string]);
}

/* NSTextField */
- (void)controlTextDidChange:(NSNotification *)obj {
    NSLog(@"control text did changed");
    textField = [obj object];
    NSLog(@"text: %@", [textField stringValue]);
}
The above methods are invoked when the text in a text view or text field changes. The same concept extends to Cocoa Touch and iOS development.

The sample project can be downloaded from github.

Wednesday, 26 April 2017

Call blocking in BlackBerry 10 for a known number

We do not need fancy app to block calls. By default, BB10 has option to block all incoming calls or none. Not individually. But there is a better way. Ideally, we should not be blocking calls, because the caller can identify that a call has been blocked or not. It will ring once and then get busy or some other tones. Better way is to just disable all notifications for a number. For that, first save the annoying number to your contacts and in the "Ringtones and Notifications" option for that contact, choose "Phone Calls" and turn off "All Notifications". That is all there is. Now the call gets received, but you would not know unless you look at the phone. No disturbance.