forked from billymeltdown/cocoafob
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Gleb Dolgich
committed
Feb 28, 2009
0 parents
commit 93a4430
Showing
16 changed files
with
895 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
Generate private EC key | ||
======================= | ||
|
||
openssl ecparam -out ec.pem -name secp160k1 -genkey | ||
|
||
Write public EC key | ||
=================== | ||
|
||
openssl ec -in ecc.pem -pubout -out ecpub.pem | ||
|
||
Convert DSA private key from PEM to DER format | ||
============================================== | ||
|
||
openssl dsa -inform PEM -outform DER -in dsapriv512.pem -out dsapriv512.der | ||
|
||
Extract public key from private key | ||
=================================== | ||
|
||
openssl dsa -in dsapriv512.pem -pubout -out dsapub512.pem | ||
|
||
openssl dsa -in dsapriv512.der -pubout -out dsapub512.der -inform DER \ | ||
-outform DER | ||
|
||
Credits | ||
======= | ||
|
||
The Base32 implementation is Copyright (C) 2007 by Samuel Tesla and comes from | ||
Ruby base32 gem: http://rubyforge.org/projects/base32/. Samuel Tesla's blog is | ||
at http://blog.alieniloquent.com/tag/base32/. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// | ||
// NSData+PECrypt.h | ||
// pxlic | ||
// | ||
// Created by Gleb Dolgich on 09/02/2009. | ||
// Copyright 2009 PixelEspresso. All rights reserved. | ||
// | ||
|
||
#import <Foundation/Foundation.h> | ||
|
||
|
||
@interface NSData (PECrypt) | ||
|
||
- (NSString *)base32; | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// | ||
// NSData+PECrypt.m | ||
// pxlic | ||
// | ||
// Created by Gleb Dolgich on 09/02/2009. | ||
// Copyright 2009 PixelEspresso. All rights reserved. | ||
// | ||
|
||
#import "NSData+PECrypt.h" | ||
#import "encoder.h" | ||
|
||
|
||
@implementation NSData (PECrypt) | ||
|
||
- (NSString *)base32 { | ||
if (![self length]) | ||
return @""; | ||
size_t bufsize = base32_encoder_buffer_size([self length]); | ||
char *buf = malloc(bufsize); | ||
if (!buf) | ||
return @""; | ||
base32_encode((uint8_t *)buf, bufsize, [self bytes], [self length]); | ||
NSString *s = [NSString stringWithCString:buf length:bufsize]; | ||
free(buf); | ||
return s; | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// | ||
// NSString+PXCrypt.h | ||
// pxlic | ||
// | ||
// Created by Gleb Dolgich on 09/02/2009. | ||
// Follow me on Twitter @gbd. | ||
// Copyright 2009 PixelEspresso. All rights reserved. | ||
// | ||
|
||
#import <Foundation/Foundation.h> | ||
|
||
@interface NSString (PXCrypt) | ||
- (NSData *)sha1; | ||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// | ||
// NSString+PXCrypt.m | ||
// pxlic | ||
// | ||
// Created by Gleb on 09/02/2009. | ||
// Copyright 2009 Gleb Dolgich. All rights reserved. | ||
// | ||
|
||
#import "NSString+PECrypt.h" | ||
#import <openssl/sha.h> | ||
|
||
@implementation NSString (PXCrypt) | ||
|
||
- (NSData *)sha1 { | ||
const int DIGEST_LEN = 20; | ||
unsigned char *buf = malloc(DIGEST_LEN); | ||
const char *str = [self UTF8String]; | ||
size_t len = strlen(str); | ||
unsigned char *p = SHA1((unsigned char *)str, len, buf); | ||
if (!p) { | ||
free(buf); | ||
return nil; | ||
} | ||
NSData *digest = [NSData dataWithBytes:buf length:DIGEST_LEN]; | ||
free(buf); | ||
return digest; | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// | ||
// PxLicGenerator.h | ||
// pxlic | ||
// | ||
// Created by Gleb Dolgich on 09/02/2009. | ||
// Follow me on Twitter @gbd. | ||
// Copyright 2009 PixelEspresso. All rights reserved. | ||
// | ||
|
||
#import <Foundation/Foundation.h> | ||
#import <openssl/dsa.h> | ||
|
||
@interface PxLicGenerator : NSObject { | ||
DSA *dsa; | ||
NSString *regName; | ||
NSString *regKey; | ||
NSString *lastError; | ||
} | ||
|
||
@property (nonatomic, copy) NSString *regName; | ||
@property (nonatomic, copy) NSString *regKey; | ||
@property (nonatomic, copy) NSString *lastError; | ||
|
||
+ (id)generatorWithPrivateKey:(NSString *)privKey; | ||
|
||
- (id)initWithPrivateKey:(NSString *)privKey; | ||
- (BOOL)setPrivateKey:(NSString *)privKey; | ||
- (BOOL)generate; | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
// | ||
// PxLicGenerator.m | ||
// pxlic | ||
// | ||
// Created by Gleb Dolgich on 09/02/2009. | ||
// Follow me on Twitter @gbd. | ||
// Copyright 2009 PixelEspresso. All rights reserved. | ||
// | ||
|
||
#import "NSData+PECrypt.h" | ||
#import "NSString+PECrypt.h" | ||
#import "PxLicGenerator.h" | ||
#import <openssl/evp.h> | ||
#import <openssl/err.h> | ||
#import <openssl/pem.h> | ||
|
||
|
||
@interface PxLicGenerator () | ||
- (void)initOpenSSL; | ||
- (void)shutdownOpenSSL; | ||
@end | ||
|
||
|
||
@implementation PxLicGenerator | ||
|
||
@synthesize regName; | ||
@synthesize regKey; | ||
@synthesize lastError; | ||
|
||
#pragma mark - | ||
#pragma mark Class methods | ||
|
||
+ (id)generatorWithPrivateKey:(NSString *)privKey { | ||
return [[[PxLicGenerator alloc] initWithPrivateKey:privKey] autorelease]; | ||
} | ||
|
||
#pragma mark - | ||
#pragma mark Lifecycle | ||
|
||
- (id)init { | ||
return [self initWithPrivateKey:nil]; | ||
} | ||
|
||
- (id)initWithPrivateKey:(NSString *)privKey { | ||
if (![super init]) | ||
return nil; | ||
[self initOpenSSL]; | ||
[self setPrivateKey:privKey]; | ||
return self; | ||
} | ||
|
||
- (void)dealloc { | ||
if (dsa) | ||
DSA_free(dsa); | ||
self.regKey = nil; | ||
self.regName = nil; | ||
self.lastError = nil; | ||
[self shutdownOpenSSL]; | ||
[super dealloc]; | ||
} | ||
|
||
#pragma mark - | ||
#pragma mark API | ||
|
||
- (BOOL)setPrivateKey:(NSString *)privKey { | ||
// Validate the argument. | ||
if (!privKey || ![privKey length]) { | ||
self.lastError = @"Invalid key"; | ||
return NO; | ||
} | ||
if (dsa) | ||
DSA_free(dsa); | ||
dsa = DSA_new(); | ||
// Prepare BIO to read PEM-encoded private key from memory. | ||
// Prepare buffer given NSString. | ||
const char *privkeyCString = [privKey UTF8String]; | ||
BIO *bio = BIO_new_mem_buf((void *)privkeyCString, -1); | ||
PEM_read_bio_DSAPrivateKey(bio, &dsa, NULL, NULL); | ||
BOOL result = YES; | ||
if (!dsa->priv_key) { | ||
self.lastError = @"Unable to decode key"; | ||
result = NO; | ||
} | ||
// Cleanup BIO | ||
BIO_vfree(bio); | ||
return result; | ||
} | ||
|
||
- (BOOL)generate { | ||
if (!regName || ![regName length] || !dsa || !dsa->priv_key) | ||
return NO; | ||
NSData *digest = [regName sha1]; | ||
unsigned int siglen; | ||
unsigned char sig[100]; | ||
int check = DSA_sign(NID_sha1, [digest bytes], [digest length], sig, &siglen, dsa); | ||
if (!check) { | ||
self.lastError = @"Signing failed"; | ||
return NO; | ||
} | ||
// Encode signature in Base32 | ||
NSData *signature = [NSData dataWithBytes:sig length:siglen]; | ||
NSString *b32Orig = [signature base32]; | ||
if (!b32Orig || ![b32Orig length]) { | ||
self.lastError = @"Unable to encode in base32"; | ||
return NO; | ||
} | ||
// Replace Os with 8s and Is with 9s | ||
NSString *replacedOWith8 = [b32Orig stringByReplacingOccurrencesOfString:@"O" withString:@"8"]; | ||
NSString *b32 = [replacedOWith8 stringByReplacingOccurrencesOfString:@"I" withString:@"9"]; | ||
// Cut off the padding. | ||
NSString *regKeyNoPadding = [b32 stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"="]]; | ||
// Add dashes every 5 characters. | ||
NSMutableString *serial = [NSMutableString stringWithString:regKeyNoPadding]; | ||
NSUInteger index = 5; | ||
while (index < [serial length]) { | ||
[serial insertString:@"-" atIndex:index]; | ||
index += 6; | ||
} | ||
self.regKey = serial; | ||
return YES; | ||
} | ||
|
||
#pragma mark - | ||
#pragma mark OpenSSL Lifecycle | ||
|
||
- (void)initOpenSSL { | ||
OpenSSL_add_all_algorithms(); | ||
ERR_load_crypto_strings(); | ||
} | ||
|
||
- (void)shutdownOpenSSL { | ||
EVP_cleanup(); | ||
ERR_free_strings(); | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
// | ||
// PxLicVerifier.h | ||
// pxlic | ||
// | ||
// Created by Gleb Dolgich on 06/02/2009. | ||
// Follow me on Twitter @gbd. | ||
// Copyright 2009 PixelEspresso. All rights reserved. | ||
// | ||
|
||
#import <Foundation/Foundation.h> | ||
#import <openssl/dsa.h> | ||
|
||
/*! | ||
@class PxLicVerifier | ||
@superclass NSObject | ||
@abstract Verifies PxLic-style registration key. | ||
@discussion Verifies PxLic-style registration key given licensing information (application name, user name, and number of copies as suggested in Potion Store) and signature in human-readable format. A signature is a base32-encoded bignum with padding removed and dashes inserted. | ||
*/ | ||
@interface PxLicVerifier : NSObject { | ||
DSA *dsa; | ||
NSString *regName; | ||
NSString *regKey; | ||
NSArray *blacklist; | ||
NSString *lastError; | ||
} | ||
|
||
@property (nonatomic, copy) NSString *regName; | ||
@property (nonatomic, copy) NSString *regKey; | ||
@property (nonatomic, retain) NSArray *blacklist; | ||
@property (nonatomic, copy) NSString *lastError; | ||
|
||
/*! | ||
@method verifierWithPublicKey: | ||
@abstract Creates a new PxLic verifier object given a DSA public key. | ||
@discussion Creates a new PxLic verifier object. Use setRegName: and setRegKey: on it, then call verify to verify registration key. | ||
@param pubKey A DSA public key in PEM encoding. See completePublicKeyPEM: for help on how to construct a PEM-encoded DSA public key. | ||
@result A new autoreleased PxLic verifier object. | ||
*/ | ||
+ (id)verifierWithPublicKey:(NSString *)pubKey; | ||
|
||
/*! | ||
@method completePublicKeyPEM: | ||
@abstract Adds header and footer to incomplete PEM text. | ||
@discussion When storing a hard-coded PEM-encoded key in the application source, precautions are needed against easy replacement of the key. One way is to construct the key's PEM encoding step by step, appending each line to a mutable string until the base64-encoded part of the key is complete. You can then pass the base64-encoded key to this function and get complete PEM-encoded key as the result, with BEGIN and END lines added. | ||
@param partialPEM Base64-encoded part of the PEM key without BEGIN or END lines. | ||
@result An autoreleased string containing complete PEM-encoded DSA public key. | ||
*/ | ||
+ (NSString *)completePublicKeyPEM:(NSString *)partialPEM; | ||
|
||
/*! | ||
@method initWithPublicKey: | ||
@abstract Designated initialiser. | ||
@discussion Initialises a newly allocated PxLicVerifier object with a PEM-encoded DSA public key. | ||
@param pubKey A PEM-encoded DSA public key. See completePublicKeyPEM: for help on how to constuct a PEM-encoded DSA key string from base64-encoded lines. | ||
@result An initialised PxLicVerifier object. | ||
*/ | ||
- (id)initWithPublicKey:(NSString *)pubKey; | ||
|
||
/*! | ||
@method setPubKey: | ||
@abstract Sets DSA public key to the passed key in PEM format. | ||
@discussion Sets DSA public key in the verifier object to the argument which is a PEM-encoded DSA public key. | ||
@param pubKey PEM-encoded DSA public key. | ||
@result YES on success, NO on error (check lastError property). | ||
*/ | ||
- (BOOL)setPublicKey:(NSString *)pubKey; | ||
- (BOOL)verify; | ||
|
||
@end |
Oops, something went wrong.