Skip to content

Commit 2476332

Browse files
authored
Comply with optional password in scala-cli-signing (#1982)
* Comply with scala-cli-signing using optional passwords * Make private key signing stable * NIT: Remove extra fromRoot clauses
1 parent f8c9930 commit 2476332

File tree

10 files changed

+254
-172
lines changed

10 files changed

+254
-172
lines changed

modules/cli/src/main/scala/scala/cli/commands/config/Config.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ object Config extends ScalaCommand[ConfigOptions] {
7474
val (pgpPublic, pgpSecret0) =
7575
ThrowawayPgpSecret.pgpSecret(
7676
mail,
77-
password,
77+
Some(password),
7878
logger,
7979
coursierCache,
8080
() =>

modules/cli/src/main/scala/scala/cli/commands/config/ThrowawayPgpSecret.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ object ThrowawayPgpSecret {
3030
}
3131
def pgpSecret(
3232
mail: String,
33-
password: Secret[String],
33+
password: Option[Secret[String]],
3434
logger: Logger,
3535
cache: FileCache[Task],
3636
javaCommand: () => String,
@@ -46,7 +46,7 @@ object ThrowawayPgpSecret {
4646
secKey.toString,
4747
mail,
4848
logger.verbosity <= 0,
49-
password.value,
49+
password.map(_.value),
5050
cache,
5151
logger,
5252
javaCommand,

modules/cli/src/main/scala/scala/cli/commands/pgp/PgpProxy.scala

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,34 @@ class PgpProxy {
1515
secKey: String,
1616
mail: String,
1717
quiet: Boolean,
18-
password: String,
18+
passwordOpt: Option[String],
1919
cache: FileCache[Task],
2020
logger: Logger,
2121
javaCommand: () => String,
2222
signingCliOptions: bo.ScalaSigningCliOptions
2323
): Either[BuildException, Int] = {
24+
25+
val (passwordOption, extraEnv) = passwordOpt match
26+
case Some(value) =>
27+
(
28+
Seq("--password", s"env:SCALA_CLI_RANDOM_KEY_PASSWORD"),
29+
Map("SCALA_CLI_RANDOM_KEY_PASSWORD" -> value)
30+
)
31+
case None => (Nil, Map.empty)
2432
val quietOptions = Nil
2533
(new PgpCreateExternal).tryRun(
2634
cache,
2735
Seq(
2836
"pgp",
2937
"create",
3038
"--pub-dest",
31-
pubKey.toString,
39+
pubKey,
3240
"--secret-dest",
33-
secKey.toString,
41+
secKey,
3442
"--email",
35-
mail,
36-
"--password",
37-
s"env:SCALA_CLI_RANDOM_KEY_PASSWORD"
38-
) ++ quietOptions,
39-
Map("SCALA_CLI_RANDOM_KEY_PASSWORD" -> password),
43+
mail
44+
) ++ passwordOption ++ quietOptions,
45+
extraEnv,
4046
logger,
4147
allowExecve = false,
4248
javaCommand,

modules/cli/src/main/scala/scala/cli/commands/pgp/PgpProxyJvm.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,19 @@ class PgpProxyJvm extends PgpProxy {
1818
secKey: String,
1919
mail: String,
2020
quiet: Boolean,
21-
password: String,
21+
passwordOpt: Option[String],
2222
cache: FileCache[Task],
2323
logger: Logger,
2424
javaCommand: () => String,
2525
signingCliOptions: bo.ScalaSigningCliOptions
2626
): Either[BuildException, Int] = {
2727

28+
val password = passwordOpt.map(password => PasswordOption.Value(Secret(password)))
29+
2830
PgpCreate.tryRun(
2931
PgpCreateOptions(
3032
email = mail,
31-
password = PasswordOption.Value(Secret(password)),
33+
password = password,
3234
pubDest = Some(pubKey),
3335
secretDest = Some(secKey),
3436
quiet = quiet

modules/cli/src/main/scala/scala/cli/commands/publish/Publish.scala

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -876,9 +876,6 @@ object Publish extends ScalaCommand[PublishOptions] with BuildCommandHelpers {
876876
}
877877
}
878878

879-
if (secretKeyPasswordOpt.isEmpty)
880-
logger.diagnostic("PGP signing with no password is not recommended since it's not stable")
881-
882879
if (forceSigningBinary)
883880
(new scala.cli.internal.BouncycastleSignerMakerSubst).get(
884881
secretKeyPasswordOpt.fold(null)(_.toCliSigning),

modules/cli/src/main/scala/scala/cli/commands/publish/checks/PgpSecretKeyCheck.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ final case class PgpSecretKeyCheck(
198198
val (pgpPublic, pgpSecret0) = value {
199199
ThrowawayPgpSecret.pgpSecret(
200200
value(maybeMail),
201-
passwordSecret,
201+
Some(passwordSecret),
202202
logger,
203203
coursierCache,
204204
value(javaCommand),

modules/cli/src/main/scala/scala/cli/publish/BouncycastleSignerMaker.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class BouncycastleSignerMaker {
1919
): Signer =
2020
BouncycastleSigner(
2121
secretKey.getBytes(),
22-
Option(passwordOrNull).fold(Secret(""))(_.get())
22+
Option(passwordOrNull).map(_.get())
2323
)
2424
def maybeInit(): Unit =
2525
Security.addProvider(new BouncyCastleProvider)

modules/integration/src/test/scala/scala/cli/integration/PgpTests.scala

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,82 @@ class PgpTests extends ScalaCliSuite {
9494
}
9595
}
9696

97+
test("pgp create") {
98+
pubKeyInputs.fromRoot { root =>
99+
os.proc(
100+
TestUtil.cli,
101+
"--power",
102+
"pgp",
103+
"create",
104+
"--email",
105+
"test@test.com",
106+
"--password",
107+
"value:1234",
108+
"--dest",
109+
"new_key"
110+
)
111+
.call(cwd = root, stdin = os.Inherit, stdout = os.Inherit)
112+
113+
val tmpFile = root / "test-file"
114+
val tmpFileAsc = root / "test-file.asc"
115+
os.write(tmpFile, "Hello")
116+
117+
os.proc(
118+
TestUtil.cli,
119+
"--power",
120+
"pgp",
121+
"sign",
122+
"--password",
123+
"value:1234",
124+
"--secret-key",
125+
"file:new_key.skr",
126+
tmpFile
127+
)
128+
.call(cwd = root, stdin = os.Inherit, stdout = os.Inherit)
129+
130+
val verifyProc =
131+
os.proc(TestUtil.cli, "--power", "pgp", "verify", "--key", "new_key.pub", tmpFileAsc)
132+
.call(cwd = root, mergeErrIntoOut = true)
133+
134+
expect(verifyProc.out.text().contains(s"$tmpFileAsc: valid signature"))
135+
}
136+
}
137+
138+
test("pgp create no password") {
139+
pubKeyInputs.fromRoot { root =>
140+
os.proc(
141+
TestUtil.cli,
142+
"--power",
143+
"pgp",
144+
"create",
145+
"--email",
146+
"test@test.com",
147+
"--dest",
148+
"new_key"
149+
)
150+
.call(cwd = root, stdin = os.Inherit, stdout = os.Inherit)
151+
152+
val tmpFile = root / "test-file"
153+
val tmpFileAsc = root / "test-file.asc"
154+
os.write(tmpFile, "Hello")
155+
156+
os.proc(
157+
TestUtil.cli,
158+
"--power",
159+
"pgp",
160+
"sign",
161+
"--secret-key",
162+
"file:new_key.skr",
163+
tmpFile
164+
)
165+
.call(cwd = root, stdin = os.Inherit, stdout = os.Inherit)
166+
167+
val verifyProc =
168+
os.proc(TestUtil.cli, "--power", "pgp", "verify", "--key", "new_key.pub", tmpFileAsc)
169+
.call(cwd = root, mergeErrIntoOut = true)
170+
171+
expect(verifyProc.out.text().contains(s"$tmpFileAsc: valid signature"))
172+
}
173+
}
174+
97175
}

0 commit comments

Comments
 (0)