Skip to content

Instantly share code, notes, and snippets.

@dayglojesus
Created August 4, 2012 17:41
Show Gist options
  • Save dayglojesus/3258901 to your computer and use it in GitHub Desktop.
Save dayglojesus/3258901 to your computer and use it in GitHub Desktop.
Password class for DSLocalRrecord
require 'pp'
require 'osx/cocoa'
include OSX
class DSLocalPassword
attr_reader :content
@@macosx_major_version = 10.7
@@password_create_methods = {
'PLAINTEXT' => :password_plain,
'SHA1' => :password_plain,
'SALTED-SHA512' => :password_salted_sha512,
'SALTED-SHA512-PBKDF2' => :password_salted_sha512_pbkdf2,
}
def initialize(args)
@label = args[:label]
@content = self.send(@@password_create_methods[@label].to_sym, args)
end
private
def password_salted_sha512(args)
data = encode_hex_to_nsdata(args[:hash])
serialize_shadow_hash_data(args[:label], data)
end
def password_salted_sha512_pbkdf2(args)
label = args[:label]
data = NSMutableDictionary.new
# This is going to sound crazy, but I think the order in which these
# keys are added to dict matters. If I add 'iterations' before the others,
# after the dict is serialized, it fails the equality test. Very bizarre.
data["entropy"] = encode_hex_to_nsdata(args[:entropy])
data["salt"] = encode_hex_to_nsdata(args[:salt])
data["iterations"] = args[:iterations]
serialize_shadow_hash_data(label, data)
end
# Convert hex string to ASCII
def convert_hex_to_ascii(hex)
hex.scan(/../).collect { |byte| byte.hex.chr }.join
end
def encode_hex_to_nsdata(hex)
ascii = convert_hex_to_ascii(hex)
data = NSData.alloc.initWithBytes_length_(ascii, ascii.length)
end
# Returns PropertyList
def serialize_shadow_hash_data(label, data)
plist = NSMutableDictionary.new
plist[label] = data
NSPropertyListSerialization.objc_send(
:dataFromPropertyList, plist,
:format, NSPropertyListBinaryFormat_v1_0,
:errorDescription, nil
)
end
# The salted SHA1 hash starts at character 169, and is 48 characters long:
# The first 8 characters are the hex value of a 4-byte salt.
end
# Password.new(:label => 'SALTED-SHA512', :foo => 'whatever')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment