#! /usr/bin/tclsh8.5 ### -*-tcl-*- ### ### Insert a certificate request into the database. ### ### (c) 2011 Mark Wooding ### ###----- Licensing notice --------------------------------------------------- ### ### This program is free software; you can redistribute it and/or modify ### it under the terms of the GNU General Public License as published by ### the Free Software Foundation; either version 2 of the License, or ### (at your option) any later version. ### ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software Foundation, ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ## Find the common utilities. source [file join [file dirname $argv0] "../lib/func.tcl"] ## Parse the command line. set O(replace) false set usage "usage: $argv0 \[-replace\] PROFILE TAG FILE" for {set i 0} {$i < [llength $argv]} {incr i} { switch -glob -- [lindex $argv $i] { "-replace" { set O(replace) true } "--" { incr i break } "-*" { puts stderr $usage exit 1 } default { break } } } set args [lrange $argv $i end] if {[llength $args] != 3} { puts stderr $usage exit 1 } lassign $args profile tag file ## Open the database. sqlite3 db "$CERTROOT/state/ca.db" ## Do most of the work in a transaction. db transaction { with-cleanup { ## Check whether this tag is already taken. if {!$O(replace) && [db exists { SELECT 1 FROM request WHERE tag = $tag AND st = 'active'; }]} { error "request `$tag' already active" } ## Check whether the profile exists. if {![db exists { SELECT 1 FROM profile WHERE label = $profile AND tombstone = 0; }]} { error "unknown profile `$profile'" } ## Copy the file away. fresh-temp "$CERTROOT/tmp" tmp { exec openssl req -text -in $file -out $tmp } cleanup { file delete $tmp } ## Get lots of information about the request. set dn [req-dn $tmp] set hash [req-key-hash $tmp] ## Get an id number for the new request. db eval { UPDATE meta SET request_seq = request_seq + 1; } set id [db eval { SELECT request_seq FROM meta; }] ## Insert the new record into the request table. db eval { UPDATE request SET st = 'withdrawn' WHERE tag = $tag AND st = 'active'; INSERT INTO request(id, tag, dn, hash, st, profile) VALUES ($id, $tag, $dn, @hash, 'active', $profile); } ## Link the file into the right place. file link -hard "$CERTROOT/req/by-id/$id" $tmp exec ln -sf "../by-id/$id" "$CERTROOT/req/active/$tag" } ## Issue a shiny new certificate. issue-cert $id [now] } ## Publish any necessary changes. update-hook