Crypt-OpenSSL-PKCS10-0.15/0000755001050700001440000000000012561317253014666 5ustar turturicausersCrypt-OpenSSL-PKCS10-0.15/META.json0000644001050700001440000000160112561317253016305 0ustar turturicausers{ "abstract" : "Perl extension to OpenSSL's PKCS10 API.", "author" : [ "JoNO " ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.120921", "license" : [ "unknown" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "Crypt-OpenSSL-PKCS10", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "Crypt::OpenSSL::RSA" : "0" } } }, "release_status" : "stable", "version" : "0.15" } Crypt-OpenSSL-PKCS10-0.15/ppport.h0000755001050700001440000007165710364234376016411 0ustar turturicausers /* ppport.h -- Perl/Pollution/Portability Version 2.009 * * Automatically Created by Devel::PPPort on Fri Jan 20 21:24:45 2006 * * Do NOT edit this file directly! -- Edit PPPort.pm instead. * * Version 2.x, Copyright (C) 2001, Paul Marquess. * Version 1.x, Copyright (C) 1999, Kenneth Albanowski. * This code may be used and distributed under the same license as any * version of Perl. * * This version of ppport.h is designed to support operation with Perl * installations back to 5.004, and has been tested up to 5.8.1. * * If this version of ppport.h is failing during the compilation of this * module, please check if a newer version of Devel::PPPort is available * on CPAN before sending a bug report. * * If you are using the latest version of Devel::PPPort and it is failing * during compilation of this module, please send a report to perlbug@perl.com * * Include all following information: * * 1. The complete output from running "perl -V" * * 2. This file. * * 3. The name & version of the module you were trying to build. * * 4. A full log of the build that failed. * * 5. Any other information that you think could be relevant. * * * For the latest version of this code, please retreive the Devel::PPPort * module from CPAN. * */ /* * In order for a Perl extension module to be as portable as possible * across differing versions of Perl itself, certain steps need to be taken. * Including this header is the first major one, then using dTHR is all the * appropriate places and using a PL_ prefix to refer to global Perl * variables is the second. * */ /* If you use one of a few functions that were not present in earlier * versions of Perl, please add a define before the inclusion of ppport.h * for a static include, or use the GLOBAL request in a single module to * produce a global definition that can be referenced from the other * modules. * * Function: Static define: Extern define: * newCONSTSUB() NEED_newCONSTSUB NEED_newCONSTSUB_GLOBAL * */ /* To verify whether ppport.h is needed for your module, and whether any * special defines should be used, ppport.h can be run through Perl to check * your source code. Simply say: * * perl -x ppport.h *.c *.h *.xs foo/bar*.c [etc] * * The result will be a list of patches suggesting changes that should at * least be acceptable, if not necessarily the most efficient solution, or a * fix for all possible problems. It won't catch where dTHR is needed, and * doesn't attempt to account for global macro or function definitions, * nested includes, typemaps, etc. * * In order to test for the need of dTHR, please try your module under a * recent version of Perl that has threading compiled-in. * */ /* #!/usr/bin/perl @ARGV = ("*.xs") if !@ARGV; %badmacros = %funcs = %macros = (); $replace = 0; foreach () { $funcs{$1} = 1 if /Provide:\s+(\S+)/; $macros{$1} = 1 if /^#\s*define\s+([a-zA-Z0-9_]+)/; $replace = $1 if /Replace:\s+(\d+)/; $badmacros{$2}=$1 if $replace and /^#\s*define\s+([a-zA-Z0-9_]+).*?\s+([a-zA-Z0-9_]+)/; $badmacros{$1}=$2 if /Replace (\S+) with (\S+)/; } foreach $filename (map(glob($_),@ARGV)) { unless (open(IN, "<$filename")) { warn "Unable to read from $file: $!\n"; next; } print "Scanning $filename...\n"; $c = ""; while () { $c .= $_; } close(IN); $need_include = 0; %add_func = (); $changes = 0; $has_include = ($c =~ /#.*include.*ppport/m); foreach $func (keys %funcs) { if ($c =~ /#.*define.*\bNEED_$func(_GLOBAL)?\b/m) { if ($c !~ /\b$func\b/m) { print "If $func isn't needed, you don't need to request it.\n" if $changes += ($c =~ s/^.*#.*define.*\bNEED_$func\b.*\n//m); } else { print "Uses $func\n"; $need_include = 1; } } else { if ($c =~ /\b$func\b/m) { $add_func{$func} =1 ; print "Uses $func\n"; $need_include = 1; } } } if (not $need_include) { foreach $macro (keys %macros) { if ($c =~ /\b$macro\b/m) { print "Uses $macro\n"; $need_include = 1; } } } foreach $badmacro (keys %badmacros) { if ($c =~ /\b$badmacro\b/m) { $changes += ($c =~ s/\b$badmacro\b/$badmacros{$badmacro}/gm); print "Uses $badmacros{$badmacro} (instead of $badmacro)\n"; $need_include = 1; } } if (scalar(keys %add_func) or $need_include != $has_include) { if (!$has_include) { $inc = join('',map("#define NEED_$_\n", sort keys %add_func)). "#include \"ppport.h\"\n"; $c = "$inc$c" unless $c =~ s/#.*include.*XSUB.*\n/$&$inc/m; } elsif (keys %add_func) { $inc = join('',map("#define NEED_$_\n", sort keys %add_func)); $c = "$inc$c" unless $c =~ s/^.*#.*include.*ppport.*$/$inc$&/m; } if (!$need_include) { print "Doesn't seem to need ppport.h.\n"; $c =~ s/^.*#.*include.*ppport.*\n//m; } $changes++; } if ($changes) { open(OUT,">/tmp/ppport.h.$$"); print OUT $c; close(OUT); open(DIFF, "diff -u $filename /tmp/ppport.h.$$|"); while () { s!/tmp/ppport\.h\.$$!$filename.patched!; print STDOUT; } close(DIFF); unlink("/tmp/ppport.h.$$"); } else { print "Looks OK\n"; } } __DATA__ */ #ifndef _P_P_PORTABILITY_H_ #define _P_P_PORTABILITY_H_ #ifndef PERL_REVISION # ifndef __PATCHLEVEL_H_INCLUDED__ # include # endif # if !(defined(PERL_VERSION) || (SUBVERSION > 0 && defined(PATCHLEVEL))) # include # endif # ifndef PERL_REVISION # define PERL_REVISION (5) /* Replace: 1 */ # define PERL_VERSION PATCHLEVEL # define PERL_SUBVERSION SUBVERSION /* Replace PERL_PATCHLEVEL with PERL_VERSION */ /* Replace: 0 */ # endif #endif #define PERL_BCDVERSION ((PERL_REVISION * 0x1000000L) + (PERL_VERSION * 0x1000L) + PERL_SUBVERSION) /* It is very unlikely that anyone will try to use this with Perl 6 (or greater), but who knows. */ #if PERL_REVISION != 5 # error ppport.h only works with Perl version 5 #endif /* PERL_REVISION != 5 */ #ifndef ERRSV # define ERRSV perl_get_sv("@",FALSE) #endif #if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION <= 5)) /* Replace: 1 */ # define PL_Sv Sv # define PL_compiling compiling # define PL_copline copline # define PL_curcop curcop # define PL_curstash curstash # define PL_defgv defgv # define PL_dirty dirty # define PL_dowarn dowarn # define PL_hints hints # define PL_na na # define PL_perldb perldb # define PL_rsfp_filters rsfp_filters # define PL_rsfpv rsfp # define PL_stdingv stdingv # define PL_sv_no sv_no # define PL_sv_undef sv_undef # define PL_sv_yes sv_yes /* Replace: 0 */ #endif #ifdef HASATTRIBUTE # if (defined(__GNUC__) && defined(__cplusplus)) || defined(__INTEL_COMPILER) # define PERL_UNUSED_DECL # else # define PERL_UNUSED_DECL __attribute__((unused)) # endif #else # define PERL_UNUSED_DECL #endif #ifndef dNOOP # define NOOP (void)0 # define dNOOP extern int Perl___notused PERL_UNUSED_DECL #endif #ifndef dTHR # define dTHR dNOOP #endif #ifndef dTHX # define dTHX dNOOP # define dTHXa(x) dNOOP # define dTHXoa(x) dNOOP #endif #ifndef pTHX # define pTHX void # define pTHX_ # define aTHX # define aTHX_ #endif /* IV could also be a quad (say, a long long), but Perls * capable of those should have IVSIZE already. */ #if !defined(IVSIZE) && defined(LONGSIZE) # define IVSIZE LONGSIZE #endif #ifndef IVSIZE # define IVSIZE 4 /* A bold guess, but the best we can make. */ #endif #ifndef UVSIZE # define UVSIZE IVSIZE #endif #ifndef NVTYPE # if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) # define NVTYPE long double # else # define NVTYPE double # endif typedef NVTYPE NV; #endif #ifndef INT2PTR #if (IVSIZE == PTRSIZE) && (UVSIZE == PTRSIZE) # define PTRV UV # define INT2PTR(any,d) (any)(d) #else # if PTRSIZE == LONGSIZE # define PTRV unsigned long # else # define PTRV unsigned # endif # define INT2PTR(any,d) (any)(PTRV)(d) #endif #define NUM2PTR(any,d) (any)(PTRV)(d) #define PTR2IV(p) INT2PTR(IV,p) #define PTR2UV(p) INT2PTR(UV,p) #define PTR2NV(p) NUM2PTR(NV,p) #if PTRSIZE == LONGSIZE # define PTR2ul(p) (unsigned long)(p) #else # define PTR2ul(p) INT2PTR(unsigned long,p) #endif #endif /* !INT2PTR */ #ifndef boolSV # define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no) #endif #ifndef gv_stashpvn # define gv_stashpvn(str,len,flags) gv_stashpv(str,flags) #endif #ifndef newSVpvn # define newSVpvn(data,len) ((len) ? newSVpv ((data), (len)) : newSVpv ("", 0)) #endif #ifndef newRV_inc /* Replace: 1 */ # define newRV_inc(sv) newRV(sv) /* Replace: 0 */ #endif /* DEFSV appears first in 5.004_56 */ #ifndef DEFSV # define DEFSV GvSV(PL_defgv) #endif #ifndef SAVE_DEFSV # define SAVE_DEFSV SAVESPTR(GvSV(PL_defgv)) #endif #ifndef newRV_noinc # ifdef __GNUC__ # define newRV_noinc(sv) \ ({ \ SV *nsv = (SV*)newRV(sv); \ SvREFCNT_dec(sv); \ nsv; \ }) # else # if defined(USE_THREADS) static SV * newRV_noinc (SV * sv) { SV *nsv = (SV*)newRV(sv); SvREFCNT_dec(sv); return nsv; } # else # define newRV_noinc(sv) \ (PL_Sv=(SV*)newRV(sv), SvREFCNT_dec(sv), (SV*)PL_Sv) # endif # endif #endif /* Provide: newCONSTSUB */ /* newCONSTSUB from IO.xs is in the core starting with 5.004_63 */ #if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION < 63)) #if defined(NEED_newCONSTSUB) static #else extern void newCONSTSUB(HV * stash, char * name, SV *sv); #endif #if defined(NEED_newCONSTSUB) || defined(NEED_newCONSTSUB_GLOBAL) void newCONSTSUB(stash,name,sv) HV *stash; char *name; SV *sv; { U32 oldhints = PL_hints; HV *old_cop_stash = PL_curcop->cop_stash; HV *old_curstash = PL_curstash; line_t oldline = PL_curcop->cop_line; PL_curcop->cop_line = PL_copline; PL_hints &= ~HINT_BLOCK_SCOPE; if (stash) PL_curstash = PL_curcop->cop_stash = stash; newSUB( #if (PERL_VERSION < 3) || ((PERL_VERSION == 3) && (PERL_SUBVERSION < 22)) /* before 5.003_22 */ start_subparse(), #else # if (PERL_VERSION == 3) && (PERL_SUBVERSION == 22) /* 5.003_22 */ start_subparse(0), # else /* 5.003_23 onwards */ start_subparse(FALSE, 0), # endif #endif newSVOP(OP_CONST, 0, newSVpv(name,0)), newSVOP(OP_CONST, 0, &PL_sv_no), /* SvPV(&PL_sv_no) == "" -- GMB */ newSTATEOP(0, Nullch, newSVOP(OP_CONST, 0, sv)) ); PL_hints = oldhints; PL_curcop->cop_stash = old_cop_stash; PL_curstash = old_curstash; PL_curcop->cop_line = oldline; } #endif #endif /* newCONSTSUB */ #ifndef START_MY_CXT /* * Boilerplate macros for initializing and accessing interpreter-local * data from C. All statics in extensions should be reworked to use * this, if you want to make the extension thread-safe. See ext/re/re.xs * for an example of the use of these macros. * * Code that uses these macros is responsible for the following: * 1. #define MY_CXT_KEY to a unique string, e.g. "DynaLoader_guts" * 2. Declare a typedef named my_cxt_t that is a structure that contains * all the data that needs to be interpreter-local. * 3. Use the START_MY_CXT macro after the declaration of my_cxt_t. * 4. Use the MY_CXT_INIT macro such that it is called exactly once * (typically put in the BOOT: section). * 5. Use the members of the my_cxt_t structure everywhere as * MY_CXT.member. * 6. Use the dMY_CXT macro (a declaration) in all the functions that * access MY_CXT. */ #if defined(MULTIPLICITY) || defined(PERL_OBJECT) || \ defined(PERL_CAPI) || defined(PERL_IMPLICIT_CONTEXT) /* This must appear in all extensions that define a my_cxt_t structure, * right after the definition (i.e. at file scope). The non-threads * case below uses it to declare the data as static. */ #define START_MY_CXT #if (PERL_VERSION < 4 || (PERL_VERSION == 4 && PERL_SUBVERSION < 68 )) /* Fetches the SV that keeps the per-interpreter data. */ #define dMY_CXT_SV \ SV *my_cxt_sv = perl_get_sv(MY_CXT_KEY, FALSE) #else /* >= perl5.004_68 */ #define dMY_CXT_SV \ SV *my_cxt_sv = *hv_fetch(PL_modglobal, MY_CXT_KEY, \ sizeof(MY_CXT_KEY)-1, TRUE) #endif /* < perl5.004_68 */ /* This declaration should be used within all functions that use the * interpreter-local data. */ #define dMY_CXT \ dMY_CXT_SV; \ my_cxt_t *my_cxtp = INT2PTR(my_cxt_t*,SvUV(my_cxt_sv)) /* Creates and zeroes the per-interpreter data. * (We allocate my_cxtp in a Perl SV so that it will be released when * the interpreter goes away.) */ #define MY_CXT_INIT \ dMY_CXT_SV; \ /* newSV() allocates one more than needed */ \ my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\ Zero(my_cxtp, 1, my_cxt_t); \ sv_setuv(my_cxt_sv, PTR2UV(my_cxtp)) /* This macro must be used to access members of the my_cxt_t structure. * e.g. MYCXT.some_data */ #define MY_CXT (*my_cxtp) /* Judicious use of these macros can reduce the number of times dMY_CXT * is used. Use is similar to pTHX, aTHX etc. */ #define pMY_CXT my_cxt_t *my_cxtp #define pMY_CXT_ pMY_CXT, #define _pMY_CXT ,pMY_CXT #define aMY_CXT my_cxtp #define aMY_CXT_ aMY_CXT, #define _aMY_CXT ,aMY_CXT #else /* single interpreter */ #define START_MY_CXT static my_cxt_t my_cxt; #define dMY_CXT_SV dNOOP #define dMY_CXT dNOOP #define MY_CXT_INIT NOOP #define MY_CXT my_cxt #define pMY_CXT void #define pMY_CXT_ #define _pMY_CXT #define aMY_CXT #define aMY_CXT_ #define _aMY_CXT #endif #endif /* START_MY_CXT */ #ifndef IVdf # if IVSIZE == LONGSIZE # define IVdf "ld" # define UVuf "lu" # define UVof "lo" # define UVxf "lx" # define UVXf "lX" # else # if IVSIZE == INTSIZE # define IVdf "d" # define UVuf "u" # define UVof "o" # define UVxf "x" # define UVXf "X" # endif # endif #endif #ifndef NVef # if defined(USE_LONG_DOUBLE) && defined(HAS_LONG_DOUBLE) && \ defined(PERL_PRIfldbl) /* Not very likely, but let's try anyway. */ # define NVef PERL_PRIeldbl # define NVff PERL_PRIfldbl # define NVgf PERL_PRIgldbl # else # define NVef "e" # define NVff "f" # define NVgf "g" # endif #endif #ifndef AvFILLp /* Older perls (<=5.003) lack AvFILLp */ # define AvFILLp AvFILL #endif #ifdef SvPVbyte # if PERL_REVISION == 5 && PERL_VERSION < 7 /* SvPVbyte does not work in perl-5.6.1, borrowed version for 5.7.3 */ # undef SvPVbyte # define SvPVbyte(sv, lp) \ ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK) \ ? ((lp = SvCUR(sv)), SvPVX(sv)) : my_sv_2pvbyte(aTHX_ sv, &lp)) static char * my_sv_2pvbyte(pTHX_ register SV *sv, STRLEN *lp) { sv_utf8_downgrade(sv,0); return SvPV(sv,*lp); } # endif #else # define SvPVbyte SvPV #endif #ifndef SvPV_nolen # define SvPV_nolen(sv) \ ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ ? SvPVX(sv) : sv_2pv_nolen(sv)) static char * sv_2pv_nolen(pTHX_ register SV *sv) { STRLEN n_a; return sv_2pv(sv, &n_a); } #endif #ifndef get_cv # define get_cv(name,create) perl_get_cv(name,create) #endif #ifndef get_sv # define get_sv(name,create) perl_get_sv(name,create) #endif #ifndef get_av # define get_av(name,create) perl_get_av(name,create) #endif #ifndef get_hv # define get_hv(name,create) perl_get_hv(name,create) #endif #ifndef call_argv # define call_argv perl_call_argv #endif #ifndef call_method # define call_method perl_call_method #endif #ifndef call_pv # define call_pv perl_call_pv #endif #ifndef call_sv # define call_sv perl_call_sv #endif #ifndef eval_pv # define eval_pv perl_eval_pv #endif #ifndef eval_sv # define eval_sv perl_eval_sv #endif #ifndef PERL_SCAN_GREATER_THAN_UV_MAX # define PERL_SCAN_GREATER_THAN_UV_MAX 0x02 #endif #ifndef PERL_SCAN_SILENT_ILLDIGIT # define PERL_SCAN_SILENT_ILLDIGIT 0x04 #endif #ifndef PERL_SCAN_ALLOW_UNDERSCORES # define PERL_SCAN_ALLOW_UNDERSCORES 0x01 #endif #ifndef PERL_SCAN_DISALLOW_PREFIX # define PERL_SCAN_DISALLOW_PREFIX 0x02 #endif #if (PERL_VERSION > 6) || ((PERL_VERSION == 6) && (PERL_SUBVERSION >= 1)) #define I32_CAST #else #define I32_CAST (I32*) #endif #ifndef grok_hex static UV _grok_hex (char *string, STRLEN *len, I32 *flags, NV *result) { NV r = scan_hex(string, *len, I32_CAST len); if (r > UV_MAX) { *flags |= PERL_SCAN_GREATER_THAN_UV_MAX; if (result) *result = r; return UV_MAX; } return (UV)r; } # define grok_hex(string, len, flags, result) \ _grok_hex((string), (len), (flags), (result)) #endif #ifndef grok_oct static UV _grok_oct (char *string, STRLEN *len, I32 *flags, NV *result) { NV r = scan_oct(string, *len, I32_CAST len); if (r > UV_MAX) { *flags |= PERL_SCAN_GREATER_THAN_UV_MAX; if (result) *result = r; return UV_MAX; } return (UV)r; } # define grok_oct(string, len, flags, result) \ _grok_oct((string), (len), (flags), (result)) #endif #if !defined(grok_bin) && defined(scan_bin) static UV _grok_bin (char *string, STRLEN *len, I32 *flags, NV *result) { NV r = scan_bin(string, *len, I32_CAST len); if (r > UV_MAX) { *flags |= PERL_SCAN_GREATER_THAN_UV_MAX; if (result) *result = r; return UV_MAX; } return (UV)r; } # define grok_bin(string, len, flags, result) \ _grok_bin((string), (len), (flags), (result)) #endif #ifndef IN_LOCALE # define IN_LOCALE \ (PL_curcop == &PL_compiling ? IN_LOCALE_COMPILETIME : IN_LOCALE_RUNTIME) #endif #ifndef IN_LOCALE_RUNTIME # define IN_LOCALE_RUNTIME (PL_curcop->op_private & HINT_LOCALE) #endif #ifndef IN_LOCALE_COMPILETIME # define IN_LOCALE_COMPILETIME (PL_hints & HINT_LOCALE) #endif #ifndef IS_NUMBER_IN_UV # define IS_NUMBER_IN_UV 0x01 # define IS_NUMBER_GREATER_THAN_UV_MAX 0x02 # define IS_NUMBER_NOT_INT 0x04 # define IS_NUMBER_NEG 0x08 # define IS_NUMBER_INFINITY 0x10 # define IS_NUMBER_NAN 0x20 #endif #ifndef grok_numeric_radix # define GROK_NUMERIC_RADIX(sp, send) grok_numeric_radix(aTHX_ sp, send) #define grok_numeric_radix Perl_grok_numeric_radix bool Perl_grok_numeric_radix(pTHX_ const char **sp, const char *send) { #ifdef USE_LOCALE_NUMERIC #if (PERL_VERSION > 6) || ((PERL_VERSION == 6) && (PERL_SUBVERSION >= 1)) if (PL_numeric_radix_sv && IN_LOCALE) { STRLEN len; char* radix = SvPV(PL_numeric_radix_sv, len); if (*sp + len <= send && memEQ(*sp, radix, len)) { *sp += len; return TRUE; } } #else /* pre5.6.0 perls don't have PL_numeric_radix_sv so the radix * must manually be requested from locale.h */ #include struct lconv *lc = localeconv(); char *radix = lc->decimal_point; if (radix && IN_LOCALE) { STRLEN len = strlen(radix); if (*sp + len <= send && memEQ(*sp, radix, len)) { *sp += len; return TRUE; } } #endif /* PERL_VERSION */ #endif /* USE_LOCALE_NUMERIC */ /* always try "." if numeric radix didn't match because * we may have data from different locales mixed */ if (*sp < send && **sp == '.') { ++*sp; return TRUE; } return FALSE; } #endif /* grok_numeric_radix */ #ifndef grok_number #define grok_number Perl_grok_number int Perl_grok_number(pTHX_ const char *pv, STRLEN len, UV *valuep) { const char *s = pv; const char *send = pv + len; const UV max_div_10 = UV_MAX / 10; const char max_mod_10 = UV_MAX % 10; int numtype = 0; int sawinf = 0; int sawnan = 0; while (s < send && isSPACE(*s)) s++; if (s == send) { return 0; } else if (*s == '-') { s++; numtype = IS_NUMBER_NEG; } else if (*s == '+') s++; if (s == send) return 0; /* next must be digit or the radix separator or beginning of infinity */ if (isDIGIT(*s)) { /* UVs are at least 32 bits, so the first 9 decimal digits cannot overflow. */ UV value = *s - '0'; /* This construction seems to be more optimiser friendly. (without it gcc does the isDIGIT test and the *s - '0' separately) With it gcc on arm is managing 6 instructions (6 cycles) per digit. In theory the optimiser could deduce how far to unroll the loop before checking for overflow. */ if (++s < send) { int digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { digit = *s - '0'; if (digit >= 0 && digit <= 9) { value = value * 10 + digit; if (++s < send) { /* Now got 9 digits, so need to check each time for overflow. */ digit = *s - '0'; while (digit >= 0 && digit <= 9 && (value < max_div_10 || (value == max_div_10 && digit <= max_mod_10))) { value = value * 10 + digit; if (++s < send) digit = *s - '0'; else break; } if (digit >= 0 && digit <= 9 && (s < send)) { /* value overflowed. skip the remaining digits, don't worry about setting *valuep. */ do { s++; } while (s < send && isDIGIT(*s)); numtype |= IS_NUMBER_GREATER_THAN_UV_MAX; goto skip_value; } } } } } } } } } } } } } } } } } } numtype |= IS_NUMBER_IN_UV; if (valuep) *valuep = value; skip_value: if (GROK_NUMERIC_RADIX(&s, send)) { numtype |= IS_NUMBER_NOT_INT; while (s < send && isDIGIT(*s)) /* optional digits after the radix */ s++; } } else if (GROK_NUMERIC_RADIX(&s, send)) { numtype |= IS_NUMBER_NOT_INT | IS_NUMBER_IN_UV; /* valuep assigned below */ /* no digits before the radix means we need digits after it */ if (s < send && isDIGIT(*s)) { do { s++; } while (s < send && isDIGIT(*s)); if (valuep) { /* integer approximation is valid - it's 0. */ *valuep = 0; } } else return 0; } else if (*s == 'I' || *s == 'i') { s++; if (s == send || (*s != 'N' && *s != 'n')) return 0; s++; if (s == send || (*s != 'F' && *s != 'f')) return 0; s++; if (s < send && (*s == 'I' || *s == 'i')) { s++; if (s == send || (*s != 'N' && *s != 'n')) return 0; s++; if (s == send || (*s != 'I' && *s != 'i')) return 0; s++; if (s == send || (*s != 'T' && *s != 't')) return 0; s++; if (s == send || (*s != 'Y' && *s != 'y')) return 0; s++; } sawinf = 1; } else if (*s == 'N' || *s == 'n') { /* XXX TODO: There are signaling NaNs and quiet NaNs. */ s++; if (s == send || (*s != 'A' && *s != 'a')) return 0; s++; if (s == send || (*s != 'N' && *s != 'n')) return 0; s++; sawnan = 1; } else return 0; if (sawinf) { numtype &= IS_NUMBER_NEG; /* Keep track of sign */ numtype |= IS_NUMBER_INFINITY | IS_NUMBER_NOT_INT; } else if (sawnan) { numtype &= IS_NUMBER_NEG; /* Keep track of sign */ numtype |= IS_NUMBER_NAN | IS_NUMBER_NOT_INT; } else if (s < send) { /* we can have an optional exponent part */ if (*s == 'e' || *s == 'E') { /* The only flag we keep is sign. Blow away any "it's UV" */ numtype &= IS_NUMBER_NEG; numtype |= IS_NUMBER_NOT_INT; s++; if (s < send && (*s == '-' || *s == '+')) s++; if (s < send && isDIGIT(*s)) { do { s++; } while (s < send && isDIGIT(*s)); } else return 0; } } while (s < send && isSPACE(*s)) s++; if (s >= send) return numtype; if (len == 10 && memEQ(pv, "0 but true", 10)) { if (valuep) *valuep = 0; return IS_NUMBER_IN_UV; } return 0; } #endif /* grok_number */ #ifndef PERL_MAGIC_sv # define PERL_MAGIC_sv '\0' #endif #ifndef PERL_MAGIC_overload # define PERL_MAGIC_overload 'A' #endif #ifndef PERL_MAGIC_overload_elem # define PERL_MAGIC_overload_elem 'a' #endif #ifndef PERL_MAGIC_overload_table # define PERL_MAGIC_overload_table 'c' #endif #ifndef PERL_MAGIC_bm # define PERL_MAGIC_bm 'B' #endif #ifndef PERL_MAGIC_regdata # define PERL_MAGIC_regdata 'D' #endif #ifndef PERL_MAGIC_regdatum # define PERL_MAGIC_regdatum 'd' #endif #ifndef PERL_MAGIC_env # define PERL_MAGIC_env 'E' #endif #ifndef PERL_MAGIC_envelem # define PERL_MAGIC_envelem 'e' #endif #ifndef PERL_MAGIC_fm # define PERL_MAGIC_fm 'f' #endif #ifndef PERL_MAGIC_regex_global # define PERL_MAGIC_regex_global 'g' #endif #ifndef PERL_MAGIC_isa # define PERL_MAGIC_isa 'I' #endif #ifndef PERL_MAGIC_isaelem # define PERL_MAGIC_isaelem 'i' #endif #ifndef PERL_MAGIC_nkeys # define PERL_MAGIC_nkeys 'k' #endif #ifndef PERL_MAGIC_dbfile # define PERL_MAGIC_dbfile 'L' #endif #ifndef PERL_MAGIC_dbline # define PERL_MAGIC_dbline 'l' #endif #ifndef PERL_MAGIC_mutex # define PERL_MAGIC_mutex 'm' #endif #ifndef PERL_MAGIC_shared # define PERL_MAGIC_shared 'N' #endif #ifndef PERL_MAGIC_shared_scalar # define PERL_MAGIC_shared_scalar 'n' #endif #ifndef PERL_MAGIC_collxfrm # define PERL_MAGIC_collxfrm 'o' #endif #ifndef PERL_MAGIC_tied # define PERL_MAGIC_tied 'P' #endif #ifndef PERL_MAGIC_tiedelem # define PERL_MAGIC_tiedelem 'p' #endif #ifndef PERL_MAGIC_tiedscalar # define PERL_MAGIC_tiedscalar 'q' #endif #ifndef PERL_MAGIC_qr # define PERL_MAGIC_qr 'r' #endif #ifndef PERL_MAGIC_sig # define PERL_MAGIC_sig 'S' #endif #ifndef PERL_MAGIC_sigelem # define PERL_MAGIC_sigelem 's' #endif #ifndef PERL_MAGIC_taint # define PERL_MAGIC_taint 't' #endif #ifndef PERL_MAGIC_uvar # define PERL_MAGIC_uvar 'U' #endif #ifndef PERL_MAGIC_uvar_elem # define PERL_MAGIC_uvar_elem 'u' #endif #ifndef PERL_MAGIC_vstring # define PERL_MAGIC_vstring 'V' #endif #ifndef PERL_MAGIC_vec # define PERL_MAGIC_vec 'v' #endif #ifndef PERL_MAGIC_utf8 # define PERL_MAGIC_utf8 'w' #endif #ifndef PERL_MAGIC_substr # define PERL_MAGIC_substr 'x' #endif #ifndef PERL_MAGIC_defelem # define PERL_MAGIC_defelem 'y' #endif #ifndef PERL_MAGIC_glob # define PERL_MAGIC_glob '*' #endif #ifndef PERL_MAGIC_arylen # define PERL_MAGIC_arylen '#' #endif #ifndef PERL_MAGIC_pos # define PERL_MAGIC_pos '.' #endif #ifndef PERL_MAGIC_backref # define PERL_MAGIC_backref '<' #endif #ifndef PERL_MAGIC_ext # define PERL_MAGIC_ext '~' #endif #endif /* _P_P_PORTABILITY_H_ */ /* End of File ppport.h */ Crypt-OpenSSL-PKCS10-0.15/README0000755001050700001440000000221510364234376015554 0ustar turturicausersMytest version 0.01 =================== The README is used to introduce the module and provide instructions on how to install the module, any machine dependencies it may have (for example C compilers and installed libraries) and any other information that should be provided before the module is installed. A README file is required for CPAN modules since CPAN extracts the README file from a module distribution so that people browsing the archive can use it get an idea of the modules uses. It is usually a good idea to provide version information here so that people can decide whether fixes for the module are worth downloading. INSTALLATION To install this module type the following: perl Makefile.PL make make test make install DEPENDENCIES This module requires these other modules and libraries: blah blah blah COPYRIGHT AND LICENCE Put the correct copyright and licence information here. Copyright (C) 2006 by U-HOME\Gigi This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.2 or, at your option, any later version of Perl 5 you may have available. Crypt-OpenSSL-PKCS10-0.15/t/0000755001050700001440000000000012561317253015131 5ustar turturicausersCrypt-OpenSSL-PKCS10-0.15/t/Mytest.t0000755001050700001440000000371112561316624016611 0ustar turturicausers# Before `make install' is performed this script should be runnable with # `make test'. After `make install' it should work as `perl Mytest.t' ######################### # change 'tests => 1' to 'tests => last_test_to_print'; use Test::More tests => 6; BEGIN { use_ok('Crypt::OpenSSL::PKCS10') }; ######################### # Insert your test code below, the Test::More module is use()ed here so read # its man page ( perldoc Test::More ) for help writing this test script. { my $req = Crypt::OpenSSL::PKCS10->new(); print STDERR $req->get_pem_req(); print STDERR $req->subject()."\n"; print STDERR $req->keyinfo()."\n"; ok($req); } use_ok('Crypt::OpenSSL::RSA'); { my $rsa = Crypt::OpenSSL::RSA->generate_key(1024); my $req = Crypt::OpenSSL::PKCS10->new_from_rsa($rsa); print STDERR $req->get_pem_req(); print STDERR $req->subject()."\n"; print STDERR $req->keyinfo()."\n"; print STDERR $req->pubkey_type()."\n"; print STDERR $req->get_pem_pubkey()."\n"; ok($req); } { my $req = Crypt::OpenSSL::PKCS10->new(); $req->set_subject("/C=RO/O=UTI/OU=ssi"); $req->add_ext(Crypt::OpenSSL::PKCS10::NID_key_usage,"critical,digitalSignature,keyEncipherment"); $req->add_ext(Crypt::OpenSSL::PKCS10::NID_ext_key_usage,"serverAuth, nsSGC, msSGC, 1.3.4"); $req->add_ext(Crypt::OpenSSL::PKCS10::NID_subject_alt_name,'email:steve@openssl.org'); $req->add_ext(Crypt::OpenSSL::PKCS10::NID_subject_key_identifier, "hash"); $req->add_custom_ext('1.2.3.3',"My new extension"); $req->add_custom_ext_raw('1.2.3.4', pack('H*','1E06006100620063')); $req->add_ext_final(); $req->sign(); print STDERR $req->get_pem_req(); print STDERR $req->subject()."\n"; print STDERR $req->keyinfo()."\n"; print STDERR $req->pubkey_type()."\n"; print STDERR $req->get_pem_pubkey()."\n"; ok($req); } { my $req = Crypt::OpenSSL::PKCS10->new_from_file("t/CSR.csr"); print STDERR $req->subject()."\n"; print STDERR $req->keyinfo()."\n"; print STDERR $req->pubkey_type()."\n"; print STDERR $req->get_pem_pubkey()."\n"; ok($req); } Crypt-OpenSSL-PKCS10-0.15/t/CSR.csr0000755001050700001440000000175112204722062016270 0ustar turturicausers-----BEGIN CERTIFICATE REQUEST----- MIICqzCCAZMCAQAwZjELMAkGA1UEBhMCREUxDDAKBgNVBAgMA05SVzEMMAoGA1UE BwwDRm9vMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxGDAWBgNV BAMMD2Zvby5kZXIuYmFyLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC ggEBAMDzGBcXKADnJj+z40ATMJY2o12Xeq2c5RDVk6BPAmANDNk280zgQhpocV3z Nsf8AXfDfqHpsQlzWqStdZ7l1DA9DpiSsuXCD3h7Sa8hTZmhmSVjWVuwL5a4lbSo oBhBbU/Ruz6ksNofCCA9hVD8KUCuEjFxVQScRctAR7BgWEY+aEYmFvvA5XYdobHB 8EfxX/9iwYG3E5LY89+/9SQKE0M9kwVCEKoPFlPjMrrcHvgEsjSYXyzBXRZ65oje mfTtivS9M8XniL0+VOHCwYjTOIT7QXZoPXYjkJRHdDO5CxqPx3/V0oIyG0z94vwX dUaXc6UZAyBowljuvn2kHggPEesCAwEAAaAAMA0GCSqGSIb3DQEBBQUAA4IBAQAM RH+7QgADqsQwW4tzTYIPU82jNoRgz7VscQeSFLp56NIxldTlXnL84aqx+WU+jMMc Z17u0GWkOr2EwWJIqFq3zfi0gtREfWnx94PXRJbEt9Cr3nmNfbTLR6bcDZuOL8rA F5sQi+FwOLPV2FZ7R6vwuVdPmI5NAWd82Ln2p+4h750WDcigzde0akVIx1CpC46e vpuaQalWhaG/RsmzlmkmYk3oy1VTfx/TYsh9SZdrVNI/erb669VExHYEVW10HtH+ UsjxRtIa8X7I8AkTFae0kdq7/BrO1I2U9Pkf3/Hij7DGnagcoV6Evf5z7bItHTP2 VAU4IMNz812NggMt3a9F -----END CERTIFICATE REQUEST----- Crypt-OpenSSL-PKCS10-0.15/MANIFEST0000755001050700001440000000040112205061717016011 0ustar turturicausersChanges typemap Makefile.PL MANIFEST PKCS10.xs ppport.h README t/Mytest.t t/CSR.csr PKCS10.pm META.yml Module meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) Crypt-OpenSSL-PKCS10-0.15/META.yml0000644001050700001440000000077712561317253016152 0ustar turturicausers--- abstract: "Perl extension to OpenSSL's PKCS10 API." author: - 'JoNO ' build_requires: ExtUtils::MakeMaker: 0 configure_requires: ExtUtils::MakeMaker: 0 dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.120921' license: unknown meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Crypt-OpenSSL-PKCS10 no_index: directory: - t - inc requires: Crypt::OpenSSL::RSA: 0 version: 0.15 Crypt-OpenSSL-PKCS10-0.15/Changes0000755001050700001440000000262012561317223016161 0ustar turturicausersRevision history for Perl extension Crypt::OpenSSL::PKCS10. 0.15 Fri Aug 7 23:12:46 PDT 2015 - UTF-8 subject support. (Adam Osuchowski) - get_pubkey() Returns the PEM encoding of the PKCS10 public key. (David Dick) 0.14 Wed Sep 16 11:49:00 PDT 2014 - SHA-256 signature default. SHA-1 signatures are no longer considered safe, and SHA-256 replaces it. (Jan Ingvoldstad) 0.13 Wed Apr 16 12:12:00 PDT 2014 - added support for NID_subject_key_identifier (Brad Davidson) 0.12 Thu Aug 20 23:40:00 PDT 2013 - Fixed missing test prerequisite in MANIFEST. 0.11 Thu Aug 19 14:40:00 PDT 2013 - Load CSR from PEM files. Read subject and keyinfo from a PKCS10 object. (Bug #87893 thanks to smile) 0.10 Thu Jul 19 10:51:00 PDT 2013 - Fixed an undefined variable in the tests (Bug #87049). 0.08 Thu Mar 01 21:52:00 PDT 2013 - Added support for raw custom extensions (thanks to Brad Davidson). 0.07 Thu Sep 27 11:19:41 PDT 2012 - Changed default hash algorithm for signing from MD5 to SHA1. 0.05 Sun Feb 19 23:31:45 2006 - Now subject can contain oids too (like /C=RO/O=UTI/OU=ssi/2.5.4.9=my street) 0.04 - Require perl 5.8.0 (to work on older OS) 0.03 Fri Jan 22 21:24:45 2006 - less memory leaks, but still there are some :( 0.01 Fri Jan 20 21:24:45 2006 - original version; created by h2xs 1.23 with options -A -n Mytest Crypt-OpenSSL-PKCS10-0.15/PKCS10.xs0000755001050700001440000003375612561316624016165 0ustar turturicausers#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include #include #include #include #include #include "ppport.h" typedef struct { X509_REQ* req; EVP_PKEY *pk; RSA **rsa; STACK_OF(X509_EXTENSION) *exts; } pkcs10Data; typedef struct { RSA* rsa; int padding; int hashMode; } Crypt__OpenSSL__RSA; #define PACKAGE_NAME "Crypt::OpenSSL::PKCS10" #define PACKAGE_CROAK(p_message) croak("%s:%d: %s", (p_message)) #define CHECK_NEW(p_var, p_size, p_type) \ if (New(0, p_var, p_size, p_type) == NULL) \ { PACKAGE_CROAK("unable to alloc buffer"); } //int add_ext_raw(STACK_OF(X509_REQUEST) *sk, int nid, unsigned char *value, int length); //int add_ext(STACK_OF(X509_REQUEST) *sk, int nid, char *value); X509_NAME *parse_name(char *str, long chtype, int multirdn); /* * subject is expected to be in the format /type0=value0/type1=value1/type2=... * where characters may be escaped by \ */ X509_NAME *parse_name(char *subject, long chtype, int multirdn) { size_t buflen = strlen(subject)+1; /* to copy the types and values into. due to escaping, the copy can only become shorter */ char *buf = OPENSSL_malloc(buflen); size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */ char **ne_types = OPENSSL_malloc(max_ne * sizeof (char *)); char **ne_values = OPENSSL_malloc(max_ne * sizeof (char *)); int *mval = OPENSSL_malloc (max_ne * sizeof (int)); char *sp = subject, *bp = buf; int i, ne_num = 0; X509_NAME *n = NULL; if (!buf || !ne_types || !ne_values) { croak("malloc error\n"); goto error; } if (*subject != '/') { croak("Subject does not start with '/'.\n"); goto error; } sp++; /* skip leading / */ /* no multivalued RDN by default */ mval[ne_num] = 0; while (*sp) { /* collect type */ ne_types[ne_num] = bp; while (*sp) { if (*sp == '\\') /* is there anything to escape in the type...? */ { if (*++sp) *bp++ = *sp++; else { croak("escape character at end of string\n"); goto error; } } else if (*sp == '=') { sp++; *bp++ = '\0'; break; } else *bp++ = *sp++; } if (!*sp) { croak("end of string encountered while processing type of subject name element #%d\n", ne_num); goto error; } ne_values[ne_num] = bp; while (*sp) { if (*sp == '\\') { if (*++sp) *bp++ = *sp++; else { croak("escape character at end of string\n"); goto error; } } else if (*sp == '/') { sp++; /* no multivalued RDN by default */ mval[ne_num+1] = 0; break; } else if (*sp == '+' && multirdn) { /* a not escaped + signals a mutlivalued RDN */ sp++; mval[ne_num+1] = -1; break; } else *bp++ = *sp++; } *bp++ = '\0'; ne_num++; } if (!(n = X509_NAME_new())) goto error; for (i = 0; i < ne_num; i++) { if (!*ne_values[i]) { croak("No value provided for Subject Attribute %s, skipped\n", ne_types[i]); continue; } if (!X509_NAME_add_entry_by_txt(n, (unsigned char*)ne_types[i], chtype, (unsigned char*)ne_values[i], -1,-1,mval[i])) goto error; } OPENSSL_free(mval); OPENSSL_free(ne_values); OPENSSL_free(ne_types); OPENSSL_free(buf); return n; error: X509_NAME_free(n); if (ne_values) OPENSSL_free(ne_values); if (ne_types) OPENSSL_free(ne_types); if (buf) OPENSSL_free(buf); return NULL; } /* Add extension using V3 code: we can set the config file as NULL * because we wont reference any other sections. */ int add_ext(STACK_OF(X509_REQUEST) *sk, X509_REQ *req, int nid, char *value) { X509_EXTENSION *ex; X509V3_CTX v3ctx; X509V3_set_ctx(&v3ctx, NULL, NULL, req, NULL, 0); ex = X509V3_EXT_conf_nid(NULL, &v3ctx, nid, value); if (!ex) return 0; sk_X509_EXTENSION_push(sk, ex); return 1; } /* Add an extention by setting the raw ASN1 octet string. */ int add_ext_raw(STACK_OF(X509_REQUEST) *sk, int nid, unsigned char *value, int length) { X509_EXTENSION *ex; ASN1_STRING *asn; asn = M_ASN1_OCTET_STRING_new(); ASN1_OCTET_STRING_set(asn, value, length); ex = X509_EXTENSION_create_by_NID(NULL, nid, 0, asn); if (!ex) return 0; sk_X509_EXTENSION_push(sk, ex); return 1; } SV* make_pkcs10_obj(SV* p_proto, X509_REQ* p_req, EVP_PKEY* p_pk, STACK_OF(X509_EXTENSION)* p_exts, RSA **p_rsa) { pkcs10Data* pkcs10; CHECK_NEW(pkcs10, 1, pkcs10Data); pkcs10->req = p_req; pkcs10->pk = p_pk; pkcs10->exts = p_exts; pkcs10->rsa = p_rsa; return sv_bless( newRV_noinc(newSViv((IV) pkcs10)), (SvROK(p_proto) ? SvSTASH(SvRV(p_proto)) : gv_stashsv(p_proto, 1))); } /* stolen from OpenSSL.xs */ long bio_write_cb(struct bio_st *bm, int m, const char *ptr, int l, long x, long y) { if (m == BIO_CB_WRITE) { SV *sv = (SV *) BIO_get_callback_arg(bm); sv_catpvn(sv, ptr, l); } if (m == BIO_CB_PUTS) { SV *sv = (SV *) BIO_get_callback_arg(bm); l = strlen(ptr); sv_catpvn(sv, ptr, l); } return l; } static BIO* sv_bio_create(void) { SV *sv = newSVpvn("",0); /* create an in-memory BIO abstraction and callbacks */ BIO *bio = BIO_new(BIO_s_mem()); BIO_set_callback(bio, bio_write_cb); BIO_set_callback_arg(bio, (void *)sv); return bio; } static BIO *sv_bio_create_file(SV *filename) { STRLEN l; return BIO_new_file(SvPV(filename, l), "wb"); } static SV* sv_bio_final(BIO *bio) { SV* sv; BIO_flush(bio); sv = (SV *)BIO_get_callback_arg(bio); BIO_free_all(bio); if (!sv) sv = &PL_sv_undef; return sv; } /* * subject is expected to be in the format /type0=value0/type1=value1/type2=... * where characters may be escaped by \ */ static int build_subject(X509_REQ *req, char *subject, unsigned long chtype, int multirdn) { X509_NAME *n; if (!(n = parse_name(subject, chtype, multirdn))) return 0; if (!X509_REQ_set_subject_name(req, n)) { X509_NAME_free(n); return 0; } X509_NAME_free(n); return 1; } MODULE = Crypt::OpenSSL::PKCS10 PACKAGE = Crypt::OpenSSL::PKCS10 PROTOTYPES: DISABLE BOOT: { /*OpenSSL_add_all_algorithms(); OpenSSL_add_all_ciphers(); OpenSSL_add_all_digests(); ERR_load_PEM_strings(); ERR_load_ASN1_strings(); ERR_load_crypto_strings(); ERR_load_X509_strings(); ERR_load_DSA_strings(); ERR_load_RSA_strings();*/ HV *stash = gv_stashpvn("Crypt::OpenSSL::PKCS10", 22, TRUE); struct { char *n; I32 v; } Crypt__OpenSSL__PKCS10__const[] = { {"NID_key_usage", NID_key_usage}, {"NID_subject_alt_name", NID_subject_alt_name}, {"NID_netscape_cert_type", NID_netscape_cert_type}, {"NID_netscape_comment", NID_netscape_comment}, {"NID_ext_key_usage", NID_ext_key_usage}, {"NID_subject_key_identifier", NID_subject_key_identifier}, {Nullch,0}}; char *name; int i; for (i = 0; (name = Crypt__OpenSSL__PKCS10__const[i].n); i++) { newCONSTSUB(stash, name, newSViv(Crypt__OpenSSL__PKCS10__const[i].v)); } } SV* new(class, keylen = 1024) SV *class int keylen PREINIT: X509_REQ *x; EVP_PKEY *pk; RSA *rsa = NULL; CODE: //CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); if ((pk=EVP_PKEY_new()) == NULL) croak ("%s - can't create PKEY", class); if ((x=X509_REQ_new()) == NULL) croak ("%s - can't create req", class); rsa=RSA_generate_key(keylen, RSA_F4, NULL, NULL); if (!EVP_PKEY_assign_RSA(pk,rsa)) croak ("%s - EVP_PKEY_assign_RSA", class); X509_REQ_set_pubkey(x,pk); X509_REQ_set_version(x,0L); RETVAL = make_pkcs10_obj(class, x, pk, NULL, NULL); OUTPUT: RETVAL void DESTROY(pkcs10) pkcs10Data *pkcs10; PREINIT: //BIO *bio_err; PPCODE: //bio_err=BIO_new_fp(stderr, BIO_NOCLOSE); if (pkcs10->pk) EVP_PKEY_free(pkcs10->pk); pkcs10->pk = 0; if (pkcs10->rsa) *pkcs10->rsa = 0; if (pkcs10->req) X509_REQ_free(pkcs10->req); pkcs10->req = 0; Safefree(pkcs10); CRYPTO_cleanup_all_ex_data(); /*CRYPTO_mem_leaks(bio_err); BIO_free(bio_err);*/ SV* new_from_rsa(class, p_rsa) SV *class SV *p_rsa PREINIT: Crypt__OpenSSL__RSA *rsa; X509_REQ *x; EVP_PKEY *pk; CODE: //CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); if ((pk=EVP_PKEY_new()) == NULL) croak ("%s - can't create PKEY", class); if ((x=X509_REQ_new()) == NULL) croak ("%s - can't create req", class); rsa = (Crypt__OpenSSL__RSA *) SvIV(SvRV(p_rsa)); if (!EVP_PKEY_assign_RSA(pk,rsa->rsa)) croak ("%s - EVP_PKEY_assign_RSA", class); X509_REQ_set_pubkey(x,pk); X509_REQ_set_version(x,0L); RETVAL = make_pkcs10_obj(class, x, pk, NULL, &rsa->rsa); OUTPUT: RETVAL int sign(pkcs10) pkcs10Data *pkcs10; PREINIT: CODE: RETVAL = X509_REQ_sign(pkcs10->req,pkcs10->pk,EVP_sha256()); if (!RETVAL) croak ("X509_REQ_sign"); OUTPUT: RETVAL SV* get_pem_pubkey(pkcs10) pkcs10Data *pkcs10; PREINIT: EVP_PKEY *pkey; BIO *bio; CODE: pkey = X509_REQ_get_pubkey(pkcs10->req); bio = sv_bio_create(); if (pkey == NULL) { BIO_free_all(bio); EVP_PKEY_free(pkey); croak("Public Key is unavailable\n"); } if (pkey->type == EVP_PKEY_RSA) { # PEM_write_bio_RSAPublicKey(bio, pkey->pkey.rsa); PEM_write_bio_RSA_PUBKEY(bio, pkey->pkey.rsa); } else if (pkey->type == EVP_PKEY_DSA) { PEM_write_bio_DSA_PUBKEY(bio, pkey->pkey.dsa); #ifndef OPENSSL_NO_EC } else if ( pkey->type == EVP_PKEY_EC ) { PEM_write_bio_EC_PUBKEY(bio, pkey->pkey.ec); #endif } else { BIO_free_all(bio); EVP_PKEY_free(pkey); croak("Wrong Algorithm type\n"); } EVP_PKEY_free(pkey); RETVAL = sv_bio_final(bio); OUTPUT: RETVAL char* pubkey_type(pkcs10) pkcs10Data *pkcs10; PREINIT: EVP_PKEY *pkey; CODE: RETVAL=NULL; pkey = X509_REQ_get_pubkey(pkcs10->req); if(!pkey) XSRETURN_UNDEF; if (pkey->type == EVP_PKEY_DSA) { RETVAL="dsa"; } else if (pkey->type == EVP_PKEY_RSA) { RETVAL="rsa"; #ifndef OPENSSL_NO_EC } else if ( pkey->type == EVP_PKEY_EC ) { RETVAL="ec"; #endif } OUTPUT: RETVAL SV* get_pem_req(pkcs10,...) pkcs10Data *pkcs10; ALIAS: write_pem_req = 1 PROTOTYPE: $;$ PREINIT: BIO *bio; CODE: if((ix != 1 && items > 1) || (ix == 1 && items != 2)) croak("get_pem_req illegal/missing args"); if(items > 1) { bio = sv_bio_create_file(ST(1)); } else { bio = sv_bio_create(); } /* get the certificate back out in a specified format. */ if(!PEM_write_bio_X509_REQ(bio,pkcs10->req)) croak ("PEM_write_bio_X509_REQ"); RETVAL = sv_bio_final(bio); OUTPUT: RETVAL SV* get_pem_pk(pkcs10,...) pkcs10Data *pkcs10; ALIAS: write_pem_pk = 1 PROTOTYPE: $;$ PREINIT: BIO *bio; CODE: if((ix != 1 && items > 1) || (ix == 1 && items != 2)) croak("get_pem_req illegal/missing args"); if(items > 1) { bio = sv_bio_create_file(ST(1)); } else { bio = sv_bio_create(); } /* get the certificate back out in a specified format. */ if(!PEM_write_bio_PrivateKey(bio,pkcs10->pk,NULL,NULL,0,NULL,NULL)) croak ("%s - PEM_write_bio_X509_REQ", pkcs10->req); RETVAL = sv_bio_final(bio); OUTPUT: RETVAL int set_subject(pkcs10, subj_SV, utf8 = 0) pkcs10Data *pkcs10; SV* subj_SV; int utf8; PREINIT: unsigned char* subj; int subj_length; CODE: subj = SvPV(subj_SV, subj_length); RETVAL = build_subject(pkcs10->req, subj, utf8 ? MBSTRING_UTF8 : MBSTRING_ASC, 0); if (!RETVAL) croak ("build_subject"); OUTPUT: RETVAL int add_ext(pkcs10, nid = NID_key_usage, ext_SV) pkcs10Data *pkcs10; int nid; SV* ext_SV; PREINIT: unsigned char* ext; int ext_length; CODE: ext = SvPV(ext_SV, ext_length); if(!pkcs10->exts) pkcs10->exts = sk_X509_EXTENSION_new_null(); RETVAL = add_ext(pkcs10->exts, pkcs10->req, nid, ext); if (!RETVAL) croak ("add_ext key_usage: %d, ext: %s", nid, ext); OUTPUT: RETVAL int add_custom_ext_raw(pkcs10, oid_SV, ext_SV) pkcs10Data *pkcs10; SV* oid_SV; SV* ext_SV; PREINIT: unsigned char* oid; unsigned char* ext; int ext_length, nid; CODE: oid = SvPV(oid_SV, ext_length); ext = SvPV(ext_SV, ext_length); if(!pkcs10->exts) pkcs10->exts = sk_X509_EXTENSION_new_null(); nid = OBJ_create(oid, "MyAlias", "My Test Alias Extension"); RETVAL = add_ext_raw(pkcs10->exts, nid, ext, ext_length); if (!RETVAL) croak ("add_custom_ext_raw oid: %s, ext: %s", oid, ext); OUTPUT: RETVAL int add_custom_ext(pkcs10, oid_SV, ext_SV) pkcs10Data *pkcs10; SV* oid_SV; SV* ext_SV; PREINIT: unsigned char* oid; unsigned char* ext; int ext_length, nid; CODE: oid = SvPV(oid_SV, ext_length); ext = SvPV(ext_SV, ext_length); if(!pkcs10->exts) pkcs10->exts = sk_X509_EXTENSION_new_null(); nid = OBJ_create(oid, "MyAlias", "My Test Alias Extension"); X509V3_EXT_add_alias(nid, NID_netscape_comment); RETVAL = add_ext(pkcs10->exts, pkcs10->req, nid, ext); if (!RETVAL) croak ("add_custom_ext oid: %s, ext: %s", oid, ext); OUTPUT: RETVAL int add_ext_final(pkcs10) pkcs10Data *pkcs10; CODE: if(pkcs10->exts) { RETVAL = X509_REQ_add_extensions(pkcs10->req, pkcs10->exts); if (!RETVAL) croak ("X509_REQ_add_extensions"); if(pkcs10->exts) sk_X509_EXTENSION_pop_free(pkcs10->exts, X509_EXTENSION_free); } else { RETVAL = NULL; } OUTPUT: RETVAL SV* new_from_file(class, filename_SV) SV* class; SV* filename_SV; PREINIT: unsigned char* filename; int filename_length; FILE* fp; X509_REQ *req; CODE: filename = SvPV(filename_SV, filename_length); fp = fopen(filename, "r"); req = PEM_read_X509_REQ (fp, NULL, NULL, NULL); fclose(fp); RETVAL = make_pkcs10_obj(class, req, NULL, NULL, NULL); OUTPUT: RETVAL SV* accessor(pkcs10) pkcs10Data *pkcs10; ALIAS: subject = 1 keyinfo = 2 PREINIT: BIO *bio; X509_NAME *name; EVP_PKEY *key; CODE: bio = sv_bio_create(); if (pkcs10->req != NULL) { if (ix == 1) { name = X509_REQ_get_subject_name(pkcs10->req); X509_NAME_print_ex(bio, name, 0, XN_FLAG_SEP_CPLUS_SPC); } else if (ix == 2 ) { key = X509_REQ_extract_key(pkcs10->req); RSA_print(bio, EVP_PKEY_get1_RSA(key), 0); } } RETVAL = sv_bio_final(bio); OUTPUT: RETVAL Crypt-OpenSSL-PKCS10-0.15/typemap0000755001050700001440000000042610364700220016262 0ustar turturicausersTYPEMAP BIGNUM* T_PTR pkcs10Data* O_OBJECT Crypt__OpenSSL__RSA* O_OBJECT INPUT O_OBJECT if (!(SvROK($arg) && sv_derived_from($arg, PACKAGE_NAME))) { croak(\"argument is not a ${type} object\"); } $var = (${type}) SvIV(SvRV($arg)); OUTPUT Crypt-OpenSSL-PKCS10-0.15/Makefile.PL0000755001050700001440000000123010370216644016635 0ustar turturicausersuse 5.008000; use ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. WriteMakefile( NAME => 'Crypt::OpenSSL::PKCS10', VERSION_FROM => 'PKCS10.pm', PREREQ_PM => { Crypt::OpenSSL::RSA => 0}, # e.g., Module::Name => 1.1 ($] >= 5.005 ? ## Add these new keywords supported since 5.005 (ABSTRACT_FROM => 'PKCS10.pm', AUTHOR => 'JoNO ') : ()), LIBS => ['-L/usr/local/ssl/lib -lcrypto'], DEFINE => '-DPERL5 -Wall', INC => '-I/usr/local/ssl/include', ); Crypt-OpenSSL-PKCS10-0.15/PKCS10.pm0000755001050700001440000001361512561316624016137 0ustar turturicauserspackage Crypt::OpenSSL::PKCS10; use 5.008000; use strict; use warnings; require Exporter; our @ISA = qw(Exporter); # Items to export into callers namespace by default. Note: do not export # names by default without a very good reason. Use EXPORT_OK instead. # Do not simply export all your public functions/methods/constants. # This allows declaration use Crypt::OpenSSL::PKCS10 ':all'; # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK # will save memory. our @NIDS = qw( NID_key_usage NID_subject_alt_name NID_netscape_cert_type NID_netscape_comment NID_ext_key_usage ); our %EXPORT_TAGS = ( 'all' => [ @NIDS ], 'const' => [ @NIDS ], ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); #our @EXPORT = qw( #); our $VERSION = '0.15'; require XSLoader; XSLoader::load('Crypt::OpenSSL::PKCS10', $VERSION); # Preloaded methods go here. 1; __END__ =head1 NAME Crypt::OpenSSL::PKCS10 - Perl extension to OpenSSL's PKCS10 API. =head1 SYNOPSIS use Crypt::OpenSSL::PKCS10::PKCS10 qw( :const ); my $req = Crypt::OpenSSL::PKCS10->new; $req->set_subject("/C=RO/O=UTI/OU=ssi"); $req->add_ext(Crypt::OpenSSL::PKCS10::NID_key_usage,"critical,digitalSignature,keyEncipherment"); $req->add_ext(Crypt::OpenSSL::PKCS10::NID_ext_key_usage,"serverAuth, nsSGC, msSGC, 1.3.4"); $req->add_ext(Crypt::OpenSSL::PKCS10::NID_subject_alt_name,"email:steve@openssl.org"); $req->add_custom_ext('1.2.3.3',"My new extension"); $req->add_ext_final(); $req->sign(); $req->write_pem_req('request.pem'); $req->write_pem_pk('pk.pem'); print $req->get_pem_pubkey(); print $req->pubkey_type(); print $req->get_pem_req(); =head1 ABSTRACT Crypt::OpenSSL::PKCS10 - Perl extension to OpenSSL's PKCS10 API. =head1 DESCRIPTION Crypt::OpenSSL::PKCS10 provides the ability to create PKCS10 certificate requests using RSA key pairs. =head1 Class Methods =over =item new Create a new Crypt::OpenSSL::PKCS10 object by generating a new RSA key pair. There is one optional argument, the key size, which has the default value of 1024 if omitted. =item new_from_rsa( $rsa_object ) Create a new Crypt::OpenSSL::PKCS10 object by using key information from a Crypt::OpenSSL::RSA object. Here is an example: my $rsa = Crypt::OpenSSL::RSA->generate_key(512); my $req = Crypt::OpenSSL::PKCS10->new_from_rsa($rsa); =item new_from_file( $filename ) Create a new Crypt::OpenSSL::PKCS10 object by reading the request and key information from a PEM formatted file. Here is an example: my $req = Crypt::OpenSSL::PKCS10->new_from_file("CSR.csr"); =back =head1 Instance Methods =over 2 =item set_subject($subject, [ $utf8 ]) Sets the subject DN of the request. Note: $subject is expected to be in the format /type0=value0/type1=value1/type2=... where characters may be escaped by \. If $utf8 is non-zero integer, $subject is interpreted as UTF-8 string. =item add_ext($nid, $extension) Adds a new extension to the request. The first argument $nid is one of the exported constants (see below). The second one $extension is a string (for more info read C). $req->add_ext(Crypt::OpenSSL::PKCS10::NID_key_usage,"critical,digitalSignature,keyEncipherment"); $req->add_ext(Crypt::OpenSSL::PKCS10::NID_ext_key_usage,"serverAuth, nsSGC, msSGC, 1.3.4"); $req->add_ext(Crypt::OpenSSL::PKCS10::NID_subject_alt_name,"email:steve@openssl.org"); =item add_custom_ext($oid, $desc) Adds a new custom extension to the request. The value is added as a text string, using ASN.1 encoding rules inherited from the Netscape Comment OID. $req->add_custom_ext('1.2.3.3',"My new extension"); =item add_custom_ext_raw($oid, $bytes) Adds a new custom extension to the request. The value is added as a raw DER octet string. Use this if you are packing your own ASN.1 structures and need to set the extension value directly. $req->add_custom_ext_raw($oid, pack('H*','1E06006100620063')) # BMPString 'abc' =item add_ext_final() This must be called after all extensions has been added. It actually copies the extension stack to request structure. $req->add_ext(Crypt::OpenSSL::PKCS10::NID_subject_alt_name,"email:my@email.org"); $req->add_ext_final(); =item sign() This adds the signature to the PKCS10 request. $req->sign(); =item pubkey_type() Returns the type of the PKCS10 public key - one of (rsa|dsa|ec). $req->pubkey_type(); =item get_pubkey() Returns the PEM encoding of the PKCS10 public key. $req->get_pubkey(); =item get_pem_req() Returns the PEM encoding of the PKCS10 request. $req->get_pem_req(); =item write_pem_req($filename) Writes the PEM encoding of the PKCS10 request to a given file. $req->write_pem_req('request.pem'); =item get_pem_pk() Returns the PEM encoding of the private key. $req->get_pem_pk(); =item write_pem_pk($filename) Writes the PEM encoding of the private key to a given file. $req->write_pem_pk('request.pem'); =item subject() returns the subject of the PKCS10 request $subject = $req->subject(); =item keyinfo() returns the human readable info about the key of the PKCS10 request $keyinfo = $req->keyinfo(); =back =head2 EXPORT None by default. On request: NID_key_usage NID_subject_alt_name NID_netscape_cert_type NID_netscape_comment NID_ext_key_usage =head1 BUGS If you destroy $req object that is linked to a Crypt::OpenSSL::RSA object, the RSA private key is also freed, thus you can't use latter object anymore. Avoid this: my $rsa = Crypt::OpenSSL::RSA->generate_key(512); my $req = Crypt::OpenSSL::PKCS10->new_from_rsa($rsa); undef $req; print $rsa->get_private_key_string(); =head1 SEE ALSO C, C. =head1 AUTHOR JoNO, Ejonozzz@yahoo.comE =head1 COPYRIGHT AND LICENSE Copyright (C) 2006 by JoNO This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.2 or, at your option, any later version of Perl 5 you may have available. =cut