|
root / base / usr / src / tools / codesign
codesign Plain Text 835 lines 22.1 KB
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#

SHFILES= \
	findcrypto \
	signproto

PERLFILES= \
	signit

MAN1ONBLDFILES= \
	signit.1onbld \
	signproto.1onbld

CLEANFILES = $(SHFILES) $(PERLFILES)

include ../Makefile.tools

$(ROOTONBLDMAN1ONBLDFILES) : FILEMODE=	644

.KEEP_STATE:

all:	$(SHFILES) $(PERLFILES) $(MAN1ONBLDFILES)

install: all .WAIT $(ROOTONBLDSHFILES) $(ROOTONBLDPERLFILES) \
		$(ROOTONBLDMAN1ONBLDFILES)

clean:
	$(RM) $(CLEANFILES)

include ../Makefile.targ

#!/usr/bin/perl
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# ident	"%Z%%M%	%I%	%E% SMI"
#
# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#

# Server program for code signing server
#
# This program implements an ssh-based service to add digital
# signatures to files. The sshd_config file on the server
# contains an entry like the following to invoke this program:
#
#	Subsystem codesign /opt/signing/bin/server
#
# The client program sends a ZIP archive of the file to be
# signed along with the name of a signing credential stored
# on the server. Each credential is a directory containing
# a public-key certificate, private key, and a script to
# perform the appropriate signing operation.
#
# This program unpacks the input ZIP archive, invokes the
# signing script for the specified credential, and sends
# back an output ZIP archive, which typically contains the
# (modified) input file but may also contain additional
# files created by the signing script.

use strict;
use File::Temp 'tempdir';
use File::Path;

my $Base = "/opt/signing";
my $Tmpdir = tempdir(CLEANUP => 1);	# Temporary directory
my $Session = $$;

#
# Main program
#

# Set up
open(AUDIT, ">>$Base/audit/log");
$| = 1;	# Flush output on every write

# Record user and client system
my $user = `/usr/ucb/whoami`;
chomp($user);
my ($client) = split(/\s/, $ENV{SSH_CLIENT});
audit("START User=$user Client=$client");

# Process signing requests
while (<STDIN>) {
	if (/^SIGN (\d+) (\S+) (\S+)/) {
		sign($1, $2, $3);
	} else {
		abnormal("WARNING Unknown command");
	}
}
exit(0);

#
# get_credential(name)
#
# Verify that the user is allowed to use the named credential and
# return the path to the credential directory. If the user is not
# authorized to use the credential, return undef.
#
sub get_credential {
	my $name = shift;
	my $dir;

	$dir = "$Base/cred/$2";
	if (!open(F, "<$dir/private")) {
		abnormal("WARNING Credential $name not available");
		$dir = undef;
	}
	close(F);
	return $dir;
}

#
# sign(size, cred, path)
#
# Sign an individual file.
#
sub sign {
	my ($size, $cred, $path) = @_;
	my ($cred_dir, $msg);

	# Read input file
	recvfile("$Tmpdir/in.zip", $size) || return;

	# Check path for use of .. or absolute pathname
	my @comp = split(m:/:, $path);
	foreach my $elem (@comp) {
		if ($elem eq "" || $elem eq "..") {
			abnormal("WARNING Invalid path $path");
			return;
		}
	}

	# Get credential directory
	$cred_dir = get_credential($cred) || return;

	# Create work area
	rmtree("$Tmpdir/reloc");
	mkdir("$Tmpdir/reloc");
	chdir("$Tmpdir/reloc");

	# Read and unpack input ZIP archive
	system("/usr/bin/unzip -qo ../in.zip $path");

	# Sign input file using credential-specific script
	$msg = `cd $cred_dir; ./sign $Tmpdir/reloc/$path`;
	if ($? != 0) {
		chomp($msg);
		abnormal("WARNING $msg");
		return;
	}

	# Pack output file(s) in ZIP archive and return
	unlink("../out.zip");
	system("/usr/bin/zip -qr ../out.zip .");
	chdir($Tmpdir);
	my $hash = `digest -a md5 $Tmpdir/reloc/$path`;
	sendfile("$Tmpdir/out.zip", $path) || return;

	# Audit successful signing
	chomp($hash);
	audit("SIGN $path $cred $hash");
}

#
# sendfile(file, path)
#
# Send a ZIP archive to the client. This involves sending
# an OK SIGN response that includes the file size, followed by
# the contents of the archive itself.
#
sub sendfile {
	my ($file, $path) = @_;
	my ($size, $bytes);

	$size = -s $file;
	if (!open(F, "<$file")) {
		abnormal("ERROR Internal read error");
		return (0);
	}
	read(F, $bytes, $size);
	close(F);
	print "OK SIGN $size $path\n";
	syswrite(STDOUT, $bytes, $size);
	return (1);
}

