~statik/ubuntu/maverick/erlang/erlang-merge-testing

« back to all changes in this revision

Viewing changes to lib/ssl/test/make_certs.erl

  • Committer: Elliot Murphy
  • Date: 2010-06-08 03:55:44 UTC
  • mfrom: (3.5.6 squeeze)
  • Revision ID: elliot@elliotmurphy.com-20100608035544-dd8zh2swk7jr5rz2
* Merge with Debian unstable; remaining Ubuntu changes:
  - Drop libwxgtk2.8-dev build dependency. Wx isn't in main, and not
    supposed to. (LP #438365)
  - Drop erlang-wx binary.
  - Drop erlang-wx dependency from -megaco, -common-test, and -reltool, they
    do not really need wx. Also drop it from -debugger; the GUI needs wx,
    but it apparently has CLI bits as well, and is also needed by -megaco,
    so let's keep the package for now.
* Added missing symlinks to /usr/include for a few new header files.
* Fixed generation of ${erlang-base:Depends} and ${erlang-x11:Depends}
  substitution variables.
* Added a fix for a re:compile/2 crash on a long regular expression.
* Changed urgency to medium as the change fixes a security bug.
* Manpages in section 1 are needed even if only arch-dependent packages are
  built. So, re-enabled them.
* Fixed HiPE architecture recognition for powerpc Debian architecture.
* Moved xsltproc and fop to build-depends-indep and do not build
  documentation if only architecture-specific packages are built.
* Refreshed all patches.
* Made Emacs look in man5 and man7 for Erlang manpages and added code
  skeleton files to erlang-mode package.
* New upstream release.
* Moved manpages from incorrect sections 4 and 6 to correct 5 and 7
  (closes: #498492).
* Made manpages regexp in Emacs mode match only 3erl pages in section 3.
* Removed docb_gen script which is no longer needed to build manpages.
* Added erlang-doc package which contains documentation in HTML and PDF
  formats. This package replaces erlang-doc-html package and it's easier
  to synchronize it with the main Erlang packages as it's built from
  a single source package (closes: #558451).
* Removed RPATH from ssl and crypto application binaries as required by
  Debian policy.
* Added libwxgtk2.4-dev and libwxgtk2.6-dev to build conflicts.
* Added a few dpendencies for erlang-dialyzer, erlang-et, erlang-observer
  and erlang-examples packages which now call functions from more modules
  than in 1:13.b.3.
* Added a workaround which disables vfork() for hppa architecture
  (closes: #562218).
* Strictened check for JDK 1.5 adding a call to String(int[], int, int)
  because GCJ 4.4 doesn't implement it and OpenJDK isn't available for all
  architectures.
* Fixed erlang-manpages package section.
* Made erlang-depends add only substvars which are requested in
  debian/control file. This minimizes number of warnings from dh_gencontrol.
  Also, improved descriptions of the functions in erlang-depends escript.
* Added erlang-erl-docgen package to erlang-nox dependencies.
* Made dummy packages erlang-nox and erlang-x11 architecture all.
* Cleaned up working with custom substitution variables in debian/rules.
* Reorganized debian/rules to ensure that manpages arent built twice, and
  aren't built at all if only architecture-dependent packages are requested.
* Fixed project links in README.Debian.
* Added a new package erlang-jinterface which provides tools for
  communication of Java programs with Erlang processes. This adds build
  depandency on default-jdk and as a result enables Java module for IDL
  compiler.
* Bumped standards version to 3.8.4.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
%%
 
2
%% %CopyrightBegin%
 
3
%% 
 
4
%% Copyright Ericsson AB 2007-2009. All Rights Reserved.
 
5
%% 
 
6
%% The contents of this file are subject to the Erlang Public License,
 
7
%% Version 1.1, (the "License"); you may not use this file except in
 
8
%% compliance with the License. You should have received a copy of the
 
9
%% Erlang Public License along with this software. If not, it can be
 
10
%% retrieved online at http://www.erlang.org/.
 
11
%% 
 
12
%% Software distributed under the License is distributed on an "AS IS"
 
13
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 
14
%% the License for the specific language governing rights and limitations
 
15
%% under the License.
 
16
%% 
 
17
%% %CopyrightEnd%
 
18
%%
 
19
 
 
20
-module(make_certs).
 
21
 
 
22
-export([all/2]).
 
23
 
 
24
-record(dn, {commonName, 
 
25
             organizationalUnitName = "Erlang OTP",
 
26
             organizationName = "Ericsson AB",
 
27
             localityName = "Stockholm",
 
28
             countryName = "SE",
 
29
             emailAddress = "peter@erix.ericsson.se"}).
 
30
 
 
31
all(DataDir, PrivDir) ->
 
32
    OpenSSLCmd = "openssl",
 
33
    create_rnd(DataDir, PrivDir),                       % For all requests
 
34
    rootCA(PrivDir, OpenSSLCmd, "erlangCA"),
 
35
    intermediateCA(PrivDir, OpenSSLCmd, "otpCA", "erlangCA"),
 
36
    endusers(PrivDir, OpenSSLCmd, "otpCA", ["client", "server"]),
 
37
    collect_certs(PrivDir, ["erlangCA", "otpCA"], ["client", "server"]),
 
38
    %% Create keycert files 
 
39
    SDir = filename:join([PrivDir, "server"]),
 
40
    SC = filename:join([SDir, "cert.pem"]),
 
41
    SK = filename:join([SDir, "key.pem"]),
 
42
    SKC = filename:join([SDir, "keycert.pem"]),
 
43
    append_files([SK, SC], SKC),
 
44
    CDir = filename:join([PrivDir, "client"]),
 
45
    CC = filename:join([CDir, "cert.pem"]),
 
46
    CK = filename:join([CDir, "key.pem"]),
 
47
    CKC = filename:join([CDir, "keycert.pem"]),
 
48
    append_files([CK, CC], CKC),
 
49
    remove_rnd(PrivDir).
 
50
 
 
51
append_files(FileNames, ResultFileName) ->
 
52
    {ok, ResultFile} = file:open(ResultFileName, [write]),
 
53
    do_append_files(FileNames, ResultFile).
 
54
 
 
55
do_append_files([], RF) ->
 
56
    ok = file:close(RF);
 
57
do_append_files([F|Fs], RF) ->
 
58
    {ok, Data} = file:read_file(F),
 
59
    ok = file:write(RF, Data),
 
60
    do_append_files(Fs, RF).
 
61
 
 
62
rootCA(Root, OpenSSLCmd, Name) ->
 
63
    create_ca_dir(Root, Name, ca_cnf(Name)),
 
64
    DN = #dn{commonName = Name},
 
65
    create_self_signed_cert(Root, OpenSSLCmd, Name, req_cnf(DN)),
 
66
    ok.
 
67
 
 
68
intermediateCA(Root, OpenSSLCmd, CA, ParentCA) ->
 
69
    CA = "otpCA", 
 
70
    create_ca_dir(Root, CA, ca_cnf(CA)),
 
71
    CARoot = filename:join([Root, CA]),
 
72
    DN = #dn{commonName = CA},
 
73
    CnfFile = filename:join([CARoot, "req.cnf"]),
 
74
    file:write_file(CnfFile, req_cnf(DN)),
 
75
    KeyFile = filename:join([CARoot, "private", "key.pem"]), 
 
76
    ReqFile =  filename:join([CARoot, "req.pem"]), 
 
77
    create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile),
 
78
    CertFile = filename:join([CARoot, "cert.pem"]),
 
79
    sign_req(Root, OpenSSLCmd, ParentCA, "ca_cert", ReqFile, CertFile).
 
80
 
 
81
endusers(Root, OpenSSLCmd, CA, Users) ->
 
82
    lists:foreach(fun(User) -> enduser(Root, OpenSSLCmd, CA, User) end, Users).
 
83
 
 
84
enduser(Root, OpenSSLCmd, CA, User) -> 
 
85
    UsrRoot = filename:join([Root, User]),
 
86
    file:make_dir(UsrRoot),
 
87
    CnfFile = filename:join([UsrRoot, "req.cnf"]),
 
88
    DN = #dn{commonName = User},
 
89
    file:write_file(CnfFile, req_cnf(DN)),
 
90
    KeyFile = filename:join([UsrRoot, "key.pem"]), 
 
91
    ReqFile =  filename:join([UsrRoot, "req.pem"]), 
 
92
    create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile),
 
93
    CertFile =  filename:join([UsrRoot, "cert.pem"]), 
 
94
    sign_req(Root, OpenSSLCmd, CA, "user_cert", ReqFile, CertFile).
 
95
 
 
96
collect_certs(Root, CAs, Users) ->
 
97
    Bins = lists:foldr(
 
98
             fun(CA, Acc) -> 
 
99
                     File = filename:join([Root, CA, "cert.pem"]),
 
100
                     {ok, Bin} = file:read_file(File),
 
101
                     [Bin, "\n" | Acc]
 
102
             end, [], CAs),
 
103
    lists:foreach(
 
104
      fun(User) ->
 
105
              File = filename:join([Root, User, "cacerts.pem"]),
 
106
              file:write_file(File, Bins)
 
107
      end, Users).
 
108
 
 
109
create_self_signed_cert(Root, OpenSSLCmd, CAName, Cnf) ->
 
110
    CARoot = filename:join([Root, CAName]),
 
111
    CnfFile = filename:join([CARoot, "req.cnf"]),
 
112
    file:write_file(CnfFile, Cnf),
 
113
    KeyFile = filename:join([CARoot, "private", "key.pem"]), 
 
114
    CertFile = filename:join([CARoot, "cert.pem"]), 
 
115
    Cmd = [OpenSSLCmd, " req"
 
116
           " -new"
 
117
           " -x509"
 
118
           " -config ", CnfFile,
 
119
           " -keyout ", KeyFile, 
 
120
           " -out ", CertFile], 
 
121
    Env = [{"ROOTDIR", Root}],  
 
122
    cmd(Cmd, Env).
 
123
 
 
124
create_ca_dir(Root, CAName, Cnf) ->
 
125
    CARoot = filename:join([Root, CAName]),
 
126
    file:make_dir(CARoot),
 
127
    create_dirs(CARoot, ["certs", "crl", "newcerts", "private"]),
 
128
    create_rnd(Root, filename:join([CAName, "private"])),
 
129
    create_files(CARoot, [{"serial", "01\n"},
 
130
                          {"index.txt", ""},
 
131
                          {"ca.cnf", Cnf}]).
 
132
 
 
133
create_req(Root, OpenSSLCmd, CnfFile, KeyFile, ReqFile) ->
 
134
    Cmd = [OpenSSLCmd, " req"
 
135
           " -new"
 
136
           " -config ", CnfFile,
 
137
           " -keyout ", KeyFile, 
 
138
           " -out ", ReqFile], 
 
139
    Env = [{"ROOTDIR", Root}], 
 
140
    cmd(Cmd, Env).
 
141
 
 
142
sign_req(Root, OpenSSLCmd, CA, CertType, ReqFile, CertFile) ->
 
143
    CACnfFile = filename:join([Root, CA, "ca.cnf"]),
 
144
    Cmd = [OpenSSLCmd, " ca"
 
145
           " -batch"
 
146
           " -notext"
 
147
           " -config ", CACnfFile, 
 
148
           " -extensions ", CertType,
 
149
           " -in ", ReqFile, 
 
150
           " -out ", CertFile],
 
151
    Env = [{"ROOTDIR", Root}], 
 
152
    cmd(Cmd, Env).
 
153
    
 
154
%%
 
155
%%  Misc
 
156
%%
 
157
    
 
158
create_dirs(Root, Dirs) ->
 
159
    lists:foreach(fun(Dir) ->
 
160
                          file:make_dir(filename:join([Root, Dir])) end,
 
161
                  Dirs).
 
162
 
 
163
create_files(Root, NameContents) ->
 
164
    lists:foreach(
 
165
      fun({Name, Contents}) ->
 
166
              file:write_file(filename:join([Root, Name]), Contents) end,
 
167
      NameContents).
 
168
 
 
169
create_rnd(FromDir, ToDir) ->
 
170
     From = filename:join([FromDir, "RAND"]),
 
171
     To = filename:join([ToDir, "RAND"]),
 
172
     file:copy(From, To).
 
173
 
 
174
remove_rnd(Dir) ->
 
175
    File = filename:join([Dir, "RAND"]),
 
176
    file:delete(File).
 
177
 
 
178
cmd(Cmd, Env) ->
 
179
    FCmd = lists:flatten(Cmd),
 
180
    Port = open_port({spawn, FCmd}, [stream, eof, exit_status, stderr_to_stdout, 
 
181
                                    {env, Env}]),
 
182
    eval_cmd(Port).
 
183
 
 
184
eval_cmd(Port) ->
 
185
    receive 
 
186
        {Port, {data, _}} ->
 
187
            eval_cmd(Port);
 
188
        {Port, eof} ->
 
189
            ok
 
190
    end,
 
191
    receive
 
192
        {Port, {exit_status, Status}} when Status /= 0 ->
 
193
            %% io:fwrite("exit status: ~w~n", [Status]),
 
194
            exit({eval_cmd, Status})
 
195
    after 0 ->
 
196
            ok
 
197
    end.
 
198
 
 
199
%%
 
200
%% Contents of configuration files 
 
201
%%
 
202
 
 
203
req_cnf(DN) ->
 
204
    ["# Purpose: Configuration for requests (end users and CAs)."
 
205
     "\n"
 
206
     "ROOTDIR           = $ENV::ROOTDIR\n"
 
207
     "\n"
 
208
 
 
209
     "[req]\n"
 
210
     "input_password    = secret\n"
 
211
     "output_password   = secret\n"
 
212
     "default_bits      = 1024\n"
 
213
     "RANDFILE          = $ROOTDIR/RAND\n"
 
214
     "encrypt_key       = no\n"
 
215
     "default_md        = sha1\n"
 
216
     "#string_mask      = pkix\n"
 
217
     "x509_extensions   = ca_ext\n"
 
218
     "prompt            = no\n"
 
219
     "distinguished_name= name\n"
 
220
     "\n"
 
221
 
 
222
     "[name]\n"
 
223
     "commonName                = ", DN#dn.commonName, "\n"
 
224
     "organizationalUnitName    = ", DN#dn.organizationalUnitName, "\n"
 
225
     "organizationName          = ", DN#dn.organizationName, "\n" 
 
226
     "localityName              = ", DN#dn.localityName, "\n"
 
227
     "countryName               = ", DN#dn.countryName, "\n"
 
228
     "emailAddress              = ", DN#dn.emailAddress, "\n"
 
229
     "\n"
 
230
 
 
231
     "[ca_ext]\n"
 
232
     "basicConstraints  = critical, CA:true\n"
 
233
     "keyUsage          = cRLSign, keyCertSign\n"
 
234
     "subjectKeyIdentifier = hash\n"
 
235
     "subjectAltName    = email:copy\n"].
 
236
 
 
237
 
 
238
ca_cnf(CA) ->
 
239
    ["# Purpose: Configuration for CAs.\n"
 
240
     "\n"
 
241
     "ROOTDIR           = $ENV::ROOTDIR\n"
 
242
     "default_ca        = ca\n"
 
243
     "\n"
 
244
 
 
245
     "[ca]\n"
 
246
     "dir               = $ROOTDIR/", CA, "\n"
 
247
     "certs             = $dir/certs\n"
 
248
     "crl_dir           = $dir/crl\n"
 
249
     "database          = $dir/index.txt\n"
 
250
     "new_certs_dir     = $dir/newcerts\n"
 
251
     "certificate       = $dir/cert.pem\n"
 
252
     "serial            = $dir/serial\n"
 
253
     "crl               = $dir/crl.pem\n"
 
254
     "private_key       = $dir/private/key.pem\n"
 
255
     "RANDFILE          = $dir/private/RAND\n"
 
256
     "\n"
 
257
     "x509_extensions   = user_cert\n"
 
258
     "default_days      = 3600\n"
 
259
     "default_md        = sha1\n"
 
260
     "preserve          = no\n"
 
261
     "policy            = policy_match\n"
 
262
     "\n"
 
263
 
 
264
     "[policy_match]\n"
 
265
     "commonName                = supplied\n"
 
266
     "organizationalUnitName    = optional\n"
 
267
     "organizationName          = match\n"
 
268
     "countryName               = match\n"
 
269
     "localityName              = match\n"
 
270
     "emailAddress              = supplied\n"
 
271
     "\n"
 
272
 
 
273
     "[user_cert]\n"
 
274
     "basicConstraints  = CA:false\n"
 
275
     "keyUsage          = nonRepudiation, digitalSignature, keyEncipherment\n"
 
276
     "subjectKeyIdentifier = hash\n"
 
277
     "authorityKeyIdentifier = keyid,issuer:always\n"
 
278
     "subjectAltName    = email:copy\n"
 
279
     "issuerAltName     = issuer:copy\n"
 
280
     "\n"
 
281
 
 
282
     "[ca_cert]\n"
 
283
     "basicConstraints  = critical,CA:true\n"
 
284
     "keyUsage          = cRLSign, keyCertSign\n"
 
285
     "subjectKeyIdentifier = hash\n"
 
286
     "authorityKeyIdentifier = keyid:always,issuer:always\n"
 
287
     "subjectAltName    = email:copy\n"
 
288
     "issuerAltName     = issuer:copy\n"].