[openssl-commits] [tools] master update
Rich Salz
rsalz at openssl.org
Sat Feb 3 23:24:09 UTC 2018
The branch master has been updated
via 27296557068a17464f17533d89d4fa6f3555b909 (commit)
from bb40e3e6bcd68b3ba9ba4e71751d9f8e630f63cf (commit)
- Log -----------------------------------------------------------------
commit 27296557068a17464f17533d89d4fa6f3555b909
Author: Rich Salz <rsalz at akamai.com>
Date: Sat Feb 3 18:23:50 2018 -0500
Add our release tools
-----------------------------------------------------------------------
Summary of changes:
release-tools/MKRELEASE.md | 168 +++++++++++++++
release-tools/README.md | 320 +++++++++++++++++++++++++++++
release-tools/do-copyright-year | 40 ++++
release-tools/do-release.pl | 209 +++++++++++++++++++
release-tools/mkrelease.pl | 427 +++++++++++++++++++++++++++++++++++++++
release-tools/release-check.pl | 215 ++++++++++++++++++++
release-tools/release-date.pl | 64 ++++++
release-tools/release-git.pl | 164 +++++++++++++++
release-tools/release-update.pl | 153 ++++++++++++++
release-tools/release-version.pl | 179 ++++++++++++++++
10 files changed, 1939 insertions(+)
create mode 100644 release-tools/MKRELEASE.md
create mode 100644 release-tools/README.md
create mode 100755 release-tools/do-copyright-year
create mode 100644 release-tools/do-release.pl
create mode 100644 release-tools/mkrelease.pl
create mode 100644 release-tools/release-check.pl
create mode 100644 release-tools/release-date.pl
create mode 100644 release-tools/release-git.pl
create mode 100644 release-tools/release-update.pl
create mode 100644 release-tools/release-version.pl
diff --git a/release-tools/MKRELEASE.md b/release-tools/MKRELEASE.md
new file mode 100644
index 0000000..04d6dc7
--- /dev/null
+++ b/release-tools/MKRELEASE.md
@@ -0,0 +1,168 @@
+# Documentation on the mkrelease.pl script
+
+This file provides an overview of the mkrelease.pl script, and how to
+configure some of its parameters (by setting environment variables).
+It is normally run by following the process in README.md and should be
+run in a pristine directgory of the branch to be released, which must
+be a stable branch.
+
+The script handles most of the processes involved in making a release
+including:
+
+1. Doing `make update`
+2. Changing version numbers in various files
+3. Tagging release
+4. Making the tarballs, .md5, .sha1, .sha256 and .gpg files
+5. Creating the signed email announcement, including hashes of release
+6. Uploading files to dev.openssl.org
+7. Updating the version for next release
+
+If you plan to make an actual release make sure your GPG key is included
+in the [OMC list](https://www.openssl.org/community/omc.html) on the website
+and in the file doc/fingerprints.txt of *all* active branches.
+
+The script mkrelease.pl calls the files release-check.pl, release-date.pl,
+release-git.pl, release-update.pl and release-version.pl, which are expected
+to all be in the same directory.
+
+You are advised to clone a fresh repository. Unless you specify `--no-clean`
+the release process will run `git clean -x -d -f`
+*WARNING* this will delete ALL untracked files from the current branch.
+
+From the branch directory if you run:
+
+ perl /path/to/mkrelease.pl --reviewer=name
+
+It should perform all of the above steps and commit changes locally. You can
+then sanity check these with `git log` before pushing them to the public repo.
+
+## Environment Variables
+
+- OPENSSL<br>
+ Path to openssl utility to use. Default is `openssl`.
+
+- OPENSSL_TAR<br>
+ The tar command to use when creating the tarball. Default is `tar`.
+
+- OPENSSL_GPG<br>
+ The gpg command to use when signing a tarball or announcement.
+ The default is `gpg` which will use gpg with the default key.
+ If you wish to use a different, key set OPENSSL_GPG to include
+ appropriate options.
+
+- OPENSSL_GPG_TAR<br>
+ Command to use to sign a tarball.
+ The default is: `$OPENSSL_GPG --use-agent -sba`
+
+- OPENSSL_GPG_ANNOUNCE<br>
+ The command to use to sign a tarball.
+ The default is: `$OPENSSL_GPG --use-agent -sta --clearsign`
+
+- OPENSSL_SCP<br>
+ The command to use to upload files.
+ The default is `scp`
+
+- OPENSSL_SCP_HOST<br>
+ The host (and optional username) needed to upload files.
+ The default is `dev.openssl.org`, but you might want to change this to
+ `username at dev.openssl.org`
+
+- OPENSSL_SCP_DIR<br>
+ The directory to upload files to.
+ Normally this wont be changed from the default which is
+ `$OPENSSL_SCP_HOST:~openssl/dist/new`
+ This is a holding area on dev.openssl.org where distributions are uploaded
+ temporarily before being moved to the web and ftp directories.
+
+For local testing, you can do something like this:
+
+ export OPENSSL_SCP=cp
+ export OPENSSL_SCP_DIR="$HOME/testdir"
+
+## Options
+
+- `--revert`<br>
+ Remove all local changes from repository and delete any release tag. This
+ returns the local tree to the same state as before a release attempt was
+ made.
+
+- `--reviewer=name`<br>
+ Add reviewer `name` to list of reviewers in commit message. Any valid
+ name for checking OMC membership will work.
+ This option may be used multiple times; at least one is required.
+
+- `--enter-pre`<br>
+ Instead of making a full release enter pre-release state. This by itself
+ will not produce a release it will just change version numbers and commit
+ the changes. Subsequent releases on this branch will be pre-release
+ versions. This option should NOT be used if the branch is already in
+ pre-release state.
+
+- `--leave-pre`<br>
+ For a branch in pre-release state, leave pre-release and make a full release.
+
+- `--label=label`<br>
+ Add the textual label `label` to the version string, where `label` must be
+ one of `alpha` or `beta`. While in pre-release state a label *must* be
+ provided.
+
+- `--no-upload`<br>
+ Do not attempt to upload release files to dev.openssl.org
+
+- `--no-clean`<br>
+ Do not clean untracked files from directory. Warning: if you use this option
+ you can end up with extraneous files in the distribution tarball.
+
+- `--no-update`<br>
+ Do not perform a `make update`.
+
+- `--verbose`<br>
+ Be more verbose at what is going on
+
+- `--debug`<br>
+ Include debug output to describe all actions in detail
+
+- `--git-info`<br>
+ Just print out details of all git branch information and exit
+
+- `--git-branch-info`<br>
+ Print out details of the currently detected branch and exit
+
+- `--branch-version=version`<br>
+ Use branch `version` instead of the one autodetected for the current branch.
+ This option is not normally needed.
+
+# The do-release script
+
+The do-release.pl script copies distributions from the temporary holding area
+to the http and ftp areas. It it intended to be run as the `openssl` user on
+dev.openssl.org.
+
+It does the following:
+
+1. Copy OpenSSL release files from the holding area to the http and ftp
+ locations: currently /v/openssl/www/source and /v/openssl/ftp/source
+2. Move OpenSSL release files from holding area to ~openssl/dist/old By
+ doing this the script wont try and make a release again with old files.
+3. Mail the release message. This is sent to openssl-dev openssl-users and
+ openssl-announce (it needs to be approved in openssl-announce). The
+ subject line is `OpenSSL version xxx released`.
+
+## do-release options
+
+- `--copy`<br>
+ Copy files to http and ftp directories. **You will have to manually move
+ the OLD files to old/<SUBDIR> directories.**
+
+- `--move`<br>
+ Move files from holding area to ~openssl/dist/old
+
+- `--mail`<br>
+ Send out announcement email: if this option is not given, the command you
+ need to call to send the release mail will be printed out.
+
+- `--full-release`<br>
+ Perform all operations for a release (copy, move and mail).
+
+Note: because several of these options are irreversible they have to be
+explicitly included.
diff --git a/release-tools/README.md b/release-tools/README.md
new file mode 100644
index 0000000..7b3767e
--- /dev/null
+++ b/release-tools/README.md
@@ -0,0 +1,320 @@
+# HOW TO MAKE A RELEASE
+
+This file documents how to make an OpenSSL release. Please fix any
+errors you find while doing, or just after, your next release!
+
+Releases are done by one person, with a second person acting as the
+reviewer and additional tester.
+
+## Pre-requisites
+
+Have a local clone of the website repo:
+
+ openssl-git at git.openssl.org:openssl-web.git
+
+Make sure you can sudo to the openssl user on dev.openssl.org; this is
+usually done by being in the openssl group. For example, ssh to the
+server and run this command:
+
+ sudo -u openssl id
+
+## Setup
+
+The day before the release, freeze the main repository. This locks out
+everyone but the named user, who is doing the release, from doing any pushes.
+Someone other than the person doing the release should run the command.
+For example:
+
+ ssh openssl-git at git.openssl.org freeze openssl NAME
+
+## Making the tarball and announcements
+
+This section generates the tarball and announcements locally. It makes
+no changes which cannot be easily undone. You will have to repeat this
+section for each version being released, so it is often easier to have
+separate copies:
+
+ git clone openssl-git at git.openssl.org:openssl.git rel-102
+ cd rel-102
+ git branch --track OpenSSL_1_0_2-stable origin/OpenSSL_1_0_2-stable
+ git checkout OpenSSL_1_0_2-stable
+
+Make sure that the CHANGES and NEWS files have been updated and reviewed.
+NEWS should contain a summary of any changes for the release, and for a
+security release is (often just a list of the CVEs addressed. You should also
+update NEWS in the master branch to include details of all releases. Just
+update the NEWS bullet points - do not change the release date, keep it as
+**under development**.
+
+Add any security fixes to the tree. Commit them but *do not push*.
+
+Make sure that the copyrights are updated. This script will update
+the copyright markers and commit the changes (where $HERE stands for
+the directory where this README is):
+
+ $HERE/do-copyright-year
+
+Perform the local automated release steps. This can normally be done with:
+
+ perl $HERE/mkrelease.pl --reviewer=NAME
+
+Alternatively, to use the openssl-team PGP key:
+
+ export OPENSSL_GPG_KEYID=8B3D79F5
+ perl $HERE/mkrelease.pl --reviewer=NAME
+
+See $HERE/MKRELEASE.md for details of the options to mkrelease.pl.
+This will leave a handful of files in the parent directory of where
+you extracted the release.
+See below for details of how to do perform this step manually if you want
+to or have to.
+
+Verify that the results of the script are sensible. Check
+the commits the automated release process has performed, using for example
+`git log`. Check the signed announcement RELEASE.asc file. Maybe check
+that the tarball length and hashes match in the .md5, .sha1, and review
+the announcment file. *Do not push* changes to the public repo at this stage.
+
+Both the person doing the release and the reviewer should sanity-check the
+release at this point. Checks to consider include the following:
+
+- Builds and make test passes on multiple plaforms - Linux, Windows, etc.
+- Builds from tarball
+
+Send the auto-generated commits to the reviewer and await their +1.
+Repeat from the begining of this section if you need to release
+multiple versions.
+
+## Website updates
+
+The changes in this section should be made in your copy of the web repo.
+
+Update the news/newsflash.txt file. This normally is one or two lines. Just
+copy and paste existing announcements making minor changes for the date and
+version number as necessary.
+
+Update the news/vulnerabilities.xml file if appropriate.
+
+If there is a Security Advisory then copy it into the news/secadv directory.
+
+Commit your changes, but *do not push* them to the website.
+
+## Publishing the release
+
+*BE CAREFUL* This section makes everything visible and is therefore
+largely irreversible. If you are performing a dry run then DO NOT
+perform any steps in this section.
+
+Check that release has been uploaded properly. The release tarballs and
+associated files should be in ~openssl/dist/new. They should be owned by the
+openssl userid and world-readable.
+
+Copy the tarballs to appropriate directories. This can be
+done using the do-release.pl script. See MKRELEASE.md for a description of
+the options. For example:
+
+ sudo -u openssl perl ~openssl/do-release.pl --copy --move
+
+This will copy the relevant files to the website and move them from
+~openssl/dist/new to ~openssl/dist/old so they will not seen by a subsequent
+release. Alternatively if you want to perform one release at a time or copy/move
+the files manually, see below.
+
+The do-release.pl script will display the commands you will need to issue to
+send the announcement emails later. Keep a note of those commands for future
+reference.
+
+Verify that the tarballs are available via FTP:
+
+ ftp://ftp.openssl.org/source/
+
+And that they are ready for the website:
+
+ ls /var/www/openssl/source
+
+Push your local changes made above to the public repo. You will
+typically want to sanity check this with:
+
+ git push -n
+
+Push new tags to public repo. Again sanity check with:
+
+ git push --tags -n
+
+to make sure no local tags were pushed.
+
+## Updating the website
+
+Push the website changes you made earlier to the OpenSSL website repo. When
+you do this, the website will get updated and a script to flush the Akamai CDN
+cache will be run. You can look at things on www-origin.openssl.org; the
+CDN-hosted www.openssl.org should only be a few minutes delayed.
+
+Verify that the release notes, which are built from the CHANGES file in the
+release, have been updated. This is done automatically by the commit-hook, but
+if you see a problem, try the following steps:
+
+ cd /var/www/openssl
+ sudo -u openssl -H make relupd
+ sudo -u openssl ./bin/purge-one-hour
+
+Wait for a while for the Akamai flush to work (normally within a few minutes).
+Have a look at the website and news announcement at:
+
+ https://www.openssl.org/
+ https://www.openssl.org/news/
+
+Check the download page has updated properly:
+
+ https://www.openssl.org/source/
+
+Check the notes look sensible at:
+
+ https://www.openssl.org/news/news.html
+
+Also check the notes here:
+
+ https://www.openssl.org/news/openssl-1.0.2-notes.html
+ https://www.openssl.org/news/openssl-1.1.0-notes.html
+
+## Send the announcement mail
+
+Send out the announcements. Generic release announcement messages will be
+created automatically by the build script and the commands you need to use to
+send them were displayed when you executed do-release.pl above.
+These should normally be sent from the openssl account. These are sent to
+openssl-users, openssl-project, and openssl-announce.
+
+If do-release.pl was used with `--move` be sure to move the
+announcement text files away from the staging directory after they have been
+sent. This is done as follows (with VERSION replaced with the version of
+OpenSSL to announce):
+
+ sudo -u openssl \
+ mv ~openssl/dist/new/openssl-VERSION.txt.asc ~openssl/dist/old
+
+Send out the Security Advisory if there is one. Copy the file to the
+openssl user home directory, and then do the following
+
+ sudo -u openssl gpg -u 8B3D79F5 --clearsign secadv_FILENAME
+ sudo -u openssl mutt -s "OpenSSL Security Advisory" \
+ openssl-project openssl-users openssl-announce
+ <~openssl/secadv_FILENAME.txt.asc
+
+Approve the openssl-announce email. Go to
+<https://mta.openssl.org/mailman/admindb/openssl-announce>
+and approve the messages.
+The administration password needed for approval is held in /opt/mailman/README
+on mta.openssl.org
+
+Check the mailing list messages have arrived.
+
+## Finish
+
+Unfreeze the repository.
+
+ ssh openssl-git at git.openssl.org unfreeze openssl
+
+If this release includes security fixes with a CVE then you should inform
+MITRE about them. See the instructions at the top of cvepool.txt in bureau.
+
+Check mailing lists over the next few hours for reports of any success
+or failure. If necessary fix these and in the worst case make another
+release.
+
+# MANUAL PROCESS
+
+If for some reason you cannot use, or do not trust, release script
+mkrelease.pl then you can perform the release manually. This is difficult to
+get right so you should avoid it if possible.
+
+Check what the automated release did for previous releases. This is the best
+way to get a feel for what happens. You can do this by checking the commit
+logs before a release tag for example:
+
+ git log --reverse 0d7717f..ebe2219
+
+The first two commits are security fixes. The third commit is (as the log
+message implies) an update of the NEWS file. The next commit which has the
+automated log message "Prepare for 1.0.1g release" includes the steps
+necessary to make the release.
+
+## Manually building the release files
+
+Do a `make update`. If necessary commit. You can push this commit to
+the repo so you have as few local changes as possible. Note that even if
+"make update" does not make any visible changes it can still update timestamps
+on some files which avoid some problems with builds (e.g. if the source files
+are all made read only).
+
+Update NEWS, README and CHANGES. These should contain the date and
+the correct version in the appropriate format.
+
+Update crypto/opensslv.h which contains the version. This contains the
+version number in the appropriate formats. For OPENSSL_VERSION_NUMBER and
+normal (not pre) releases you change the last digit from 0 (meaning -dev)
+to f (meaning release). Change the text forms in OPENSSL_VERSION_TEXT for
+normal and FIPS builds.
+
+Double-check that the version is right. If you mess up the syntax you can end
+up with the wrong release number or worse break compilation.
+
+Commit the changes you made so far, and check that the logs look sensible.
+
+Make a local tag; the public repo requires annotated tags:
+
+ git tag -s -m "OpenSSL 1.0.2L release tag" OpenSSL_1_0_2L
+
+or if you want to use the openssl-team key:
+
+ git tag -u 8B3D79F5 -m "OpenSSL 1.0.2L release tag" OpenSSL_1_0_2L
+
+Make the release tarball. You do this with:
+
+ make dist
+
+Create .sha1, .sha256 and .asc files manually. You can use:
+
+ openssl sha1
+ openssl sha256
+
+Create .sha1, .sha256 and .asc files manually. You can use the openssl sha1 and
+sha256 commands, obviously. Sign the tarball:
+
+ gpg -sba opensslversion.tar.gz
+
+or if you want to use the openssl-team key:
+
+ gpg -u 8B3D79F5 -sba opensslversion.tar.gz
+
+Create an announcement file. You can use an existing one as a
+template for example something in ~openssl/dist/old/ update the version
+numbers, tarball size and hashes. Sign announcement with:
+
+ gpg -sta --clearsign announce.txt
+
+or if you want to use the openssl-team key:
+
+ gpg -u 8B3D79F5 -sta --clearsign announce.txt
+
+Prepare for next development version by updating CHANGES, NEWS, README
+crypto/opensslv.h and openssl.spec. The automated scripts use the comment
+message `Prepare for 1.0.1h-dev`.
+
+Be absolutely *certain* you did not make any mistakes, so check
+several times preferably by different people.
+
+Upload tarballs to dev.openssl.org
+
+## Manually releasing the files
+
+If you do not want to use do-release.pl, you can manually perform
+the steps necessary for the release. This is (fortunately) much simpler
+than the manual release process above.
+
+Copy release files to web source directory. The four files (tarball,
+sha1, .sha256 and .asc) need to be manually copied to /var/www/openssl/source
+Also move any outdated releases to /var/www/openssl/source/old/SUBDIR
+
+Copy files to ftp source directory, /srv/ftp/source.
+Also move any oudated releases to /srv/ftp/source/old/SUBDIR
diff --git a/release-tools/do-copyright-year b/release-tools/do-copyright-year
new file mode 100755
index 0000000..59b9235
--- /dev/null
+++ b/release-tools/do-copyright-year
@@ -0,0 +1,40 @@
+#!/usr/bin/env bash
+#
+# Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+this_year=`date +%Y`
+some_year="[12][0-9][0-9][0-9]"
+year_range="(${some_year})(-${some_year})?"
+
+copyright_owner="The OpenSSL Project"
+copyright="Copyright .*${year_range} .*${copyright_owner}"
+
+# sed_script:
+# for all lines that contain ${copyright} : {
+# replace years yyyy-zzzz (or year yyyy) by yyyy-${this_year}
+# replace repeated years yyyy-yyyy by yyyy
+# }
+ss=/tmp/sed$$
+cat <<EOF >$ss
+/${copyright}/ {
+s|${year_range}|\1-${this_year}|
+s|(${some_year})-\1|\1|
+}
+EOF
+
+NYD=`date +%Y-01-01`
+echo Updating copryight
+git diff-tree -r --name-only `git rev-list -1 --before=$NYD HEAD`..HEAD \
+ | while read FILE ; do
+ sed -E -f /tmp/sed$$ "$FILE" >/tmp/$$
+ mv /tmp/$$ "$FILE"
+ git add "$FILE"
+done
+echo Committing change locally.
+git commit -m 'Update copyright year'
+rm -f $ss
diff --git a/release-tools/do-release.pl b/release-tools/do-release.pl
new file mode 100644
index 0000000..1725055
--- /dev/null
+++ b/release-tools/do-release.pl
@@ -0,0 +1,209 @@
+#! /usr/bin/env perl
+# Copyright 2010-2018 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+use strict;
+use warnings;
+
+my $homedir = glob("~openssl");
+my $tmpdir = $ENV{"OPENSSL_TMP_DIR"} // $homedir . "/dist/new";
+my $olddir = $ENV{"OPENSSL_OLD_DIR"} // $homedir . "/dist/old";
+my $srcdir = $ENV{"OPENSSL_SRC_DIR"} // "/var/www/openssl/source";
+my $ftpdir = $ENV{"OPENSSL_FTP_DIR"} // "/srv/ftp/source";
+my $mail = $ENV{"OPENSSL_MAIL"} // "mutt -s SUBJECT RECIP < BODY";
+
+my $do_mail = 0;
+my $do_copy = 0;
+my $do_move = 0;
+my $mail_only = 0;
+
+foreach (@ARGV) {
+ if (/--tmpdir=(.*)$/) {
+ $tmpdir = $1;
+ } elsif (/^--copy$/) {
+ $do_copy = 1;
+ }
+ elsif (/^--move$/) {
+ $do_move = 1;
+ } elsif (/^--mail$/) {
+ $do_mail = 1;
+ } elsif (/^--mail-only$/) {
+ $mail_only = 1;
+ $do_mail = 1;
+ } elsif (/^--full-release$/) {
+ $do_mail = 1;
+ $do_copy = 1;
+ $do_move = 1;
+ } else {
+ print STDERR "Unknown command line argument $_";
+ exit 1;
+ }
+}
+
+if ( getpwuid($<) ne "openssl" && !exists $ENV{"OPENSSL_RELEASE_TEST"} ) {
+ print "This script must be run as the \"openssl\" user\n";
+ exit 1;
+}
+
+die "Can't find distribution directory $tmpdir" unless -d $tmpdir;
+die "Can't find old distribution directory $olddir" unless -d $olddir;
+die "Can't find source directory $srcdir" unless -d $srcdir;
+die "Can't find ftp directory $ftpdir" unless -d $ftpdir;
+
+my @versions;
+my @series;
+my @files = glob("$tmpdir/*.txt.asc");
+
+foreach (@files) {
+ if (/^.*\/openssl-(\d+\.\d+\.\d+[a-z]*-pre\d+)\..*$/) {
+ push @versions, $1;
+ } elsif (/^.*\/openssl-(\d+\.\d+\.\d+[a-z]*)\..*$/) {
+ push @versions, $1;
+ } else {
+ die "Unexpected filename $_";
+ }
+}
+foreach (@versions) {
+ if (/^(\d+\.\d+\.\d+)[a-z]*$/) {
+ my $serie = $1;
+ push @series, $serie unless grep /^$serie/, @series;
+ }
+}
+die "No distribution in temp directory!" if ( scalar @versions == 0 );
+print "OpenSSL versions to be released:\n";
+foreach (@versions) {
+ print "$_\n";
+}
+print "OK? (y/n)\n";
+$_ = <STDIN>;
+exit 1 unless /^y/i;
+
+my @distfiles;
+my @announce;
+
+foreach (@versions) {
+ push @distfiles, "openssl-$_.tar.gz";
+ push @distfiles, "openssl-$_.tar.gz.sha1";
+ push @distfiles, "openssl-$_.tar.gz.sha256";
+ push @distfiles, "openssl-$_.tar.gz.asc";
+ push @announce, "openssl-$_.txt.asc";
+}
+
+$do_copy = 0 if $mail_only;
+
+my $bad = 0;
+if ($do_copy) {
+ foreach (@distfiles) {
+ if ( !-f "$tmpdir/$_" ) {
+ print STDERR "File $_ not found in temp directory!\n";
+ $bad = 1;
+ }
+ if ( -e "$srcdir/$_" ) {
+ print STDERR "File $_ already present in source directory!\n";
+ $bad = 1;
+ }
+ if ( -e "$ftpdir/$_" ) {
+ print STDERR "File $_ already present in ftp directory!\n";
+ $bad = 1;
+ }
+ if ( -e "$olddir/$_" ) {
+ print STDERR
+ "File $_ already present in old distributions directory!\n";
+ $bad = 1;
+ }
+ }
+}
+
+exit 1 if $bad;
+
+print "Directory sanity check OK\n";
+
+print "Starting release for OpenSSL @versions\n";
+
+if ($do_copy) {
+ foreach (@distfiles) {
+ system("cp $tmpdir/$_ $srcdir/$_");
+ die "Error copying $_ to source directory!" if $?;
+ system("cp $tmpdir/$_ $ftpdir/$_");
+ die "Error copying $_ to ftp directory!" if $?;
+ }
+ print "Copied distributions files to source and ftp directories\n";
+ foreach my $serie (@series) {
+ my $tomove_oldsrc = "$srcdir/old/$serie";
+ my @tomove_src =
+ map {
+ my $x = $_;
+ $x =~ s|.*/||g;
+ grep( /^$x$/, @distfiles ) ? () : $x
+ }
+ grep { -f $_ }
+ glob("$srcdir/openssl-$serie.tar.gz $srcdir/openssl-$serie?.tar.gz");
+ my $tomove_oldftp = "$ftpdir/old/$serie";
+ my @tomove_ftp =
+ map {
+ my $x = $_;
+ $x =~ s|.*/||g;
+ grep( /^$x$/, @distfiles ) ? () : $x
+ }
+ grep { -f $_ }
+ glob("$ftpdir/openssl-$serie.tar.gz $ftpdir/openssl-$serie?.tar.gz");
+
+ mkdir $tomove_oldsrc
+ or die "Couldn't mkdir $tomove_oldsrc : $!"
+ if !-d $tomove_oldsrc;
+ mkdir $tomove_oldftp
+ or die "Couldn't mkdir $tomove_oldftp : $!"
+ if !-d $tomove_oldftp;
+ foreach (@tomove_src) {
+ system("mv $srcdir/$_* $tomove_oldsrc/");
+ die "Error moving $_* to old source directory!" if $?;
+ }
+ foreach (@tomove_ftp) {
+ system("mv $ftpdir/$_* $tomove_oldftp/");
+ die "Error moving $_* to old ftp directory!" if $?;
+ }
+ }
+ print
+ "Moved old distributions files to source/old and ftp/old directories\n";
+}
+else {
+ print "Test mode: no files copied\n";
+}
+
+foreach (@versions) {
+ my $announce = "openssl-$_.txt.asc";
+ my $annversion = $_;
+ $annversion =~ s/-pre(\d+$)/ pre release $1/;
+ my $annmail = $mail;
+ $annmail =~ s/SUBJECT/"OpenSSL version $annversion published"/;
+ $annmail =~ s/RECIP/openssl-project openssl-users openssl-announce/;
+ $annmail =~ s|BODY|$tmpdir/$announce|;
+
+ if ($do_mail) {
+ print "Sending announcement email for OpenSSL $_...\n";
+ system("$annmail");
+ die "Error sending announcement email!" if $?;
+ print "Don't forget to authorise the openssl-announce email.\n";
+ push @distfiles, $announce if $do_move;
+ } else {
+ print "Announcement email not sent automatically\n";
+ print "\nSend announcement mail manually with command:\n\n$annmail\n\n";
+ print
+"When done, move the announcement file away with command:\n\nmv $tmpdir/$announce $olddir/$announce\n\n"
+ if $do_move;
+ }
+}
+
+if ($do_move) {
+ foreach (@distfiles) {
+ rename( "$tmpdir/$_", "$olddir/$_" ) || die "Can't move $_: $!";
+ }
+ print "Moved distribution files to old directory\n";
+}
+
+print "Successful!\n";
+
diff --git a/release-tools/mkrelease.pl b/release-tools/mkrelease.pl
new file mode 100644
index 0000000..4012e4d
--- /dev/null
+++ b/release-tools/mkrelease.pl
@@ -0,0 +1,427 @@
+#! /usr/bin/env perl
+# Copyright 2010-2018 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+# OpenSSL release generation script.
+
+use strict;
+use warnings;
+use File::Basename;
+use lib dirname(__FILE__);
+use Module::Load::Conditional qw(can_load);
+can_load(modules => { 'OpenSSL::Query::DB' => undef });
+use OpenSSL::Query::REST;
+
+require "release-check.pl";
+require "release-date.pl";
+require "release-git.pl";
+require "release-update.pl";
+require "release-version.pl";
+
+our $debug = 0;
+our $verbose = 0;
+my @reviewers;
+my @openssl_branches;
+my $revert;
+my $pre;
+my $info_only;
+my $branch_info_only;
+my $no_clean;
+my $no_update;
+my $no_release;
+my $no_upload;
+my $bversion;
+my $ok;
+my $label;
+
+#Determine include path
+our $includepath;
+if ( -e "crypto/opensslv.h" ) {
+ $includepath = "crypto";
+}
+else {
+ $includepath = "include/openssl";
+}
+
+sub print_git_info {
+ my ( $rinfo, $branch, $s ) = @_;
+ my $version = openssl_git_expected_version( $rinfo, $branch );
+ my $last = openssl_git_last_release( $rinfo, $branch );
+ my $last_full = openssl_git_last_release( $rinfo, $branch, 1, 1 );
+
+ # Auto detect pre release if we haven't forced it.
+ $pre = $version =~ /-pre/ unless defined $pre;
+ my $next = openssl_version_next( $version, $pre );
+
+ print "${s}Branch version: $branch\n";
+ print "${s}Last release: $last\n";
+ print "${s}Last full release: $last_full\n";
+ print "${s}Current version: $version\n";
+ print "${s}Next release: $next\n";
+}
+
+sub print_branch_info {
+ my ($rinfo) = @_;
+ my ( $rtags, $rbranches ) = @$rinfo;
+ print "All Branch details:\n";
+ foreach (@$rbranches) {
+ print "\n";
+ print_git_info( $rinfo, $_, "\t" );
+ }
+ print "\n";
+}
+
+# Initialise git version tables, OMC database.
+my $gitinfo = openssl_git_init();
+my $query = OpenSSL::Query->new();
+
+foreach (@ARGV) {
+ if (/^--git-info$/) {
+ $info_only = 1;
+ } elsif (/^--branch-version=(.*)$/) {
+ $bversion = $1;
+ } elsif (/^--git-branch-info/) {
+ $branch_info_only = 1;
+ } elsif (/^--no-clean/) {
+ $no_clean = 1;
+ } elsif (/^--no-release/) {
+ $no_release = 1;
+ } elsif (/^--no-update/) {
+ $no_update = 1;
+ } elsif (/^--no-upload/) {
+ $no_upload = 1;
+ } elsif (/^--revert/) {
+ $revert = 1;
+ } elsif (/^--leave-pre/) {
+ $pre = 0;
+ } elsif (/^--enter-pre/) {
+ $pre = 1;
+ } elsif (/^--debug/) {
+ $debug = 1;
+ $verbose = 1;
+ } elsif (/^--verbose/) {
+ $verbose = 1;
+ } elsif (/^--reviewer=(.*)$/) {
+ my $r = $1;
+ my $rname = $query->find_person_tag($r, 'rev');
+ die "Unknown reviewer $1" unless $rname;
+ push @reviewers, $rname;
+ } elsif (/^--label=(.*)$/) {
+ $label = $1;
+ if ( $label ne "alpha" && $label ne "beta" ) {
+ die "Invalid label";
+ }
+ } else {
+ print "Uknown option $_\n";
+ exit 1;
+ }
+}
+
+if ($revert) {
+ $_ = openssl_git_current_branch();
+ print "Reverting to repository version for $_\n";
+ system("git reset --hard origin/$_");
+ die "Error reverting!!" if $?;
+ openssl_git_delete_local_tags($_);
+ exit 0;
+}
+
+$bversion = openssl_git_branch_version() unless defined $bversion;
+
+if ($info_only) {
+ print_git_info( $gitinfo, $bversion, "" );
+ exit 0;
+}
+
+if ($branch_info_only) {
+ print_branch_info($gitinfo);
+ exit 0;
+}
+
+die "No reviewer set!" unless @reviewers;
+
+print "Current branch version is $bversion\n";
+
+if ( openssl_git_check_changes() ) {
+ print "ERROR: unstaged changes in current branch!\n";
+ exit 1;
+}
+
+my $expected_version = openssl_git_expected_version( $gitinfo, $bversion );
+
+# If this is first pre release there will be no releases from this branch
+# So set expected version to pre1-dev as we can't detect this from
+# tags.
+
+if ( $expected_version !~ /-pre/ && openssl_check_first_pre() ) {
+ $expected_version =~ s/-dev/-pre1-dev/;
+}
+
+# Auto detect pre release if we haven't forced it.
+$pre = $expected_version =~ /-pre/ unless defined $pre;
+
+if ( !$pre && defined $label ) {
+ die "Not a pre-release but a label has been defined";
+}
+if ( $pre && !defined $label ) {
+ die "This is a pre-release but a label has not been defined";
+}
+
+my $last_version = openssl_git_last_release( $gitinfo, $bversion, 1, 1 );
+my $last_branch_release = openssl_git_last_release( $gitinfo, $bversion, 1 );
+my $next_version = openssl_version_next( $expected_version, $pre );
+
+print "Branch feature version: $bversion\n";
+print "Last release on this branch: $last_branch_release\n";
+print "Current branch version $expected_version\n";
+print "Next release version $next_version\n";
+print "Last full release version $last_version\n";
+
+$ok = openssl_check_all( $expected_version, $last_version );
+
+print "Branch sanity check: " . ( $ok ? "OK" : "NOT OK" ) . "\n";
+
+if ( $ok == 0 ) {
+ print "Sanity check failed, cannot continue\n";
+ exit 1;
+}
+
+if ( !$no_clean ) {
+ print "Cleaning directory\n";
+ system("git clean -x -d -f");
+ die "Error cleaning directory" if $?;
+}
+
+openssl_git_make_update(@reviewers) unless $no_update;
+
+$expected_version = openssl_version_next( $expected_version, $pre );
+
+my $date = openssl_current_date() unless $expected_version =~ /-pre1-dev/;
+
+print "Updating versions to $expected_version\n";
+
+openssl_update_all( $expected_version, $date, $label );
+
+$ok = openssl_check_all( $expected_version, $last_version, $date );
+
+print "Changes sanity check: " . ( $ok ? "OK" : "NOT OK" ) . "\n";
+
+if ( $ok == 0 ) {
+ print "Release sanity check failed, cannot continue\n";
+ exit 1;
+}
+
+print "Committing changes:\n";
+
+# If we changed from -dev to -pre1-dev a dev version is
+# entering pre release. Just commit changes without a release.
+
+if ( $expected_version =~ /pre1-dev/ ) {
+ my $main_version = $expected_version;
+ $main_version =~ s/-pre1-dev//;
+ openssl_git_commit( "OpenSSL $main_version is now in pre release",
+ @reviewers );
+ die "Error comitting changes!" if $?;
+ print "Version set to $expected_version, exiting\n";
+ exit 0;
+}
+
+openssl_git_commit( "Prepare for $expected_version release", @reviewers );
+die "Error comitting release changes!" if $?;
+
+my $tag = "OpenSSL_$expected_version";
+my $tagkey =
+ defined( $ENV{OPENSSL_GPG_KEYID} ) ? " -u $ENV{OPENSSL_GPG_KEYID}" : " -s";
+
+$tag =~ tr/\./_/;
+
+print
+ "Tagging release with tag $tag (you will need to provide a pass phrase)\n";
+
+system("git tag$tagkey -m \"OpenSSL $expected_version release tag\" $tag");
+die "Error tagging release!" if $?;
+
+my $TAR = defined( $ENV{OPENSSL_TAR} ) ? "TAR=$ENV{OPENSSL_TAR}" : "";
+
+if ( !$no_release ) {
+ print "Generating release tarball.\n";
+ my $openssl = $ENV{"OPENSSL"} // "openssl";
+ my $gpgkeyid =
+ defined( $ENV{OPENSSL_GPG_KEYID} ) ? " -u $ENV{OPENSSL_GPG_KEYID}" : "";
+ my $gpg = $ENV{"OPENSSL_GPG"} // "gpg$gpgkeyid";
+ my $gpgtar = $ENV{"OPENSSL_GPG_TAR"} // "$gpg --use-agent -sba";
+ my $gpgann = $ENV{"OPENSSL_GPG_ANNOUNCE"}
+ // "$gpg --use-agent -sta --clearsign";
+ my $tarfile = "openssl-${expected_version}.tar.gz";
+ system("(./config; make $TAR dist) >../$tarfile.log 2>&1");
+ die "Error generating release!" if $?;
+ die "Can't find tarball!!" unless -f "../$tarfile";
+
+ my $length = -s "../$tarfile";
+ print "Creating hash files\n";
+ my $sha1hash = `$openssl sha1 < ../$tarfile`;
+ chomp $sha1hash;
+ $sha1hash =~ s/^.*=\s//;
+ die "invalid hash" unless $sha1hash =~ /[0-9a-f]{20}/;
+ my $sha256hash = `$openssl sha256 < ../$tarfile`;
+ chomp $sha256hash;
+ $sha256hash =~ s/^.*=\s//;
+ die "invalid hash" unless $sha256hash =~ /[0-9a-f]{20}/;
+ open OUT, ">../$tarfile.sha1";
+ print OUT $sha1hash . "\n";
+ close OUT;
+ open OUT, ">../$tarfile.sha256";
+ print OUT $sha256hash . "\n";
+ close OUT;
+ print "Creating PGP signature:\n";
+ unlink("../${tarfile}.asc");
+ system("$gpgtar ../$tarfile");
+ die "Error creating signature" if $?;
+
+ my $anntxt = "../openssl-${expected_version}.txt";
+
+ open OUT, ">$anntxt";
+ if ( $expected_version =~ /-pre/ ) {
+
+ # Note the variable name is the same length as the real
+ # version so the announcement can be made to look pretty.
+ # If we ever go to pre10 it will be one character longer...
+ my $openssl_ver = $expected_version;
+ $openssl_ver =~ s/^(.*)-pre(\d+)$/$1 pre release $2/;
+ my $fvers = $expected_version;
+ $fvers =~ s/-pre\d+//;
+ print OUT <<EOF;
+
+ OpenSSL version $openssl_ver ($label)
+ ===========================================
+
+ OpenSSL - The Open Source toolkit for SSL/TLS
+ https://www.openssl.org/
+
+ OpenSSL $fvers is currently in $label. OpenSSL $openssl_ver has now
+ been made available. For details of changes and known issues see the
+ release notes at:
+
+ https://www.openssl.org/news/openssl-$bversion-notes.html
+
+ Note: This OpenSSL pre-release has been provided for testing ONLY.
+ It should NOT be used for security critical purposes.
+
+ The $label release is available for download via HTTP and FTP from the
+ following master locations (you can find the various FTP mirrors under
+ https://www.openssl.org/source/mirror.html):
+
+ * https://www.openssl.org/source/
+ * ftp://ftp.openssl.org/source/
+
+ The distribution file name is:
+
+ o $tarfile
+ Size: $length
+ SHA1 checksum: $sha1hash
+ SHA256 checksum: $sha256hash
+
+ The checksums were calculated using the following commands:
+
+ openssl sha1 $tarfile
+ openssl sha256 $tarfile
+
+ Please download and check this $label release as soon as possible.
+ To report a bug, open an issue on GitHub:
+
+ ttps://github.com/openssl/openssl/issues
+
+ Please check the release notes and mailing lists to avoid duplicate
+ reports of known issues.
+
+ Yours,
+
+ The OpenSSL Project Team.
+
+EOF
+ } else {
+ # Using $avers so its length is similar to a real version
+ # length so it's easier to make the announcement look pretty.
+ my $avers = $expected_version;
+ print OUT <<EOF;
+
+ OpenSSL version $avers released
+ ===============================
+
+ OpenSSL - The Open Source toolkit for SSL/TLS
+ https://www.openssl.org/
+
+ The OpenSSL project team is pleased to announce the release of
+ version $avers of our open source toolkit for SSL/TLS. For details
+ of changes and known issues see the release notes at:
+
+ https://www.openssl.org/news/openssl-$bversion-notes.html
+
+ OpenSSL $avers is available for download via HTTP and FTP from the
+ following master locations (you can find the various FTP mirrors under
+ https://www.openssl.org/source/mirror.html):
+
+ * https://www.openssl.org/source/
+ * ftp://ftp.openssl.org/source/
+
+ The distribution file name is:
+
+ o $tarfile
+ Size: $length
+ SHA1 checksum: $sha1hash
+ SHA256 checksum: $sha256hash
+
+ The checksums were calculated using the following commands:
+
+ openssl sha1 $tarfile
+ openssl sha256 $tarfile
+
+ Yours,
+
+ The OpenSSL Project Team.
+
+EOF
+
+ }
+
+ close OUT;
+ unlink("${anntxt}.asc");
+ system("$gpgann $anntxt");
+ die "Cannot sign announcement file!" if $?;
+ die "Signature file not found!" unless -f "$anntxt.asc";
+
+ if ( !$no_upload ) {
+ my $scp = $ENV{OPENSSL_SCP} // "scp";
+ my $scphost = $ENV{OPENSSL_SCP_HOST} // "dev.openssl.org";
+ my $scpdir = $ENV{OPENSSL_SCP_DIR} // "$scphost:~openssl/dist/new";
+ print "Uploading release files\n";
+ system(
+"$scp ../$tarfile ../$tarfile.sha1 ../$tarfile.sha256 ../$tarfile.asc $anntxt.asc ${scpdir}"
+ );
+ die "Error uploading release files" if $?;
+ }
+
+}
+
+$last_version = $expected_version unless $pre;
+$expected_version = openssl_version_next( $expected_version, $pre );
+
+print "Updating versions to $expected_version\n";
+
+openssl_update_all($expected_version);
+
+$ok = openssl_check_all( $expected_version, $last_version );
+
+print "Sanity check: " . ( $ok ? "OK" : "NOT OK" ) . "\n";
+
+if ( $ok == 0 ) {
+ print "Sanity check failed, cannot continue\n";
+ exit 1;
+}
+
+openssl_git_commit( "Prepare for $expected_version", @reviewers );
+die "Error comitting release changes!" if $?;
diff --git a/release-tools/release-check.pl b/release-tools/release-check.pl
new file mode 100644
index 0000000..91ee7c0
--- /dev/null
+++ b/release-tools/release-check.pl
@@ -0,0 +1,215 @@
+#! /usr/bin/env perl
+# Copyright 2010-2018 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+use strict;
+
+sub check_str {
+ my ( $message, $expected, $value, $pok ) = @_;
+ die "Bad checkstr values for $message"
+ if !defined $value || !defined $expected;
+ if ( $value ne $expected ) {
+ print
+ "$message: check failed, expecting \"$expected\", got \"$value\"!!\n";
+ $$pok = 0;
+ } elsif ($main::debug) {
+ print "$message: checking \"$value\" against \"$expected\"\n";
+ }
+}
+
+# Check syntax of README file.
+
+sub openssl_check_README {
+ my ( $version, $indate ) = @_;
+ my $ok = 1;
+ my $date = openssl_date($indate);
+ open( IN, "README" ) || die "Can't open README";
+ while (<IN>) {
+ if (/^.*OpenSSL\s+(\S+)\s+(\([[:alpha:]]+\)\s+)?(.*)$/) {
+ check_str( "README version", $version, $1, \$ok );
+ if ( defined $indate ) {
+ check_str( "README date", $date, $3, \$ok );
+ }
+ close IN;
+ return $ok;
+ }
+ }
+ close IN;
+ print STDERR "Invalid syntax in README\n";
+ return 0;
+}
+
+sub openssl_check_NEWS {
+ my ( $version, $prev, $indate ) = @_;
+ my $date = openssl_date( $version =~ /-pre/ ? undef : $indate );
+ my $ok = 1;
+ if ( $date =~ /XXX/ ) {
+ if ( $version =~ /-pre/ ) {
+ $date = "in pre-release";
+ } else {
+ $date = "under development";
+ }
+ }
+ $version =~ s/-dev$//;
+ $version =~ s/-pre.*$//;
+ open( IN, "NEWS" ) || die "Can't open NEWS";
+
+ while (<IN>) {
+ if (
+/^ Major changes between OpenSSL (\S+) and OpenSSL (\S+)\s+\[0?(.*)\]/
+ )
+ {
+ check_str( "NEWS previous version", $prev, $1, \$ok );
+ check_str( "NEWS version", $version, $2, \$ok );
+ check_str( "NEWS date", $date, $3, \$ok );
+ close IN;
+ return $ok;
+ }
+ }
+ close IN;
+ print STDERR "Invalid syntax in NEWS\n";
+ return 0;
+}
+
+sub openssl_check_CHANGES {
+ my ( $version, $prev, $indate ) = @_;
+ my $date = openssl_date( $version =~ /-pre/ ? undef : $indate );
+ my $ok = 1;
+ $version =~ s/-dev$//;
+ $version =~ s/-pre.*$//;
+ open( IN, "CHANGES" ) || die "Can't open CHANGES";
+
+ while (<IN>) {
+ if (/^ Changes between (\S+) and (\S+)\s+\[0?(.*)\]/) {
+ check_str( "CHANGES previous version", $prev, $1, \$ok );
+ check_str( "CHANGES version", $version, $2, \$ok );
+ check_str( "CHANGES date", $date, $3, \$ok );
+ close IN;
+ return $ok;
+ }
+ }
+ close IN;
+ print STDERR "Invalid syntax in CHANGES\n";
+ return 0;
+}
+
+sub openssl_check_version_h {
+ my ( $version, $indate ) = @_;
+ my ( $hex_done, $fips_done, $version_done );
+ my $hexversion = openssl_version_hex($version);
+ my $ok = 1;
+ my $version_fips = $version . "-fips";
+ $version_fips =~ s/-dev-fips/-fips-dev/;
+ my $date = openssl_date($indate);
+ open( IN, "$main::includepath/opensslv.h" ) || die "Can't open opensslv.h";
+
+ while (<IN>) {
+ if (/OPENSSL_VERSION_NUMBER\s+(0x[0-9a-f]+)L/) {
+ check_str( "opensslv.h: HEX version", $hexversion, $1, \$ok );
+ $hex_done = 1;
+ } elsif (
+/OPENSSL_VERSION_TEXT\s+\"OpenSSL (\S*fips\S*)\s+(\([[:alpha:]]+\)\s+)?(.*)\"/
+ )
+ {
+ check_str( "opensslv.h: FIPS version", $version_fips, $1, \$ok );
+ check_str( "opensslv.h: FIPS date", $date, $3, \$ok );
+ $fips_done = 1;
+ } elsif (
+/OPENSSL_VERSION_TEXT\s+\"OpenSSL (\S*)\s+(\([[:alpha:]]+\)\s+)?(.*)\"/
+ )
+ {
+ check_str( "opensslv.h: version", $version, $1, \$ok );
+ check_str( "opensslv.h: date", $date, $3, \$ok );
+ $version_done = 1;
+ }
+ if ( $hex_done && $fips_done && $version_done ) {
+ close IN;
+ return $ok;
+ }
+ }
+ print STDERR "Invalid syntax in opensslv.h\n";
+ close IN;
+ return 0;
+}
+
+sub openssl_check_spec {
+ my ($version) = @_;
+ my $ok = 1;
+ $version =~ s/-dev$//;
+ $version =~ s/-pre.*$//;
+ open( IN, "openssl.spec" ) || die "Can't open openssl.spec";
+ while (<IN>) {
+ if (/^Version:\s+(\S+)$/) {
+ check_str( "openssl.spec version", $version, $1, \$ok );
+ close IN;
+ return $ok;
+ }
+ }
+ close IN;
+ print STDERR "Invalid syntax in README\n";
+ return 0;
+}
+
+sub print_ok {
+ my ( $file, $ok ) = @_;
+ print "File: $file " . ( $ok ? "OK" : "NOT OK!!" ) . "\n"
+ if ($main::verbose);
+}
+
+sub openssl_check_all {
+ my ( $version, $last_version, $date ) = @_;
+
+ my $readme_ok = openssl_check_README( $version, $date );
+
+ print_ok( "README", $readme_ok );
+
+ my $changes_ok = openssl_check_CHANGES( $version, $last_version, $date );
+
+ print_ok( "CHANGES", $changes_ok );
+
+ my $news_ok = openssl_check_NEWS( $version, $last_version, $date );
+
+ print_ok( "NEWS", $news_ok );
+
+ my $v_h_ok = openssl_check_version_h( $version, $date );
+
+ print_ok( "opensslv.h", $v_h_ok );
+
+ # Newer versions don't have openssl.spec
+ my $spec_ok = 1;
+ if ( -f "openssl.spec" ) {
+ $spec_ok = openssl_check_spec($version);
+
+ print_ok( "openssl.spec", $spec_ok );
+ }
+
+ return $readme_ok && $changes_ok && $news_ok && $v_h_ok && $spec_ok;
+}
+
+# If there are no tagged releases for the current version
+# and we are in pre release mode then either we are just entering
+# pre release and the next version will be pre1-dev or we are already
+# at pre1-dev and we need to do a release of pre1.
+# Check opensslv.h to determine which
+
+sub openssl_check_first_pre {
+ open( IN, "$main::includepath/opensslv.h" ) || die "Can't open opensslv.h";
+
+ while (<IN>) {
+ if (/OPENSSL_VERSION_TEXT\s+\"OpenSSL \S*\s+.*\"/) {
+ close IN;
+
+ # Ignore -fips in string
+ s/-fips//;
+ return /pre1-dev/;
+ }
+ }
+ close IN;
+ die "Invalid sysntax in opensslv.h";
+}
+
+return 1;
diff --git a/release-tools/release-date.pl b/release-tools/release-date.pl
new file mode 100644
index 0000000..c5b5c38
--- /dev/null
+++ b/release-tools/release-date.pl
@@ -0,0 +1,64 @@
+#! /usr/bin/env perl
+# Copyright 2010-2018 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+# Return date into a form suitable for the FAQ, version file and
+# CHANGES file entries. Optionally can be passed date in the form
+# mm/dd/yyyy
+
+sub openssl_date {
+ my ($datestr) = @_;
+ my ( $mday, $mon, $year );
+
+ if ( defined $datestr ) {
+ if ( $datestr =~ /(\d+)\/(\d+)\/(\d+)/ ) {
+ $mday = $1;
+ $mon = $2;
+ $year = $3;
+ $mon--;
+ } else {
+ die "Invalid date syntax $datestr, expecting mm/dd/yyyy";
+ }
+ } else {
+ return ( "xx XXX xxxx", undef, undef ) if wantarray;
+ return "xx XXX xxxx";
+ }
+
+ my $mdsuff;
+ if ( $mday % 10 > 0 && $mday % 10 <= 3 && ( $mday < 10 || $mday > 20 ) ) {
+ my @mday_ord = qw(st nd rd);
+ $mdsuff = $mday_ord[ $mday % 10 - 1 ];
+ } else {
+ $mdsuff = "th";
+ }
+
+ my @mnames =
+ qw(January February March April May June July August September October November December);
+
+ my $mname = $mnames[$mon];
+ my $mname_short = substr $mname, 0, 3;
+
+ my $date_ch = sprintf "%d %s %d", $mday, $mname_short, $year;
+ return $date_ch unless wantarray;
+ my $date_ab = sprintf "%s %d%s, %d", $mname_short, $mday, $mdsuff, $year;
+ my $date_full = sprintf "%-9s %2d%s, %d", $mname, $mday, $mdsuff, $year;
+
+ return ( $date_ch, $date_ab, $date_full );
+
+}
+
+# Return current date in dd/mm/yyyy format suitable to passing into
+# openssl_date().
+
+sub openssl_current_date {
+ my ( $mday, $mon, $year ) = (localtime)[ 3 .. 5 ];
+ $year += 1900;
+ $mon++;
+ return "$mday/$mon/$year";
+}
+
+return 1;
diff --git a/release-tools/release-git.pl b/release-tools/release-git.pl
new file mode 100644
index 0000000..2b6ac1a
--- /dev/null
+++ b/release-tools/release-git.pl
@@ -0,0 +1,164 @@
+#! /usr/bin/env perl
+# Copyright 2010-2018 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+use strict;
+use warnings;
+
+# OpenSSL git version utilities.
+
+# Retrieve list of branches and release tags in a reference usable by other
+# functions.
+
+sub openssl_git_init {
+ my @tmpbranches =
+ grep { chomp; s|^\s+origin/OpenSSL_(\w*\d)-stable$|$1|; } `git branch -r`;
+ die "Error retrieving branch details!" if $?;
+
+ # Create initial dev version entry: lowest possible version for
+ # branch which will be accurate if no releases have take place.
+ my @branches;
+ foreach ( sort @tmpbranches ) {
+ tr/_/\./;
+ next if /^0/ && $_ ne "0.9.8";
+ push @branches, $_;
+ }
+
+ # Create list of tags
+ my @rtags = grep { chomp; s/OpenSSL_(\d.*)$/$1/; } `git tag`;
+ die "Error retrieving tag details!" if $?;
+ my @tags;
+ foreach (@rtags) {
+
+ # Skip if tag has - and it isn't pre
+ next if ( /-/ && !/-pre\d+$/ );
+ tr/_/\./;
+ next if /^0/ && !/^0.9.8/;
+ push @tags, $_;
+ }
+ my $aref = [ \@tags, \@branches ];
+ return $aref;
+}
+
+# Return last release number on supplied branch.
+# If $nopre is set, skip pre releases, if $prev set
+# return last release on previous branch if no release
+# on current branch.
+
+sub openssl_git_last_release {
+ my ( $rinfo, $branch, $nopre, $prev ) = @_;
+ my ( $rtag, $rbranch ) = @$rinfo;
+ my $brhex = openssl_version_branch_hex($branch);
+ my $rv = "";
+ my $rvhex = "";
+ foreach (@$rtag) {
+ next if ( $nopre && /-pre/ );
+ my $taghex = openssl_version_hex($_);
+ my $tagbhex = openssl_version_branch_hex($_);
+
+ # Is tag for current branch?
+ if ( $tagbhex ne $brhex ) {
+
+ # Discard if only want current branch or greater
+ # than current branch
+ next if ( !$prev || $tagbhex gt $brhex );
+ }
+
+ # If release is later than last value replace.
+ if ( $taghex gt $rvhex ) {
+ $rv = $_;
+ $rvhex = openssl_version_hex($rv);
+ }
+ }
+ return $rv eq "" ? "none" : $rv;
+}
+
+sub openssl_git_current_branch {
+
+ # Current branch
+ $_ = `git rev-parse --abbrev-ref HEAD`;
+ die "Can't get current branch!" if $?;
+ chomp;
+ return $_;
+}
+
+sub openssl_git_branch_version {
+ ($_) = @_;
+ $_ = openssl_git_current_branch() unless defined $_;
+ die "Unexpected branch name $_" unless s/OpenSSL_//;
+ tr /_/\./;
+ die "Unexpected branch name $_" unless s/-stable$//;
+ return $_;
+}
+
+sub openssl_git_expected_version {
+ my ( $rinfo, $branch ) = @_;
+ $branch = openssl_git_major_version() unless defined $branch;
+ my $rv = openssl_git_last_release( $rinfo, $branch );
+ return $branch .= "-dev" if $rv eq "none";
+ return openssl_version_next($rv);
+}
+
+sub openssl_git_check_changes {
+
+ # For some reason this is unreliable if you use --quiet ...
+ system("git diff --exit-code >/dev/null");
+ return 0 if $? == 0;
+ return 1 if $? == 256;
+ die "Unexpected status $?";
+}
+
+sub openssl_git_make_update {
+ print "Configuring system\n";
+ system("perl Configure gcc >/dev/null 2>&1");
+ die "Error configuring system" if $?;
+
+ print "Doing make update\n";
+ system("make update >/dev/null 2>&1");
+ die "make update error" if $?;
+ if ( openssl_git_check_changes() ) {
+ print "Source modified, committing changes\n";
+ openssl_git_commit( "make update", @_ );
+ die "Error committing update" if $?;
+ } else {
+ print "No changes\n";
+ }
+ system("find . -name Makefile.save -exec rm \\\{\\\} \\\;");
+ die "Error removing Makefile.save files" if $?;
+}
+
+sub openssl_git_delete_local_tags {
+ my ($branch) = @_;
+ $branch =~ s/-stable//;
+ my @tags = grep { chomp; } `git tag -l $branch\*`;
+ my @rtags =
+ grep { chomp; s|^.*refs/tags/||; } `git ls-remote --tags origin`;
+ my %rtaghash;
+ foreach (@rtags) {
+ $rtaghash{$_} = 1;
+ }
+ foreach (@tags) {
+ if ( !defined $rtaghash{$_} ) {
+ print "Deleting local tag $_\n" if $main::verbose;
+ system("git tag -d $_");
+ }
+ }
+}
+
+sub openssl_git_commit {
+ my @args = ( "git", "commit", "-a" );
+ my ( $message, @reviewers ) = @_;
+ $message .= "\n\n";
+ foreach (@reviewers) {
+ $message .= "Reviewed-by: $_\n";
+ }
+ push @args, "-m", "$message";
+ system(@args);
+ die "Error committing update" if $?;
+}
+
+return 1;
diff --git a/release-tools/release-update.pl b/release-tools/release-update.pl
new file mode 100644
index 0000000..a8d5687
--- /dev/null
+++ b/release-tools/release-update.pl
@@ -0,0 +1,153 @@
+#! /usr/bin/env perl
+# Copyright 2010-2018 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+use strict;
+use warnings;
+
+sub openssl_update_file {
+ my $fref = pop @_;
+ my $file = pop @_;
+ my $file_new = $file . ".new";
+ my $finished = 0;
+ open( IN, "$file" ) || die "Can't open $file";
+ open( OUT, ">$file_new" ) || die "Can't open $file_new";
+ while (<IN>) {
+ $finished = &$fref(@_) unless $finished;
+ print OUT;
+ }
+ close IN;
+ close OUT;
+ unlink $file;
+ rename $file_new, $file;
+ print "Updated $file\n" if $main::verbose;
+}
+
+sub openssl_update_README {
+ my ( $version, $indate, $label ) = @_;
+ my $date = openssl_date($indate);
+ my $update = sub {
+ if (/^.*OpenSSL/) {
+ $_ = " OpenSSL $version";
+ $_ .= " $label" if ( defined $label );
+ $_ .= " $date" if ( defined $indate );
+ $_ .= "\n";
+ return 1;
+ }
+ return 0;
+ };
+ openssl_update_file( @_, "README", $update );
+}
+
+sub openssl_update_CHANGES {
+ my ( $version, $indate ) = @_;
+ my $date = openssl_date($indate);
+ $version =~ s/-dev//;
+ my $update = sub {
+ if (/^ Changes between \S+ and (\S+)\s+\[0?(.*)\]/) {
+ my $chversion = $1;
+ my $chdate = $2;
+ if ( defined $indate ) {
+ s/$chdate/$date/;
+ } else {
+ my $newchanges = <<END;
+ Changes between $chversion and $version [xx XXX xxxx]
+
+ *)
+
+END
+ $_ = $newchanges . $_;
+ }
+ return 1;
+ }
+ return 0;
+ };
+ openssl_update_file( @_, "CHANGES", $update );
+}
+
+sub openssl_update_NEWS {
+ my ( $version, $indate ) = @_;
+ my $date;
+ if ( $version =~ /-pre1-dev/ ) {
+ $date = "in pre-release";
+ $indate = "";
+ } elsif ( $version =~ /-pre/ ) {
+ return 1;
+ } else {
+ $date = openssl_date($indate);
+ }
+ $version =~ s/-dev//;
+ my $update = sub {
+ if (
+/^ Major changes between OpenSSL \S+ and OpenSSL (\S+)\s+\[0?(.*)\]/
+ )
+ {
+ my $chversion = $1;
+ my $chdate = $2;
+ if ( defined $indate ) {
+ s/$chdate/$date/;
+ } else {
+ my $newchanges = <<END;
+ Major changes between OpenSSL $chversion and OpenSSL $version [under development]
+
+ o
+
+END
+ $_ = $newchanges . $_;
+ }
+ return 1;
+ }
+ return 0;
+ };
+ openssl_update_file( @_, "NEWS", $update );
+}
+
+sub openssl_update_version_h {
+ my ( $version, $indate, $label ) = @_;
+ my $hexversion = openssl_version_hex($version);
+ my $date = openssl_date($indate);
+ my $version_fips = $version . "-fips";
+ $version_fips =~ s/-dev-fips/-fips-dev/;
+ if ( !defined $label ) {
+ $label = "";
+ }
+ my $update = sub {
+ if (/(#\s*define\s+OPENSSL_VERSION_NUMBER\s+)/) {
+ $_ = "${1}${hexversion}L\n";
+ } elsif (/(#\s*define\s+OPENSSL_VERSION_TEXT\s+).*fips/) {
+ $_ = "${1}\"OpenSSL $version_fips $label $date\"\n";
+ } elsif (/(#\s*define\s+OPENSSL_VERSION_TEXT\s+)/) {
+ $_ = "${1}\"OpenSSL $version $label $date\"\n";
+ }
+ return 0;
+ };
+ openssl_update_file( @_, "$main::includepath/opensslv.h", $update );
+}
+
+sub openssl_update_spec {
+ my ($version) = @_;
+ $version =~ s/-dev$//;
+ my $update = sub {
+ s/^Version:\s+(\S+)$/Version: $version/;
+ };
+ openssl_update_file( @_, "openssl.spec", $update );
+}
+
+sub openssl_update_all {
+ my ( $version, $date, $label ) = @_;
+ my $ispre = $version =~ /-pre/;
+ if ( defined $label ) {
+ $label = "($label)";
+ }
+ openssl_update_version_h( $version, $date, $label );
+ openssl_update_spec($version) if ( !$ispre && -f "openssl.spec" );
+ openssl_update_README( $version, $date, $label );
+ openssl_update_CHANGES( $version, $date ) unless $ispre;
+ openssl_update_NEWS( $version, $date );
+}
+
+return 1;
diff --git a/release-tools/release-version.pl b/release-tools/release-version.pl
new file mode 100644
index 0000000..3e163b0
--- /dev/null
+++ b/release-tools/release-version.pl
@@ -0,0 +1,179 @@
+#! /usr/bin/env perl
+# Copyright 2010-2018 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the OpenSSL license (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+use strict;
+use warnings;
+
+# OpenSSL version utility functions.
+
+# Convert string version to hex format
+# usage is version_hex($version_string, $tag)
+# where "tag" is 1 if the version comes from a git tag.
+# Return version in hex format.
+
+sub openssl_version_hex {
+ my ( $version, $tag ) = @_;
+ my $ov = $version;
+ $tag = $version =~ /_/ unless defined $tag;
+ $version =~ tr/_/\./ if $tag;
+
+ # Separate version string into fields and convert each one.
+
+ if ( !( $version =~ /([\d])\.([\d]+).([\d]+)(.*)$/ ) ) {
+ die "Invalid version syntax \"$version\"";
+ }
+ my $M = $1;
+ my $NN = sprintf "%02x", $2;
+ my $FF = sprintf "%02x", $3;
+ my $rest = $4;
+
+ if ( length $M > 1 || length $NN > 2 || length $FF > 2 ) {
+ die "Invalid version syntax";
+ }
+
+ my ( $PP, $S );
+
+ if ( $rest eq "" ) {
+ $PP = "00";
+ $S = "f";
+ } else {
+ $S = "";
+ if ( $rest =~ s/-dev$// ) {
+ $S = "0";
+ }
+
+ # Note pre release development versions of the form -preX-dev
+ # version is same for pre release and development versions
+ # So check for -preX after we have stripped off any
+ # -dev above.
+ if ( $rest =~ s/-pre([\d]+)$// ) {
+ $S = sprintf "%x", $1;
+ }
+
+ # No -dev or -pre, must be release
+ $S = "f" if $S eq "";
+
+ if ( $rest eq "" ) {
+ $PP = "00";
+ } elsif ( $rest =~ /^z([a-z]$)/ ) {
+ $PP = sprintf "%02x", ord($1) - ord("a") + 26;
+ } elsif ( $rest =~ /(^[a-z]$)/ ) {
+ $PP = sprintf "%02x", ord($1) - ord("a") + 1;
+ } else {
+ die "Invalid version syntax: \"$ov\"";
+ }
+ }
+
+ if ( length $S > 1 || length $PP > 2 ) {
+ die "Invalid version syntax";
+ }
+
+ return "0x$M$NN$FF$PP$S";
+
+}
+
+# Convert hex format to string
+# Usage is version_str($hex_version), returns version as a string.
+
+sub openssl_version_str {
+ my ($hexversion) = @_;
+ my ( $chk, $M, $NN, $FF, $PP, $S ) = unpack "A2AA2A2A2A", $hexversion;
+ die "Bad hex version $hexversion" if $chk ne "0x" || $S eq "";
+ my $version_str = hex($M) . "." . hex($NN) . "." . hex($FF);
+
+ if ( $PP ne "00" ) {
+ my $hex_PP = hex($PP);
+ if ( $hex_PP > 25 ) {
+ $version_str .= "z";
+ $hex_PP -= 25;
+ }
+ $version_str .= chr( $hex_PP + ord("a") - 1 );
+ }
+
+ if ( $S eq "0" ) {
+ $version_str .= "-dev";
+ } elsif ( $S ne "f" ) {
+ $version_str .= "-pre" . hex($S);
+ }
+
+ return $version_str;
+
+}
+
+# Given a hex number work out the next version.
+# Usage is openssl_next_version($version, $pre, $dev)
+# $pre indicates whether we should use pre releases
+# $dev indicates we should use a development version.
+
+sub openssl_version_next {
+ my ( $version, $pre, $dev ) = @_;
+ my $hexversion = openssl_version_hex($version);
+ my ( $chk, $M, $NN, $FF, $PP, $S ) = unpack "A2AA2A2A2A", $hexversion;
+ die "Invalid syntax $version" if $S eq "";
+
+ # If $pre or $dev not set work out what we want.
+ $dev = $version !~ /-dev/ unless defined $dev;
+ $pre = $version =~ /-pre/ unless defined $pre;
+
+ # If we want a release then just need to get rid of "-dev" part.
+ #
+ if ( $dev == 0 ) {
+ die "Expecting a development version!!" if $version !~ /-dev/;
+
+ # NB version number is identical for pre and pre development.
+ # So just strip out "-dev" part.
+ $version =~ s/-dev//;
+
+ # Special case: if we are going from X.Y.Z-dev and using pre releases
+ # next version is X.Y.Z-pre1-dev and this wont be a release,
+ # just changing version numbers for beginning of pre releases.
+ $version .= "-pre1-dev" if $pre && $S eq "0";
+
+ # If moving out of pre release return full release
+ $version =~ s/-pre.*$// unless $pre;
+ return $version;
+ }
+ die "Not expecting a development version!!" if $version =~ /-dev/;
+
+ # If a pre release we need to increment the pre release portion
+ if ( $pre != 0 ) {
+
+ # Hex version can only handle 14 pre releases.
+ die "Can't go past pre release 14!!" if ( $S eq "e" );
+
+ # Must be a pre release or development version.
+ die "Can't go from release to pre release!!" if $S eq "f";
+ $S = sprintf "%x", hex($S) + 1;
+ $hexversion =~ s/.$/$S/;
+ $version = openssl_version_str($hexversion);
+ $version .= "-dev" if $dev;
+ return $version;
+ }
+
+ # If last version pre release and not doing pre releases any more then switch
+ # to full release.
+ return openssl_version_str("0x$M$NN$FF${PP}f") if ( $version =~ /pre/ );
+
+ # Otherwise need to increment letter value if not a pre release.
+ $PP = sprintf "%02x", hex($PP) + 1;
+ die "Invalid letter version!!" if ( length $PP > 2 );
+ return openssl_version_str("0x$M$NN$FF${PP}0");
+}
+
+# Return hex branch version belongs to.
+# So "1.0.1a-pre2-dev" returns hex of "1.0.1" for example.
+
+sub openssl_version_branch_hex {
+ my ($version) = @_;
+ my $hexversion = openssl_version_hex($version);
+ my ( $chk, $M, $NN, $FF, $PP, $S ) = unpack "A2AA2A2A2A", $hexversion;
+ die "Invalid syntax $version" if $S eq "";
+ return "0x$M$NN${FF}00F";
+}
+
+return 1;
More information about the openssl-commits
mailing list