#
# recvfile(file, size)
#
# Receive a ZIP archive from the client. The caller
# provides the size argument previously obtained from the 
# client request.
#
sub recvfile {
	my ($file, $size) = @_;
	my $bytes;
	
	if (!read(STDIN, $bytes, $size)) {
		abnormal("ERROR No input data");
		return (0);
	}
	if (!open(F, ">$file")) {
		abnormal("ERROR Internal write error");
		return (0);
	}
	syswrite(F, $bytes, $size);
	close(F);
	return (1);
}

#
# audit(msg)
#
# Create an audit record. All records have this format:
#	[date] [time] [session] [keyword] [other parameters]
# The keywords START and END mark the boundaries of a session.
#
sub audit {
	my ($msg) = @_;
	my ($sec, $min, $hr, $day, $mon, $yr) = localtime(time);
	my $timestamp = sprintf("%04d-%02d-%02d %02d:%02d:%02d",
		$yr+1900, $mon+1, $day, $hr, $min, $sec);

	print AUDIT "$timestamp $Session $msg\n";
}

#
# abnormal(msg)
#
# Respond to an abnormal condition, which may be fatal (ERROR) or
# non-fatal (WARNING). Send the message to the audit error log
# and to the client program. Exit in case of fatal errors.
#
sub abnormal {
	my $msg = shift;

	audit($msg);
	print("$msg\n");
	exit(1) if ($msg =~ /^ERROR/);
}

#
# END()
#
# Clean up prior to normal or abnormal exit.
#
sub END {
	audit("END");
	close(AUDIT);
	chdir("");	# so $Tmpdir can be removed
}
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
#
# The following is a list of regular expressions that are matched against
# the (temporary) signature on a crypto module created during the build
# process. The first regular expression that matches is used to select the
# signing credential to use for the file.
#
# Credential name	Regular expression
# ---------------	------------------
Crypto_v2               Solaris Cryptographic Framework
#!/bin/ksh
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#

#
# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#

# findcrypto cred_file
#
# Utility to find cryptographic modules in the proto area.  Prints out
# one line for each binary, using the form
#
#   cred path
#
# where "path" identifies the binary (relative to $ROOT), and "cred"
# says how the binary should get signed.
#
# The cred_file argument is the same as for signproto.sh.
#

# Directories in proto area that may contain crypto objects
DIRS="platform kernel usr/lib/security"

# Read list of credentials and regular expressions
n=0
grep -v "^#" $1 | while read c r
do
	cred[$n]=$c
	regex[$n]=$r
	(( n = n + 1 ))
done

# Search proto area for crypto modules
cd $ROOT
find $DIRS -type f -print | while read f; do
	s=`elfsign list -f signer -e $f 2>/dev/null`
	if [[ $? != 0 ]]; then 
		continue
	fi
	# Determine credential based on signature
	i=0
	while [[ i -lt n ]]; do
		if expr "$s" : ".*${regex[i]}" >/dev/null; then
			echo "${cred[i]} $f"
			break
		fi
		(( i = i + 1 ))
	done
done

exit 0
.\"
.\" CDDL HEADER START
.\"
.\" The contents of this file are subject to the terms of the
.\" Common Development and Distribution License (the "License").
.\" You may not use this file except in compliance with the License.
.\"
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
.\" or http://www.opensolaris.org/os/licensing.
.\" See the License for the specific language governing permissions
.\" and limitations under the License.
.\"
.\" When distributing Covered Code, include this CDDL HEADER in each
.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE.
.\" If applicable, add the following below this CDDL HEADER, with the
.\" fields enclosed by brackets "[]" replaced with your own identifying
.\" information: Portions Copyright [yyyy] [name of copyright owner]
.\"
.\" CDDL HEADER END
.\"
.\" Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
.\" Use is subject to license terms.
.\"
.TH SIGNIT 1ONBLD "Jun 13, 2007"
.SH NAME
.I signit
\- sign files using code signing server
.SH SYNOPSIS
\fBsignit [-q] [-i dir] [-o dir] [-l user]\fP
.SH DESCRIPTION
.LP
.I signit
is the client program for use with Sun's code signing server. It
reads a list of signing credential names and relative pathnames
from standard input. Each file is read from the input directory,
sent to the signing server, signed with the specified credential,
and written to the output directory.
.SH OPTIONS
.LP
The following options are supported:
.TP 4
.B \-q
Quiet operation: This option suppresses printing the names of files
that are signed successfully.
.TP 4
.B -i \fIdir\fP
Specifies the base input directory from which the relative pathnames
of files to be signed are interpreted. If not specified, the
input directory defaults to the current directory.
.TP 4
.B -o \fIdir\fP
Specifies the base output directory to which signed files
are written.  If not specified, the
output directory matches the input directory.
.TP 4
.B -l \fIuser\fP
Specifies the user login name on the code signing server. If not
specified, the login name of the user running
.I signit
is used.
.SH ENVIRONMENT
.TP 4
.B CODESIGN_SERVER
Specifies the hostname or IP address of the code signing server. If
this variable is not set, it defaults to quill.sfbay.
.SH EXIT STATUS
.LP
The following exit status values are returned:
.IP "\fB0\fR" 4
All specified files were signed successfully.
.IP "\fB1\fR" 4
One or more files were not signed successfully.
.SH SEE ALSO
.LP
signproto(1ONBLD)
#!/usr/bin/perl
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# ident	"%Z%%M%	%I%	%E% SMI"
#
# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#

# signit [-q] [-i dir][-o dir] [-l user]
#
# Client program for use with code signing server.
# Reads a list of signing credential names and file pathnames
# from standard input. Each file is read from the input directory,
# sent to the signing server, signed with the specified credential, 
# and written to the output directory.
#
# Options:
#	-q	quiet operation: avoid printing files successfully signed
#	-i dir	input directory (defaults to current dir)
#	-o dir	output directory (defautls to input dir)
#	-l user	user account on signing server (defaults to current user)
#
# The CODESIGN_SERVER environment variable can be used to
# specify the hostname or IP address of the signing server
# (defaults to quill.sfbay).

use strict;
use Cwd;
use File::Temp 'tempdir';
use Getopt::Std;
use IPC::Open2;

#
# Global variables
#
my ($Indir, $Outdir);	# Input and output directories (may be the same)
my $Server;		# Signing server hostname
my $Quiet;		# Suppress printing each file successfully signed
my ($pid);		# Process id for ssh client
my @cred_rules;		# Array of path prefixes and credentials to use
my $Tmpdir = tempdir(CLEANUP => 1);	# Temporary directory
my $Warnings = 0;	# Count of warnings returned


#
# Main program
#

$Server = $ENV{CODESIGN_SERVER} || "quill.sfbay";

# Get command-line arguments
our($opt_c, $opt_i, $opt_o, $opt_l, $opt_q);
if (!getopts("i:o:c:l:q")) {
	die "Usage: $0 [-i dir] [-o dir] [-l user]\n";
}
$Quiet = $opt_q;

# Get input/output directories
$Indir = $opt_i || getcwd();	# default to current dir
$Outdir = $opt_o || $Indir;	# default to input dir
$Indir = getcwd() . "/$Indir" if (substr($Indir, 0, 1) ne "/");
$Outdir = getcwd() . "/$Outdir" if (substr($Outdir, 0, 1) ne "/");

# Ignore SIGPIPE to allow proper error messages
$SIG{PIPE} = 'IGNORE';

# Create ssh connection to server
my(@args);
if (defined($opt_l)) {
	push @args, "-l", $opt_l;
}
push @args, "-s", $Server, "codesign";
$pid = open2(*SRV_OUT, *SRV_IN, "/usr/bin/ssh", @args) or 
	die "ERROR Connection to server $Server failed\n";
select(SRV_IN); $| = 1; select(STDOUT);	# unbuffered writes

# Sign each file with the specified credential
chdir($Indir);
while (<>) {
	my ($cred, $path) = split;

	sign_file($cred, $path);
}
exit($Warnings > 0);

#
# END()
#
# Clean up after normal or abnormal exit.
#
sub END {
	my $old_status = $?;

	$? = 0;
	close(SRV_IN);
	close(SRV_OUT);
	waitpid($pid, 0) if ($pid);
	if ($?) {
		print STDERR "ERROR Connection to server $Server failed\n";
		$? = 1;
	}
	$? = $old_status if ($? == 0);
}

#
# debug(msg)
#
# Print debug message to standard error.
#
sub debug {
	print STDERR "### @_";
}

#
# check_response(str)
#
# Validate response from server. Print messages for warnings or errors,
# and exit in the case of an error. If the response indicates a successful
# signing operation, return the size of the output data.
#
sub check_response {
	my ($str) = @_;

	if ($str =~ /^OK SIGN (\d+)/) {
		return ($1);
	}
	elsif ($str =~ /^OK/) {
		return (0);
	}
	elsif ($str =~ /^WARNING/) {
		print STDERR $str;
		$Warnings++;
		return (-1);
	}
	elsif ($str =~ /^ERROR/) {
		print STDERR $str;
		exit(1);
	}
	else {
		printf STDERR "ERROR Protocol failure (%d)\n", length($str);
		exit(1);
	}
}

#
# sign_file(credential, filename)
#
# Send the file to the server for signing. Package the file into a
# ZIP archive, send to the server, and extract the ZIP archive that
# is returned. The input ZIP archive always contains a single file,
# but the returned archive may contain one or more files.
#
sub sign_file {
	my ($cred, $path) = @_;
	my ($res, $size);

	$path =~ s:^\./::g; # remove leading "./"
	unlink("$Tmpdir/in.zip");
	system("cd $Indir; /usr/bin/zip -q $Tmpdir/in.zip $path");

	sendfile("$Tmpdir/in.zip", "$cred $path") || return;

	$res = <SRV_OUT>;
	$size = check_response($res);
	if ($size > 0) {
		recvfile("$Tmpdir/out.zip", $size) || return;
		
		if (system("cd $Outdir; /usr/bin/unzip -qo $Tmpdir/out.zip")) {
			$Warnings++;
		} else {
			print "$cred\t$path\n" unless $Quiet;
		}
	}
}

#
# sendfile(file, args)
#
# Send a ZIP archive file to the signing server. This involves
# sending a SIGN command with the given arguments, followed by
# the contents of the archive itself.
#
sub sendfile {
	my ($file, $args) = @_;
	my ($size, $bytes);

	$size = -s $file;
	print SRV_IN "SIGN $size $args\n";
	if (!open(F, "<$file")) {
		print STDERR "$file: $!\n";
		return (0);
	}
	read(F, $bytes, $size);
	close(F);
	if (!syswrite(SRV_IN, $bytes, $size)) {
		print STDERR "Can't send to server: $!\n";
		return (0);
	}
	return (1);
}

#
# recvfile(file, size)
#
# Receive a ZIP archive from the signing server. The caller
# provides the size argument previously obtained from the 
# server response.
#
sub recvfile {
	my ($file, $size) = @_;
	my $bytes;
	
	if (!read(SRV_OUT, $bytes, $size)) {
		print STDERR "Can't read from server: $!\n";
		return (0);
	}
	if (!open(F, ">$file")) {
		print STDERR "$file: $!\n";
		return (0);
	}
	syswrite(F, $bytes, $size);
	close(F);
	return (1);
}
.\"
.\" CDDL HEADER START
.\"
.\" The contents of this file are subject to the terms of the
.\" Common Development and Distribution License (the "License").
.\" You may not use this file except in compliance with the License.
.\"
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
.\" or http://www.opensolaris.org/os/licensing.
.\" See the License for the specific language governing permissions
.\" and limitations under the License.
.\"
.\" When distributing Covered Code, include this CDDL HEADER in each
.\" file and include the License file at usr/src/OPENSOLARIS.LICENSE.
.\" If applicable, add the following below this CDDL HEADER, with the
.\" fields enclosed by brackets "[]" replaced with your own identifying
.\" information: Portions Copyright [yyyy] [name of copyright owner]
.\"
.\" CDDL HEADER END
.\"
.\" Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
.\" Use is subject to license terms.
.\"
.TH SIGNPROTO 1ONBLD "Jun 13, 2007"
.SH NAME
.I signproto
\- sign ELF objects in proto area
.SH SYNOPSIS
\fBsignproto \fIcred_file\fP
.SH DESCRIPTION
.LP
.I signproto
finds ELF objects in the ON proto area and re-signs them
using
.IR signit (1ONBLD).
This operation is normally invoked only for
release builds, as it replaces the internal development
signatures with official Sun signatures. The actual signing using
Sun's private key is performed by a code signing server which
is accessed via
.IR signit .
.LP
Cryptographic modules are identified by examining the signature
embedded by
.IR elfsign (1)
during the build process.
.I signproto
requires a single command-line argument, which is a file containing
the mapping between each signing server credential name and the Subject
Distinguished Name (DN) of the certificate used to
sign the ELF file. Each line in the file contains a credential name
followed by a regular expression. The first regular expression that
matches the Subject DN embedded in the ELF file determines the
credential name passed to
.I signit
to re-sign the file.
.SH ENVIRONMENT
.TP 4
.B CODESIGN_USER
Login name for the code signing server passed to
.I signit .
If this variable is not set, the value in LOGNAME is used instead.
.TP 4
.B ROOT
Location of ON proto area containing files to be signed.
.SH SEE ALSO
.LP
signit(1ONBLD), elfsign(1)
#!/bin/ksh
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#

#
# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#

#
# signproto cred_file
#
# Utility to find cryptographic modules in the proto area and
# sign them using signit. Since the binaries have already been
# signed (using development keys) during the build process,
# we determine the correct signing credential to use based on
# the existing signature. The cred_file argument contains a
# list of signing server credentials and the corresponding
# regular expressions to match against the file signatures.

# Get absolute path of current directory; used later to invoke signit
cd .
dir=`dirname $0`
dir=`[[ $dir = /* ]] && print $dir || print $PWD/$dir`

findcrypto $1 | $dir/signit -i $ROOT -l ${CODESIGN_USER:-${LOGNAME}}
stat=$?

if [ $stat != 0 ]; then
	echo "ERROR failure in signing operation"
	exit $stat
fi

exit 0