Archive for July 28, 2017

Friday, July 28, 2017

A Binary Coder for Swift

Mike Ash:

This coder serializes fields by writing them out sequentially as raw bytes, with no metadata.

[…]

Now we can see why I implemented BinaryEncoder’s encode method with a big switch statement instead of using separate implementations for all of the various supported types. Overloaded methods are resolved at compile time based on the static type that’s available at the call site. The above call to encoder.encode(value) will always call func encode(_ encodable: Encodable) even if the actual value passed in is, say, a Double or a Bool. In order to allow for this simple wrapper, the implementation in BinaryEncoder has to work with a single entry point, which means it needs to be a big switch statement.

[…]

Swift’s new Codable protocols are a welcome addition to the language to eliminate a lot of boilerplate code. It’s flexible enough to make it straightforward to use/abuse it for things well beyond JSON and property list parsing. Unsophisticated binary formats such as this are not often called for, but they have their uses, and it’s interesting to see how Codable can be used for something so different from the built-in facilities. The Encoder and Decoder protocols are large, but judicious use of generics can cut down a lot of the repetitive code, and implementation is relatively simple in the end.

See also: HashingSingleValueEncodingContainer, MinimalDecoder (via Stephen Celis).

Previously: Swift.Codable.

Update (2017-07-31): See also: Hacker News.

Arc Hub USB-C Adapter

Jeff Geerling:

So when I saw the Arc Hub’s specs, I thought it was finally the hub to end all hubs—4K at 60 Hz over Mini DisplayPort, plus a UHS-I-ish SD card reader, and HDMI port, two USB 3.0 type A ports, and a USB-C plug for up to 85W power delivery? I’m in!

[…]

I was excited the day the Hub arrived, because it would be the first day in my life I could plug but one cable into my Mac and have full charging and connectivity. It’s the dream we’ve all had since the first time we saw a PowerBook Duo Dock! No more dealing with a tangle of cables any time you wanted to grab your laptop and go, or when you set it back on/in your desk!

Well, the excitement kind of died down once I tested both of my two Mini DisplayPort cables, as well as two HDMI 2.0-rated cables. None of them offered me a full 60 Hz refresh rate!

Apple’s Photos App and Lens Correction

Kirk McElhearn:

If you shoot RAW files, many apps that process these files can also apply lens correction, using metadata stored with the files, to create better images. In some cases, this can even be using a huge database of information about lenses and cameras.

It’s interesting to know that Apple’s Photos app also applies lens correction, yet doesn’t tell you anything about it. This lens correction is not only applied in the Photos app, but also within macOS; if you have a RAW file and view it using Quick Look (select the file and press the space bar), lens correction is applied.

[…]

Here is a good explanation of these types of distortion, with a number of images showing how each one presents in photos.

Update (2017-07-31): Nick Heer:

For what it’s worth, I’ve found that the automatic preprocessing done in Photos is less visually pleasing than that in Lightroom.

Receipt Validation in Swift

Andrew Bancroft:

The aim of this guide is to help you take a look inside the PKCS #7 container, and verify the presence and authenticity of the signature on the receipt.

Andrew Bancroft:

The aim of this guide is to help you parse a receipt and decode it so that you have readable pieces of metadata to inspect and finalize all of the receipt validation steps.

[…]

In-app purchase receipts are encoded as ASN.1 Sets (with ASN.1 Sequences within) inside the primary ASN.1 Set receipt payload. In other words, they’re nested ASN.1 Sets within the overall ASN.1 Set that encodes the whole receipt. The nested Set contains the in-app purchase receipt attributes.

Update (2017-07-31): Andrew Bancroft:

The aim of this guide is to help you finalize the receipt validation process by computing the GUID hash for your app, and comparing it to the hash that’s stored within your receipt itself.

Update (2023-08-09): Felix Schwarz:

Two days ago I finally got annoyed enough with the OpenSSL dependency for App Store receipt parsing and validation that I had another shot at an ASN.1 parser.

Today I have ObjC parsers for ASN.1 and PKCS#7, signature validation through Security.framework and can drop OpenSSL from my App Store project(s). 🥳

In retrospect I wish I had found that courage earlier instead of spending a lot more time than this on getting OpenSSL to build for all the various Apple platforms and CPUs.

So much time and storage space have been collectively been wasted on this. Why couldn’t Apple have just used a plist or JSON?

Previously:

Passwords Evolved: Authentication Guidance for the Modern Era

Troy Hunt (via Hacker News):

These are simple examples but the thought process I’m trying to get going is that we can be a lot smarter than the traditional binary authentication state that still prevails in the vast majority of systems today.

[…]

In addition to the problems mentioned above, short arbitrary limits like this regularly cause people to speculate that password storage is insufficient. When cryptographically hashed, all passwords are stored with the same fixed length so an arbitrary limit such as the one above may indicate the password is stored in a plain text and the column only allows 10 characters.

[…]

What tends to happen when there are requirements around password complexity is that people first try something basic then they tweak characters until it comes up to the minimum requirement of the site.

[…]

Closely related to the use of password managers is the ability to paste passwords into the login screen. There are plenty of password managers that can auto-fill credentials, but there are occasions where either pasting is still necessary or where a service blocks a password that hasn’t been typed in character by character (easily identified with a bit of JavaScript).

[…]

Let’s think through the rationale of this approach for a moment: the premise of a regular password change is that should that password be compromised, forcing a change means it is no longer valid, ergo it cannot be used by malicious parties. The problem is, attackers have got up to 3 months in the example I gave earlier or in some cases, even longer[…]