Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Gleb Dolgich committed Feb 28, 2009
0 parents commit 93a4430
Show file tree
Hide file tree
Showing 16 changed files with 895 additions and 0 deletions.
29 changes: 29 additions & 0 deletions README.txt
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/.
16 changes: 16 additions & 0 deletions objc/NSData+PECrypt.h
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
28 changes: 28 additions & 0 deletions objc/NSData+PECrypt.m
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
14 changes: 14 additions & 0 deletions objc/NSString+PECrypt.h
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
29 changes: 29 additions & 0 deletions objc/NSString+PECrypt.m
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
30 changes: 30 additions & 0 deletions objc/PxLicGenerator.h
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
136 changes: 136 additions & 0 deletions objc/PxLicGenerator.m
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
69 changes: 69 additions & 0 deletions objc/PxLicVerifier.h
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
Loading

0 comments on commit 93a4430

Please sign in to comment.